From 030d2dd450a628b7a8e31e980af3d05854f68edb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Jan 2010 14:59:56 -0700 Subject: mtd: Update ep93xx/ts72xx to use generic platform nand driver Update the ts72xx platform's nand driver support. This changes the ts72xx platform from using a custom nand driver (ts7250.c) to the generic platform nand driver (plat_nand.c). Tested on TS-7250 with 32MiB NAND. Signed-off-by: H Hartley Sweeten Tested-by: Matthieu Crapet Cc: Jesse Off Signed-off-by: David Woodhouse --- arch/arm/mach-ep93xx/ts72xx.c | 188 +++++++++++++++++++++++++++++------------- 1 file changed, 131 insertions(+), 57 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 259f7822ba52..47a86f07831d 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -10,12 +10,16 @@ * your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include #include #include #include +#include +#include #include #include @@ -54,92 +58,162 @@ static struct map_desc ts72xx_io_desc[] __initdata = { } }; -static struct map_desc ts72xx_nand_io_desc[] __initdata = { - { - .virtual = TS72XX_NAND_DATA_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_DATA_PHYS_BASE), - .length = TS72XX_NAND_DATA_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_CONTROL_PHYS_BASE), - .length = TS72XX_NAND_CONTROL_SIZE, - .type = MT_DEVICE, - }, { - .virtual = TS72XX_NAND_BUSY_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND1_BUSY_PHYS_BASE), - .length = TS72XX_NAND_BUSY_SIZE, - .type = MT_DEVICE, +static void __init ts72xx_map_io(void) +{ + ep93xx_map_io(); + iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc)); +} + + +/************************************************************************* + * NAND flash + *************************************************************************/ +#define TS72XX_NAND_CONTROL_ADDR_LINE 22 /* 0xN0400000 */ +#define TS72XX_NAND_BUSY_ADDR_LINE 23 /* 0xN0800000 */ + +static void ts72xx_nand_hwcontrol(struct mtd_info *mtd, + int cmd, unsigned int ctrl) +{ + struct nand_chip *chip = mtd->priv; + + if (ctrl & NAND_CTRL_CHANGE) { + void __iomem *addr = chip->IO_ADDR_R; + unsigned char bits; + + addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE); + + bits = __raw_readb(addr) & ~0x07; + bits |= (ctrl & NAND_NCE) << 2; /* bit 0 -> bit 2 */ + bits |= (ctrl & NAND_CLE); /* bit 1 -> bit 1 */ + bits |= (ctrl & NAND_ALE) >> 2; /* bit 2 -> bit 0 */ + + __raw_writeb(bits, addr); } -}; -static struct map_desc ts72xx_alternate_nand_io_desc[] __initdata = { + if (cmd != NAND_CMD_NONE) + __raw_writeb(cmd, chip->IO_ADDR_W); +} + +static int ts72xx_nand_device_ready(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + void __iomem *addr = chip->IO_ADDR_R; + + addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE); + + return !!(__raw_readb(addr) & 0x20); +} + +static const char *ts72xx_nand_part_probes[] = { "cmdlinepart", NULL }; + +#define TS72XX_BOOTROM_PART_SIZE (SZ_16K) +#define TS72XX_REDBOOT_PART_SIZE (SZ_2M + SZ_1M) + +static struct mtd_partition ts72xx_nand_parts[] = { { - .virtual = TS72XX_NAND_DATA_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND2_DATA_PHYS_BASE), - .length = TS72XX_NAND_DATA_SIZE, - .type = MT_DEVICE, + .name = "TS-BOOTROM", + .offset = 0, + .size = TS72XX_BOOTROM_PART_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { - .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND2_CONTROL_PHYS_BASE), - .length = TS72XX_NAND_CONTROL_SIZE, - .type = MT_DEVICE, + .name = "Linux", + .offset = MTDPART_OFS_APPEND, + .size = 0, /* filled in later */ }, { - .virtual = TS72XX_NAND_BUSY_VIRT_BASE, - .pfn = __phys_to_pfn(TS72XX_NAND2_BUSY_PHYS_BASE), - .length = TS72XX_NAND_BUSY_SIZE, - .type = MT_DEVICE, - } + .name = "RedBoot", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, }; -static void __init ts72xx_map_io(void) +static void ts72xx_nand_set_parts(uint64_t size, + struct platform_nand_chip *chip) { - ep93xx_map_io(); - iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc)); + /* Factory TS-72xx boards only come with 32MiB or 128MiB NAND options */ + if (size == SZ_32M || size == SZ_128M) { + /* Set the "Linux" partition size */ + ts72xx_nand_parts[1].size = size - TS72XX_REDBOOT_PART_SIZE; - /* - * The TS-7200 has NOR flash, the other models have NAND flash. - */ - if (!board_is_ts7200()) { - if (is_ts9420_installed()) { - iotable_init(ts72xx_alternate_nand_io_desc, - ARRAY_SIZE(ts72xx_alternate_nand_io_desc)); - } else { - iotable_init(ts72xx_nand_io_desc, - ARRAY_SIZE(ts72xx_nand_io_desc)); - } + chip->partitions = ts72xx_nand_parts; + chip->nr_partitions = ARRAY_SIZE(ts72xx_nand_parts); + } else { + pr_warning("Unknown nand disk size:%lluMiB\n", size >> 20); } } +static struct platform_nand_data ts72xx_nand_data = { + .chip = { + .nr_chips = 1, + .chip_offset = 0, + .chip_delay = 15, + .part_probe_types = ts72xx_nand_part_probes, + .set_parts = ts72xx_nand_set_parts, + }, + .ctrl = { + .cmd_ctrl = ts72xx_nand_hwcontrol, + .dev_ready = ts72xx_nand_device_ready, + }, +}; + +static struct resource ts72xx_nand_resource[] = { + { + .start = 0, /* filled in later */ + .end = 0, /* filled in later */ + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device ts72xx_nand_flash = { + .name = "gen_nand", + .id = -1, + .dev.platform_data = &ts72xx_nand_data, + .resource = ts72xx_nand_resource, + .num_resources = ARRAY_SIZE(ts72xx_nand_resource), +}; + + /************************************************************************* * NOR flash (TS-7200 only) *************************************************************************/ -static struct physmap_flash_data ts72xx_flash_data = { +static struct physmap_flash_data ts72xx_nor_data = { .width = 2, }; -static struct resource ts72xx_flash_resource = { +static struct resource ts72xx_nor_resource = { .start = EP93XX_CS6_PHYS_BASE, .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1, .flags = IORESOURCE_MEM, }; -static struct platform_device ts72xx_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ts72xx_flash_data, - }, - .num_resources = 1, - .resource = &ts72xx_flash_resource, +static struct platform_device ts72xx_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev.platform_data = &ts72xx_nor_data, + .resource = &ts72xx_nor_resource, + .num_resources = 1, }; static void __init ts72xx_register_flash(void) { - if (board_is_ts7200()) - platform_device_register(&ts72xx_flash); + if (board_is_ts7200()) { + platform_device_register(&ts72xx_nor_flash); + } else { + resource_size_t start; + + if (is_ts9420_installed()) + start = EP93XX_CS7_PHYS_BASE; + else + start = EP93XX_CS6_PHYS_BASE; + + ts72xx_nand_resource[0].start = start; + ts72xx_nand_resource[0].end = start + SZ_16M - 1; + + platform_device_register(&ts72xx_nand_flash); + } } + static unsigned char ts72xx_rtc_readbyte(unsigned long addr) { __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); -- cgit v1.2.3-59-g8ed1b From 7603757993e7ce3e63b2280ccf61d8058b7b2414 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 5 Jan 2010 14:59:58 -0700 Subject: mtd: Remove now-defunct ts7250 nand driver The ts72xx platform has been updated to use the generic platform nand driver (plat_nand.c). This removes the now-defunct ts7250.c nand driver. Signed-off-by: H Hartley Sweeten Cc: Matthieu Crapet Cc: Jesse Off Signed-off-by: David Woodhouse --- arch/arm/mach-ep93xx/include/mach/ts72xx.h | 19 --- drivers/mtd/nand/Kconfig | 6 - drivers/mtd/nand/Makefile | 1 - drivers/mtd/nand/ts7250.c | 207 ----------------------------- 4 files changed, 233 deletions(-) delete mode 100644 drivers/mtd/nand/ts7250.c (limited to 'arch') diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h index 3bd934e9a7f1..61c0e132c63e 100644 --- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h +++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h @@ -9,9 +9,6 @@ * febff000 22000000 4K model number register * febfe000 22400000 4K options register * febfd000 22800000 4K options register #2 - * febfc000 [67]0000000 4K NAND data register - * febfb000 [67]0400000 4K NAND control register - * febfa000 [67]0800000 4K NAND busy register * febf9000 10800000 4K TS-5620 RTC index register * febf8000 11700000 4K TS-5620 RTC data register */ @@ -41,22 +38,6 @@ #define TS72XX_OPTIONS2_TS9420_BOOT 0x02 -#define TS72XX_NAND1_DATA_PHYS_BASE 0x60000000 -#define TS72XX_NAND2_DATA_PHYS_BASE 0x70000000 -#define TS72XX_NAND_DATA_VIRT_BASE 0xfebfc000 -#define TS72XX_NAND_DATA_SIZE 0x00001000 - -#define TS72XX_NAND1_CONTROL_PHYS_BASE 0x60400000 -#define TS72XX_NAND2_CONTROL_PHYS_BASE 0x70400000 -#define TS72XX_NAND_CONTROL_VIRT_BASE 0xfebfb000 -#define TS72XX_NAND_CONTROL_SIZE 0x00001000 - -#define TS72XX_NAND1_BUSY_PHYS_BASE 0x60800000 -#define TS72XX_NAND2_BUSY_PHYS_BASE 0x70800000 -#define TS72XX_NAND_BUSY_VIRT_BASE 0xfebfa000 -#define TS72XX_NAND_BUSY_SIZE 0x00001000 - - #define TS72XX_RTC_INDEX_VIRT_BASE 0xfebf9000 #define TS72XX_RTC_INDEX_PHYS_BASE 0x10800000 #define TS72XX_RTC_INDEX_SIZE 0x00001000 diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 2dcbccb50da7..318ef2f2194f 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -95,12 +95,6 @@ config MTD_NAND_OMAP_PREFETCH_DMA or in DMA interrupt mode. Say y for DMA mode or MPU mode will be used -config MTD_NAND_TS7250 - tristate "NAND Flash device on TS-7250 board" - depends on MACH_TS72XX - help - Support for NAND flash on Technologic Systems TS-7250 platform. - config MTD_NAND_IDS tristate diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index bba5addadb95..355786846bc9 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o obj-$(CONFIG_MTD_NAND_H1900) += h1910.o obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o -obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c deleted file mode 100644 index 0f5562aeedc1..000000000000 --- a/drivers/mtd/nand/ts7250.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * drivers/mtd/nand/ts7250.c - * - * Copyright (C) 2004 Technologic Systems (support@embeddedARM.com) - * - * Derived from drivers/mtd/nand/edb7312.c - * Copyright (C) 2004 Marius Gröger (mag@sysgo.de) - * - * Derived from drivers/mtd/nand/autcpu12.c - * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) - * - * 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. - * - * Overview: - * This is a device driver for the NAND flash device found on the - * TS-7250 board which utilizes a Samsung 32 Mbyte part. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -/* - * MTD structure for TS7250 board - */ -static struct mtd_info *ts7250_mtd = NULL; - -#ifdef CONFIG_MTD_PARTITIONS -static const char *part_probes[] = { "cmdlinepart", NULL }; - -#define NUM_PARTITIONS 3 - -/* - * Define static partitions for flash device - */ -static struct mtd_partition partition_info32[] = { - { - .name = "TS-BOOTROM", - .offset = 0x00000000, - .size = 0x00004000, - }, { - .name = "Linux", - .offset = 0x00004000, - .size = 0x01d00000, - }, { - .name = "RedBoot", - .offset = 0x01d04000, - .size = 0x002fc000, - }, -}; - -/* - * Define static partitions for flash device - */ -static struct mtd_partition partition_info128[] = { - { - .name = "TS-BOOTROM", - .offset = 0x00000000, - .size = 0x00004000, - }, { - .name = "Linux", - .offset = 0x00004000, - .size = 0x07d00000, - }, { - .name = "RedBoot", - .offset = 0x07d04000, - .size = 0x002fc000, - }, -}; -#endif - - -/* - * hardware specific access to control-lines - * - * ctrl: - * NAND_NCE: bit 0 -> bit 2 - * NAND_CLE: bit 1 -> bit 1 - * NAND_ALE: bit 2 -> bit 0 - */ -static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ - struct nand_chip *chip = mtd->priv; - - if (ctrl & NAND_CTRL_CHANGE) { - unsigned long addr = TS72XX_NAND_CONTROL_VIRT_BASE; - unsigned char bits; - - bits = (ctrl & NAND_NCE) << 2; - bits |= ctrl & NAND_CLE; - bits |= (ctrl & NAND_ALE) >> 2; - - __raw_writeb((__raw_readb(addr) & ~0x7) | bits, addr); - } - - if (cmd != NAND_CMD_NONE) - writeb(cmd, chip->IO_ADDR_W); -} - -/* - * read device ready pin - */ -static int ts7250_device_ready(struct mtd_info *mtd) -{ - return __raw_readb(TS72XX_NAND_BUSY_VIRT_BASE) & 0x20; -} - -/* - * Main initialization routine - */ -static int __init ts7250_init(void) -{ - struct nand_chip *this; - const char *part_type = 0; - int mtd_parts_nb = 0; - struct mtd_partition *mtd_parts = 0; - - if (!machine_is_ts72xx() || board_is_ts7200()) - return -ENXIO; - - /* Allocate memory for MTD device structure and private data */ - ts7250_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); - if (!ts7250_mtd) { - printk("Unable to allocate TS7250 NAND MTD device structure.\n"); - return -ENOMEM; - } - - /* Get pointer to private data */ - this = (struct nand_chip *)(&ts7250_mtd[1]); - - /* Initialize structures */ - memset(ts7250_mtd, 0, sizeof(struct mtd_info)); - memset(this, 0, sizeof(struct nand_chip)); - - /* Link the private data with the MTD structure */ - ts7250_mtd->priv = this; - ts7250_mtd->owner = THIS_MODULE; - - /* insert callbacks */ - this->IO_ADDR_R = (void *)TS72XX_NAND_DATA_VIRT_BASE; - this->IO_ADDR_W = (void *)TS72XX_NAND_DATA_VIRT_BASE; - this->cmd_ctrl = ts7250_hwcontrol; - this->dev_ready = ts7250_device_ready; - this->chip_delay = 15; - this->ecc.mode = NAND_ECC_SOFT; - - printk("Searching for NAND flash...\n"); - /* Scan to find existence of the device */ - if (nand_scan(ts7250_mtd, 1)) { - kfree(ts7250_mtd); - return -ENXIO; - } -#ifdef CONFIG_MTD_PARTITIONS - ts7250_mtd->name = "ts7250-nand"; - mtd_parts_nb = parse_mtd_partitions(ts7250_mtd, part_probes, &mtd_parts, 0); - if (mtd_parts_nb > 0) - part_type = "command line"; - else - mtd_parts_nb = 0; -#endif - if (mtd_parts_nb == 0) { - mtd_parts = partition_info32; - if (ts7250_mtd->size >= (128 * 0x100000)) - mtd_parts = partition_info128; - mtd_parts_nb = NUM_PARTITIONS; - part_type = "static"; - } - - /* Register the partitions */ - printk(KERN_NOTICE "Using %s partition definition\n", part_type); - add_mtd_partitions(ts7250_mtd, mtd_parts, mtd_parts_nb); - - /* Return happy */ - return 0; -} - -module_init(ts7250_init); - -/* - * Clean up routine - */ -static void __exit ts7250_cleanup(void) -{ - /* Unregister the device */ - del_mtd_device(ts7250_mtd); - - /* Free the MTD device structure */ - kfree(ts7250_mtd); -} - -module_exit(ts7250_cleanup); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jesse Off "); -MODULE_DESCRIPTION("MTD map driver for Technologic Systems TS-7250 board"); -- cgit v1.2.3-59-g8ed1b From be5a0c126ad1dea2128dc5aef12c87083518d1ab Mon Sep 17 00:00:00 2001 From: "venkatesh.pallipadi@intel.com" Date: Wed, 10 Feb 2010 11:57:06 -0800 Subject: x86, pat: Preparatory changes in pat.c for bigger rbtree change Minor changes in pat.c to cleanup code and make it smoother to introduce bigger rbtree only change in the following patch. The changes are cleaup only and should not have any functional impact. Signed-off-by: Venkatesh Pallipadi LKML-Reference: <20100210195909.792781000@intel.com> Signed-off-by: Suresh Siddha Signed-off-by: H. Peter Anvin --- arch/x86/mm/pat.c | 170 +++++++++++++++++++++++---------------------- arch/x86/mm/pat_internal.h | 28 ++++++++ 2 files changed, 116 insertions(+), 82 deletions(-) create mode 100644 arch/x86/mm/pat_internal.h (limited to 'arch') diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index ae9648eb1c7f..628e507b7936 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -30,6 +30,8 @@ #include #include +#include "pat_internal.h" + #ifdef CONFIG_X86_PAT int __read_mostly pat_enabled = 1; @@ -53,19 +55,15 @@ static inline void pat_disable(const char *reason) #endif -static int debug_enable; +int pat_debug_enable; static int __init pat_debug_setup(char *str) { - debug_enable = 1; + pat_debug_enable = 1; return 0; } __setup("debugpat", pat_debug_setup); -#define dprintk(fmt, arg...) \ - do { if (debug_enable) printk(KERN_INFO fmt, ##arg); } while (0) - - static u64 __read_mostly boot_pat_state; enum { @@ -132,17 +130,6 @@ void pat_init(void) #undef PAT -static char *cattr_name(unsigned long flags) -{ - switch (flags & _PAGE_CACHE_MASK) { - case _PAGE_CACHE_UC: return "uncached"; - case _PAGE_CACHE_UC_MINUS: return "uncached-minus"; - case _PAGE_CACHE_WB: return "write-back"; - case _PAGE_CACHE_WC: return "write-combining"; - default: return "broken"; - } -} - /* * The global memtype list keeps track of memory type for specific * physical memory areas. Conflicting memory types in different @@ -159,14 +146,6 @@ static char *cattr_name(unsigned long flags) * memtype_lock protects both the linear list and rbtree. */ -struct memtype { - u64 start; - u64 end; - unsigned long type; - struct list_head nd; - struct rb_node rb; -}; - static struct rb_root memtype_rbroot = RB_ROOT; static LIST_HEAD(memtype_list); static DEFINE_SPINLOCK(memtype_lock); /* protects memtype list */ @@ -349,6 +328,64 @@ static int free_ram_pages_type(u64 start, u64 end) return 0; } +static int memtype_check_insert(struct memtype *new, unsigned long *new_type) +{ + struct memtype *entry; + u64 start, end; + unsigned long actual_type; + struct list_head *where; + int err = 0; + + start = new->start; + end = new->end; + actual_type = new->type; + + /* Search for existing mapping that overlaps the current range */ + where = NULL; + list_for_each_entry(entry, &memtype_list, nd) { + if (end <= entry->start) { + where = entry->nd.prev; + break; + } else if (start <= entry->start) { /* end > entry->start */ + err = chk_conflict(new, entry, new_type); + if (!err) { + dprintk("Overlap at 0x%Lx-0x%Lx\n", + entry->start, entry->end); + where = entry->nd.prev; + } + break; + } else if (start < entry->end) { /* start > entry->start */ + err = chk_conflict(new, entry, new_type); + if (!err) { + dprintk("Overlap at 0x%Lx-0x%Lx\n", + entry->start, entry->end); + + /* + * Move to right position in the linked + * list to add this new entry + */ + list_for_each_entry_continue(entry, + &memtype_list, nd) { + if (start <= entry->start) { + where = entry->nd.prev; + break; + } + } + } + break; + } + } + if (!err) { + if (where) + list_add(&new->nd, where); + else + list_add_tail(&new->nd, &memtype_list); + + memtype_rb_insert(&memtype_rbroot, new); + } + return err; +} + /* * req_type typically has one of the: * - _PAGE_CACHE_WB @@ -364,9 +401,8 @@ static int free_ram_pages_type(u64 start, u64 end) int reserve_memtype(u64 start, u64 end, unsigned long req_type, unsigned long *new_type) { - struct memtype *new, *entry; + struct memtype *new; unsigned long actual_type; - struct list_head *where; int is_range_ram; int err = 0; @@ -423,42 +459,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, spin_lock(&memtype_lock); - /* Search for existing mapping that overlaps the current range */ - where = NULL; - list_for_each_entry(entry, &memtype_list, nd) { - if (end <= entry->start) { - where = entry->nd.prev; - break; - } else if (start <= entry->start) { /* end > entry->start */ - err = chk_conflict(new, entry, new_type); - if (!err) { - dprintk("Overlap at 0x%Lx-0x%Lx\n", - entry->start, entry->end); - where = entry->nd.prev; - } - break; - } else if (start < entry->end) { /* start > entry->start */ - err = chk_conflict(new, entry, new_type); - if (!err) { - dprintk("Overlap at 0x%Lx-0x%Lx\n", - entry->start, entry->end); - - /* - * Move to right position in the linked - * list to add this new entry - */ - list_for_each_entry_continue(entry, - &memtype_list, nd) { - if (start <= entry->start) { - where = entry->nd.prev; - break; - } - } - } - break; - } - } - + err = memtype_check_insert(new, new_type); if (err) { printk(KERN_INFO "reserve_memtype failed 0x%Lx-0x%Lx, " "track %s, req %s\n", @@ -469,13 +470,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, return err; } - if (where) - list_add(&new->nd, where); - else - list_add_tail(&new->nd, &memtype_list); - - memtype_rb_insert(&memtype_rbroot, new); - spin_unlock(&memtype_lock); dprintk("reserve_memtype added 0x%Lx-0x%Lx, track %s, req %s, ret %s\n", @@ -937,28 +931,40 @@ EXPORT_SYMBOL_GPL(pgprot_writecombine); #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_X86_PAT) /* get Nth element of the linked list */ -static struct memtype *memtype_get_idx(loff_t pos) +static int copy_memtype_nth_element(struct memtype *out, loff_t pos) { - struct memtype *list_node, *print_entry; + struct memtype *list_node; int i = 1; - print_entry = kmalloc(sizeof(struct memtype), GFP_KERNEL); - if (!print_entry) - return NULL; - - spin_lock(&memtype_lock); list_for_each_entry(list_node, &memtype_list, nd) { if (pos == i) { - *print_entry = *list_node; - spin_unlock(&memtype_lock); - return print_entry; + *out = *list_node; + return 0; } ++i; } + return 1; +} + +static struct memtype *memtype_get_idx(loff_t pos) +{ + struct memtype *print_entry; + int ret; + + print_entry = kzalloc(sizeof(struct memtype), GFP_KERNEL); + if (!print_entry) + return NULL; + + spin_lock(&memtype_lock); + ret = copy_memtype_nth_element(print_entry, pos); spin_unlock(&memtype_lock); - kfree(print_entry); - return NULL; + if (!ret) { + return print_entry; + } else { + kfree(print_entry); + return NULL; + } } static void *memtype_seq_start(struct seq_file *seq, loff_t *pos) diff --git a/arch/x86/mm/pat_internal.h b/arch/x86/mm/pat_internal.h new file mode 100644 index 000000000000..6c98780eb731 --- /dev/null +++ b/arch/x86/mm/pat_internal.h @@ -0,0 +1,28 @@ +#ifndef __PAT_INTERNAL_H_ +#define __PAT_INTERNAL_H_ + +extern int pat_debug_enable; + +#define dprintk(fmt, arg...) \ + do { if (pat_debug_enable) printk(KERN_INFO fmt, ##arg); } while (0) + +struct memtype { + u64 start; + u64 end; + unsigned long type; + struct list_head nd; + struct rb_node rb; +}; + +static inline char *cattr_name(unsigned long flags) +{ + switch (flags & _PAGE_CACHE_MASK) { + case _PAGE_CACHE_UC: return "uncached"; + case _PAGE_CACHE_UC_MINUS: return "uncached-minus"; + case _PAGE_CACHE_WB: return "write-back"; + case _PAGE_CACHE_WC: return "write-combining"; + default: return "broken"; + } +} + +#endif /* __PAT_INTERNAL_H_ */ -- cgit v1.2.3-59-g8ed1b From 9e41a49aab88a5a6c8f4875bf10a5543bc321f2d Mon Sep 17 00:00:00 2001 From: "Pallipadi, Venkatesh" Date: Wed, 10 Feb 2010 15:26:07 -0800 Subject: x86, pat: Migrate to rbtree only backend for pat memtype management Move pat backend to fully rbtree based implementation from the existing rbtree and linked list hybrid. New rbtree based solution uses interval trees (augmented rbtrees) in order to store the PAT ranges. The new code seprates out the pat backend to pat_rbtree.c file, making is cleaner. The change also makes the PAT lookup, reserve and free operations more optimal, as we don't have to traverse linear linked list of few tens of entries in normal case. Signed-off-by: Venkatesh Pallipadi LKML-Reference: <20100210232607.GB11465@linux-os.sc.intel.com> Signed-off-by: Suresh Siddha Signed-off-by: H. Peter Anvin --- arch/x86/mm/Makefile | 1 + arch/x86/mm/pat.c | 209 +--------------------------------- arch/x86/mm/pat_internal.h | 20 +++- arch/x86/mm/pat_rbtree.c | 271 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 296 insertions(+), 205 deletions(-) create mode 100644 arch/x86/mm/pat_rbtree.c (limited to 'arch') diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index 06630d26e56d..a4c768397baa 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile @@ -6,6 +6,7 @@ nostackp := $(call cc-option, -fno-stack-protector) CFLAGS_physaddr.o := $(nostackp) CFLAGS_setup_nx.o := $(nostackp) +obj-$(CONFIG_X86_PAT) += pat_rbtree.o obj-$(CONFIG_SMP) += tlb.o obj-$(CONFIG_X86_32) += pgtable_32.o iomap_32.o diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 628e507b7936..951011166ef5 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -130,65 +130,7 @@ void pat_init(void) #undef PAT -/* - * The global memtype list keeps track of memory type for specific - * physical memory areas. Conflicting memory types in different - * mappings can cause CPU cache corruption. To avoid this we keep track. - * - * The list is sorted based on starting address and can contain multiple - * entries for each address (this allows reference counting for overlapping - * areas). All the aliases have the same cache attributes of course. - * Zero attributes are represented as holes. - * - * The data structure is a list that is also organized as an rbtree - * sorted on the start address of memtype range. - * - * memtype_lock protects both the linear list and rbtree. - */ - -static struct rb_root memtype_rbroot = RB_ROOT; -static LIST_HEAD(memtype_list); -static DEFINE_SPINLOCK(memtype_lock); /* protects memtype list */ - -static struct memtype *memtype_rb_search(struct rb_root *root, u64 start) -{ - struct rb_node *node = root->rb_node; - struct memtype *last_lower = NULL; - - while (node) { - struct memtype *data = container_of(node, struct memtype, rb); - - if (data->start < start) { - last_lower = data; - node = node->rb_right; - } else if (data->start > start) { - node = node->rb_left; - } else - return data; - } - - /* Will return NULL if there is no entry with its start <= start */ - return last_lower; -} - -static void memtype_rb_insert(struct rb_root *root, struct memtype *data) -{ - struct rb_node **new = &(root->rb_node); - struct rb_node *parent = NULL; - - while (*new) { - struct memtype *this = container_of(*new, struct memtype, rb); - - parent = *new; - if (data->start <= this->start) - new = &((*new)->rb_left); - else if (data->start > this->start) - new = &((*new)->rb_right); - } - - rb_link_node(&data->rb, parent, new); - rb_insert_color(&data->rb, root); -} +static DEFINE_SPINLOCK(memtype_lock); /* protects memtype accesses */ /* * Does intersection of PAT memory type and MTRR memory type and returns @@ -216,33 +158,6 @@ static unsigned long pat_x_mtrr_type(u64 start, u64 end, unsigned long req_type) return req_type; } -static int -chk_conflict(struct memtype *new, struct memtype *entry, unsigned long *type) -{ - if (new->type != entry->type) { - if (type) { - new->type = entry->type; - *type = entry->type; - } else - goto conflict; - } - - /* check overlaps with more than one entry in the list */ - list_for_each_entry_continue(entry, &memtype_list, nd) { - if (new->end <= entry->start) - break; - else if (new->type != entry->type) - goto conflict; - } - return 0; - - conflict: - printk(KERN_INFO "%s:%d conflicting memory types " - "%Lx-%Lx %s<->%s\n", current->comm, current->pid, new->start, - new->end, cattr_name(new->type), cattr_name(entry->type)); - return -EBUSY; -} - static int pat_pagerange_is_ram(unsigned long start, unsigned long end) { int ram_page = 0, not_rampage = 0; @@ -328,64 +243,6 @@ static int free_ram_pages_type(u64 start, u64 end) return 0; } -static int memtype_check_insert(struct memtype *new, unsigned long *new_type) -{ - struct memtype *entry; - u64 start, end; - unsigned long actual_type; - struct list_head *where; - int err = 0; - - start = new->start; - end = new->end; - actual_type = new->type; - - /* Search for existing mapping that overlaps the current range */ - where = NULL; - list_for_each_entry(entry, &memtype_list, nd) { - if (end <= entry->start) { - where = entry->nd.prev; - break; - } else if (start <= entry->start) { /* end > entry->start */ - err = chk_conflict(new, entry, new_type); - if (!err) { - dprintk("Overlap at 0x%Lx-0x%Lx\n", - entry->start, entry->end); - where = entry->nd.prev; - } - break; - } else if (start < entry->end) { /* start > entry->start */ - err = chk_conflict(new, entry, new_type); - if (!err) { - dprintk("Overlap at 0x%Lx-0x%Lx\n", - entry->start, entry->end); - - /* - * Move to right position in the linked - * list to add this new entry - */ - list_for_each_entry_continue(entry, - &memtype_list, nd) { - if (start <= entry->start) { - where = entry->nd.prev; - break; - } - } - } - break; - } - } - if (!err) { - if (where) - list_add(&new->nd, where); - else - list_add_tail(&new->nd, &memtype_list); - - memtype_rb_insert(&memtype_rbroot, new); - } - return err; -} - /* * req_type typically has one of the: * - _PAGE_CACHE_WB @@ -459,7 +316,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, spin_lock(&memtype_lock); - err = memtype_check_insert(new, new_type); + err = rbt_memtype_check_insert(new, new_type); if (err) { printk(KERN_INFO "reserve_memtype failed 0x%Lx-0x%Lx, " "track %s, req %s\n", @@ -481,7 +338,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, int free_memtype(u64 start, u64 end) { - struct memtype *entry, *saved_entry; int err = -EINVAL; int is_range_ram; @@ -505,46 +361,7 @@ int free_memtype(u64 start, u64 end) } spin_lock(&memtype_lock); - - entry = memtype_rb_search(&memtype_rbroot, start); - if (unlikely(entry == NULL)) - goto unlock_ret; - - /* - * Saved entry points to an entry with start same or less than what - * we searched for. Now go through the list in both directions to look - * for the entry that matches with both start and end, with list stored - * in sorted start address - */ - saved_entry = entry; - list_for_each_entry_from(entry, &memtype_list, nd) { - if (entry->start == start && entry->end == end) { - rb_erase(&entry->rb, &memtype_rbroot); - list_del(&entry->nd); - kfree(entry); - err = 0; - break; - } else if (entry->start > start) { - break; - } - } - - if (!err) - goto unlock_ret; - - entry = saved_entry; - list_for_each_entry_reverse(entry, &memtype_list, nd) { - if (entry->start == start && entry->end == end) { - rb_erase(&entry->rb, &memtype_rbroot); - list_del(&entry->nd); - kfree(entry); - err = 0; - break; - } else if (entry->start < start) { - break; - } - } -unlock_ret: + err = rbt_memtype_erase(start, end); spin_unlock(&memtype_lock); if (err) { @@ -593,7 +410,7 @@ static unsigned long lookup_memtype(u64 paddr) spin_lock(&memtype_lock); - entry = memtype_rb_search(&memtype_rbroot, paddr); + entry = rbt_memtype_lookup(paddr); if (entry != NULL) rettype = entry->type; else @@ -930,22 +747,6 @@ EXPORT_SYMBOL_GPL(pgprot_writecombine); #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_X86_PAT) -/* get Nth element of the linked list */ -static int copy_memtype_nth_element(struct memtype *out, loff_t pos) -{ - struct memtype *list_node; - int i = 1; - - list_for_each_entry(list_node, &memtype_list, nd) { - if (pos == i) { - *out = *list_node; - return 0; - } - ++i; - } - return 1; -} - static struct memtype *memtype_get_idx(loff_t pos) { struct memtype *print_entry; @@ -956,7 +757,7 @@ static struct memtype *memtype_get_idx(loff_t pos) return NULL; spin_lock(&memtype_lock); - ret = copy_memtype_nth_element(print_entry, pos); + ret = rbt_memtype_copy_nth_element(print_entry, pos); spin_unlock(&memtype_lock); if (!ret) { diff --git a/arch/x86/mm/pat_internal.h b/arch/x86/mm/pat_internal.h index 6c98780eb731..4f39eefa3e61 100644 --- a/arch/x86/mm/pat_internal.h +++ b/arch/x86/mm/pat_internal.h @@ -9,8 +9,8 @@ extern int pat_debug_enable; struct memtype { u64 start; u64 end; + u64 subtree_max_end; unsigned long type; - struct list_head nd; struct rb_node rb; }; @@ -25,4 +25,22 @@ static inline char *cattr_name(unsigned long flags) } } +#ifdef CONFIG_X86_PAT +extern int rbt_memtype_check_insert(struct memtype *new, + unsigned long *new_type); +extern int rbt_memtype_erase(u64 start, u64 end); +extern struct memtype *rbt_memtype_lookup(u64 addr); +extern int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos); +#else +static inline int rbt_memtype_check_insert(struct memtype *new, + unsigned long *new_type) +{ return 0; } +static inline int rbt_memtype_erase(u64 start, u64 end) +{ return 0; } +static inline struct memtype *rbt_memtype_lookup(u64 addr) +{ return NULL; } +static inline int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos) +{ return 0; } +#endif + #endif /* __PAT_INTERNAL_H_ */ diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c new file mode 100644 index 000000000000..9063f40b638b --- /dev/null +++ b/arch/x86/mm/pat_rbtree.c @@ -0,0 +1,271 @@ +/* + * Handle caching attributes in page tables (PAT) + * + * Authors: Venkatesh Pallipadi + * Suresh B Siddha + * + * Interval tree (augmented rbtree) used to store the PAT memory type + * reservations. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "pat_internal.h" + +/* + * The memtype tree keeps track of memory type for specific + * physical memory areas. Without proper tracking, conflicting memory + * types in different mappings can cause CPU cache corruption. + * + * The tree is an interval tree (augmented rbtree) with tree ordered + * on starting address. Tree can contain multiple entries for + * different regions which overlap. All the aliases have the same + * cache attributes of course. + * + * memtype_lock protects the rbtree. + */ + +static void memtype_rb_augment_cb(struct rb_node *node); +static struct rb_root memtype_rbroot = RB_AUGMENT_ROOT(&memtype_rb_augment_cb); + +static int is_node_overlap(struct memtype *node, u64 start, u64 end) +{ + if (node->start >= end || node->end <= start) + return 0; + + return 1; +} + +static u64 get_subtree_max_end(struct rb_node *node) +{ + u64 ret = 0; + if (node) { + struct memtype *data = container_of(node, struct memtype, rb); + ret = data->subtree_max_end; + } + return ret; +} + +/* Update 'subtree_max_end' for a node, based on node and its children */ +static void update_node_max_end(struct rb_node *node) +{ + struct memtype *data; + u64 max_end, child_max_end; + + if (!node) + return; + + data = container_of(node, struct memtype, rb); + max_end = data->end; + + child_max_end = get_subtree_max_end(node->rb_right); + if (child_max_end > max_end) + max_end = child_max_end; + + child_max_end = get_subtree_max_end(node->rb_left); + if (child_max_end > max_end) + max_end = child_max_end; + + data->subtree_max_end = max_end; +} + +/* Update 'subtree_max_end' for a node and all its ancestors */ +static void update_path_max_end(struct rb_node *node) +{ + u64 old_max_end, new_max_end; + + while (node) { + struct memtype *data = container_of(node, struct memtype, rb); + + old_max_end = data->subtree_max_end; + update_node_max_end(node); + new_max_end = data->subtree_max_end; + + if (new_max_end == old_max_end) + break; + + node = rb_parent(node); + } +} + +/* Find the first (lowest start addr) overlapping range from rb tree */ +static struct memtype *memtype_rb_lowest_match(struct rb_root *root, + u64 start, u64 end) +{ + struct rb_node *node = root->rb_node; + struct memtype *last_lower = NULL; + + while (node) { + struct memtype *data = container_of(node, struct memtype, rb); + + if (get_subtree_max_end(node->rb_left) > start) { + /* Lowest overlap if any must be on left side */ + node = node->rb_left; + } else if (is_node_overlap(data, start, end)) { + last_lower = data; + break; + } else if (start >= data->start) { + /* Lowest overlap if any must be on right side */ + node = node->rb_right; + } else { + break; + } + } + return last_lower; /* Returns NULL if there is no overlap */ +} + +static struct memtype *memtype_rb_exact_match(struct rb_root *root, + u64 start, u64 end) +{ + struct memtype *match; + + match = memtype_rb_lowest_match(root, start, end); + while (match != NULL && match->start < end) { + struct rb_node *node; + + if (match->start == start && match->end == end) + return match; + + node = rb_next(&match->rb); + if (node) + match = container_of(node, struct memtype, rb); + else + match = NULL; + } + + return NULL; /* Returns NULL if there is no exact match */ +} + +static int memtype_rb_check_conflict(struct rb_root *root, + u64 start, u64 end, + unsigned long reqtype, unsigned long *newtype) +{ + struct rb_node *node; + struct memtype *match; + int found_type = reqtype; + + match = memtype_rb_lowest_match(&memtype_rbroot, start, end); + if (match == NULL) + goto success; + + if (match->type != found_type && newtype == NULL) + goto failure; + + dprintk("Overlap at 0x%Lx-0x%Lx\n", match->start, match->end); + found_type = match->type; + + node = rb_next(&match->rb); + while (node) { + match = container_of(node, struct memtype, rb); + + if (match->start >= end) /* Checked all possible matches */ + goto success; + + if (is_node_overlap(match, start, end) && + match->type != found_type) { + goto failure; + } + + node = rb_next(&match->rb); + } +success: + if (newtype) + *newtype = found_type; + + return 0; + +failure: + printk(KERN_INFO "%s:%d conflicting memory types " + "%Lx-%Lx %s<->%s\n", current->comm, current->pid, start, + end, cattr_name(found_type), cattr_name(match->type)); + return -EBUSY; +} + +static void memtype_rb_augment_cb(struct rb_node *node) +{ + if (node) + update_path_max_end(node); +} + +static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata) +{ + struct rb_node **node = &(root->rb_node); + struct rb_node *parent = NULL; + + while (*node) { + struct memtype *data = container_of(*node, struct memtype, rb); + + parent = *node; + if (newdata->start <= data->start) + node = &((*node)->rb_left); + else if (newdata->start > data->start) + node = &((*node)->rb_right); + } + + rb_link_node(&newdata->rb, parent, node); + rb_insert_color(&newdata->rb, root); +} + +int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) +{ + int err = 0; + + err = memtype_rb_check_conflict(&memtype_rbroot, new->start, new->end, + new->type, ret_type); + + if (!err) { + new->type = *ret_type; + memtype_rb_insert(&memtype_rbroot, new); + } + return err; +} + +int rbt_memtype_erase(u64 start, u64 end) +{ + struct memtype *data; + + data = memtype_rb_exact_match(&memtype_rbroot, start, end); + if (!data) + return -EINVAL; + + rb_erase(&data->rb, &memtype_rbroot); + return 0; +} + +struct memtype *rbt_memtype_lookup(u64 addr) +{ + struct memtype *data; + data = memtype_rb_lowest_match(&memtype_rbroot, addr, addr + PAGE_SIZE); + return data; +} + +#if defined(CONFIG_DEBUG_FS) +int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos) +{ + struct rb_node *node; + int i = 1; + + node = rb_first(&memtype_rbroot); + while (node && pos != i) { + node = rb_next(node); + i++; + } + + if (node) { /* pos == i */ + struct memtype *this = container_of(node, struct memtype, rb); + *out = *this; + return 0; + } else { + return 1; + } +} +#endif -- cgit v1.2.3-59-g8ed1b From b3ac891b67bd4b1fc728d1c784cad1212dea433d Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Wed, 24 Feb 2010 10:54:22 +0100 Subject: x86: Add support for lock prefix in alternatives The current lock prefix UP/SMP alternative code doesn't allow LOCK_PREFIX to be used in alternatives code. This patch solves the problem by adding a new LOCK_PREFIX_ALTERNATIVE_PATCH macro that only records the lock prefix location but does not emit the prefix. The user of this macro can then start any alternative sequence with "lock" and have it UP/SMP patched. To make this work, the UP/SMP alternative code is changed to do the lock/DS prefix switching only if the byte actually contains a lock or DS prefix. Thus, if an alternative without the "lock" is selected, it will now do nothing instead of clobbering the code. Changes in v2: - Naming change - Change label to not conflict with alternatives Signed-off-by: Luca Barbieri LKML-Reference: <1267005265-27958-2-git-send-email-luca@luca-barbieri.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/alternative.h | 8 +++++--- arch/x86/kernel/alternative.c | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 3b5b828767b6..55fee12cea6d 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -28,12 +28,14 @@ */ #ifdef CONFIG_SMP -#define LOCK_PREFIX \ +#define LOCK_PREFIX_HERE \ ".section .smp_locks,\"a\"\n" \ _ASM_ALIGN "\n" \ - _ASM_PTR "661f\n" /* address */ \ + _ASM_PTR "671f\n" /* address */ \ ".previous\n" \ - "661:\n\tlock; " + "671:" + +#define LOCK_PREFIX LOCK_PREFIX_HERE "\n\tlock; " #else /* ! CONFIG_SMP */ #define LOCK_PREFIX "" diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 2589ea4c60ce..80b222ea4cf6 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -244,7 +244,8 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) if (*ptr > text_end) continue; /* turn DS segment override prefix into lock prefix */ - text_poke(*ptr, ((unsigned char []){0xf0}), 1); + if (**ptr == 0x3e) + text_poke(*ptr, ((unsigned char []){0xf0}), 1); }; mutex_unlock(&text_mutex); } @@ -263,7 +264,8 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end if (*ptr > text_end) continue; /* turn lock prefix into DS segment override prefix */ - text_poke(*ptr, ((unsigned char []){0x3E}), 1); + if (**ptr == 0xf0) + text_poke(*ptr, ((unsigned char []){0x3E}), 1); }; mutex_unlock(&text_mutex); } -- cgit v1.2.3-59-g8ed1b From 9c76b38476b18c45f97098a10b0176b321eba3ea Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Wed, 24 Feb 2010 10:54:23 +0100 Subject: x86-32: Allow UP/SMP lock replacement in cmpxchg64 Use the functionality just introduced in the previous patch: mark the lock prefixes in cmpxchg64 alternatives for UP removal. Changes in v2: - Naming change Signed-off-by: Luca Barbieri LKML-Reference: <1267005265-27958-3-git-send-email-luca@luca-barbieri.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/cmpxchg_32.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h index ffb9bb6b6c37..8859e12dd3cf 100644 --- a/arch/x86/include/asm/cmpxchg_32.h +++ b/arch/x86/include/asm/cmpxchg_32.h @@ -271,7 +271,8 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64); __typeof__(*(ptr)) __ret; \ __typeof__(*(ptr)) __old = (o); \ __typeof__(*(ptr)) __new = (n); \ - alternative_io("call cmpxchg8b_emu", \ + alternative_io(LOCK_PREFIX_HERE \ + "call cmpxchg8b_emu", \ "lock; cmpxchg8b (%%esi)" , \ X86_FEATURE_CX8, \ "=A" (__ret), \ -- cgit v1.2.3-59-g8ed1b From a7e926abc3adfbd2e5e20d2b46177adb4e313915 Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Wed, 24 Feb 2010 10:54:25 +0100 Subject: x86-32: Rewrite 32-bit atomic64 functions in assembly This patch replaces atomic64_32.c with two assembly implementations, one for 386/486 machines using pushf/cli/popf and one for 586+ machines using cmpxchg8b. The cmpxchg8b implementation provides the following advantages over the current one: 1. Implements atomic64_add_unless, atomic64_dec_if_positive and atomic64_inc_not_zero 2. Uses the ZF flag changed by cmpxchg8b instead of doing a comparison 3. Uses custom register calling conventions that reduce or eliminate register moves to suit cmpxchg8b 4. Reads the initial value instead of using cmpxchg8b to do that. Currently we use lock xaddl and movl, which seems the fastest. 5. Does not use the lock prefix for atomic64_set 64-bit writes are already atomic, so we don't need that. We still need it for atomic64_read to avoid restoring a value changed in the meantime. 6. Allocates registers as well or better than gcc The 386 implementation provides support for 386 and 486 machines. 386/486 SMP is not supported (we dropped it), but such support can be added easily if desired. A pure assembly implementation is required due to the custom calling conventions, and desire to use %ebp in atomic64_add_return (we need 7 registers...), as well as the ability to use pushf/popf in the 386 code without an intermediate pop/push. The parameter names are changed to match the convention in atomic_64.h Changes in v3 (due to rebasing to tip/x86/asm): - Patches atomic64_32.h instead of atomic_32.h - Uses the CALL alternative mechanism from commit 1b1d9258181bae199dc940f4bd0298126b9a73d9 Changes in v2: - Merged 386 and cx8 support in the same patch - 386 support now done in assembly, C code no longer used at all - cmpxchg64 is used for atomic64_cmpxchg - stop using macros, use one-line inline functions instead - miscellanous changes and improvements Signed-off-by: Luca Barbieri LKML-Reference: <1267005265-27958-5-git-send-email-luca@luca-barbieri.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/atomic64_32.h | 278 ++++++++++++++++++++++++++++--------- arch/x86/lib/Makefile | 3 +- arch/x86/lib/atomic64_32.c | 273 +++++++----------------------------- arch/x86/lib/atomic64_386_32.S | 175 +++++++++++++++++++++++ arch/x86/lib/atomic64_cx8_32.S | 225 ++++++++++++++++++++++++++++++ 5 files changed, 664 insertions(+), 290 deletions(-) create mode 100644 arch/x86/lib/atomic64_386_32.S create mode 100644 arch/x86/lib/atomic64_cx8_32.S (limited to 'arch') diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h index 03027bf28de5..2a934aa19a43 100644 --- a/arch/x86/include/asm/atomic64_32.h +++ b/arch/x86/include/asm/atomic64_32.h @@ -14,109 +14,193 @@ typedef struct { #define ATOMIC64_INIT(val) { (val) } -extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val); +#ifdef CONFIG_X86_CMPXCHG64 +#define ATOMIC64_ALTERNATIVE_(f, g) "call atomic64_" #g "_cx8" +#else +#define ATOMIC64_ALTERNATIVE_(f, g) ALTERNATIVE("call atomic64_" #f "_386", "call atomic64_" #g "_cx8", X86_FEATURE_CX8) +#endif + +#define ATOMIC64_ALTERNATIVE(f) ATOMIC64_ALTERNATIVE_(f, f) + +/** + * atomic64_cmpxchg - cmpxchg atomic64 variable + * @p: pointer to type atomic64_t + * @o: expected value + * @n: new value + * + * Atomically sets @v to @n if it was equal to @o and returns + * the old value. + */ + +static inline long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n) +{ + return cmpxchg64(&v->counter, o, n); +} /** * atomic64_xchg - xchg atomic64 variable - * @ptr: pointer to type atomic64_t - * @new_val: value to assign + * @v: pointer to type atomic64_t + * @n: value to assign * - * Atomically xchgs the value of @ptr to @new_val and returns + * Atomically xchgs the value of @v to @n and returns * the old value. */ -extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val); +static inline long long atomic64_xchg(atomic64_t *v, long long n) +{ + long long o; + unsigned high = (unsigned)(n >> 32); + unsigned low = (unsigned)n; + asm volatile(ATOMIC64_ALTERNATIVE(xchg) + : "=A" (o), "+b" (low), "+c" (high) + : "S" (v) + : "memory" + ); + return o; +} /** * atomic64_set - set atomic64 variable - * @ptr: pointer to type atomic64_t - * @new_val: value to assign + * @v: pointer to type atomic64_t + * @n: value to assign * - * Atomically sets the value of @ptr to @new_val. + * Atomically sets the value of @v to @n. */ -extern void atomic64_set(atomic64_t *ptr, u64 new_val); +static inline void atomic64_set(atomic64_t *v, long long i) +{ + unsigned high = (unsigned)(i >> 32); + unsigned low = (unsigned)i; + asm volatile(ATOMIC64_ALTERNATIVE(set) + : "+b" (low), "+c" (high) + : "S" (v) + : "eax", "edx", "memory" + ); +} /** * atomic64_read - read atomic64 variable - * @ptr: pointer to type atomic64_t + * @v: pointer to type atomic64_t * - * Atomically reads the value of @ptr and returns it. + * Atomically reads the value of @v and returns it. */ -static inline u64 atomic64_read(atomic64_t *ptr) +static inline long long atomic64_read(atomic64_t *v) { - u64 res; - - /* - * Note, we inline this atomic64_t primitive because - * it only clobbers EAX/EDX and leaves the others - * untouched. We also (somewhat subtly) rely on the - * fact that cmpxchg8b returns the current 64-bit value - * of the memory location we are touching: - */ - asm volatile( - "mov %%ebx, %%eax\n\t" - "mov %%ecx, %%edx\n\t" - LOCK_PREFIX "cmpxchg8b %1\n" - : "=&A" (res) - : "m" (*ptr) - ); - - return res; -} - -extern u64 atomic64_read(atomic64_t *ptr); + long long r; + asm volatile(ATOMIC64_ALTERNATIVE(read) + : "=A" (r), "+c" (v) + : : "memory" + ); + return r; + } /** * atomic64_add_return - add and return - * @delta: integer value to add - * @ptr: pointer to type atomic64_t + * @i: integer value to add + * @v: pointer to type atomic64_t * - * Atomically adds @delta to @ptr and returns @delta + *@ptr + * Atomically adds @i to @v and returns @i + *@v */ -extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr); +static inline long long atomic64_add_return(long long i, atomic64_t *v) +{ + asm volatile(ATOMIC64_ALTERNATIVE(add_return) + : "+A" (i), "+c" (v) + : : "memory" + ); + return i; +} /* * Other variants with different arithmetic operators: */ -extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr); -extern u64 atomic64_inc_return(atomic64_t *ptr); -extern u64 atomic64_dec_return(atomic64_t *ptr); +static inline long long atomic64_sub_return(long long i, atomic64_t *v) +{ + asm volatile(ATOMIC64_ALTERNATIVE(sub_return) + : "+A" (i), "+c" (v) + : : "memory" + ); + return i; +} + +static inline long long atomic64_inc_return(atomic64_t *v) +{ + long long a; + asm volatile(ATOMIC64_ALTERNATIVE(inc_return) + : "=A" (a) + : "S" (v) + : "memory", "ecx" + ); + return a; +} + +static inline long long atomic64_dec_return(atomic64_t *v) +{ + long long a; + asm volatile(ATOMIC64_ALTERNATIVE(dec_return) + : "=A" (a) + : "S" (v) + : "memory", "ecx" + ); + return a; +} /** * atomic64_add - add integer to atomic64 variable - * @delta: integer value to add - * @ptr: pointer to type atomic64_t + * @i: integer value to add + * @v: pointer to type atomic64_t * - * Atomically adds @delta to @ptr. + * Atomically adds @i to @v. */ -extern void atomic64_add(u64 delta, atomic64_t *ptr); +static inline long long atomic64_add(long long i, atomic64_t *v) +{ + asm volatile(ATOMIC64_ALTERNATIVE_(add, add_return) + : "+A" (i), "+c" (v) + : : "memory" + ); + return i; +} /** * atomic64_sub - subtract the atomic64 variable - * @delta: integer value to subtract - * @ptr: pointer to type atomic64_t + * @i: integer value to subtract + * @v: pointer to type atomic64_t * - * Atomically subtracts @delta from @ptr. + * Atomically subtracts @i from @v. */ -extern void atomic64_sub(u64 delta, atomic64_t *ptr); +static inline long long atomic64_sub(long long i, atomic64_t *v) +{ + asm volatile(ATOMIC64_ALTERNATIVE_(sub, sub_return) + : "+A" (i), "+c" (v) + : : "memory" + ); + return i; +} /** * atomic64_sub_and_test - subtract value from variable and test result - * @delta: integer value to subtract - * @ptr: pointer to type atomic64_t - * - * Atomically subtracts @delta from @ptr and returns + * @i: integer value to subtract + * @v: pointer to type atomic64_t + * + * Atomically subtracts @i from @v and returns * true if the result is zero, or false for all * other cases. */ -extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr); +static inline int atomic64_sub_and_test(long long i, atomic64_t *v) +{ + return atomic64_sub_return(i, v) == 0; +} /** * atomic64_inc - increment atomic64 variable - * @ptr: pointer to type atomic64_t + * @v: pointer to type atomic64_t * - * Atomically increments @ptr by 1. + * Atomically increments @v by 1. */ -extern void atomic64_inc(atomic64_t *ptr); +static inline void atomic64_inc(atomic64_t *v) +{ + asm volatile(ATOMIC64_ALTERNATIVE_(inc, inc_return) + : : "S" (v) + : "memory", "eax", "ecx", "edx" + ); +} /** * atomic64_dec - decrement atomic64 variable @@ -124,37 +208,97 @@ extern void atomic64_inc(atomic64_t *ptr); * * Atomically decrements @ptr by 1. */ -extern void atomic64_dec(atomic64_t *ptr); +static inline void atomic64_dec(atomic64_t *v) +{ + asm volatile(ATOMIC64_ALTERNATIVE_(dec, dec_return) + : : "S" (v) + : "memory", "eax", "ecx", "edx" + ); +} /** * atomic64_dec_and_test - decrement and test - * @ptr: pointer to type atomic64_t + * @v: pointer to type atomic64_t * - * Atomically decrements @ptr by 1 and + * Atomically decrements @v by 1 and * returns true if the result is 0, or false for all other * cases. */ -extern int atomic64_dec_and_test(atomic64_t *ptr); +static inline int atomic64_dec_and_test(atomic64_t *v) +{ + return atomic64_dec_return(v) == 0; +} /** * atomic64_inc_and_test - increment and test - * @ptr: pointer to type atomic64_t + * @v: pointer to type atomic64_t * - * Atomically increments @ptr by 1 + * Atomically increments @v by 1 * and returns true if the result is zero, or false for all * other cases. */ -extern int atomic64_inc_and_test(atomic64_t *ptr); +static inline int atomic64_inc_and_test(atomic64_t *v) +{ + return atomic64_inc_return(v) == 0; +} /** * atomic64_add_negative - add and test if negative - * @delta: integer value to add - * @ptr: pointer to type atomic64_t + * @i: integer value to add + * @v: pointer to type atomic64_t * - * Atomically adds @delta to @ptr and returns true + * Atomically adds @i to @v and returns true * if the result is negative, or false when * result is greater than or equal to zero. */ -extern int atomic64_add_negative(u64 delta, atomic64_t *ptr); +static inline int atomic64_add_negative(long long i, atomic64_t *v) +{ + return atomic64_add_return(i, v) < 0; +} + +/** + * atomic64_add_unless - add unless the number is a given value + * @v: pointer of type atomic64_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @v, so long as it was not @u. + * Returns non-zero if @v was not @u, and zero otherwise. + */ +static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) +{ + unsigned low = (unsigned)u; + unsigned high = (unsigned)(u >> 32); + asm volatile(ATOMIC64_ALTERNATIVE(add_unless) "\n\t" + : "+A" (a), "+c" (v), "+S" (low), "+D" (high) + : : "memory"); + return (int)a; +} + + +static inline int atomic64_inc_not_zero(atomic64_t *v) +{ + int r; + asm volatile(ATOMIC64_ALTERNATIVE(inc_not_zero) + : "=a" (r) + : "S" (v) + : "ecx", "edx", "memory" + ); + return r; +} + +static inline long long atomic64_dec_if_positive(atomic64_t *v) +{ + long long r; + asm volatile(ATOMIC64_ALTERNATIVE(dec_if_positive) + : "=A" (r) + : "S" (v) + : "ecx", "memory" + ); + return r; +} + +#undef ATOMIC64_ALTERNATIVE +#undef ATOMIC64_ALTERNATIVE_ #endif /* _ASM_X86_ATOMIC64_32_H */ diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index cffd754f3039..05d686bbbe9f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -26,11 +26,12 @@ obj-y += msr.o msr-reg.o msr-reg-export.o ifeq ($(CONFIG_X86_32),y) obj-y += atomic64_32.o + lib-y += atomic64_cx8_32.o lib-y += checksum_32.o lib-y += strstr_32.o lib-y += semaphore_32.o string_32.o ifneq ($(CONFIG_X86_CMPXCHG64),y) - lib-y += cmpxchg8b_emu.o + lib-y += cmpxchg8b_emu.o atomic64_386_32.o endif lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o else diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c index 824fa0be55a3..540179e8e9fa 100644 --- a/arch/x86/lib/atomic64_32.c +++ b/arch/x86/lib/atomic64_32.c @@ -6,225 +6,54 @@ #include #include -static noinline u64 cmpxchg8b(u64 *ptr, u64 old, u64 new) -{ - u32 low = new; - u32 high = new >> 32; - - asm volatile( - LOCK_PREFIX "cmpxchg8b %1\n" - : "+A" (old), "+m" (*ptr) - : "b" (low), "c" (high) - ); - return old; -} - -u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val) -{ - return cmpxchg8b(&ptr->counter, old_val, new_val); -} -EXPORT_SYMBOL(atomic64_cmpxchg); - -/** - * atomic64_xchg - xchg atomic64 variable - * @ptr: pointer to type atomic64_t - * @new_val: value to assign - * - * Atomically xchgs the value of @ptr to @new_val and returns - * the old value. - */ -u64 atomic64_xchg(atomic64_t *ptr, u64 new_val) -{ - /* - * Try first with a (possibly incorrect) assumption about - * what we have there. We'll do two loops most likely, - * but we'll get an ownership MESI transaction straight away - * instead of a read transaction followed by a - * flush-for-ownership transaction: - */ - u64 old_val, real_val = 0; - - do { - old_val = real_val; - - real_val = atomic64_cmpxchg(ptr, old_val, new_val); - - } while (real_val != old_val); - - return old_val; -} -EXPORT_SYMBOL(atomic64_xchg); - -/** - * atomic64_set - set atomic64 variable - * @ptr: pointer to type atomic64_t - * @new_val: value to assign - * - * Atomically sets the value of @ptr to @new_val. - */ -void atomic64_set(atomic64_t *ptr, u64 new_val) -{ - atomic64_xchg(ptr, new_val); -} -EXPORT_SYMBOL(atomic64_set); - -/** -EXPORT_SYMBOL(atomic64_read); - * atomic64_add_return - add and return - * @delta: integer value to add - * @ptr: pointer to type atomic64_t - * - * Atomically adds @delta to @ptr and returns @delta + *@ptr - */ -noinline u64 atomic64_add_return(u64 delta, atomic64_t *ptr) -{ - /* - * Try first with a (possibly incorrect) assumption about - * what we have there. We'll do two loops most likely, - * but we'll get an ownership MESI transaction straight away - * instead of a read transaction followed by a - * flush-for-ownership transaction: - */ - u64 old_val, new_val, real_val = 0; - - do { - old_val = real_val; - new_val = old_val + delta; - - real_val = atomic64_cmpxchg(ptr, old_val, new_val); - - } while (real_val != old_val); - - return new_val; -} -EXPORT_SYMBOL(atomic64_add_return); - -u64 atomic64_sub_return(u64 delta, atomic64_t *ptr) -{ - return atomic64_add_return(-delta, ptr); -} -EXPORT_SYMBOL(atomic64_sub_return); - -u64 atomic64_inc_return(atomic64_t *ptr) -{ - return atomic64_add_return(1, ptr); -} -EXPORT_SYMBOL(atomic64_inc_return); - -u64 atomic64_dec_return(atomic64_t *ptr) -{ - return atomic64_sub_return(1, ptr); -} -EXPORT_SYMBOL(atomic64_dec_return); - -/** - * atomic64_add - add integer to atomic64 variable - * @delta: integer value to add - * @ptr: pointer to type atomic64_t - * - * Atomically adds @delta to @ptr. - */ -void atomic64_add(u64 delta, atomic64_t *ptr) -{ - atomic64_add_return(delta, ptr); -} -EXPORT_SYMBOL(atomic64_add); - -/** - * atomic64_sub - subtract the atomic64 variable - * @delta: integer value to subtract - * @ptr: pointer to type atomic64_t - * - * Atomically subtracts @delta from @ptr. - */ -void atomic64_sub(u64 delta, atomic64_t *ptr) -{ - atomic64_add(-delta, ptr); -} -EXPORT_SYMBOL(atomic64_sub); - -/** - * atomic64_sub_and_test - subtract value from variable and test result - * @delta: integer value to subtract - * @ptr: pointer to type atomic64_t - * - * Atomically subtracts @delta from @ptr and returns - * true if the result is zero, or false for all - * other cases. - */ -int atomic64_sub_and_test(u64 delta, atomic64_t *ptr) -{ - u64 new_val = atomic64_sub_return(delta, ptr); - - return new_val == 0; -} -EXPORT_SYMBOL(atomic64_sub_and_test); - -/** - * atomic64_inc - increment atomic64 variable - * @ptr: pointer to type atomic64_t - * - * Atomically increments @ptr by 1. - */ -void atomic64_inc(atomic64_t *ptr) -{ - atomic64_add(1, ptr); -} -EXPORT_SYMBOL(atomic64_inc); - -/** - * atomic64_dec - decrement atomic64 variable - * @ptr: pointer to type atomic64_t - * - * Atomically decrements @ptr by 1. - */ -void atomic64_dec(atomic64_t *ptr) -{ - atomic64_sub(1, ptr); -} -EXPORT_SYMBOL(atomic64_dec); - -/** - * atomic64_dec_and_test - decrement and test - * @ptr: pointer to type atomic64_t - * - * Atomically decrements @ptr by 1 and - * returns true if the result is 0, or false for all other - * cases. - */ -int atomic64_dec_and_test(atomic64_t *ptr) -{ - return atomic64_sub_and_test(1, ptr); -} -EXPORT_SYMBOL(atomic64_dec_and_test); - -/** - * atomic64_inc_and_test - increment and test - * @ptr: pointer to type atomic64_t - * - * Atomically increments @ptr by 1 - * and returns true if the result is zero, or false for all - * other cases. - */ -int atomic64_inc_and_test(atomic64_t *ptr) -{ - return atomic64_sub_and_test(-1, ptr); -} -EXPORT_SYMBOL(atomic64_inc_and_test); - -/** - * atomic64_add_negative - add and test if negative - * @delta: integer value to add - * @ptr: pointer to type atomic64_t - * - * Atomically adds @delta to @ptr and returns true - * if the result is negative, or false when - * result is greater than or equal to zero. - */ -int atomic64_add_negative(u64 delta, atomic64_t *ptr) -{ - s64 new_val = atomic64_add_return(delta, ptr); - - return new_val < 0; -} -EXPORT_SYMBOL(atomic64_add_negative); +long long atomic64_read_cx8(long long, const atomic64_t *v); +EXPORT_SYMBOL(atomic64_read_cx8); +long long atomic64_set_cx8(long long, const atomic64_t *v); +EXPORT_SYMBOL(atomic64_set_cx8); +long long atomic64_xchg_cx8(long long, unsigned high); +EXPORT_SYMBOL(atomic64_xchg_cx8); +long long atomic64_add_return_cx8(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_add_return_cx8); +long long atomic64_sub_return_cx8(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_sub_return_cx8); +long long atomic64_inc_return_cx8(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_inc_return_cx8); +long long atomic64_dec_return_cx8(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_dec_return_cx8); +long long atomic64_dec_if_positive_cx8(atomic64_t *v); +EXPORT_SYMBOL(atomic64_dec_if_positive_cx8); +int atomic64_inc_not_zero_cx8(atomic64_t *v); +EXPORT_SYMBOL(atomic64_inc_not_zero_cx8); +int atomic64_add_unless_cx8(atomic64_t *v, long long a, long long u); +EXPORT_SYMBOL(atomic64_add_unless_cx8); + +#ifndef CONFIG_X86_CMPXCHG64 +long long atomic64_read_386(long long, const atomic64_t *v); +EXPORT_SYMBOL(atomic64_read_386); +long long atomic64_set_386(long long, const atomic64_t *v); +EXPORT_SYMBOL(atomic64_set_386); +long long atomic64_xchg_386(long long, unsigned high); +EXPORT_SYMBOL(atomic64_xchg_386); +long long atomic64_add_return_386(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_add_return_386); +long long atomic64_sub_return_386(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_sub_return_386); +long long atomic64_inc_return_386(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_inc_return_386); +long long atomic64_dec_return_386(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_dec_return_386); +long long atomic64_add_386(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_add_386); +long long atomic64_sub_386(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_sub_386); +long long atomic64_inc_386(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_inc_386); +long long atomic64_dec_386(long long a, atomic64_t *v); +EXPORT_SYMBOL(atomic64_dec_386); +long long atomic64_dec_if_positive_386(atomic64_t *v); +EXPORT_SYMBOL(atomic64_dec_if_positive_386); +int atomic64_inc_not_zero_386(atomic64_t *v); +EXPORT_SYMBOL(atomic64_inc_not_zero_386); +int atomic64_add_unless_386(atomic64_t *v, long long a, long long u); +EXPORT_SYMBOL(atomic64_add_unless_386); +#endif diff --git a/arch/x86/lib/atomic64_386_32.S b/arch/x86/lib/atomic64_386_32.S new file mode 100644 index 000000000000..5db07fe4a0ca --- /dev/null +++ b/arch/x86/lib/atomic64_386_32.S @@ -0,0 +1,175 @@ +/* + * atomic64_t for 386/486 + * + * Copyright © 2010 Luca Barbieri + * + * 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. + */ + +#include +#include +#include + +/* if you want SMP support, implement these with real spinlocks */ +.macro LOCK reg + pushfl + CFI_ADJUST_CFA_OFFSET 4 + cli +.endm + +.macro UNLOCK reg + popfl + CFI_ADJUST_CFA_OFFSET -4 +.endm + +.macro BEGIN func reg +$v = \reg + +ENTRY(atomic64_\func\()_386) + CFI_STARTPROC + LOCK $v + +.macro RETURN + UNLOCK $v + ret +.endm + +.macro END_ + CFI_ENDPROC +ENDPROC(atomic64_\func\()_386) +.purgem RETURN +.purgem END_ +.purgem END +.endm + +.macro END +RETURN +END_ +.endm +.endm + +BEGIN read %ecx + movl ($v), %eax + movl 4($v), %edx +END + +BEGIN set %esi + movl %ebx, ($v) + movl %ecx, 4($v) +END + +BEGIN xchg %esi + movl ($v), %eax + movl 4($v), %edx + movl %ebx, ($v) + movl %ecx, 4($v) +END + +BEGIN add %ecx + addl %eax, ($v) + adcl %edx, 4($v) +END + +BEGIN add_return %ecx + addl ($v), %eax + adcl 4($v), %edx + movl %eax, ($v) + movl %edx, 4($v) +END + +BEGIN sub %ecx + subl %eax, ($v) + sbbl %edx, 4($v) +END + +BEGIN sub_return %ecx + negl %edx + negl %eax + sbbl $0, %edx + addl ($v), %eax + adcl 4($v), %edx + movl %eax, ($v) + movl %edx, 4($v) +END + +BEGIN inc %esi + addl $1, ($v) + adcl $0, 4($v) +END + +BEGIN inc_return %esi + movl ($v), %eax + movl 4($v), %edx + addl $1, %eax + adcl $0, %edx + movl %eax, ($v) + movl %edx, 4($v) +END + +BEGIN dec %esi + subl $1, ($v) + sbbl $0, 4($v) +END + +BEGIN dec_return %esi + movl ($v), %eax + movl 4($v), %edx + subl $1, %eax + sbbl $0, %edx + movl %eax, ($v) + movl %edx, 4($v) +END + +BEGIN add_unless %ecx + addl %eax, %esi + adcl %edx, %edi + addl ($v), %eax + adcl 4($v), %edx + cmpl %eax, %esi + je 3f +1: + movl %eax, ($v) + movl %edx, 4($v) + xorl %eax, %eax +2: +RETURN +3: + cmpl %edx, %edi + jne 1b + movl $1, %eax + jmp 2b +END_ + +BEGIN inc_not_zero %esi + movl ($v), %eax + movl 4($v), %edx + testl %eax, %eax + je 3f +1: + addl $1, %eax + adcl $0, %edx + movl %eax, ($v) + movl %edx, 4($v) + xorl %eax, %eax +2: +RETURN +3: + testl %edx, %edx + jne 1b + movl $1, %eax + jmp 2b +END_ + +BEGIN dec_if_positive %esi + movl ($v), %eax + movl 4($v), %edx + subl $1, %eax + sbbl $0, %edx + js 1f + movl %eax, ($v) + movl %edx, 4($v) +1: +END diff --git a/arch/x86/lib/atomic64_cx8_32.S b/arch/x86/lib/atomic64_cx8_32.S new file mode 100644 index 000000000000..e49c4ebca9f4 --- /dev/null +++ b/arch/x86/lib/atomic64_cx8_32.S @@ -0,0 +1,225 @@ +/* + * atomic64_t for 586+ + * + * Copyright © 2010 Luca Barbieri + * + * 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. + */ + +#include +#include +#include + +.macro SAVE reg + pushl %\reg + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET \reg, 0 +.endm + +.macro RESTORE reg + popl %\reg + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE \reg +.endm + +.macro read64 reg + movl %ebx, %eax + movl %ecx, %edx +/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */ + LOCK_PREFIX + cmpxchg8b (\reg) +.endm + +ENTRY(atomic64_read_cx8) + CFI_STARTPROC + + read64 %ecx + ret + CFI_ENDPROC +ENDPROC(atomic64_read_cx8) + +ENTRY(atomic64_set_cx8) + CFI_STARTPROC + +1: +/* we don't need LOCK_PREFIX since aligned 64-bit writes + * are atomic on 586 and newer */ + cmpxchg8b (%esi) + jne 1b + + ret + CFI_ENDPROC +ENDPROC(atomic64_set_cx8) + +ENTRY(atomic64_xchg_cx8) + CFI_STARTPROC + + movl %ebx, %eax + movl %ecx, %edx +1: + LOCK_PREFIX + cmpxchg8b (%esi) + jne 1b + + ret + CFI_ENDPROC +ENDPROC(atomic64_xchg_cx8) + +.macro addsub_return func ins insc +ENTRY(atomic64_\func\()_return_cx8) + CFI_STARTPROC + SAVE ebp + SAVE ebx + SAVE esi + SAVE edi + + movl %eax, %esi + movl %edx, %edi + movl %ecx, %ebp + + read64 %ebp +1: + movl %eax, %ebx + movl %edx, %ecx + \ins\()l %esi, %ebx + \insc\()l %edi, %ecx + LOCK_PREFIX + cmpxchg8b (%ebp) + jne 1b + +10: + movl %ebx, %eax + movl %ecx, %edx + RESTORE edi + RESTORE esi + RESTORE ebx + RESTORE ebp + ret + CFI_ENDPROC +ENDPROC(atomic64_\func\()_return_cx8) +.endm + +addsub_return add add adc +addsub_return sub sub sbb + +.macro incdec_return func ins insc +ENTRY(atomic64_\func\()_return_cx8) + CFI_STARTPROC + SAVE ebx + + read64 %esi +1: + movl %eax, %ebx + movl %edx, %ecx + \ins\()l $1, %ebx + \insc\()l $0, %ecx + LOCK_PREFIX + cmpxchg8b (%esi) + jne 1b + +10: + movl %ebx, %eax + movl %ecx, %edx + RESTORE ebx + ret + CFI_ENDPROC +ENDPROC(atomic64_\func\()_return_cx8) +.endm + +incdec_return inc add adc +incdec_return dec sub sbb + +ENTRY(atomic64_dec_if_positive_cx8) + CFI_STARTPROC + SAVE ebx + + read64 %esi +1: + movl %eax, %ebx + movl %edx, %ecx + subl $1, %ebx + sbb $0, %ecx + js 2f + LOCK_PREFIX + cmpxchg8b (%esi) + jne 1b + +2: + movl %ebx, %eax + movl %ecx, %edx + RESTORE ebx + ret + CFI_ENDPROC +ENDPROC(atomic64_dec_if_positive_cx8) + +ENTRY(atomic64_add_unless_cx8) + CFI_STARTPROC + SAVE ebp + SAVE ebx +/* these just push these two parameters on the stack */ + SAVE edi + SAVE esi + + movl %ecx, %ebp + movl %eax, %esi + movl %edx, %edi + + read64 %ebp +1: + cmpl %eax, 0(%esp) + je 4f +2: + movl %eax, %ebx + movl %edx, %ecx + addl %esi, %ebx + adcl %edi, %ecx + LOCK_PREFIX + cmpxchg8b (%ebp) + jne 1b + + xorl %eax, %eax +3: + addl $8, %esp + CFI_ADJUST_CFA_OFFSET -8 + RESTORE ebx + RESTORE ebp + ret +4: + cmpl %edx, 4(%esp) + jne 2b + movl $1, %eax + jmp 3b + CFI_ENDPROC +ENDPROC(atomic64_add_unless_cx8) + +ENTRY(atomic64_inc_not_zero_cx8) + CFI_STARTPROC + SAVE ebx + + read64 %esi +1: + testl %eax, %eax + je 4f +2: + movl %eax, %ebx + movl %edx, %ecx + addl $1, %ebx + adcl $0, %ecx + LOCK_PREFIX + cmpxchg8b (%esi) + jne 1b + + xorl %eax, %eax +3: + RESTORE ebx + ret +4: + testl %edx, %edx + jne 2b + movl $1, %eax + jmp 3b + CFI_ENDPROC +ENDPROC(atomic64_inc_not_zero_cx8) -- cgit v1.2.3-59-g8ed1b From d7f6de1e9c4a12e11ba7186c70f0f40caa76f590 Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Fri, 26 Feb 2010 12:22:41 +0100 Subject: x86: Implement atomic[64]_dec_if_positive() Add support for atomic_dec_if_positive(), and atomic64_dec_if_positive() for x86-64. atomic64_dec_if_positive() for x86-32 was already implemented in a previous patch. Signed-off-by: Luca Barbieri LKML-Reference: <1267183361-20775-2-git-send-email-luca@luca-barbieri.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/atomic.h | 23 +++++++++++++++++++++++ arch/x86/include/asm/atomic64_64.h | 23 +++++++++++++++++++++++ lib/atomic64_test.c | 2 +- 3 files changed, 47 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index 8f8217b9bdac..706c69492c14 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -246,6 +246,29 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) +/* + * atomic_dec_if_positive - decrement by 1 if old value positive + * @v: pointer of type atomic_t + * + * The function returns the old value of *v minus 1, even if + * the atomic variable, v, was not decremented. + */ +static inline int atomic_dec_if_positive(atomic_t *v) +{ + int c, old, dec; + c = atomic_read(v); + for (;;) { + dec = c - 1; + if (unlikely(dec < 0)) + break; + old = atomic_cmpxchg((v), c, dec); + if (likely(old == c)) + break; + c = old; + } + return dec; +} + /** * atomic_inc_short - increment of a short integer * @v: pointer to type int diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h index 51c5b4056929..4d6e2cd6c88c 100644 --- a/arch/x86/include/asm/atomic64_64.h +++ b/arch/x86/include/asm/atomic64_64.h @@ -221,4 +221,27 @@ static inline int atomic64_add_unless(atomic64_t *v, long a, long u) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) +/* + * atomic64_dec_if_positive - decrement by 1 if old value positive + * @v: pointer of type atomic_t + * + * The function returns the old value of *v minus 1, even if + * the atomic variable, v, was not decremented. + */ +static inline long atomic64_dec_if_positive(atomic64_t *v) +{ + long c, old, dec; + c = atomic64_read(v); + for (;;) { + dec = c - 1; + if (unlikely(dec < 0)) + break; + old = atomic64_cmpxchg((v), c, dec); + if (likely(old == c)) + break; + c = old; + } + return dec; +} + #endif /* _ASM_X86_ATOMIC64_64_H */ diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c index 0effcacbebda..58efdabb3845 100644 --- a/lib/atomic64_test.c +++ b/lib/atomic64_test.c @@ -112,7 +112,7 @@ static __init int test_atomic64(void) r += one; BUG_ON(v.counter != r); -#if defined(CONFIG_X86_32) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(_ASM_GENERIC_ATOMIC64_H) +#if defined(CONFIG_X86) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(_ASM_GENERIC_ATOMIC64_H) INIT(onestwos); BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1)); r -= one; -- cgit v1.2.3-59-g8ed1b From 6e6104fe085026e6ef82cc5cc303d6c8ceb7e411 Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Mon, 1 Mar 2010 19:55:46 +0100 Subject: x86-32: Fix atomic64_add_unless return value convention atomic64_add_unless must return 1 if it perfomed the add and 0 otherwise. The implementation did the opposite thing. Reported-by: H. Peter Anvin Signed-off-by: Luca Barbieri LKML-Reference: <1267469749-11878-3-git-send-email-luca@luca-barbieri.com> Signed-off-by: H. Peter Anvin --- arch/x86/lib/atomic64_386_32.S | 4 ++-- arch/x86/lib/atomic64_cx8_32.S | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/lib/atomic64_386_32.S b/arch/x86/lib/atomic64_386_32.S index 5db07fe4a0ca..a2f847c88b89 100644 --- a/arch/x86/lib/atomic64_386_32.S +++ b/arch/x86/lib/atomic64_386_32.S @@ -133,13 +133,13 @@ BEGIN add_unless %ecx 1: movl %eax, ($v) movl %edx, 4($v) - xorl %eax, %eax + movl $1, %eax 2: RETURN 3: cmpl %edx, %edi jne 1b - movl $1, %eax + xorl %eax, %eax jmp 2b END_ diff --git a/arch/x86/lib/atomic64_cx8_32.S b/arch/x86/lib/atomic64_cx8_32.S index e49c4ebca9f4..d0e37b189f82 100644 --- a/arch/x86/lib/atomic64_cx8_32.S +++ b/arch/x86/lib/atomic64_cx8_32.S @@ -180,7 +180,7 @@ ENTRY(atomic64_add_unless_cx8) cmpxchg8b (%ebp) jne 1b - xorl %eax, %eax + movl $1, %eax 3: addl $8, %esp CFI_ADJUST_CFA_OFFSET -8 @@ -190,7 +190,7 @@ ENTRY(atomic64_add_unless_cx8) 4: cmpl %edx, 4(%esp) jne 2b - movl $1, %eax + xorl %eax, %eax jmp 3b CFI_ENDPROC ENDPROC(atomic64_add_unless_cx8) -- cgit v1.2.3-59-g8ed1b From f3e83131469e29032a700217aa394996107b8fc5 Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Mon, 1 Mar 2010 19:55:49 +0100 Subject: x86-32: Fix atomic64_inc_not_zero return value convention atomic64_inc_not_zero must return 1 if it perfomed the add and 0 otherwise. It was doing the opposite thing. Signed-off-by: Luca Barbieri LKML-Reference: <1267469749-11878-6-git-send-email-luca@luca-barbieri.com> Signed-off-by: H. Peter Anvin --- arch/x86/lib/atomic64_386_32.S | 3 +-- arch/x86/lib/atomic64_cx8_32.S | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/lib/atomic64_386_32.S b/arch/x86/lib/atomic64_386_32.S index a2f847c88b89..4a5979aa6883 100644 --- a/arch/x86/lib/atomic64_386_32.S +++ b/arch/x86/lib/atomic64_386_32.S @@ -153,13 +153,12 @@ BEGIN inc_not_zero %esi adcl $0, %edx movl %eax, ($v) movl %edx, 4($v) - xorl %eax, %eax + movl $1, %eax 2: RETURN 3: testl %edx, %edx jne 1b - movl $1, %eax jmp 2b END_ diff --git a/arch/x86/lib/atomic64_cx8_32.S b/arch/x86/lib/atomic64_cx8_32.S index d0e37b189f82..71e080de3352 100644 --- a/arch/x86/lib/atomic64_cx8_32.S +++ b/arch/x86/lib/atomic64_cx8_32.S @@ -212,14 +212,13 @@ ENTRY(atomic64_inc_not_zero_cx8) cmpxchg8b (%esi) jne 1b - xorl %eax, %eax + movl $1, %eax 3: RESTORE ebx ret 4: testl %edx, %edx jne 2b - movl $1, %eax jmp 3b CFI_ENDPROC ENDPROC(atomic64_inc_not_zero_cx8) -- cgit v1.2.3-59-g8ed1b From 4daa2a8093ecd1148270a1fc64e99f072b8c2901 Mon Sep 17 00:00:00 2001 From: "Pallipadi, Venkatesh" Date: Wed, 24 Feb 2010 13:43:55 -0800 Subject: x86, pat: In rbt_memtype_check_insert(), update new->type only if valid new->type should only change when there is a valid ret_type. Otherwise the requested type and return type should be same. Signed-off-by: Venkatesh Pallipadi LKML-Reference: <20100224214355.GA16431@linux-os.sc.intel.com> Tested-by: Jack Steiner Signed-off-by: H. Peter Anvin --- arch/x86/mm/pat_rbtree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c index 9063f40b638b..07de4cb8cc30 100644 --- a/arch/x86/mm/pat_rbtree.c +++ b/arch/x86/mm/pat_rbtree.c @@ -223,7 +223,9 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) new->type, ret_type); if (!err) { - new->type = *ret_type; + if (ret_type) + new->type = *ret_type; + memtype_rb_insert(&memtype_rbroot, new); } return err; -- cgit v1.2.3-59-g8ed1b From ced918eb748ce30b3aace549fd17540e40ffdca0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 17 Feb 2010 16:47:10 +0000 Subject: i8253: Convert i8253_lock to raw_spinlock i8253_lock needs to be a real spinlock in preempt-rt, i.e. it can not be converted to a sleeping lock. Convert it to raw_spinlock and fix up all users. Signed-off-by: Thomas Gleixner Acked-by: Ralf Baechle Acked-by: Dmitry Torokhov Acked-by: Takashi Iwai Cc: Jens Axboe LKML-Reference: <20100217163751.030764372@linutronix.de> --- arch/mips/include/asm/i8253.h | 2 +- arch/mips/kernel/i8253.c | 14 +++++++------- arch/x86/include/asm/i8253.h | 2 +- arch/x86/kernel/apm_32.c | 4 ++-- arch/x86/kernel/i8253.c | 14 +++++++------- drivers/block/hd.c | 4 ++-- drivers/input/gameport/gameport.c | 4 ++-- drivers/input/joystick/analog.c | 4 ++-- drivers/input/misc/pcspkr.c | 6 +++--- sound/drivers/pcsp/pcsp.h | 2 +- sound/drivers/pcsp/pcsp_input.c | 4 ++-- sound/drivers/pcsp/pcsp_lib.c | 12 ++++++------ 12 files changed, 36 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/i8253.h b/arch/mips/include/asm/i8253.h index 032ca73f181b..48bb82372994 100644 --- a/arch/mips/include/asm/i8253.h +++ b/arch/mips/include/asm/i8253.h @@ -12,7 +12,7 @@ #define PIT_CH0 0x40 #define PIT_CH2 0x42 -extern spinlock_t i8253_lock; +extern raw_spinlock_t i8253_lock; extern void setup_pit_timer(void); diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index ed5c441615e4..94794062a177 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/i8253.c @@ -15,7 +15,7 @@ #include #include -DEFINE_SPINLOCK(i8253_lock); +DEFINE_RAW_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); /* @@ -26,7 +26,7 @@ EXPORT_SYMBOL(i8253_lock); static void init_pit_timer(enum clock_event_mode mode, struct clock_event_device *evt) { - spin_lock(&i8253_lock); + raw_spin_lock(&i8253_lock); switch(mode) { case CLOCK_EVT_MODE_PERIODIC: @@ -55,7 +55,7 @@ static void init_pit_timer(enum clock_event_mode mode, /* Nothing to do here */ break; } - spin_unlock(&i8253_lock); + raw_spin_unlock(&i8253_lock); } /* @@ -65,10 +65,10 @@ static void init_pit_timer(enum clock_event_mode mode, */ static int pit_next_event(unsigned long delta, struct clock_event_device *evt) { - spin_lock(&i8253_lock); + raw_spin_lock(&i8253_lock); outb_p(delta & 0xff , PIT_CH0); /* LSB */ outb(delta >> 8 , PIT_CH0); /* MSB */ - spin_unlock(&i8253_lock); + raw_spin_unlock(&i8253_lock); return 0; } @@ -137,7 +137,7 @@ static cycle_t pit_read(struct clocksource *cs) static int old_count; static u32 old_jifs; - spin_lock_irqsave(&i8253_lock, flags); + raw_spin_lock_irqsave(&i8253_lock, flags); /* * Although our caller may have the read side of xtime_lock, * this is now a seqlock, and we are cheating in this routine @@ -183,7 +183,7 @@ static cycle_t pit_read(struct clocksource *cs) old_count = count; old_jifs = jifs; - spin_unlock_irqrestore(&i8253_lock, flags); + raw_spin_unlock_irqrestore(&i8253_lock, flags); count = (LATCH - 1) - count; diff --git a/arch/x86/include/asm/i8253.h b/arch/x86/include/asm/i8253.h index 1edbf89680fd..fc1f579fb965 100644 --- a/arch/x86/include/asm/i8253.h +++ b/arch/x86/include/asm/i8253.h @@ -6,7 +6,7 @@ #define PIT_CH0 0x40 #define PIT_CH2 0x42 -extern spinlock_t i8253_lock; +extern raw_spinlock_t i8253_lock; extern struct clock_event_device *global_clock_event; diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 031aa887b0eb..c4f9182ca3ac 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -1224,7 +1224,7 @@ static void reinit_timer(void) #ifdef INIT_TIMER_AFTER_SUSPEND unsigned long flags; - spin_lock_irqsave(&i8253_lock, flags); + raw_spin_lock_irqsave(&i8253_lock, flags); /* set the clock to HZ */ outb_pit(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ udelay(10); @@ -1232,7 +1232,7 @@ static void reinit_timer(void) udelay(10); outb_pit(LATCH >> 8, PIT_CH0); /* MSB */ udelay(10); - spin_unlock_irqrestore(&i8253_lock, flags); + raw_spin_unlock_irqrestore(&i8253_lock, flags); #endif } diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c index 23c167925a5c..2dfd31597443 100644 --- a/arch/x86/kernel/i8253.c +++ b/arch/x86/kernel/i8253.c @@ -16,7 +16,7 @@ #include #include -DEFINE_SPINLOCK(i8253_lock); +DEFINE_RAW_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); /* @@ -33,7 +33,7 @@ struct clock_event_device *global_clock_event; static void init_pit_timer(enum clock_event_mode mode, struct clock_event_device *evt) { - spin_lock(&i8253_lock); + raw_spin_lock(&i8253_lock); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: @@ -62,7 +62,7 @@ static void init_pit_timer(enum clock_event_mode mode, /* Nothing to do here */ break; } - spin_unlock(&i8253_lock); + raw_spin_unlock(&i8253_lock); } /* @@ -72,10 +72,10 @@ static void init_pit_timer(enum clock_event_mode mode, */ static int pit_next_event(unsigned long delta, struct clock_event_device *evt) { - spin_lock(&i8253_lock); + raw_spin_lock(&i8253_lock); outb_pit(delta & 0xff , PIT_CH0); /* LSB */ outb_pit(delta >> 8 , PIT_CH0); /* MSB */ - spin_unlock(&i8253_lock); + raw_spin_unlock(&i8253_lock); return 0; } @@ -130,7 +130,7 @@ static cycle_t pit_read(struct clocksource *cs) int count; u32 jifs; - spin_lock_irqsave(&i8253_lock, flags); + raw_spin_lock_irqsave(&i8253_lock, flags); /* * Although our caller may have the read side of xtime_lock, * this is now a seqlock, and we are cheating in this routine @@ -176,7 +176,7 @@ static cycle_t pit_read(struct clocksource *cs) old_count = count; old_jifs = jifs; - spin_unlock_irqrestore(&i8253_lock, flags); + raw_spin_unlock_irqrestore(&i8253_lock, flags); count = (LATCH - 1) - count; diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 5116c65c07cb..b9868ad0278d 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -165,12 +165,12 @@ unsigned long read_timer(void) unsigned long t, flags; int i; - spin_lock_irqsave(&i8253_lock, flags); + raw_spin_lock_irqsave(&i8253_lock, flags); t = jiffies * 11932; outb_p(0, 0x43); i = inb_p(0x40); i |= inb(0x40) << 8; - spin_unlock_irqrestore(&i8253_lock, flags); + raw_spin_unlock_irqrestore(&i8253_lock, flags); return(t - i); } #endif diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 7e18bcf05a66..46239e47a260 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -59,11 +59,11 @@ static unsigned int get_time_pit(void) unsigned long flags; unsigned int count; - spin_lock_irqsave(&i8253_lock, flags); + raw_spin_lock_irqsave(&i8253_lock, flags); outb_p(0x00, 0x43); count = inb_p(0x40); count |= inb_p(0x40) << 8; - spin_unlock_irqrestore(&i8253_lock, flags); + raw_spin_unlock_irqrestore(&i8253_lock, flags); return count; } diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 1c0b529c06aa..4afe0a3b4884 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -146,11 +146,11 @@ static unsigned int get_time_pit(void) unsigned long flags; unsigned int count; - spin_lock_irqsave(&i8253_lock, flags); + raw_spin_lock_irqsave(&i8253_lock, flags); outb_p(0x00, 0x43); count = inb_p(0x40); count |= inb_p(0x40) << 8; - spin_unlock_irqrestore(&i8253_lock, flags); + raw_spin_unlock_irqrestore(&i8253_lock, flags); return count; } diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index ea4e1fd12651..f080dd31499b 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -30,7 +30,7 @@ MODULE_ALIAS("platform:pcspkr"); #include #else #include -static DEFINE_SPINLOCK(i8253_lock); +static DEFINE_RAW_SPINLOCK(i8253_lock); #endif static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) @@ -50,7 +50,7 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c if (value > 20 && value < 32767) count = PIT_TICK_RATE / value; - spin_lock_irqsave(&i8253_lock, flags); + raw_spin_lock_irqsave(&i8253_lock, flags); if (count) { /* set command for counter 2, 2 byte write */ @@ -65,7 +65,7 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c outb(inb_p(0x61) & 0xFC, 0x61); } - spin_unlock_irqrestore(&i8253_lock, flags); + raw_spin_unlock_irqrestore(&i8253_lock, flags); return 0; } diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h index 1e123077923d..4ff6c8cc5077 100644 --- a/sound/drivers/pcsp/pcsp.h +++ b/sound/drivers/pcsp/pcsp.h @@ -16,7 +16,7 @@ #include #else #include -static DEFINE_SPINLOCK(i8253_lock); +static DEFINE_RAW_SPINLOCK(i8253_lock); #endif #define PCSP_SOUND_VERSION 0x400 /* read 4.00 */ diff --git a/sound/drivers/pcsp/pcsp_input.c b/sound/drivers/pcsp/pcsp_input.c index 0444cdeb4bec..b5e2b54c2604 100644 --- a/sound/drivers/pcsp/pcsp_input.c +++ b/sound/drivers/pcsp/pcsp_input.c @@ -21,7 +21,7 @@ static void pcspkr_do_sound(unsigned int count) { unsigned long flags; - spin_lock_irqsave(&i8253_lock, flags); + raw_spin_lock_irqsave(&i8253_lock, flags); if (count) { /* set command for counter 2, 2 byte write */ @@ -36,7 +36,7 @@ static void pcspkr_do_sound(unsigned int count) outb(inb_p(0x61) & 0xFC, 0x61); } - spin_unlock_irqrestore(&i8253_lock, flags); + raw_spin_unlock_irqrestore(&i8253_lock, flags); } void pcspkr_stop_sound(void) diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index e1145ac6e908..f6a2e72b8cde 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -65,7 +65,7 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip) timer_cnt = val * CUR_DIV() / 256; if (timer_cnt && chip->enable) { - spin_lock_irqsave(&i8253_lock, flags); + raw_spin_lock_irqsave(&i8253_lock, flags); if (!nforce_wa) { outb_p(chip->val61, 0x61); outb_p(timer_cnt, 0x42); @@ -74,7 +74,7 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip) outb(chip->val61 ^ 2, 0x61); chip->thalf = 1; } - spin_unlock_irqrestore(&i8253_lock, flags); + raw_spin_unlock_irqrestore(&i8253_lock, flags); } chip->ns_rem = PCSP_PERIOD_NS(); @@ -158,10 +158,10 @@ static int pcsp_start_playing(struct snd_pcsp *chip) return -EIO; } - spin_lock(&i8253_lock); + raw_spin_lock(&i8253_lock); chip->val61 = inb(0x61) | 0x03; outb_p(0x92, 0x43); /* binary, mode 1, LSB only, ch 2 */ - spin_unlock(&i8253_lock); + raw_spin_unlock(&i8253_lock); atomic_set(&chip->timer_active, 1); chip->thalf = 0; @@ -178,11 +178,11 @@ static void pcsp_stop_playing(struct snd_pcsp *chip) return; atomic_set(&chip->timer_active, 0); - spin_lock(&i8253_lock); + raw_spin_lock(&i8253_lock); /* restore the timer */ outb_p(0xb6, 0x43); /* binary, mode 3, LSB/MSB, ch 2 */ outb(chip->val61 & 0xFC, 0x61); - spin_unlock(&i8253_lock); + raw_spin_unlock(&i8253_lock); } /* -- cgit v1.2.3-59-g8ed1b From 4abc14a733f9002c05623db755aaafdd27fa7a91 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 20 Jan 2010 14:52:23 +0100 Subject: iommu-api: Rename ->{un}map function pointers to ->{un}map_range The new function pointer names match better with the top-level functions of the iommu-api which are using them. Main intention of this change is to make the ->{un}map pointer names free for two new mapping functions. Signed-off-by: Joerg Roedel --- arch/x86/kernel/amd_iommu.c | 4 ++-- drivers/base/iommu.c | 4 ++-- drivers/pci/intel-iommu.c | 4 ++-- include/linux/iommu.h | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index adb0ba025702..59cae7c4df54 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2515,8 +2515,8 @@ static struct iommu_ops amd_iommu_ops = { .domain_destroy = amd_iommu_domain_destroy, .attach_dev = amd_iommu_attach_device, .detach_dev = amd_iommu_detach_device, - .map = amd_iommu_map_range, - .unmap = amd_iommu_unmap_range, + .map_range = amd_iommu_map_range, + .unmap_range = amd_iommu_unmap_range, .iova_to_phys = amd_iommu_iova_to_phys, .domain_has_cap = amd_iommu_domain_has_cap, }; diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c index 8ad4ffea6920..f4c86c429297 100644 --- a/drivers/base/iommu.c +++ b/drivers/base/iommu.c @@ -83,14 +83,14 @@ EXPORT_SYMBOL_GPL(iommu_detach_device); int iommu_map_range(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot) { - return iommu_ops->map(domain, iova, paddr, size, prot); + return iommu_ops->map_range(domain, iova, paddr, size, prot); } EXPORT_SYMBOL_GPL(iommu_map_range); void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova, size_t size) { - iommu_ops->unmap(domain, iova, size); + iommu_ops->unmap_range(domain, iova, size); } EXPORT_SYMBOL_GPL(iommu_unmap_range); diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 417312528ddf..a714e3db13c1 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -3714,8 +3714,8 @@ static struct iommu_ops intel_iommu_ops = { .domain_destroy = intel_iommu_domain_destroy, .attach_dev = intel_iommu_attach_device, .detach_dev = intel_iommu_detach_device, - .map = intel_iommu_map_range, - .unmap = intel_iommu_unmap_range, + .map_range = intel_iommu_map_range, + .unmap_range = intel_iommu_unmap_range, .iova_to_phys = intel_iommu_iova_to_phys, .domain_has_cap = intel_iommu_domain_has_cap, }; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 3af4ffd591b9..0f18f37a6503 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -36,10 +36,10 @@ struct iommu_ops { void (*domain_destroy)(struct iommu_domain *domain); int (*attach_dev)(struct iommu_domain *domain, struct device *dev); void (*detach_dev)(struct iommu_domain *domain, struct device *dev); - int (*map)(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot); - void (*unmap)(struct iommu_domain *domain, unsigned long iova, - size_t size); + int (*map_range)(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t size, int prot); + void (*unmap_range)(struct iommu_domain *domain, unsigned long iova, + size_t size); phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, unsigned long iova); int (*domain_has_cap)(struct iommu_domain *domain, -- cgit v1.2.3-59-g8ed1b From cbb9d729f3433c9c2660b01dc52e6deb89488886 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 15 Jan 2010 14:41:15 +0100 Subject: x86/amd-iommu: Make iommu_map_page and alloc_pte aware of page sizes This patch changes the old map_size parameter of alloc_pte to a page_size parameter which can be used more easily to alloc a pte for intermediate page sizes. Signed-off-by: Joerg Roedel --- arch/x86/include/asm/amd_iommu_types.h | 28 ++++++++++++++++++ arch/x86/kernel/amd_iommu.c | 53 +++++++++++++++++++++------------- 2 files changed, 61 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index ba19ad4c47d0..5e8da56755dd 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h @@ -172,6 +172,34 @@ (~((1ULL << (12 + ((lvl) * 9))) - 1))) #define PM_ALIGNED(lvl, addr) ((PM_MAP_MASK(lvl) & (addr)) == (addr)) +/* + * Returns the page table level to use for a given page size + * Pagesize is expected to be a power-of-two + */ +#define PAGE_SIZE_LEVEL(pagesize) \ + ((__ffs(pagesize) - 12) / 9) +/* + * Returns the number of ptes to use for a given page size + * Pagesize is expected to be a power-of-two + */ +#define PAGE_SIZE_PTE_COUNT(pagesize) \ + (1ULL << ((__ffs(pagesize) - 12) % 9)) + +/* + * Aligns a given io-virtual address to a given page size + * Pagesize is expected to be a power-of-two + */ +#define PAGE_SIZE_ALIGN(address, pagesize) \ + ((address) & ~((pagesize) - 1)) +/* + * Creates an IOMMU PTE for an address an a given pagesize + * The PTE has no permission bits set + * Pagesize is expected to be a power-of-two larger than 4096 + */ +#define PAGE_SIZE_PTE(address, pagesize) \ + (((address) | ((pagesize) - 1)) & \ + (~(pagesize >> 1)) & PM_ADDR_MASK) + #define IOMMU_PTE_P (1ULL << 0) #define IOMMU_PTE_TV (1ULL << 1) #define IOMMU_PTE_U (1ULL << 59) diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 59cae7c4df54..41700314f3e0 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -730,18 +730,22 @@ static bool increase_address_space(struct protection_domain *domain, static u64 *alloc_pte(struct protection_domain *domain, unsigned long address, - int end_lvl, + unsigned long page_size, u64 **pte_page, gfp_t gfp) { + int level, end_lvl; u64 *pte, *page; - int level; + + BUG_ON(!is_power_of_2(page_size)); while (address > PM_LEVEL_SIZE(domain->mode)) increase_address_space(domain, gfp); - level = domain->mode - 1; - pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; + level = domain->mode - 1; + pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; + address = PAGE_SIZE_ALIGN(address, page_size); + end_lvl = PAGE_SIZE_LEVEL(page_size); while (level > end_lvl) { if (!IOMMU_PTE_PRESENT(*pte)) { @@ -751,6 +755,10 @@ static u64 *alloc_pte(struct protection_domain *domain, *pte = PM_LEVEL_PDE(level, virt_to_phys(page)); } + /* No level skipping support yet */ + if (PM_PTE_LEVEL(*pte) != level) + return NULL; + level -= 1; pte = IOMMU_PTE_PAGE(*pte); @@ -806,31 +814,36 @@ static int iommu_map_page(struct protection_domain *dom, unsigned long bus_addr, unsigned long phys_addr, int prot, - int map_size) + unsigned long page_size) { u64 __pte, *pte; - - bus_addr = PAGE_ALIGN(bus_addr); - phys_addr = PAGE_ALIGN(phys_addr); - - BUG_ON(!PM_ALIGNED(map_size, bus_addr)); - BUG_ON(!PM_ALIGNED(map_size, phys_addr)); + int i, count; if (!(prot & IOMMU_PROT_MASK)) return -EINVAL; - pte = alloc_pte(dom, bus_addr, map_size, NULL, GFP_KERNEL); + bus_addr = PAGE_ALIGN(bus_addr); + phys_addr = PAGE_ALIGN(phys_addr); + count = PAGE_SIZE_PTE_COUNT(page_size); + pte = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL); + + for (i = 0; i < count; ++i) + if (IOMMU_PTE_PRESENT(pte[i])) + return -EBUSY; - if (IOMMU_PTE_PRESENT(*pte)) - return -EBUSY; + if (page_size > PAGE_SIZE) { + __pte = PAGE_SIZE_PTE(phys_addr, page_size); + __pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC; + } else + __pte = phys_addr | IOMMU_PTE_P | IOMMU_PTE_FC; - __pte = phys_addr | IOMMU_PTE_P; if (prot & IOMMU_PROT_IR) __pte |= IOMMU_PTE_IR; if (prot & IOMMU_PROT_IW) __pte |= IOMMU_PTE_IW; - *pte = __pte; + for (i = 0; i < count; ++i) + pte[i] = __pte; update_domain(dom); @@ -877,7 +890,7 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, for (addr = e->address_start; addr < e->address_end; addr += PAGE_SIZE) { ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot, - PM_MAP_4k); + PAGE_SIZE); if (ret) return ret; /* @@ -1005,7 +1018,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom, u64 *pte, *pte_page; for (i = 0; i < num_ptes; ++i) { - pte = alloc_pte(&dma_dom->domain, address, PM_MAP_4k, + pte = alloc_pte(&dma_dom->domain, address, PAGE_SIZE, &pte_page, gfp); if (!pte) goto out_free; @@ -1711,7 +1724,7 @@ static u64* dma_ops_get_pte(struct dma_ops_domain *dom, pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)]; if (!pte) { - pte = alloc_pte(&dom->domain, address, PM_MAP_4k, &pte_page, + pte = alloc_pte(&dom->domain, address, PAGE_SIZE, &pte_page, GFP_ATOMIC); aperture->pte_pages[APERTURE_PAGE_INDEX(address)] = pte_page; } else @@ -2457,7 +2470,7 @@ static int amd_iommu_map_range(struct iommu_domain *dom, paddr &= PAGE_MASK; for (i = 0; i < npages; ++i) { - ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k); + ret = iommu_map_page(domain, iova, paddr, prot, PAGE_SIZE); if (ret) return ret; -- cgit v1.2.3-59-g8ed1b From 24cd772315c19e4d9409d0d21367ec1ebab3149f Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Tue, 19 Jan 2010 17:27:39 +0100 Subject: x86/amd-iommu: Make iommu_unmap_page and fetch_pte aware of page sizes This patch extends the functionality of iommu_unmap_page and fetch_pte to support arbitrary page sizes. Signed-off-by: Joerg Roedel --- arch/x86/include/asm/amd_iommu_types.h | 6 +++ arch/x86/kernel/amd_iommu.c | 90 +++++++++++++++++++++++++++------- 2 files changed, 78 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index 5e8da56755dd..b150c74e0d48 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h @@ -200,6 +200,12 @@ (((address) | ((pagesize) - 1)) & \ (~(pagesize >> 1)) & PM_ADDR_MASK) +/* + * Takes a PTE value with mode=0x07 and returns the page size it maps + */ +#define PTE_PAGE_SIZE(pte) \ + (1ULL << (1 + ffz(((pte) | 0xfffULL)))) + #define IOMMU_PTE_P (1ULL << 0) #define IOMMU_PTE_TV (1ULL << 1) #define IOMMU_PTE_U (1ULL << 59) diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 41700314f3e0..503d312f9d6f 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -776,28 +776,47 @@ static u64 *alloc_pte(struct protection_domain *domain, * This function checks if there is a PTE for a given dma address. If * there is one, it returns the pointer to it. */ -static u64 *fetch_pte(struct protection_domain *domain, - unsigned long address, int map_size) +static u64 *fetch_pte(struct protection_domain *domain, unsigned long address) { int level; u64 *pte; - level = domain->mode - 1; - pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; + if (address > PM_LEVEL_SIZE(domain->mode)) + return NULL; + + level = domain->mode - 1; + pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; - while (level > map_size) { + while (level > 0) { + + /* Not Present */ if (!IOMMU_PTE_PRESENT(*pte)) return NULL; + /* Large PTE */ + if (PM_PTE_LEVEL(*pte) == 0x07) { + unsigned long pte_mask, __pte; + + /* + * If we have a series of large PTEs, make + * sure to return a pointer to the first one. + */ + pte_mask = PTE_PAGE_SIZE(*pte); + pte_mask = ~((PAGE_SIZE_PTE_COUNT(pte_mask) << 3) - 1); + __pte = ((unsigned long)pte) & pte_mask; + + return (u64 *)__pte; + } + + /* No level skipping support yet */ + if (PM_PTE_LEVEL(*pte) != level) + return NULL; + level -= 1; + /* Walk to the next level */ pte = IOMMU_PTE_PAGE(*pte); pte = &pte[PM_LEVEL_INDEX(level, address)]; - - if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) { - pte = NULL; - break; - } } return pte; @@ -850,13 +869,48 @@ static int iommu_map_page(struct protection_domain *dom, return 0; } -static void iommu_unmap_page(struct protection_domain *dom, - unsigned long bus_addr, int map_size) +static unsigned long iommu_unmap_page(struct protection_domain *dom, + unsigned long bus_addr, + unsigned long page_size) { - u64 *pte = fetch_pte(dom, bus_addr, map_size); + unsigned long long unmap_size, unmapped; + u64 *pte; + + BUG_ON(!is_power_of_2(page_size)); + + unmapped = 0; + + while (unmapped < page_size) { + + pte = fetch_pte(dom, bus_addr); + + if (!pte) { + /* + * No PTE for this address + * move forward in 4kb steps + */ + unmap_size = PAGE_SIZE; + } else if (PM_PTE_LEVEL(*pte) == 0) { + /* 4kb PTE found for this address */ + unmap_size = PAGE_SIZE; + *pte = 0ULL; + } else { + int count, i; + + /* Large PTE found which maps this address */ + unmap_size = PTE_PAGE_SIZE(*pte); + count = PAGE_SIZE_PTE_COUNT(unmap_size); + for (i = 0; i < count; i++) + pte[i] = 0ULL; + } + + bus_addr = (bus_addr & ~(unmap_size - 1)) + unmap_size; + unmapped += unmap_size; + } + + BUG_ON(!is_power_of_2(unmapped)); - if (pte) - *pte = 0; + return unmapped; } /* @@ -1054,7 +1108,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom, for (i = dma_dom->aperture[index]->offset; i < dma_dom->aperture_size; i += PAGE_SIZE) { - u64 *pte = fetch_pte(&dma_dom->domain, i, PM_MAP_4k); + u64 *pte = fetch_pte(&dma_dom->domain, i); if (!pte || !IOMMU_PTE_PRESENT(*pte)) continue; @@ -2491,7 +2545,7 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom, iova &= PAGE_MASK; for (i = 0; i < npages; ++i) { - iommu_unmap_page(domain, iova, PM_MAP_4k); + iommu_unmap_page(domain, iova, PAGE_SIZE); iova += PAGE_SIZE; } @@ -2506,7 +2560,7 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, phys_addr_t paddr; u64 *pte; - pte = fetch_pte(domain, iova, PM_MAP_4k); + pte = fetch_pte(domain, iova); if (!pte || !IOMMU_PTE_PRESENT(*pte)) return 0; -- cgit v1.2.3-59-g8ed1b From f03152bb7d0a74f409ad63ed36916444a7493d72 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 21 Jan 2010 16:15:24 +0100 Subject: x86/amd-iommu: Make amd_iommu_iova_to_phys aware of multiple page sizes This patch extends the amd_iommu_iova_to_phys() function to handle different page sizes correctly. It doesn't use fetch_pte() anymore because we don't know (or care about) the page_size used for mapping the given iova. Signed-off-by: Joerg Roedel --- arch/x86/kernel/amd_iommu.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 503d312f9d6f..52e44af15705 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2556,17 +2556,22 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, unsigned long iova) { struct protection_domain *domain = dom->priv; - unsigned long offset = iova & ~PAGE_MASK; + unsigned long offset_mask; phys_addr_t paddr; - u64 *pte; + u64 *pte, __pte; pte = fetch_pte(domain, iova); if (!pte || !IOMMU_PTE_PRESENT(*pte)) return 0; - paddr = *pte & IOMMU_PAGE_MASK; - paddr |= offset; + if (PM_PTE_LEVEL(*pte) == 0) + offset_mask = PAGE_SIZE - 1; + else + offset_mask = PTE_PAGE_SIZE(*pte) - 1; + + __pte = *pte & PM_ADDR_MASK; + paddr = (__pte & ~offset_mask) | (iova & offset_mask); return paddr; } -- cgit v1.2.3-59-g8ed1b From 468e2366cdb80cf8a691b8bc212260cfbdbd518e Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 21 Jan 2010 16:37:36 +0100 Subject: x86/amd-iommu: Implement ->{un}map callbacks for iommu-api This patch implements the new callbacks for the IOMMU-API with functions that can handle different page sizes in the IOMMU page table. Signed-off-by: Joerg Roedel --- arch/x86/kernel/amd_iommu.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 52e44af15705..0e068c9ca5f5 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2552,6 +2552,33 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom, iommu_flush_tlb_pde(domain); } +static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, + phys_addr_t paddr, int gfp_order, int iommu_prot) +{ + unsigned long page_size = 0x1000UL << gfp_order; + struct protection_domain *domain = dom->priv; + int prot = 0; + + if (iommu_prot & IOMMU_READ) + prot |= IOMMU_PROT_IR; + if (iommu_prot & IOMMU_WRITE) + prot |= IOMMU_PROT_IW; + + return iommu_map_page(domain, iova, paddr, prot, page_size); +} + +static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, + int gfp_order) +{ + struct protection_domain *domain = dom->priv; + unsigned long page_size, unmap_size; + + page_size = 0x1000UL << gfp_order; + unmap_size = iommu_unmap_page(domain, iova, page_size); + + return get_order(unmap_size); +} + static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, unsigned long iova) { @@ -2587,6 +2614,8 @@ static struct iommu_ops amd_iommu_ops = { .domain_destroy = amd_iommu_domain_destroy, .attach_dev = amd_iommu_attach_device, .detach_dev = amd_iommu_detach_device, + .map = amd_iommu_map, + .unmap = amd_iommu_unmap, .map_range = amd_iommu_map_range, .unmap_range = amd_iommu_unmap_range, .iova_to_phys = amd_iommu_iova_to_phys, -- cgit v1.2.3-59-g8ed1b From 12c7389abe5786349d3ea6da1961cf78d0c1c7cd Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 21 Jan 2010 11:50:28 +0100 Subject: iommu-api: Remove iommu_{un}map_range functions These functions are not longer used and can be removed savely. There functionality is now provided by the iommu_{un}map functions which are also capable of multiple page sizes. Signed-off-by: Joerg Roedel --- arch/x86/kernel/amd_iommu.c | 48 --------------------------------------------- drivers/base/iommu.c | 26 ++---------------------- include/linux/iommu.h | 20 ------------------- 3 files changed, 2 insertions(+), 92 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 0e068c9ca5f5..d8da9988edd9 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2506,52 +2506,6 @@ static int amd_iommu_attach_device(struct iommu_domain *dom, return ret; } -static int amd_iommu_map_range(struct iommu_domain *dom, - unsigned long iova, phys_addr_t paddr, - size_t size, int iommu_prot) -{ - struct protection_domain *domain = dom->priv; - unsigned long i, npages = iommu_num_pages(paddr, size, PAGE_SIZE); - int prot = 0; - int ret; - - if (iommu_prot & IOMMU_READ) - prot |= IOMMU_PROT_IR; - if (iommu_prot & IOMMU_WRITE) - prot |= IOMMU_PROT_IW; - - iova &= PAGE_MASK; - paddr &= PAGE_MASK; - - for (i = 0; i < npages; ++i) { - ret = iommu_map_page(domain, iova, paddr, prot, PAGE_SIZE); - if (ret) - return ret; - - iova += PAGE_SIZE; - paddr += PAGE_SIZE; - } - - return 0; -} - -static void amd_iommu_unmap_range(struct iommu_domain *dom, - unsigned long iova, size_t size) -{ - - struct protection_domain *domain = dom->priv; - unsigned long i, npages = iommu_num_pages(iova, size, PAGE_SIZE); - - iova &= PAGE_MASK; - - for (i = 0; i < npages; ++i) { - iommu_unmap_page(domain, iova, PAGE_SIZE); - iova += PAGE_SIZE; - } - - iommu_flush_tlb_pde(domain); -} - static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, phys_addr_t paddr, int gfp_order, int iommu_prot) { @@ -2616,8 +2570,6 @@ static struct iommu_ops amd_iommu_ops = { .detach_dev = amd_iommu_detach_device, .map = amd_iommu_map, .unmap = amd_iommu_unmap, - .map_range = amd_iommu_map_range, - .unmap_range = amd_iommu_unmap_range, .iova_to_phys = amd_iommu_iova_to_phys, .domain_has_cap = amd_iommu_domain_has_cap, }; diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c index 55d37e4609eb..6e6b6a11b3ce 100644 --- a/drivers/base/iommu.c +++ b/drivers/base/iommu.c @@ -80,20 +80,6 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev) } EXPORT_SYMBOL_GPL(iommu_detach_device); -int iommu_map_range(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) -{ - return iommu_ops->map_range(domain, iova, paddr, size, prot); -} -EXPORT_SYMBOL_GPL(iommu_map_range); - -void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova, - size_t size) -{ - iommu_ops->unmap_range(domain, iova, size); -} -EXPORT_SYMBOL_GPL(iommu_unmap_range); - phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, unsigned long iova) { @@ -119,10 +105,7 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova, BUG_ON((iova | paddr) & invalid_mask); - if (iommu_ops->map) - return iommu_ops->map(domain, iova, paddr, gfp_order, prot); - - return iommu_ops->map_range(domain, iova, paddr, size, prot); + return iommu_ops->map(domain, iova, paddr, gfp_order, prot); } EXPORT_SYMBOL_GPL(iommu_map); @@ -136,11 +119,6 @@ int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order) BUG_ON(iova & invalid_mask); - if (iommu_ops->unmap) - return iommu_ops->unmap(domain, iova, gfp_order); - - iommu_ops->unmap_range(domain, iova, size); - - return gfp_order; + return iommu_ops->unmap(domain, iova, gfp_order); } EXPORT_SYMBOL_GPL(iommu_unmap); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 5a7a3d888dac..be22ad83689c 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -40,10 +40,6 @@ struct iommu_ops { phys_addr_t paddr, int gfp_order, int prot); int (*unmap)(struct iommu_domain *domain, unsigned long iova, int gfp_order); - int (*map_range)(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot); - void (*unmap_range)(struct iommu_domain *domain, unsigned long iova, - size_t size); phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, unsigned long iova); int (*domain_has_cap)(struct iommu_domain *domain, @@ -60,10 +56,6 @@ extern int iommu_attach_device(struct iommu_domain *domain, struct device *dev); extern void iommu_detach_device(struct iommu_domain *domain, struct device *dev); -extern int iommu_map_range(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot); -extern void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova, - size_t size); extern int iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, int gfp_order, int prot); extern int iommu_unmap(struct iommu_domain *domain, unsigned long iova, @@ -104,18 +96,6 @@ static inline void iommu_detach_device(struct iommu_domain *domain, { } -static inline int iommu_map_range(struct iommu_domain *domain, - unsigned long iova, phys_addr_t paddr, - size_t size, int prot) -{ - return -ENODEV; -} - -static inline void iommu_unmap_range(struct iommu_domain *domain, - unsigned long iova, size_t size) -{ -} - static inline int iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, int gfp_order, int prot) { -- cgit v1.2.3-59-g8ed1b From 51a5006afcd13176276f0935ee57c4cc6f210e83 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 8 Mar 2010 21:45:19 +0900 Subject: sh: Merge clkdev API updates. This rolls in the remainder of the clkdev API bits from the ARM tree. This can more or less be used verbatim, so we just copy it over and nuke our local version. Signed-off-by: Paul Mundt --- arch/sh/include/asm/clkdev.h | 35 ++++++++++ arch/sh/include/asm/clock.h | 7 -- arch/sh/kernel/Makefile | 2 +- arch/sh/kernel/clkdev.c | 162 +++++++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/cpu/clock.c | 55 +-------------- 5 files changed, 199 insertions(+), 62 deletions(-) create mode 100644 arch/sh/include/asm/clkdev.h create mode 100644 arch/sh/kernel/clkdev.c (limited to 'arch') diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h new file mode 100644 index 000000000000..5645f358128b --- /dev/null +++ b/arch/sh/include/asm/clkdev.h @@ -0,0 +1,35 @@ +/* + * arch/sh/include/asm/clkdev.h + * + * Cloned from arch/arm/include/asm/clkdev.h: + * + * Copyright (C) 2008 Russell King. + * + * 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. + * + * Helper for the clk API to assist looking up a struct clk. + */ +#ifndef __ASM_CLKDEV_H +#define __ASM_CLKDEV_H + +struct clk; + +struct clk_lookup { + struct list_head node; + const char *dev_id; + const char *con_id; + struct clk *clk; +}; + +struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, + const char *dev_fmt, ...); + +void clkdev_add(struct clk_lookup *cl); +void clkdev_drop(struct clk_lookup *cl); + +void clkdev_add_table(struct clk_lookup *, size_t); +int clk_add_alias(const char *, const char *, char *, struct device *); + +#endif diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 11da4c5beb68..4b19179230fe 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -45,13 +45,6 @@ struct clk { struct cpufreq_frequency_table *freq_table; }; -struct clk_lookup { - struct list_head node; - const char *dev_id; - const char *con_id; - struct clk *clk; -}; - #define CLK_ENABLE_ON_INIT (1 << 0) /* Should be defined by processor-specific code */ diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 02fd3ae8b0ee..650b92f00ee5 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -11,7 +11,7 @@ endif CFLAGS_REMOVE_return_address.o = -pg -obj-y := debugtraps.o dma-nommu.o dumpstack.o \ +obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \ idle.o io.o io_generic.o irq.o \ irq_$(BITS).o machvec.o nmi_debug.o process.o \ process_$(BITS).o ptrace_$(BITS).o \ diff --git a/arch/sh/kernel/clkdev.c b/arch/sh/kernel/clkdev.c new file mode 100644 index 000000000000..29cd802ac388 --- /dev/null +++ b/arch/sh/kernel/clkdev.c @@ -0,0 +1,162 @@ +/* + * arch/sh/kernel/clkdev.c + * + * Cloned from arch/arm/common/clkdev.c: + * + * Copyright (C) 2008 Russell King. + * + * 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. + * + * Helper for the clk API to assist looking up a struct clk. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); + +/* + * Find the correct struct clk for the device and connection ID. + * We do slightly fuzzy matching here: + * An entry with a NULL ID is assumed to be a wildcard. + * If an entry has a device ID, it must match + * If an entry has a connection ID, it must match + * Then we take the most specific entry - with the following + * order of precidence: dev+con > dev only > con only. + */ +static struct clk *clk_find(const char *dev_id, const char *con_id) +{ + struct clk_lookup *p; + struct clk *clk = NULL; + int match, best = 0; + + list_for_each_entry(p, &clocks, node) { + match = 0; + if (p->dev_id) { + if (!dev_id || strcmp(p->dev_id, dev_id)) + continue; + match += 2; + } + if (p->con_id) { + if (!con_id || strcmp(p->con_id, con_id)) + continue; + match += 1; + } + if (match == 0) + continue; + + if (match > best) { + clk = p->clk; + best = match; + } + } + return clk; +} + +struct clk *clk_get_sys(const char *dev_id, const char *con_id) +{ + struct clk *clk; + + mutex_lock(&clocks_mutex); + clk = clk_find(dev_id, con_id); + mutex_unlock(&clocks_mutex); + + return clk ? clk : ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get_sys); + +void clkdev_add(struct clk_lookup *cl) +{ + mutex_lock(&clocks_mutex); + list_add_tail(&cl->node, &clocks); + mutex_unlock(&clocks_mutex); +} +EXPORT_SYMBOL(clkdev_add); + +void __init clkdev_add_table(struct clk_lookup *cl, size_t num) +{ + mutex_lock(&clocks_mutex); + while (num--) { + list_add_tail(&cl->node, &clocks); + cl++; + } + mutex_unlock(&clocks_mutex); +} + +#define MAX_DEV_ID 20 +#define MAX_CON_ID 16 + +struct clk_lookup_alloc { + struct clk_lookup cl; + char dev_id[MAX_DEV_ID]; + char con_id[MAX_CON_ID]; +}; + +struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, + const char *dev_fmt, ...) +{ + struct clk_lookup_alloc *cla; + + cla = kzalloc(sizeof(*cla), GFP_KERNEL); + if (!cla) + return NULL; + + cla->cl.clk = clk; + if (con_id) { + strlcpy(cla->con_id, con_id, sizeof(cla->con_id)); + cla->cl.con_id = cla->con_id; + } + + if (dev_fmt) { + va_list ap; + + va_start(ap, dev_fmt); + vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap); + cla->cl.dev_id = cla->dev_id; + va_end(ap); + } + + return &cla->cl; +} +EXPORT_SYMBOL(clkdev_alloc); + +int clk_add_alias(const char *alias, const char *alias_dev_name, char *id, + struct device *dev) +{ + struct clk *r = clk_get(dev, id); + struct clk_lookup *l; + + if (IS_ERR(r)) + return PTR_ERR(r); + + l = clkdev_alloc(r, alias, alias_dev_name); + clk_put(r); + if (!l) + return -ENODEV; + clkdev_add(l); + return 0; +} +EXPORT_SYMBOL(clk_add_alias); + +/* + * clkdev_drop - remove a clock dynamically allocated + */ +void clkdev_drop(struct clk_lookup *cl) +{ + mutex_lock(&clocks_mutex); + list_del(&cl->node); + mutex_unlock(&clocks_mutex); + kfree(cl); +} +EXPORT_SYMBOL(clkdev_drop); diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 83da5debeedf..9ded1bc29260 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -10,10 +10,6 @@ * * Modified for omap shared clock framework by Tony Lindgren * - * With clkdev bits: - * - * Copyright (C) 2008 Russell King. - * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -30,6 +26,7 @@ #include #include #include +#include #include #include @@ -397,56 +394,6 @@ long clk_round_rate(struct clk *clk, unsigned long rate) } EXPORT_SYMBOL_GPL(clk_round_rate); -/* - * Find the correct struct clk for the device and connection ID. - * We do slightly fuzzy matching here: - * An entry with a NULL ID is assumed to be a wildcard. - * If an entry has a device ID, it must match - * If an entry has a connection ID, it must match - * Then we take the most specific entry - with the following - * order of precidence: dev+con > dev only > con only. - */ -static struct clk *clk_find(const char *dev_id, const char *con_id) -{ - struct clk_lookup *p; - struct clk *clk = NULL; - int match, best = 0; - - list_for_each_entry(p, &clock_list, node) { - match = 0; - if (p->dev_id) { - if (!dev_id || strcmp(p->dev_id, dev_id)) - continue; - match += 2; - } - if (p->con_id) { - if (!con_id || strcmp(p->con_id, con_id)) - continue; - match += 1; - } - if (match == 0) - continue; - - if (match > best) { - clk = p->clk; - best = match; - } - } - return clk; -} - -struct clk *clk_get_sys(const char *dev_id, const char *con_id) -{ - struct clk *clk; - - mutex_lock(&clock_list_sem); - clk = clk_find(dev_id, con_id); - mutex_unlock(&clock_list_sem); - - return clk ? clk : ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL_GPL(clk_get_sys); - /* * Returns a clock. Note that we first try to use device id on the bus * and clock name. If this fails, we try to use clock name only. -- cgit v1.2.3-59-g8ed1b From 2e733b3f84fa9c2ae60513c5f7b56d599ed2ae02 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 8 Mar 2010 21:46:37 +0900 Subject: sh: Support early clkdev allocations. early platform devices and the like may need to set up clock aliases, which require an allocation at a time well before the slab allocators are available. The clock framework comes up after bootmem, so using bootmem as a fallback should be sufficient. Signed-off-by: Paul Mundt --- arch/sh/kernel/clkdev.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/clkdev.c b/arch/sh/kernel/clkdev.c index 29cd802ac388..defdd6e30908 100644 --- a/arch/sh/kernel/clkdev.c +++ b/arch/sh/kernel/clkdev.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #include #include @@ -103,12 +106,16 @@ struct clk_lookup_alloc { char con_id[MAX_CON_ID]; }; -struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, - const char *dev_fmt, ...) +struct clk_lookup * __init_refok +clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...) { struct clk_lookup_alloc *cla; - cla = kzalloc(sizeof(*cla), GFP_KERNEL); + if (!slab_is_available()) + cla = alloc_bootmem_low_pages(sizeof(*cla)); + else + cla = kzalloc(sizeof(*cla), GFP_KERNEL); + if (!cla) return NULL; -- cgit v1.2.3-59-g8ed1b From ec0ffe2ee0e0fb9da4409d86bfd72636450f32df Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 10 Mar 2010 16:28:16 +0900 Subject: sh: Kill off all timer name clobbering. Now that dev_name() can be used early, we no longer require a static string. Kill off all of the superfluous timer names. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 4 ---- arch/sh/kernel/cpu/sh2a/setup-mxg.c | 6 ------ arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 6 ------ arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 8 -------- arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 10 ---------- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 6 ------ arch/sh/kernel/cpu/sh3/setup-sh770x.c | 6 ------ arch/sh/kernel/cpu/sh3/setup-sh7710.c | 6 ------ arch/sh/kernel/cpu/sh3/setup-sh7720.c | 16 ---------------- arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 6 ------ arch/sh/kernel/cpu/sh4/setup-sh7750.c | 10 ---------- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 6 ------ arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 8 -------- arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 8 -------- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 8 -------- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 14 -------------- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 14 -------------- arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 4 ---- arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 12 ------------ arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 18 ------------------ arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 12 ------------ arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 12 ------------ arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 24 ------------------------ arch/sh/kernel/cpu/sh4a/setup-shx3.c | 12 ------------ arch/sh/kernel/cpu/sh5/setup-sh5.c | 6 ------ 25 files changed, 242 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 114c7cee7184..9b96457ccc7b 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -128,7 +128,6 @@ static struct platform_device eth_device = { }; static struct sh_timer_config cmt0_platform_data = { - .name = "CMT0", .channel_offset = 0x02, .timer_bit = 0, .clk = "peripheral_clk", @@ -138,7 +137,6 @@ static struct sh_timer_config cmt0_platform_data = { static struct resource cmt0_resources[] = { [0] = { - .name = "CMT0", .start = 0xf84a0072, .end = 0xf84a0077, .flags = IORESOURCE_MEM, @@ -160,7 +158,6 @@ static struct platform_device cmt0_device = { }; static struct sh_timer_config cmt1_platform_data = { - .name = "CMT1", .channel_offset = 0x08, .timer_bit = 1, .clk = "peripheral_clk", @@ -170,7 +167,6 @@ static struct sh_timer_config cmt1_platform_data = { static struct resource cmt1_resources[] = { [0] = { - .name = "CMT1", .start = 0xf84a0078, .end = 0xf84a007d, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index 8f669dc9b0da..5301450656cc 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -115,7 +115,6 @@ static DECLARE_INTC_DESC(intc_desc, "mxg", vectors, groups, mask_registers, prio_registers, NULL); static struct sh_timer_config mtu2_0_platform_data = { - .name = "MTU2_0", .channel_offset = -0x80, .timer_bit = 0, .clk = "peripheral_clk", @@ -124,7 +123,6 @@ static struct sh_timer_config mtu2_0_platform_data = { static struct resource mtu2_0_resources[] = { [0] = { - .name = "MTU2_0", .start = 0xff801300, .end = 0xff801326, .flags = IORESOURCE_MEM, @@ -146,7 +144,6 @@ static struct platform_device mtu2_0_device = { }; static struct sh_timer_config mtu2_1_platform_data = { - .name = "MTU2_1", .channel_offset = -0x100, .timer_bit = 1, .clk = "peripheral_clk", @@ -155,7 +152,6 @@ static struct sh_timer_config mtu2_1_platform_data = { static struct resource mtu2_1_resources[] = { [0] = { - .name = "MTU2_1", .start = 0xff801380, .end = 0xff801390, .flags = IORESOURCE_MEM, @@ -177,7 +173,6 @@ static struct platform_device mtu2_1_device = { }; static struct sh_timer_config mtu2_2_platform_data = { - .name = "MTU2_2", .channel_offset = 0x80, .timer_bit = 2, .clk = "peripheral_clk", @@ -186,7 +181,6 @@ static struct sh_timer_config mtu2_2_platform_data = { static struct resource mtu2_2_resources[] = { [0] = { - .name = "MTU2_2", .start = 0xff801000, .end = 0xff80100a, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index 4ccfeb59eb1a..5b07ab57acfd 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -318,7 +318,6 @@ static struct platform_device rtc_device = { }; static struct sh_timer_config mtu2_0_platform_data = { - .name = "MTU2_0", .channel_offset = -0x80, .timer_bit = 0, .clk = "peripheral_clk", @@ -327,7 +326,6 @@ static struct sh_timer_config mtu2_0_platform_data = { static struct resource mtu2_0_resources[] = { [0] = { - .name = "MTU2_0", .start = 0xfffe4300, .end = 0xfffe4326, .flags = IORESOURCE_MEM, @@ -349,7 +347,6 @@ static struct platform_device mtu2_0_device = { }; static struct sh_timer_config mtu2_1_platform_data = { - .name = "MTU2_1", .channel_offset = -0x100, .timer_bit = 1, .clk = "peripheral_clk", @@ -358,7 +355,6 @@ static struct sh_timer_config mtu2_1_platform_data = { static struct resource mtu2_1_resources[] = { [0] = { - .name = "MTU2_1", .start = 0xfffe4380, .end = 0xfffe4390, .flags = IORESOURCE_MEM, @@ -380,7 +376,6 @@ static struct platform_device mtu2_1_device = { }; static struct sh_timer_config mtu2_2_platform_data = { - .name = "MTU2_2", .channel_offset = 0x80, .timer_bit = 2, .clk = "peripheral_clk", @@ -389,7 +384,6 @@ static struct sh_timer_config mtu2_2_platform_data = { static struct resource mtu2_2_resources[] = { [0] = { - .name = "MTU2_2", .start = 0xfffe4000, .end = 0xfffe400a, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 3136966cc9b3..433ac5301314 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -234,7 +234,6 @@ static struct platform_device scif3_device = { }; static struct sh_timer_config cmt0_platform_data = { - .name = "CMT0", .channel_offset = 0x02, .timer_bit = 0, .clk = "peripheral_clk", @@ -244,7 +243,6 @@ static struct sh_timer_config cmt0_platform_data = { static struct resource cmt0_resources[] = { [0] = { - .name = "CMT0", .start = 0xfffec002, .end = 0xfffec007, .flags = IORESOURCE_MEM, @@ -266,7 +264,6 @@ static struct platform_device cmt0_device = { }; static struct sh_timer_config cmt1_platform_data = { - .name = "CMT1", .channel_offset = 0x08, .timer_bit = 1, .clk = "peripheral_clk", @@ -276,7 +273,6 @@ static struct sh_timer_config cmt1_platform_data = { static struct resource cmt1_resources[] = { [0] = { - .name = "CMT1", .start = 0xfffec008, .end = 0xfffec00d, .flags = IORESOURCE_MEM, @@ -298,7 +294,6 @@ static struct platform_device cmt1_device = { }; static struct sh_timer_config mtu2_0_platform_data = { - .name = "MTU2_0", .channel_offset = -0x80, .timer_bit = 0, .clk = "peripheral_clk", @@ -307,7 +302,6 @@ static struct sh_timer_config mtu2_0_platform_data = { static struct resource mtu2_0_resources[] = { [0] = { - .name = "MTU2_0", .start = 0xfffe4300, .end = 0xfffe4326, .flags = IORESOURCE_MEM, @@ -329,7 +323,6 @@ static struct platform_device mtu2_0_device = { }; static struct sh_timer_config mtu2_1_platform_data = { - .name = "MTU2_1", .channel_offset = -0x100, .timer_bit = 1, .clk = "peripheral_clk", @@ -338,7 +331,6 @@ static struct sh_timer_config mtu2_1_platform_data = { static struct resource mtu2_1_resources[] = { [0] = { - .name = "MTU2_1", .start = 0xfffe4380, .end = 0xfffe4390, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 064873585a8b..8caecb41e4e6 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -194,7 +194,6 @@ static struct platform_device scif3_device = { }; static struct sh_timer_config cmt0_platform_data = { - .name = "CMT0", .channel_offset = 0x02, .timer_bit = 0, .clk = "peripheral_clk", @@ -204,7 +203,6 @@ static struct sh_timer_config cmt0_platform_data = { static struct resource cmt0_resources[] = { [0] = { - .name = "CMT0", .start = 0xfffec002, .end = 0xfffec007, .flags = IORESOURCE_MEM, @@ -226,7 +224,6 @@ static struct platform_device cmt0_device = { }; static struct sh_timer_config cmt1_platform_data = { - .name = "CMT1", .channel_offset = 0x08, .timer_bit = 1, .clk = "peripheral_clk", @@ -236,7 +233,6 @@ static struct sh_timer_config cmt1_platform_data = { static struct resource cmt1_resources[] = { [0] = { - .name = "CMT1", .start = 0xfffec008, .end = 0xfffec00d, .flags = IORESOURCE_MEM, @@ -258,7 +254,6 @@ static struct platform_device cmt1_device = { }; static struct sh_timer_config mtu2_0_platform_data = { - .name = "MTU2_0", .channel_offset = -0x80, .timer_bit = 0, .clk = "peripheral_clk", @@ -267,7 +262,6 @@ static struct sh_timer_config mtu2_0_platform_data = { static struct resource mtu2_0_resources[] = { [0] = { - .name = "MTU2_0", .start = 0xfffe4300, .end = 0xfffe4326, .flags = IORESOURCE_MEM, @@ -289,7 +283,6 @@ static struct platform_device mtu2_0_device = { }; static struct sh_timer_config mtu2_1_platform_data = { - .name = "MTU2_1", .channel_offset = -0x100, .timer_bit = 1, .clk = "peripheral_clk", @@ -298,7 +291,6 @@ static struct sh_timer_config mtu2_1_platform_data = { static struct resource mtu2_1_resources[] = { [0] = { - .name = "MTU2_1", .start = 0xfffe4380, .end = 0xfffe4390, .flags = IORESOURCE_MEM, @@ -320,7 +312,6 @@ static struct platform_device mtu2_1_device = { }; static struct sh_timer_config mtu2_2_platform_data = { - .name = "MTU2_2", .channel_offset = 0x80, .timer_bit = 2, .clk = "peripheral_clk", @@ -329,7 +320,6 @@ static struct sh_timer_config mtu2_2_platform_data = { static struct resource mtu2_2_resources[] = { [0] = { - .name = "MTU2_2", .start = 0xfffe4000, .end = 0xfffe400a, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 7b892d60e3a0..5e45fb7338fd 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -124,7 +124,6 @@ static struct platform_device rtc_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x02, .timer_bit = 0, .clk = "peripheral_clk", @@ -133,7 +132,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xfffffe94, .end = 0xfffffe9f, .flags = IORESOURCE_MEM, @@ -155,7 +153,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0xe, .timer_bit = 1, .clk = "peripheral_clk", @@ -164,7 +161,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xfffffea0, .end = 0xfffffeab, .flags = IORESOURCE_MEM, @@ -186,7 +182,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1a, .timer_bit = 2, .clk = "peripheral_clk", @@ -194,7 +189,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xfffffeac, .end = 0xfffffebb, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index bc0c4f68c7c7..9adb853a9184 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -157,7 +157,6 @@ static struct platform_device scif2_device = { #endif static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x02, .timer_bit = 0, .clk = "peripheral_clk", @@ -166,7 +165,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xfffffe94, .end = 0xfffffe9f, .flags = IORESOURCE_MEM, @@ -188,7 +186,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0xe, .timer_bit = 1, .clk = "peripheral_clk", @@ -197,7 +194,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xfffffea0, .end = 0xfffffeab, .flags = IORESOURCE_MEM, @@ -219,7 +215,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1a, .timer_bit = 2, .clk = "peripheral_clk", @@ -227,7 +222,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xfffffeac, .end = 0xfffffebb, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 0845a3ad006d..2e581e30d13d 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -127,7 +127,6 @@ static struct platform_device scif1_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x02, .timer_bit = 0, .clk = "peripheral_clk", @@ -136,7 +135,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xa412fe94, .end = 0xa412fe9f, .flags = IORESOURCE_MEM, @@ -158,7 +156,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0xe, .timer_bit = 1, .clk = "peripheral_clk", @@ -167,7 +164,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xa412fea0, .end = 0xa412feab, .flags = IORESOURCE_MEM, @@ -189,7 +185,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1a, .timer_bit = 2, .clk = "peripheral_clk", @@ -197,7 +192,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xa412feac, .end = 0xa412feb5, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index a718a6231091..9a006e13b41d 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -130,7 +130,6 @@ static struct platform_device usbf_device = { }; static struct sh_timer_config cmt0_platform_data = { - .name = "CMT0", .channel_offset = 0x10, .timer_bit = 0, .clk = "peripheral_clk", @@ -140,7 +139,6 @@ static struct sh_timer_config cmt0_platform_data = { static struct resource cmt0_resources[] = { [0] = { - .name = "CMT0", .start = 0x044a0010, .end = 0x044a001b, .flags = IORESOURCE_MEM, @@ -162,7 +160,6 @@ static struct platform_device cmt0_device = { }; static struct sh_timer_config cmt1_platform_data = { - .name = "CMT1", .channel_offset = 0x20, .timer_bit = 1, .clk = "peripheral_clk", @@ -170,7 +167,6 @@ static struct sh_timer_config cmt1_platform_data = { static struct resource cmt1_resources[] = { [0] = { - .name = "CMT1", .start = 0x044a0020, .end = 0x044a002b, .flags = IORESOURCE_MEM, @@ -192,7 +188,6 @@ static struct platform_device cmt1_device = { }; static struct sh_timer_config cmt2_platform_data = { - .name = "CMT2", .channel_offset = 0x30, .timer_bit = 2, .clk = "peripheral_clk", @@ -200,7 +195,6 @@ static struct sh_timer_config cmt2_platform_data = { static struct resource cmt2_resources[] = { [0] = { - .name = "CMT2", .start = 0x044a0030, .end = 0x044a003b, .flags = IORESOURCE_MEM, @@ -222,7 +216,6 @@ static struct platform_device cmt2_device = { }; static struct sh_timer_config cmt3_platform_data = { - .name = "CMT3", .channel_offset = 0x40, .timer_bit = 3, .clk = "peripheral_clk", @@ -230,7 +223,6 @@ static struct sh_timer_config cmt3_platform_data = { static struct resource cmt3_resources[] = { [0] = { - .name = "CMT3", .start = 0x044a0040, .end = 0x044a004b, .flags = IORESOURCE_MEM, @@ -252,7 +244,6 @@ static struct platform_device cmt3_device = { }; static struct sh_timer_config cmt4_platform_data = { - .name = "CMT4", .channel_offset = 0x50, .timer_bit = 4, .clk = "peripheral_clk", @@ -260,7 +251,6 @@ static struct sh_timer_config cmt4_platform_data = { static struct resource cmt4_resources[] = { [0] = { - .name = "CMT4", .start = 0x044a0050, .end = 0x044a005b, .flags = IORESOURCE_MEM, @@ -282,7 +272,6 @@ static struct platform_device cmt4_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x02, .timer_bit = 0, .clk = "peripheral_clk", @@ -291,7 +280,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xa412fe94, .end = 0xa412fe9f, .flags = IORESOURCE_MEM, @@ -313,7 +301,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0xe, .timer_bit = 1, .clk = "peripheral_clk", @@ -322,7 +309,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xa412fea0, .end = 0xa412feab, .flags = IORESOURCE_MEM, @@ -344,7 +330,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1a, .timer_bit = 2, .clk = "peripheral_clk", @@ -352,7 +337,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xa412feac, .end = 0xa412feb5, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index b9b7e10ad68f..223d06657775 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -31,7 +31,6 @@ static struct platform_device scif0_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -40,7 +39,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -62,7 +60,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -71,7 +68,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -93,7 +89,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -101,7 +96,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002f, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index ffd79e57254f..2f337b143c8f 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -66,7 +66,6 @@ static struct platform_device scif1_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -75,7 +74,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -97,7 +95,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -106,7 +103,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -128,7 +124,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -136,7 +131,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002f, .flags = IORESOURCE_MEM, @@ -163,7 +157,6 @@ static struct platform_device tmu2_device = { defined(CONFIG_CPU_SUBTYPE_SH7751R) static struct sh_timer_config tmu3_platform_data = { - .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -171,7 +164,6 @@ static struct sh_timer_config tmu3_platform_data = { static struct resource tmu3_resources[] = { [0] = { - .name = "TMU3", .start = 0xfe100008, .end = 0xfe100013, .flags = IORESOURCE_MEM, @@ -193,7 +185,6 @@ static struct platform_device tmu3_device = { }; static struct sh_timer_config tmu4_platform_data = { - .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -201,7 +192,6 @@ static struct sh_timer_config tmu4_platform_data = { static struct resource tmu4_resources[] = { [0] = { - .name = "TMU4", .start = 0xfe100014, .end = 0xfe10001f, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index a16eb3656f4b..fa43da0502bd 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -187,7 +187,6 @@ static struct platform_device scif3_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -196,7 +195,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -218,7 +216,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -227,7 +224,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -249,7 +245,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -257,7 +252,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002f, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index 45eb1bfd42c9..fdbd7d07a69f 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -207,7 +207,6 @@ static struct platform_device jpu_device = { }; static struct sh_timer_config cmt_platform_data = { - .name = "CMT", .channel_offset = 0x60, .timer_bit = 5, .clk = "cmt0", @@ -217,7 +216,6 @@ static struct sh_timer_config cmt_platform_data = { static struct resource cmt_resources[] = { [0] = { - .name = "CMT", .start = 0x044a0060, .end = 0x044a006b, .flags = IORESOURCE_MEM, @@ -239,7 +237,6 @@ static struct platform_device cmt_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "tmu0", @@ -248,7 +245,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -270,7 +266,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "tmu0", @@ -279,7 +274,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -301,7 +295,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "tmu0", @@ -309,7 +302,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index c494c193e3b6..d90fe0a65c2a 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -169,7 +169,6 @@ static struct platform_device veu1_device = { }; static struct sh_timer_config cmt_platform_data = { - .name = "CMT", .channel_offset = 0x60, .timer_bit = 5, .clk = "cmt0", @@ -179,7 +178,6 @@ static struct sh_timer_config cmt_platform_data = { static struct resource cmt_resources[] = { [0] = { - .name = "CMT", .start = 0x044a0060, .end = 0x044a006b, .flags = IORESOURCE_MEM, @@ -201,7 +199,6 @@ static struct platform_device cmt_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "tmu0", @@ -210,7 +207,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -232,7 +228,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "tmu0", @@ -241,7 +236,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -263,7 +257,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "tmu0", @@ -271,7 +264,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index fd7e3639e845..83ae9ad19874 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -401,7 +401,6 @@ static struct platform_device jpu_device = { }; static struct sh_timer_config cmt_platform_data = { - .name = "CMT", .channel_offset = 0x60, .timer_bit = 5, .clk = "cmt0", @@ -411,7 +410,6 @@ static struct sh_timer_config cmt_platform_data = { static struct resource cmt_resources[] = { [0] = { - .name = "CMT", .start = 0x044a0060, .end = 0x044a006b, .flags = IORESOURCE_MEM, @@ -436,7 +434,6 @@ static struct platform_device cmt_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "tmu0", @@ -445,7 +442,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -470,7 +466,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "tmu0", @@ -479,7 +474,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -504,7 +498,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "tmu0", @@ -512,7 +505,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 85c61f624702..68446b3f06af 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -211,7 +211,6 @@ static struct platform_device veu1_device = { }; static struct sh_timer_config cmt_platform_data = { - .name = "CMT", .channel_offset = 0x60, .timer_bit = 5, .clk = "cmt0", @@ -221,7 +220,6 @@ static struct sh_timer_config cmt_platform_data = { static struct resource cmt_resources[] = { [0] = { - .name = "CMT", .start = 0x044a0060, .end = 0x044a006b, .flags = IORESOURCE_MEM, @@ -246,7 +244,6 @@ static struct platform_device cmt_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "tmu0", @@ -255,7 +252,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -280,7 +276,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "tmu0", @@ -289,7 +284,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -314,7 +308,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "tmu0", @@ -322,7 +315,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002b, .flags = IORESOURCE_MEM, @@ -347,7 +339,6 @@ static struct platform_device tmu2_device = { }; static struct sh_timer_config tmu3_platform_data = { - .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, .clk = "tmu1", @@ -355,7 +346,6 @@ static struct sh_timer_config tmu3_platform_data = { static struct resource tmu3_resources[] = { [0] = { - .name = "TMU3", .start = 0xffd90008, .end = 0xffd90013, .flags = IORESOURCE_MEM, @@ -380,7 +370,6 @@ static struct platform_device tmu3_device = { }; static struct sh_timer_config tmu4_platform_data = { - .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, .clk = "tmu1", @@ -388,7 +377,6 @@ static struct sh_timer_config tmu4_platform_data = { static struct resource tmu4_resources[] = { [0] = { - .name = "TMU4", .start = 0xffd90014, .end = 0xffd9001f, .flags = IORESOURCE_MEM, @@ -413,7 +401,6 @@ static struct platform_device tmu4_device = { }; static struct sh_timer_config tmu5_platform_data = { - .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, .clk = "tmu1", @@ -421,7 +408,6 @@ static struct sh_timer_config tmu5_platform_data = { static struct resource tmu5_resources[] = { [0] = { - .name = "TMU5", .start = 0xffd90020, .end = 0xffd9002b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index e7fa2a92fc1f..abc98b0fef91 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -485,7 +485,6 @@ static struct platform_device veu1_device = { }; static struct sh_timer_config cmt_platform_data = { - .name = "CMT", .channel_offset = 0x60, .timer_bit = 5, .clk = "cmt0", @@ -495,7 +494,6 @@ static struct sh_timer_config cmt_platform_data = { static struct resource cmt_resources[] = { [0] = { - .name = "CMT", .start = 0x044a0060, .end = 0x044a006b, .flags = IORESOURCE_MEM, @@ -520,7 +518,6 @@ static struct platform_device cmt_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "tmu0", @@ -529,7 +526,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -554,7 +550,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "tmu0", @@ -563,7 +558,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -588,7 +582,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "tmu0", @@ -596,7 +589,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002b, .flags = IORESOURCE_MEM, @@ -622,7 +614,6 @@ static struct platform_device tmu2_device = { static struct sh_timer_config tmu3_platform_data = { - .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, .clk = "tmu1", @@ -630,7 +621,6 @@ static struct sh_timer_config tmu3_platform_data = { static struct resource tmu3_resources[] = { [0] = { - .name = "TMU3", .start = 0xffd90008, .end = 0xffd90013, .flags = IORESOURCE_MEM, @@ -655,7 +645,6 @@ static struct platform_device tmu3_device = { }; static struct sh_timer_config tmu4_platform_data = { - .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, .clk = "tmu1", @@ -663,7 +652,6 @@ static struct sh_timer_config tmu4_platform_data = { static struct resource tmu4_resources[] = { [0] = { - .name = "TMU4", .start = 0xffd90014, .end = 0xffd9001f, .flags = IORESOURCE_MEM, @@ -688,7 +676,6 @@ static struct platform_device tmu4_device = { }; static struct sh_timer_config tmu5_platform_data = { - .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, .clk = "tmu1", @@ -696,7 +683,6 @@ static struct sh_timer_config tmu5_platform_data = { static struct resource tmu5_resources[] = { [0] = { - .name = "TMU5", .start = 0xffd90020, .end = 0xffd9002b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index e75edf58796a..25eddf24f634 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -63,7 +63,6 @@ static struct platform_device scif4_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -72,7 +71,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xfe430008, .end = 0xfe430013, .flags = IORESOURCE_MEM, @@ -94,7 +92,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -103,7 +100,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xfe430014, .end = 0xfe43001f, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 7f6b0a5f7f82..a91263e0358b 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -131,7 +131,6 @@ static struct platform_device usbf_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -140,7 +139,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -162,7 +160,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -171,7 +168,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -193,7 +189,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -201,7 +196,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002f, .flags = IORESOURCE_MEM, @@ -223,7 +217,6 @@ static struct platform_device tmu2_device = { }; static struct sh_timer_config tmu3_platform_data = { - .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -231,7 +224,6 @@ static struct sh_timer_config tmu3_platform_data = { static struct resource tmu3_resources[] = { [0] = { - .name = "TMU3", .start = 0xffd88008, .end = 0xffd88013, .flags = IORESOURCE_MEM, @@ -253,7 +245,6 @@ static struct platform_device tmu3_device = { }; static struct sh_timer_config tmu4_platform_data = { - .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -261,7 +252,6 @@ static struct sh_timer_config tmu4_platform_data = { static struct resource tmu4_resources[] = { [0] = { - .name = "TMU4", .start = 0xffd88014, .end = 0xffd8801f, .flags = IORESOURCE_MEM, @@ -283,7 +273,6 @@ static struct platform_device tmu4_device = { }; static struct sh_timer_config tmu5_platform_data = { - .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -291,7 +280,6 @@ static struct sh_timer_config tmu5_platform_data = { static struct resource tmu5_resources[] = { [0] = { - .name = "TMU5", .start = 0xffd88020, .end = 0xffd8802b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 86d681ecf90e..83a27b0e4ed2 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -165,7 +165,6 @@ static struct platform_device scif9_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -174,7 +173,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -196,7 +194,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -205,7 +202,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -227,7 +223,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -235,7 +230,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002f, .flags = IORESOURCE_MEM, @@ -257,7 +251,6 @@ static struct platform_device tmu2_device = { }; static struct sh_timer_config tmu3_platform_data = { - .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -265,7 +258,6 @@ static struct sh_timer_config tmu3_platform_data = { static struct resource tmu3_resources[] = { [0] = { - .name = "TMU3", .start = 0xffd81008, .end = 0xffd81013, .flags = IORESOURCE_MEM, @@ -287,7 +279,6 @@ static struct platform_device tmu3_device = { }; static struct sh_timer_config tmu4_platform_data = { - .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -295,7 +286,6 @@ static struct sh_timer_config tmu4_platform_data = { static struct resource tmu4_resources[] = { [0] = { - .name = "TMU4", .start = 0xffd81014, .end = 0xffd8101f, .flags = IORESOURCE_MEM, @@ -317,7 +307,6 @@ static struct platform_device tmu4_device = { }; static struct sh_timer_config tmu5_platform_data = { - .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -325,7 +314,6 @@ static struct sh_timer_config tmu5_platform_data = { static struct resource tmu5_resources[] = { [0] = { - .name = "TMU5", .start = 0xffd81020, .end = 0xffd8102f, .flags = IORESOURCE_MEM, @@ -347,7 +335,6 @@ static struct platform_device tmu5_device = { }; static struct sh_timer_config tmu6_platform_data = { - .name = "TMU6", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -355,7 +342,6 @@ static struct sh_timer_config tmu6_platform_data = { static struct resource tmu6_resources[] = { [0] = { - .name = "TMU6", .start = 0xffd82008, .end = 0xffd82013, .flags = IORESOURCE_MEM, @@ -377,7 +363,6 @@ static struct platform_device tmu6_device = { }; static struct sh_timer_config tmu7_platform_data = { - .name = "TMU7", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -385,7 +370,6 @@ static struct sh_timer_config tmu7_platform_data = { static struct resource tmu7_resources[] = { [0] = { - .name = "TMU7", .start = 0xffd82014, .end = 0xffd8201f, .flags = IORESOURCE_MEM, @@ -407,7 +391,6 @@ static struct platform_device tmu7_device = { }; static struct sh_timer_config tmu8_platform_data = { - .name = "TMU8", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -415,7 +398,6 @@ static struct sh_timer_config tmu8_platform_data = { static struct resource tmu8_resources[] = { [0] = { - .name = "TMU8", .start = 0xffd82020, .end = 0xffd8202b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 02e792c90de6..f7c48e92b95b 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -49,7 +49,6 @@ static struct platform_device scif1_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -58,7 +57,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -80,7 +78,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -89,7 +86,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -111,7 +107,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -119,7 +114,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002f, .flags = IORESOURCE_MEM, @@ -141,7 +135,6 @@ static struct platform_device tmu2_device = { }; static struct sh_timer_config tmu3_platform_data = { - .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -149,7 +142,6 @@ static struct sh_timer_config tmu3_platform_data = { static struct resource tmu3_resources[] = { [0] = { - .name = "TMU3", .start = 0xffdc0008, .end = 0xffdc0013, .flags = IORESOURCE_MEM, @@ -171,7 +163,6 @@ static struct platform_device tmu3_device = { }; static struct sh_timer_config tmu4_platform_data = { - .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -179,7 +170,6 @@ static struct sh_timer_config tmu4_platform_data = { static struct resource tmu4_resources[] = { [0] = { - .name = "TMU4", .start = 0xffdc0014, .end = 0xffdc001f, .flags = IORESOURCE_MEM, @@ -201,7 +191,6 @@ static struct platform_device tmu4_device = { }; static struct sh_timer_config tmu5_platform_data = { - .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -209,7 +198,6 @@ static struct sh_timer_config tmu5_platform_data = { static struct resource tmu5_resources[] = { [0] = { - .name = "TMU5", .start = 0xffdc0020, .end = 0xffdc002b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 1fcd88b1671e..05e9308505cf 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -117,7 +117,6 @@ static struct platform_device scif5_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "tmu012_fck", @@ -126,7 +125,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -148,7 +146,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "tmu012_fck", @@ -157,7 +154,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -179,7 +175,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "tmu012_fck", @@ -187,7 +182,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002f, .flags = IORESOURCE_MEM, @@ -209,7 +203,6 @@ static struct platform_device tmu2_device = { }; static struct sh_timer_config tmu3_platform_data = { - .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, .clk = "tmu345_fck", @@ -217,7 +210,6 @@ static struct sh_timer_config tmu3_platform_data = { static struct resource tmu3_resources[] = { [0] = { - .name = "TMU3", .start = 0xffdc0008, .end = 0xffdc0013, .flags = IORESOURCE_MEM, @@ -239,7 +231,6 @@ static struct platform_device tmu3_device = { }; static struct sh_timer_config tmu4_platform_data = { - .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, .clk = "tmu345_fck", @@ -247,7 +238,6 @@ static struct sh_timer_config tmu4_platform_data = { static struct resource tmu4_resources[] = { [0] = { - .name = "TMU4", .start = 0xffdc0014, .end = 0xffdc001f, .flags = IORESOURCE_MEM, @@ -269,7 +259,6 @@ static struct platform_device tmu4_device = { }; static struct sh_timer_config tmu5_platform_data = { - .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, .clk = "tmu345_fck", @@ -277,7 +266,6 @@ static struct sh_timer_config tmu5_platform_data = { static struct resource tmu5_resources[] = { [0] = { - .name = "TMU5", .start = 0xffdc0020, .end = 0xffdc002b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 7e585320710a..542ced88e50f 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -117,7 +117,6 @@ static struct platform_device scif5_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -126,7 +125,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffd80008, .end = 0xffd80013, .flags = IORESOURCE_MEM, @@ -148,7 +146,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -157,7 +154,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffd80014, .end = 0xffd8001f, .flags = IORESOURCE_MEM, @@ -179,7 +175,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -187,7 +182,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffd80020, .end = 0xffd8002f, .flags = IORESOURCE_MEM, @@ -209,7 +203,6 @@ static struct platform_device tmu2_device = { }; static struct sh_timer_config tmu3_platform_data = { - .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -217,7 +210,6 @@ static struct sh_timer_config tmu3_platform_data = { static struct resource tmu3_resources[] = { [0] = { - .name = "TMU3", .start = 0xffda0008, .end = 0xffda0013, .flags = IORESOURCE_MEM, @@ -239,7 +231,6 @@ static struct platform_device tmu3_device = { }; static struct sh_timer_config tmu4_platform_data = { - .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -247,7 +238,6 @@ static struct sh_timer_config tmu4_platform_data = { static struct resource tmu4_resources[] = { [0] = { - .name = "TMU4", .start = 0xffda0014, .end = 0xffda001f, .flags = IORESOURCE_MEM, @@ -269,7 +259,6 @@ static struct platform_device tmu4_device = { }; static struct sh_timer_config tmu5_platform_data = { - .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -277,7 +266,6 @@ static struct sh_timer_config tmu5_platform_data = { static struct resource tmu5_resources[] = { [0] = { - .name = "TMU5", .start = 0xffda0020, .end = 0xffda002b, .flags = IORESOURCE_MEM, @@ -299,7 +287,6 @@ static struct platform_device tmu5_device = { }; static struct sh_timer_config tmu6_platform_data = { - .name = "TMU6", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -307,7 +294,6 @@ static struct sh_timer_config tmu6_platform_data = { static struct resource tmu6_resources[] = { [0] = { - .name = "TMU6", .start = 0xffdc0008, .end = 0xffdc0013, .flags = IORESOURCE_MEM, @@ -329,7 +315,6 @@ static struct platform_device tmu6_device = { }; static struct sh_timer_config tmu7_platform_data = { - .name = "TMU7", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -337,7 +322,6 @@ static struct sh_timer_config tmu7_platform_data = { static struct resource tmu7_resources[] = { [0] = { - .name = "TMU7", .start = 0xffdc0014, .end = 0xffdc001f, .flags = IORESOURCE_MEM, @@ -359,7 +343,6 @@ static struct platform_device tmu7_device = { }; static struct sh_timer_config tmu8_platform_data = { - .name = "TMU8", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -367,7 +350,6 @@ static struct sh_timer_config tmu8_platform_data = { static struct resource tmu8_resources[] = { [0] = { - .name = "TMU8", .start = 0xffdc0020, .end = 0xffdc002b, .flags = IORESOURCE_MEM, @@ -389,7 +371,6 @@ static struct platform_device tmu8_device = { }; static struct sh_timer_config tmu9_platform_data = { - .name = "TMU9", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -397,7 +378,6 @@ static struct sh_timer_config tmu9_platform_data = { static struct resource tmu9_resources[] = { [0] = { - .name = "TMU9", .start = 0xffde0008, .end = 0xffde0013, .flags = IORESOURCE_MEM, @@ -419,7 +399,6 @@ static struct platform_device tmu9_device = { }; static struct sh_timer_config tmu10_platform_data = { - .name = "TMU10", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -427,7 +406,6 @@ static struct sh_timer_config tmu10_platform_data = { static struct resource tmu10_resources[] = { [0] = { - .name = "TMU10", .start = 0xffde0014, .end = 0xffde001f, .flags = IORESOURCE_MEM, @@ -449,7 +427,6 @@ static struct platform_device tmu10_device = { }; static struct sh_timer_config tmu11_platform_data = { - .name = "TMU11", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -457,7 +434,6 @@ static struct sh_timer_config tmu11_platform_data = { static struct resource tmu11_resources[] = { [0] = { - .name = "TMU11", .start = 0xffde0020, .end = 0xffde002b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 780ba17a5599..ba545b5ccc15 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -70,7 +70,6 @@ static struct platform_device scif2_device = { }; static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -79,7 +78,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = 0xffc10008, .end = 0xffc10013, .flags = IORESOURCE_MEM, @@ -101,7 +99,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -110,7 +107,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = 0xffc10014, .end = 0xffc1001f, .flags = IORESOURCE_MEM, @@ -132,7 +128,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -140,7 +135,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = 0xffc10020, .end = 0xffc1002f, .flags = IORESOURCE_MEM, @@ -162,7 +156,6 @@ static struct platform_device tmu2_device = { }; static struct sh_timer_config tmu3_platform_data = { - .name = "TMU3", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -170,7 +163,6 @@ static struct sh_timer_config tmu3_platform_data = { static struct resource tmu3_resources[] = { [0] = { - .name = "TMU3", .start = 0xffc20008, .end = 0xffc20013, .flags = IORESOURCE_MEM, @@ -192,7 +184,6 @@ static struct platform_device tmu3_device = { }; static struct sh_timer_config tmu4_platform_data = { - .name = "TMU4", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -200,7 +191,6 @@ static struct sh_timer_config tmu4_platform_data = { static struct resource tmu4_resources[] = { [0] = { - .name = "TMU4", .start = 0xffc20014, .end = 0xffc2001f, .flags = IORESOURCE_MEM, @@ -222,7 +212,6 @@ static struct platform_device tmu4_device = { }; static struct sh_timer_config tmu5_platform_data = { - .name = "TMU5", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -230,7 +219,6 @@ static struct sh_timer_config tmu5_platform_data = { static struct resource tmu5_resources[] = { [0] = { - .name = "TMU5", .start = 0xffc20020, .end = 0xffc2002b, .flags = IORESOURCE_MEM, diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index e7a3c1e4b604..c84ca204240b 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -68,7 +68,6 @@ static struct platform_device rtc_device = { #define TMU2_BASE (TMU_BASE + 0x8 + (0xc * 0x2)) static struct sh_timer_config tmu0_platform_data = { - .name = "TMU0", .channel_offset = 0x04, .timer_bit = 0, .clk = "peripheral_clk", @@ -77,7 +76,6 @@ static struct sh_timer_config tmu0_platform_data = { static struct resource tmu0_resources[] = { [0] = { - .name = "TMU0", .start = TMU0_BASE, .end = TMU0_BASE + 0xc - 1, .flags = IORESOURCE_MEM, @@ -99,7 +97,6 @@ static struct platform_device tmu0_device = { }; static struct sh_timer_config tmu1_platform_data = { - .name = "TMU1", .channel_offset = 0x10, .timer_bit = 1, .clk = "peripheral_clk", @@ -108,7 +105,6 @@ static struct sh_timer_config tmu1_platform_data = { static struct resource tmu1_resources[] = { [0] = { - .name = "TMU1", .start = TMU1_BASE, .end = TMU1_BASE + 0xc - 1, .flags = IORESOURCE_MEM, @@ -130,7 +126,6 @@ static struct platform_device tmu1_device = { }; static struct sh_timer_config tmu2_platform_data = { - .name = "TMU2", .channel_offset = 0x1c, .timer_bit = 2, .clk = "peripheral_clk", @@ -138,7 +133,6 @@ static struct sh_timer_config tmu2_platform_data = { static struct resource tmu2_resources[] = { [0] = { - .name = "TMU2", .start = TMU2_BASE, .end = TMU2_BASE + 0xc - 1, .flags = IORESOURCE_MEM, -- cgit v1.2.3-59-g8ed1b From c7ed1ab3f7b2fe0dedebf34cbf40bf12cb5ae48b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 10 Mar 2010 18:35:14 +0900 Subject: serial: sh-sci: clkdev updates for MSTP gating. This fixes up some of the I/D/F clock ambiguity in the sh-sci driver. The interface clock in most cases just wraps back to the peripheral clock, while the function clock wraps in to the MSTP bits. As the logic was somewhat inverted, this cleans that up, and also enables all CPUs with SCI MSTP bits to match function clocks through clkdev lookup. As a result, this gets rid of the clk string abuse on the sh side, and the clock string will be killed off once the ARM code has had a chance to sync up. This also enables MSTP gating on CPUs like 7786 which had never wired it up before. Impacted CPUs are primarily all SH-Mobiles, SH7785, and SH7786. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 8 ++--- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 6 ++-- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 6 ++-- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 12 +++---- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 12 +++---- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 12 +++---- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 12 +++---- arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 4 --- arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 1 - arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 3 -- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 6 ---- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 6 ---- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 6 ---- drivers/serial/sh-sci.c | 57 ++++++++++++++++++++++------------ 14 files changed, 71 insertions(+), 80 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index 2c16df37eda6..c541301c7f2b 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -159,10 +159,10 @@ static struct clk mstp_clks[] = { MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0), MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0), MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0), - MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 7, 0), - MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 6, 0), - MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 5, 0), - MSTP("scif3", &div4_clks[DIV4_P], MSTPCR0, 4, 0), + SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 7, 0), + SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 6, 0), + SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 5, 0), + SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 4, 0), MSTP("sio0", &div4_clks[DIV4_P], MSTPCR0, 3, 0), MSTP("siof0", &div4_clks[DIV4_P], MSTPCR0, 2, 0), MSTP("siof1", &div4_clks[DIV4_P], MSTPCR0, 1, 0), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 91588d280cd8..e10c64fd8095 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -163,9 +163,9 @@ static struct clk mstp_clks[] = { MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0), MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0), MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0), - MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 7, 0), - MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 6, 0), - MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 5, 0), + SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 7, 0), + SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 6, 0), + SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 5, 0), MSTP("msiof0", &div4_clks[DIV4_P], MSTPCR0, 2, 0), MSTP("sbr0", &div4_clks[DIV4_P], MSTPCR0, 1, 0), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 15db6d521c5c..0732c8bab1e2 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -164,9 +164,9 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0), SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0), SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0), - SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0), - SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0), - SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0), + SH_HWBLK_CLK("sci_fck", 0, P_CLK, HWBLK_SCIF0, 0), + SH_HWBLK_CLK("sci_fck", 1, P_CLK, HWBLK_SCIF1, 0), + SH_HWBLK_CLK("sci_fck", 2, P_CLK, HWBLK_SCIF2, 0), SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0), SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 50babe01fe44..4d4c123d02c4 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -177,12 +177,12 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0), SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0), SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0), - SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0), - SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0), - SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0), - SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0), - SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0), - SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0), + SH_HWBLK_CLK("sci_fck", 0, P_CLK, HWBLK_SCIF0, 0), + SH_HWBLK_CLK("sci_fck", 1, P_CLK, HWBLK_SCIF1, 0), + SH_HWBLK_CLK("sci_fck", 2, P_CLK, HWBLK_SCIF2, 0), + SH_HWBLK_CLK("sci_fck", 3, B_CLK, HWBLK_SCIF3, 0), + SH_HWBLK_CLK("sci_fck", 4, B_CLK, HWBLK_SCIF4, 0), + SH_HWBLK_CLK("sci_fck", 5, B_CLK, HWBLK_SCIF5, 0), SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0), SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0), SH_HWBLK_CLK("meram0", -1, SH_CLK, HWBLK_MERAM, 0), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 6707061fbf54..bcf2b97db300 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -194,12 +194,12 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0), SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0), SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0), - SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0), - SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0), - SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0), - SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0), - SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0), - SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0), + SH_HWBLK_CLK("sci_fck", 0, P_CLK, HWBLK_SCIF0, 0), + SH_HWBLK_CLK("sci_fck", 1, P_CLK, HWBLK_SCIF1, 0), + SH_HWBLK_CLK("sci_fck", 2, P_CLK, HWBLK_SCIF2, 0), + SH_HWBLK_CLK("sci_fck", 3, B_CLK, HWBLK_SCIF3, 0), + SH_HWBLK_CLK("sci_fck", 4, B_CLK, HWBLK_SCIF4, 0), + SH_HWBLK_CLK("sci_fck", 5, B_CLK, HWBLK_SCIF5, 0), SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0), SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index d997f0a25b10..6061c736c281 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -88,12 +88,12 @@ struct clk div4_clks[DIV4_NR] = { static struct clk mstp_clks[] = { /* MSTPCR0 */ - SH_CLK_MSTP32("scif_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), - SH_CLK_MSTP32("scif_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), - SH_CLK_MSTP32("scif_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), - SH_CLK_MSTP32("scif_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), - SH_CLK_MSTP32("scif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), - SH_CLK_MSTP32("scif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), + SH_CLK_MSTP32("sci_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), + SH_CLK_MSTP32("sci_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), + SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), + SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), + SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), + SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0), SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0), SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index af69fd468703..85e8d57f4971 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -87,12 +87,12 @@ struct clk div4_clks[DIV4_NR] = { static struct clk mstp_clks[] = { /* MSTPCR0 */ - SH_CLK_MSTP32("scif_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), - SH_CLK_MSTP32("scif_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), - SH_CLK_MSTP32("scif_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), - SH_CLK_MSTP32("scif_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), - SH_CLK_MSTP32("scif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), - SH_CLK_MSTP32("scif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), + SH_CLK_MSTP32("sci_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), + SH_CLK_MSTP32("sci_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), + SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), + SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), + SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), + SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), SH_CLK_MSTP32("ssi_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 23, 0), SH_CLK_MSTP32("ssi_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 22, 0), SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0), diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index fdbd7d07a69f..6f8394942fc5 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -21,7 +21,6 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, - .clk = "scif0", }; static struct platform_device scif0_device = { @@ -37,7 +36,6 @@ static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, - .clk = "scif1", }; static struct platform_device scif1_device = { @@ -53,7 +51,6 @@ static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, - .clk = "scif2", }; static struct platform_device scif2_device = { @@ -69,7 +66,6 @@ static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 83, 83, 83, 83 }, - .clk = "scif3", }; static struct platform_device scif3_device = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index d90fe0a65c2a..1d897ed256b0 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -23,7 +23,6 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, - .clk = "scif0", }; static struct platform_device scif0_device = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 83ae9ad19874..847a27619af5 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -174,7 +174,6 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, - .clk = "scif0", }; static struct platform_device scif0_device = { @@ -190,7 +189,6 @@ static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, - .clk = "scif1", }; static struct platform_device scif1_device = { @@ -206,7 +204,6 @@ static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, - .clk = "scif2", }; static struct platform_device scif2_device = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 68446b3f06af..187462b51be0 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -26,7 +26,6 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, - .clk = "scif0", }; static struct platform_device scif0_device = { @@ -42,7 +41,6 @@ static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, - .clk = "scif1", }; static struct platform_device scif1_device = { @@ -58,7 +56,6 @@ static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, - .clk = "scif2", }; static struct platform_device scif2_device = { @@ -74,7 +71,6 @@ static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIFA, .irqs = { 56, 56, 56, 56 }, - .clk = "scif3", }; static struct platform_device scif3_device = { @@ -90,7 +86,6 @@ static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIFA, .irqs = { 88, 88, 88, 88 }, - .clk = "scif4", }; static struct platform_device scif4_device = { @@ -106,7 +101,6 @@ static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIFA, .irqs = { 109, 109, 109, 109 }, - .clk = "scif5", }; static struct platform_device scif5_device = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index abc98b0fef91..ee9789003193 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -213,7 +213,6 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, - .clk = "scif0", }; static struct platform_device scif0_device = { @@ -229,7 +228,6 @@ static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, - .clk = "scif1", }; static struct platform_device scif1_device = { @@ -245,7 +243,6 @@ static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, - .clk = "scif2", }; static struct platform_device scif2_device = { @@ -261,7 +258,6 @@ static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIFA, .irqs = { 56, 56, 56, 56 }, - .clk = "scif3", }; static struct platform_device scif3_device = { @@ -277,7 +273,6 @@ static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIFA, .irqs = { 88, 88, 88, 88 }, - .clk = "scif4", }; static struct platform_device scif4_device = { @@ -293,7 +288,6 @@ static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIFA, .irqs = { 109, 109, 109, 109 }, - .clk = "scif5", }; static struct platform_device scif5_device = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 05e9308505cf..76afe571f3a2 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -25,7 +25,6 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, - .clk = "scif_fck", }; static struct platform_device scif0_device = { @@ -41,7 +40,6 @@ static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 44, 44, 44, 44 }, - .clk = "scif_fck", }; static struct platform_device scif1_device = { @@ -57,7 +55,6 @@ static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 60, 60, 60, 60 }, - .clk = "scif_fck", }; static struct platform_device scif2_device = { @@ -73,7 +70,6 @@ static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 61, 61, 61, 61 }, - .clk = "scif_fck", }; static struct platform_device scif3_device = { @@ -89,7 +85,6 @@ static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 62, 62, 62, 62 }, - .clk = "scif_fck", }; static struct platform_device scif4_device = { @@ -105,7 +100,6 @@ static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .irqs = { 63, 63, 63, 63 }, - .clk = "scif_fck", }; static struct platform_device scif5_device = { diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 980f39449ee5..054a8427c739 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -83,8 +83,8 @@ struct sci_port { /* Interface clock */ struct clk *iclk; - /* Data clock */ - struct clk *dclk; + /* Function clock */ + struct clk *fclk; struct list_head node; struct dma_chan *chan_tx; @@ -803,7 +803,7 @@ static int sci_notifier(struct notifier_block *self, (phase == CPUFREQ_RESUMECHANGE)) { spin_lock_irqsave(&priv->lock, flags); list_for_each_entry(sci_port, &priv->ports, node) - sci_port->port.uartclk = clk_get_rate(sci_port->dclk); + sci_port->port.uartclk = clk_get_rate(sci_port->iclk); spin_unlock_irqrestore(&priv->lock, flags); } @@ -814,21 +814,17 @@ static void sci_clk_enable(struct uart_port *port) { struct sci_port *sci_port = to_sci_port(port); - clk_enable(sci_port->dclk); - sci_port->port.uartclk = clk_get_rate(sci_port->dclk); - - if (sci_port->iclk) - clk_enable(sci_port->iclk); + clk_enable(sci_port->iclk); + sci_port->port.uartclk = clk_get_rate(sci_port->iclk); + clk_enable(sci_port->fclk); } static void sci_clk_disable(struct uart_port *port) { struct sci_port *sci_port = to_sci_port(port); - if (sci_port->iclk) - clk_disable(sci_port->iclk); - - clk_disable(sci_port->dclk); + clk_disable(sci_port->fclk); + clk_disable(sci_port->iclk); } static int sci_request_irq(struct sci_port *port) @@ -1557,10 +1553,10 @@ static struct uart_ops sci_uart_ops = { #endif }; -static void __devinit sci_init_single(struct platform_device *dev, - struct sci_port *sci_port, - unsigned int index, - struct plat_sci_port *p) +static int __devinit sci_init_single(struct platform_device *dev, + struct sci_port *sci_port, + unsigned int index, + struct plat_sci_port *p) { struct uart_port *port = &sci_port->port; @@ -1581,8 +1577,23 @@ static void __devinit sci_init_single(struct platform_device *dev, } if (dev) { - sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; - sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); + sci_port->iclk = clk_get(&dev->dev, "sci_ick"); + if (IS_ERR(sci_port->iclk)) { + sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); + if (IS_ERR(sci_port->iclk)) { + dev_err(&dev->dev, "can't get iclk\n"); + return PTR_ERR(sci_port->iclk); + } + } + + /* + * The function clock is optional, ignore it if we can't + * find it. + */ + sci_port->fclk = clk_get(&dev->dev, "sci_fck"); + if (IS_ERR(sci_port->fclk)) + sci_port->fclk = NULL; + sci_port->enable = sci_clk_enable; sci_port->disable = sci_clk_disable; port->dev = &dev->dev; @@ -1609,6 +1620,7 @@ static void __devinit sci_init_single(struct platform_device *dev, #endif memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); + return 0; } #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE @@ -1758,8 +1770,11 @@ static int sci_remove(struct platform_device *dev) cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); spin_lock_irqsave(&priv->lock, flags); - list_for_each_entry(p, &priv->ports, node) + list_for_each_entry(p, &priv->ports, node) { uart_remove_one_port(&sci_uart_driver, &p->port); + clk_put(p->iclk); + clk_put(p->fclk); + } spin_unlock_irqrestore(&priv->lock, flags); kfree(priv); @@ -1785,7 +1800,9 @@ static int __devinit sci_probe_single(struct platform_device *dev, return 0; } - sci_init_single(dev, sciport, index, p); + ret = sci_init_single(dev, sciport, index, p); + if (ret) + return ret; ret = uart_add_one_port(&sci_uart_driver, &sciport->port); if (ret) -- cgit v1.2.3-59-g8ed1b From 12387a46bb150f5608de4aa9a90dfdddbf991e3f Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Wed, 10 Mar 2010 18:28:55 +0800 Subject: crypto: aesni-intel - Add AES-NI accelerated CTR mode To take advantage of the hardware pipeline implementation of AES-NI instructions. CTR mode cryption is implemented in ASM to schedule multiple AES-NI instructions one after another. This way, some latency of AES-NI instruction can be eliminated. Performance testing based on dm-crypt should 50% reduction of ecryption/decryption time. Signed-off-by: Huang Ying Signed-off-by: Herbert Xu --- arch/x86/crypto/aesni-intel_asm.S | 115 ++++++++++++++++++++++++++++++++ arch/x86/crypto/aesni-intel_glue.c | 130 +++++++++++++++++++++++++++++++++++-- 2 files changed, 238 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index 20bb0e1ac681..822846a9eba9 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S @@ -32,6 +32,9 @@ #define IN IN1 #define KEY %xmm2 #define IV %xmm3 +#define BSWAP_MASK %xmm10 +#define CTR %xmm11 +#define INC %xmm12 #define KEYP %rdi #define OUTP %rsi @@ -42,6 +45,7 @@ #define T1 %r10 #define TKEYP T1 #define T2 %r11 +#define TCTR_LOW T2 _key_expansion_128: _key_expansion_256a: @@ -724,3 +728,114 @@ ENTRY(aesni_cbc_dec) movups IV, (IVP) .Lcbc_dec_just_ret: ret + +.align 16 +.Lbswap_mask: + .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 + +/* + * _aesni_inc_init: internal ABI + * setup registers used by _aesni_inc + * input: + * IV + * output: + * CTR: == IV, in little endian + * TCTR_LOW: == lower qword of CTR + * INC: == 1, in little endian + * BSWAP_MASK == endian swapping mask + */ +_aesni_inc_init: + movaps .Lbswap_mask, BSWAP_MASK + movaps IV, CTR + PSHUFB_XMM BSWAP_MASK CTR + mov $1, TCTR_LOW + movq TCTR_LOW, INC + movq CTR, TCTR_LOW + ret + +/* + * _aesni_inc: internal ABI + * Increase IV by 1, IV is in big endian + * input: + * IV + * CTR: == IV, in little endian + * TCTR_LOW: == lower qword of CTR + * INC: == 1, in little endian + * BSWAP_MASK == endian swapping mask + * output: + * IV: Increase by 1 + * changed: + * CTR: == output IV, in little endian + * TCTR_LOW: == lower qword of CTR + */ +_aesni_inc: + paddq INC, CTR + add $1, TCTR_LOW + jnc .Linc_low + pslldq $8, INC + paddq INC, CTR + psrldq $8, INC +.Linc_low: + movaps CTR, IV + PSHUFB_XMM BSWAP_MASK IV + ret + +/* + * void aesni_ctr_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src, + * size_t len, u8 *iv) + */ +ENTRY(aesni_ctr_enc) + cmp $16, LEN + jb .Lctr_enc_just_ret + mov 480(KEYP), KLEN + movups (IVP), IV + call _aesni_inc_init + cmp $64, LEN + jb .Lctr_enc_loop1 +.align 4 +.Lctr_enc_loop4: + movaps IV, STATE1 + call _aesni_inc + movups (INP), IN1 + movaps IV, STATE2 + call _aesni_inc + movups 0x10(INP), IN2 + movaps IV, STATE3 + call _aesni_inc + movups 0x20(INP), IN3 + movaps IV, STATE4 + call _aesni_inc + movups 0x30(INP), IN4 + call _aesni_enc4 + pxor IN1, STATE1 + movups STATE1, (OUTP) + pxor IN2, STATE2 + movups STATE2, 0x10(OUTP) + pxor IN3, STATE3 + movups STATE3, 0x20(OUTP) + pxor IN4, STATE4 + movups STATE4, 0x30(OUTP) + sub $64, LEN + add $64, INP + add $64, OUTP + cmp $64, LEN + jge .Lctr_enc_loop4 + cmp $16, LEN + jb .Lctr_enc_ret +.align 4 +.Lctr_enc_loop1: + movaps IV, STATE + call _aesni_inc + movups (INP), IN + call _aesni_enc1 + pxor IN, STATE + movups STATE, (OUTP) + sub $16, LEN + add $16, INP + add $16, OUTP + cmp $16, LEN + jge .Lctr_enc_loop1 +.Lctr_enc_ret: + movups IV, (IVP) +.Lctr_enc_just_ret: + ret diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 49c552c060e9..2cb3dcc4490a 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -58,6 +59,8 @@ asmlinkage void aesni_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in, unsigned int len, u8 *iv); asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in, unsigned int len, u8 *iv); +asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, + const u8 *in, unsigned int len, u8 *iv); static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx) { @@ -321,6 +324,72 @@ static struct crypto_alg blk_cbc_alg = { }, }; +static void ctr_crypt_final(struct crypto_aes_ctx *ctx, + struct blkcipher_walk *walk) +{ + u8 *ctrblk = walk->iv; + u8 keystream[AES_BLOCK_SIZE]; + u8 *src = walk->src.virt.addr; + u8 *dst = walk->dst.virt.addr; + unsigned int nbytes = walk->nbytes; + + aesni_enc(ctx, keystream, ctrblk); + crypto_xor(keystream, src, nbytes); + memcpy(dst, keystream, nbytes); + crypto_inc(ctrblk, AES_BLOCK_SIZE); +} + +static int ctr_crypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) +{ + struct crypto_aes_ctx *ctx = aes_ctx(crypto_blkcipher_ctx(desc->tfm)); + struct blkcipher_walk walk; + int err; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + + kernel_fpu_begin(); + while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) { + aesni_ctr_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr, + nbytes & AES_BLOCK_MASK, walk.iv); + nbytes &= AES_BLOCK_SIZE - 1; + err = blkcipher_walk_done(desc, &walk, nbytes); + } + if (walk.nbytes) { + ctr_crypt_final(ctx, &walk); + err = blkcipher_walk_done(desc, &walk, 0); + } + kernel_fpu_end(); + + return err; +} + +static struct crypto_alg blk_ctr_alg = { + .cra_name = "__ctr-aes-aesni", + .cra_driver_name = "__driver-ctr-aes-aesni", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct crypto_aes_ctx)+AESNI_ALIGN-1, + .cra_alignmask = 0, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(blk_ctr_alg.cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = aes_set_key, + .encrypt = ctr_crypt, + .decrypt = ctr_crypt, + }, + }, +}; + static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int key_len) { @@ -467,13 +536,11 @@ static struct crypto_alg ablk_cbc_alg = { }, }; -#ifdef HAS_CTR static int ablk_ctr_init(struct crypto_tfm *tfm) { struct cryptd_ablkcipher *cryptd_tfm; - cryptd_tfm = cryptd_alloc_ablkcipher("fpu(ctr(__driver-aes-aesni))", - 0, 0); + cryptd_tfm = cryptd_alloc_ablkcipher("__driver-ctr-aes-aesni", 0, 0); if (IS_ERR(cryptd_tfm)) return PTR_ERR(cryptd_tfm); ablk_init_common(tfm, cryptd_tfm); @@ -500,11 +567,50 @@ static struct crypto_alg ablk_ctr_alg = { .ivsize = AES_BLOCK_SIZE, .setkey = ablk_set_key, .encrypt = ablk_encrypt, - .decrypt = ablk_decrypt, + .decrypt = ablk_encrypt, .geniv = "chainiv", }, }, }; + +#ifdef HAS_CTR +static int ablk_rfc3686_ctr_init(struct crypto_tfm *tfm) +{ + struct cryptd_ablkcipher *cryptd_tfm; + + cryptd_tfm = cryptd_alloc_ablkcipher( + "rfc3686(__driver-ctr-aes-aesni)", 0, 0); + if (IS_ERR(cryptd_tfm)) + return PTR_ERR(cryptd_tfm); + ablk_init_common(tfm, cryptd_tfm); + return 0; +} + +static struct crypto_alg ablk_rfc3686_ctr_alg = { + .cra_name = "rfc3686(ctr(aes))", + .cra_driver_name = "rfc3686-ctr-aes-aesni", + .cra_priority = 400, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct async_aes_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(ablk_rfc3686_ctr_alg.cra_list), + .cra_init = ablk_rfc3686_ctr_init, + .cra_exit = ablk_exit, + .cra_u = { + .ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE+CTR_RFC3686_NONCE_SIZE, + .max_keysize = AES_MAX_KEY_SIZE+CTR_RFC3686_NONCE_SIZE, + .ivsize = CTR_RFC3686_IV_SIZE, + .setkey = ablk_set_key, + .encrypt = ablk_encrypt, + .decrypt = ablk_decrypt, + .geniv = "seqiv", + }, + }, +}; #endif #ifdef HAS_LRW @@ -640,13 +746,17 @@ static int __init aesni_init(void) goto blk_ecb_err; if ((err = crypto_register_alg(&blk_cbc_alg))) goto blk_cbc_err; + if ((err = crypto_register_alg(&blk_ctr_alg))) + goto blk_ctr_err; if ((err = crypto_register_alg(&ablk_ecb_alg))) goto ablk_ecb_err; if ((err = crypto_register_alg(&ablk_cbc_alg))) goto ablk_cbc_err; -#ifdef HAS_CTR if ((err = crypto_register_alg(&ablk_ctr_alg))) goto ablk_ctr_err; +#ifdef HAS_CTR + if ((err = crypto_register_alg(&ablk_rfc3686_ctr_alg))) + goto ablk_rfc3686_ctr_err; #endif #ifdef HAS_LRW if ((err = crypto_register_alg(&ablk_lrw_alg))) @@ -675,13 +785,17 @@ ablk_pcbc_err: ablk_lrw_err: #endif #ifdef HAS_CTR + crypto_unregister_alg(&ablk_rfc3686_ctr_alg); +ablk_rfc3686_ctr_err: +#endif crypto_unregister_alg(&ablk_ctr_alg); ablk_ctr_err: -#endif crypto_unregister_alg(&ablk_cbc_alg); ablk_cbc_err: crypto_unregister_alg(&ablk_ecb_alg); ablk_ecb_err: + crypto_unregister_alg(&blk_ctr_alg); +blk_ctr_err: crypto_unregister_alg(&blk_cbc_alg); blk_cbc_err: crypto_unregister_alg(&blk_ecb_alg); @@ -705,10 +819,12 @@ static void __exit aesni_exit(void) crypto_unregister_alg(&ablk_lrw_alg); #endif #ifdef HAS_CTR - crypto_unregister_alg(&ablk_ctr_alg); + crypto_unregister_alg(&ablk_rfc3686_ctr_alg); #endif + crypto_unregister_alg(&ablk_ctr_alg); crypto_unregister_alg(&ablk_cbc_alg); crypto_unregister_alg(&ablk_ecb_alg); + crypto_unregister_alg(&blk_ctr_alg); crypto_unregister_alg(&blk_cbc_alg); crypto_unregister_alg(&blk_ecb_alg); crypto_unregister_alg(&__aesni_alg); -- cgit v1.2.3-59-g8ed1b From ca037701a025334e724e5c61b3b1082940c8b981 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 2 Mar 2010 19:52:12 +0100 Subject: perf, x86: Add PEBS infrastructure This patch implements support for Intel Precise Event Based Sampling, which is an alternative counter mode in which the counter triggers a hardware assist to collect information on events. The hardware assist takes a trap like snapshot of a subset of the machine registers. This data is written to the Intel Debug-Store, which can be programmed with a data threshold at which to raise a PMI. With the PEBS hardware assist being trap like, the reported IP is always one instruction after the actual instruction that triggered the event. This implements a simple PEBS model that always takes a single PEBS event at a time. This is done so that the interaction with the rest of the system is as expected (freq adjust, period randomization, lbr, callchains, etc.). It adds an ABI element: perf_event_attr::precise, which indicates that we wish to use this (constrained, but precise) mode. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <20100304140100.392111285@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 223 +++++------- arch/x86/kernel/cpu/perf_event_intel.c | 150 ++------ arch/x86/kernel/cpu/perf_event_intel_ds.c | 557 ++++++++++++++++++++++++++++++ include/linux/perf_event.h | 3 +- 4 files changed, 671 insertions(+), 262 deletions(-) create mode 100644 arch/x86/kernel/cpu/perf_event_intel_ds.c (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 1d665a0b202c..0c03d5c1671f 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -31,45 +31,6 @@ static u64 perf_event_mask __read_mostly; -/* The maximal number of PEBS events: */ -#define MAX_PEBS_EVENTS 4 - -/* The size of a BTS record in bytes: */ -#define BTS_RECORD_SIZE 24 - -/* The size of a per-cpu BTS buffer in bytes: */ -#define BTS_BUFFER_SIZE (BTS_RECORD_SIZE * 2048) - -/* The BTS overflow threshold in bytes from the end of the buffer: */ -#define BTS_OVFL_TH (BTS_RECORD_SIZE * 128) - - -/* - * Bits in the debugctlmsr controlling branch tracing. - */ -#define X86_DEBUGCTL_TR (1 << 6) -#define X86_DEBUGCTL_BTS (1 << 7) -#define X86_DEBUGCTL_BTINT (1 << 8) -#define X86_DEBUGCTL_BTS_OFF_OS (1 << 9) -#define X86_DEBUGCTL_BTS_OFF_USR (1 << 10) - -/* - * A debug store configuration. - * - * We only support architectures that use 64bit fields. - */ -struct debug_store { - u64 bts_buffer_base; - u64 bts_index; - u64 bts_absolute_maximum; - u64 bts_interrupt_threshold; - u64 pebs_buffer_base; - u64 pebs_index; - u64 pebs_absolute_maximum; - u64 pebs_interrupt_threshold; - u64 pebs_event_reset[MAX_PEBS_EVENTS]; -}; - struct event_constraint { union { unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; @@ -88,17 +49,29 @@ struct amd_nb { }; struct cpu_hw_events { + /* + * Generic x86 PMC bits + */ struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */ unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; unsigned long interrupts; int enabled; - struct debug_store *ds; int n_events; int n_added; int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */ u64 tags[X86_PMC_IDX_MAX]; struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ + + /* + * Intel DebugStore bits + */ + struct debug_store *ds; + u64 pebs_enabled; + + /* + * AMD specific bits + */ struct amd_nb *amd_nb; }; @@ -112,12 +85,24 @@ struct cpu_hw_events { #define EVENT_CONSTRAINT(c, n, m) \ __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n)) +/* + * Constraint on the Event code. + */ #define INTEL_EVENT_CONSTRAINT(c, n) \ EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVTSEL_MASK) +/* + * Constraint on the Event code + UMask + fixed-mask + */ #define FIXED_EVENT_CONSTRAINT(c, n) \ EVENT_CONSTRAINT(c, (1ULL << (32+n)), INTEL_ARCH_FIXED_MASK) +/* + * Constraint on the Event code + UMask + */ +#define PEBS_EVENT_CONSTRAINT(c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK) + #define EVENT_CONSTRAINT_END \ EVENT_CONSTRAINT(0, 0, 0) @@ -128,6 +113,9 @@ struct cpu_hw_events { * struct x86_pmu - generic x86 pmu */ struct x86_pmu { + /* + * Generic x86 PMC bits + */ const char *name; int version; int (*handle_irq)(struct pt_regs *); @@ -146,10 +134,6 @@ struct x86_pmu { u64 event_mask; int apic; u64 max_period; - u64 intel_ctrl; - void (*enable_bts)(u64 config); - void (*disable_bts)(void); - struct event_constraint * (*get_event_constraints)(struct cpu_hw_events *cpuc, struct perf_event *event); @@ -162,6 +146,19 @@ struct x86_pmu { void (*cpu_starting)(int cpu); void (*cpu_dying)(int cpu); void (*cpu_dead)(int cpu); + + /* + * Intel Arch Perfmon v2+ + */ + u64 intel_ctrl; + + /* + * Intel DebugStore bits + */ + int bts, pebs; + int pebs_record_size; + void (*drain_pebs)(struct pt_regs *regs); + struct event_constraint *pebs_constraints; }; static struct x86_pmu x86_pmu __read_mostly; @@ -293,110 +290,14 @@ static void release_pmc_hardware(void) #endif } -static inline bool bts_available(void) -{ - return x86_pmu.enable_bts != NULL; -} - -static void init_debug_store_on_cpu(int cpu) -{ - struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; - - if (!ds) - return; - - wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, - (u32)((u64)(unsigned long)ds), - (u32)((u64)(unsigned long)ds >> 32)); -} - -static void fini_debug_store_on_cpu(int cpu) -{ - if (!per_cpu(cpu_hw_events, cpu).ds) - return; - - wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0); -} - -static void release_bts_hardware(void) -{ - int cpu; - - if (!bts_available()) - return; - - get_online_cpus(); - - for_each_online_cpu(cpu) - fini_debug_store_on_cpu(cpu); - - for_each_possible_cpu(cpu) { - struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; - - if (!ds) - continue; - - per_cpu(cpu_hw_events, cpu).ds = NULL; - - kfree((void *)(unsigned long)ds->bts_buffer_base); - kfree(ds); - } - - put_online_cpus(); -} - -static int reserve_bts_hardware(void) -{ - int cpu, err = 0; - - if (!bts_available()) - return 0; - - get_online_cpus(); - - for_each_possible_cpu(cpu) { - struct debug_store *ds; - void *buffer; - - err = -ENOMEM; - buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL); - if (unlikely(!buffer)) - break; - - ds = kzalloc(sizeof(*ds), GFP_KERNEL); - if (unlikely(!ds)) { - kfree(buffer); - break; - } - - ds->bts_buffer_base = (u64)(unsigned long)buffer; - ds->bts_index = ds->bts_buffer_base; - ds->bts_absolute_maximum = - ds->bts_buffer_base + BTS_BUFFER_SIZE; - ds->bts_interrupt_threshold = - ds->bts_absolute_maximum - BTS_OVFL_TH; - - per_cpu(cpu_hw_events, cpu).ds = ds; - err = 0; - } - - if (err) - release_bts_hardware(); - else { - for_each_online_cpu(cpu) - init_debug_store_on_cpu(cpu); - } - - put_online_cpus(); - - return err; -} +static int reserve_ds_buffers(void); +static void release_ds_buffers(void); static void hw_perf_event_destroy(struct perf_event *event) { if (atomic_dec_and_mutex_lock(&active_events, &pmc_reserve_mutex)) { release_pmc_hardware(); - release_bts_hardware(); + release_ds_buffers(); mutex_unlock(&pmc_reserve_mutex); } } @@ -459,7 +360,7 @@ static int __hw_perf_event_init(struct perf_event *event) if (!reserve_pmc_hardware()) err = -EBUSY; else - err = reserve_bts_hardware(); + err = reserve_ds_buffers(); } if (!err) atomic_inc(&active_events); @@ -537,7 +438,7 @@ static int __hw_perf_event_init(struct perf_event *event) if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && (hwc->sample_period == 1)) { /* BTS is not supported by this architecture. */ - if (!bts_available()) + if (!x86_pmu.bts) return -EOPNOTSUPP; /* BTS is currently only allowed for user-mode. */ @@ -995,6 +896,7 @@ static void x86_pmu_unthrottle(struct perf_event *event) void perf_event_print_debug(void) { u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed; + u64 pebs; struct cpu_hw_events *cpuc; unsigned long flags; int cpu, idx; @@ -1012,12 +914,14 @@ void perf_event_print_debug(void) rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow); rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed); + rdmsrl(MSR_IA32_PEBS_ENABLE, pebs); pr_info("\n"); pr_info("CPU#%d: ctrl: %016llx\n", cpu, ctrl); pr_info("CPU#%d: status: %016llx\n", cpu, status); pr_info("CPU#%d: overflow: %016llx\n", cpu, overflow); pr_info("CPU#%d: fixed: %016llx\n", cpu, fixed); + pr_info("CPU#%d: pebs: %016llx\n", cpu, pebs); } pr_info("CPU#%d: active: %016llx\n", cpu, *(u64 *)cpuc->active_mask); @@ -1333,6 +1237,7 @@ undo: #include "perf_event_amd.c" #include "perf_event_p6.c" +#include "perf_event_intel_ds.c" #include "perf_event_intel.c" static int __cpuinit @@ -1464,6 +1369,32 @@ static const struct pmu pmu = { .unthrottle = x86_pmu_unthrottle, }; +/* + * validate that we can schedule this event + */ +static int validate_event(struct perf_event *event) +{ + struct cpu_hw_events *fake_cpuc; + struct event_constraint *c; + int ret = 0; + + fake_cpuc = kmalloc(sizeof(*fake_cpuc), GFP_KERNEL | __GFP_ZERO); + if (!fake_cpuc) + return -ENOMEM; + + c = x86_pmu.get_event_constraints(fake_cpuc, event); + + if (!c || !c->weight) + ret = -ENOSPC; + + if (x86_pmu.put_event_constraints) + x86_pmu.put_event_constraints(fake_cpuc, event); + + kfree(fake_cpuc); + + return ret; +} + /* * validate a single event group * @@ -1529,6 +1460,8 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) if (event->group_leader != event) err = validate_group(event); + else + err = validate_event(event); event->pmu = tmp; } diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 84bfde64a337..11446412e4c7 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -470,42 +470,6 @@ static u64 intel_pmu_raw_event(u64 hw_event) return hw_event & CORE_EVNTSEL_MASK; } -static void intel_pmu_enable_bts(u64 config) -{ - unsigned long debugctlmsr; - - debugctlmsr = get_debugctlmsr(); - - debugctlmsr |= X86_DEBUGCTL_TR; - debugctlmsr |= X86_DEBUGCTL_BTS; - debugctlmsr |= X86_DEBUGCTL_BTINT; - - if (!(config & ARCH_PERFMON_EVENTSEL_OS)) - debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS; - - if (!(config & ARCH_PERFMON_EVENTSEL_USR)) - debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR; - - update_debugctlmsr(debugctlmsr); -} - -static void intel_pmu_disable_bts(void) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - unsigned long debugctlmsr; - - if (!cpuc->ds) - return; - - debugctlmsr = get_debugctlmsr(); - - debugctlmsr &= - ~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT | - X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR); - - update_debugctlmsr(debugctlmsr); -} - static void intel_pmu_disable_all(void) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); @@ -514,6 +478,8 @@ static void intel_pmu_disable_all(void) if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) intel_pmu_disable_bts(); + + intel_pmu_pebs_disable_all(); } static void intel_pmu_enable_all(void) @@ -531,6 +497,8 @@ static void intel_pmu_enable_all(void) intel_pmu_enable_bts(event->hw.config); } + + intel_pmu_pebs_enable_all(); } static inline u64 intel_pmu_get_status(void) @@ -547,8 +515,7 @@ static inline void intel_pmu_ack_status(u64 ack) wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack); } -static inline void -intel_pmu_disable_fixed(struct hw_perf_event *hwc) +static void intel_pmu_disable_fixed(struct hw_perf_event *hwc) { int idx = hwc->idx - X86_PMC_IDX_FIXED; u64 ctrl_val, mask; @@ -560,68 +527,7 @@ intel_pmu_disable_fixed(struct hw_perf_event *hwc) (void)checking_wrmsrl(hwc->config_base, ctrl_val); } -static void intel_pmu_drain_bts_buffer(void) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct debug_store *ds = cpuc->ds; - struct bts_record { - u64 from; - u64 to; - u64 flags; - }; - struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS]; - struct bts_record *at, *top; - struct perf_output_handle handle; - struct perf_event_header header; - struct perf_sample_data data; - struct pt_regs regs; - - if (!event) - return; - - if (!ds) - return; - - at = (struct bts_record *)(unsigned long)ds->bts_buffer_base; - top = (struct bts_record *)(unsigned long)ds->bts_index; - - if (top <= at) - return; - - ds->bts_index = ds->bts_buffer_base; - - perf_sample_data_init(&data, 0); - - data.period = event->hw.last_period; - regs.ip = 0; - - /* - * Prepare a generic sample, i.e. fill in the invariant fields. - * We will overwrite the from and to address before we output - * the sample. - */ - perf_prepare_sample(&header, &data, event, ®s); - - if (perf_output_begin(&handle, event, - header.size * (top - at), 1, 1)) - return; - - for (; at < top; at++) { - data.ip = at->from; - data.addr = at->to; - - perf_output_sample(&handle, &header, &data, event); - } - - perf_output_end(&handle); - - /* There's new data available. */ - event->hw.interrupts++; - event->pending_kill = POLL_IN; -} - -static inline void -intel_pmu_disable_event(struct perf_event *event) +static void intel_pmu_disable_event(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; @@ -637,10 +543,12 @@ intel_pmu_disable_event(struct perf_event *event) } x86_pmu_disable_event(event); + + if (unlikely(event->attr.precise)) + intel_pmu_pebs_disable(hwc); } -static inline void -intel_pmu_enable_fixed(struct hw_perf_event *hwc) +static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) { int idx = hwc->idx - X86_PMC_IDX_FIXED; u64 ctrl_val, bits, mask; @@ -689,6 +597,9 @@ static void intel_pmu_enable_event(struct perf_event *event) return; } + if (unlikely(event->attr.precise)) + intel_pmu_pebs_enable(hwc); + __x86_pmu_enable_event(hwc); } @@ -762,6 +673,13 @@ again: inc_irq_stat(apic_perf_irqs); ack = status; + + /* + * PEBS overflow sets bit 62 in the global status register + */ + if (__test_and_clear_bit(62, (unsigned long *)&status)) + x86_pmu.drain_pebs(regs); + for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { struct perf_event *event = cpuc->events[bit]; @@ -791,22 +709,18 @@ done: return 1; } -static struct event_constraint bts_constraint = - EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0); - static struct event_constraint * -intel_special_constraints(struct perf_event *event) +intel_bts_constraints(struct perf_event *event) { - unsigned int hw_event; - - hw_event = event->hw.config & INTEL_ARCH_EVENT_MASK; + struct hw_perf_event *hwc = &event->hw; + unsigned int hw_event, bts_event; - if (unlikely((hw_event == - x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) && - (event->hw.sample_period == 1))) { + hw_event = hwc->config & INTEL_ARCH_EVENT_MASK; + bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS); + if (unlikely(hw_event == bts_event && hwc->sample_period == 1)) return &bts_constraint; - } + return NULL; } @@ -815,7 +729,11 @@ intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event { struct event_constraint *c; - c = intel_special_constraints(event); + c = intel_bts_constraints(event); + if (c) + return c; + + c = intel_pebs_constraints(event); if (c) return c; @@ -864,8 +782,6 @@ static __initconst struct x86_pmu intel_pmu = { * the generic event period: */ .max_period = (1ULL << 31) - 1, - .enable_bts = intel_pmu_enable_bts, - .disable_bts = intel_pmu_disable_bts, .get_event_constraints = intel_get_event_constraints, .cpu_starting = init_debug_store_on_cpu, @@ -915,6 +831,8 @@ static __init int intel_pmu_init(void) if (version > 1) x86_pmu.num_events_fixed = max((int)edx.split.num_events_fixed, 3); + intel_ds_init(); + /* * Install the hw-cache-events table: */ diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c new file mode 100644 index 000000000000..0d994ef213b9 --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -0,0 +1,557 @@ +#ifdef CONFIG_CPU_SUP_INTEL + +/* The maximal number of PEBS events: */ +#define MAX_PEBS_EVENTS 4 + +/* The size of a BTS record in bytes: */ +#define BTS_RECORD_SIZE 24 + +#define BTS_BUFFER_SIZE (PAGE_SIZE << 4) +#define PEBS_BUFFER_SIZE PAGE_SIZE + +/* + * pebs_record_32 for p4 and core not supported + +struct pebs_record_32 { + u32 flags, ip; + u32 ax, bc, cx, dx; + u32 si, di, bp, sp; +}; + + */ + +struct pebs_record_core { + u64 flags, ip; + u64 ax, bx, cx, dx; + u64 si, di, bp, sp; + u64 r8, r9, r10, r11; + u64 r12, r13, r14, r15; +}; + +struct pebs_record_nhm { + u64 flags, ip; + u64 ax, bx, cx, dx; + u64 si, di, bp, sp; + u64 r8, r9, r10, r11; + u64 r12, r13, r14, r15; + u64 status, dla, dse, lat; +}; + +/* + * Bits in the debugctlmsr controlling branch tracing. + */ +#define X86_DEBUGCTL_TR (1 << 6) +#define X86_DEBUGCTL_BTS (1 << 7) +#define X86_DEBUGCTL_BTINT (1 << 8) +#define X86_DEBUGCTL_BTS_OFF_OS (1 << 9) +#define X86_DEBUGCTL_BTS_OFF_USR (1 << 10) + +/* + * A debug store configuration. + * + * We only support architectures that use 64bit fields. + */ +struct debug_store { + u64 bts_buffer_base; + u64 bts_index; + u64 bts_absolute_maximum; + u64 bts_interrupt_threshold; + u64 pebs_buffer_base; + u64 pebs_index; + u64 pebs_absolute_maximum; + u64 pebs_interrupt_threshold; + u64 pebs_event_reset[MAX_PEBS_EVENTS]; +}; + +static void init_debug_store_on_cpu(int cpu) +{ + struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; + + if (!ds) + return; + + wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, + (u32)((u64)(unsigned long)ds), + (u32)((u64)(unsigned long)ds >> 32)); +} + +static void fini_debug_store_on_cpu(int cpu) +{ + if (!per_cpu(cpu_hw_events, cpu).ds) + return; + + wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0); +} + +static void release_ds_buffers(void) +{ + int cpu; + + if (!x86_pmu.bts && !x86_pmu.pebs) + return; + + get_online_cpus(); + + for_each_online_cpu(cpu) + fini_debug_store_on_cpu(cpu); + + for_each_possible_cpu(cpu) { + struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; + + if (!ds) + continue; + + per_cpu(cpu_hw_events, cpu).ds = NULL; + + kfree((void *)(unsigned long)ds->pebs_buffer_base); + kfree((void *)(unsigned long)ds->bts_buffer_base); + kfree(ds); + } + + put_online_cpus(); +} + +static int reserve_ds_buffers(void) +{ + int cpu, err = 0; + + if (!x86_pmu.bts && !x86_pmu.pebs) + return 0; + + get_online_cpus(); + + for_each_possible_cpu(cpu) { + struct debug_store *ds; + void *buffer; + int max, thresh; + + err = -ENOMEM; + ds = kzalloc(sizeof(*ds), GFP_KERNEL); + if (unlikely(!ds)) { + kfree(buffer); + break; + } + per_cpu(cpu_hw_events, cpu).ds = ds; + + if (x86_pmu.bts) { + buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL); + if (unlikely(!buffer)) + break; + + max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE; + thresh = max / 16; + + ds->bts_buffer_base = (u64)(unsigned long)buffer; + ds->bts_index = ds->bts_buffer_base; + ds->bts_absolute_maximum = ds->bts_buffer_base + + max * BTS_RECORD_SIZE; + ds->bts_interrupt_threshold = ds->bts_absolute_maximum - + thresh * BTS_RECORD_SIZE; + } + + if (x86_pmu.pebs) { + buffer = kzalloc(PEBS_BUFFER_SIZE, GFP_KERNEL); + if (unlikely(!buffer)) + break; + + max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size; + + ds->pebs_buffer_base = (u64)(unsigned long)buffer; + ds->pebs_index = ds->pebs_buffer_base; + ds->pebs_absolute_maximum = ds->pebs_buffer_base + + max * x86_pmu.pebs_record_size; + /* + * Always use single record PEBS + */ + ds->pebs_interrupt_threshold = ds->pebs_buffer_base + + x86_pmu.pebs_record_size; + } + + err = 0; + } + + if (err) + release_ds_buffers(); + else { + for_each_online_cpu(cpu) + init_debug_store_on_cpu(cpu); + } + + put_online_cpus(); + + return err; +} + +/* + * BTS + */ + +static struct event_constraint bts_constraint = + EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0); + +static void intel_pmu_enable_bts(u64 config) +{ + unsigned long debugctlmsr; + + debugctlmsr = get_debugctlmsr(); + + debugctlmsr |= X86_DEBUGCTL_TR; + debugctlmsr |= X86_DEBUGCTL_BTS; + debugctlmsr |= X86_DEBUGCTL_BTINT; + + if (!(config & ARCH_PERFMON_EVENTSEL_OS)) + debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS; + + if (!(config & ARCH_PERFMON_EVENTSEL_USR)) + debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR; + + update_debugctlmsr(debugctlmsr); +} + +static void intel_pmu_disable_bts(void) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + unsigned long debugctlmsr; + + if (!cpuc->ds) + return; + + debugctlmsr = get_debugctlmsr(); + + debugctlmsr &= + ~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT | + X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR); + + update_debugctlmsr(debugctlmsr); +} + +static void intel_pmu_drain_bts_buffer(void) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + struct debug_store *ds = cpuc->ds; + struct bts_record { + u64 from; + u64 to; + u64 flags; + }; + struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS]; + struct bts_record *at, *top; + struct perf_output_handle handle; + struct perf_event_header header; + struct perf_sample_data data; + struct pt_regs regs; + + if (!event) + return; + + if (!ds) + return; + + at = (struct bts_record *)(unsigned long)ds->bts_buffer_base; + top = (struct bts_record *)(unsigned long)ds->bts_index; + + if (top <= at) + return; + + ds->bts_index = ds->bts_buffer_base; + + perf_sample_data_init(&data, 0); + data.period = event->hw.last_period; + regs.ip = 0; + + /* + * Prepare a generic sample, i.e. fill in the invariant fields. + * We will overwrite the from and to address before we output + * the sample. + */ + perf_prepare_sample(&header, &data, event, ®s); + + if (perf_output_begin(&handle, event, header.size * (top - at), 1, 1)) + return; + + for (; at < top; at++) { + data.ip = at->from; + data.addr = at->to; + + perf_output_sample(&handle, &header, &data, event); + } + + perf_output_end(&handle); + + /* There's new data available. */ + event->hw.interrupts++; + event->pending_kill = POLL_IN; +} + +/* + * PEBS + */ + +static struct event_constraint intel_core_pebs_events[] = { + PEBS_EVENT_CONSTRAINT(0x00c0, 0x1), /* INSTR_RETIRED.ANY */ + PEBS_EVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */ + PEBS_EVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */ + PEBS_EVENT_CONSTRAINT(0x1fc7, 0x1), /* SIMD_INST_RETURED.ANY */ + PEBS_EVENT_CONSTRAINT(0x01cb, 0x1), /* MEM_LOAD_RETIRED.L1D_MISS */ + PEBS_EVENT_CONSTRAINT(0x02cb, 0x1), /* MEM_LOAD_RETIRED.L1D_LINE_MISS */ + PEBS_EVENT_CONSTRAINT(0x04cb, 0x1), /* MEM_LOAD_RETIRED.L2_MISS */ + PEBS_EVENT_CONSTRAINT(0x08cb, 0x1), /* MEM_LOAD_RETIRED.L2_LINE_MISS */ + PEBS_EVENT_CONSTRAINT(0x10cb, 0x1), /* MEM_LOAD_RETIRED.DTLB_MISS */ + EVENT_CONSTRAINT_END +}; + +static struct event_constraint intel_nehalem_pebs_events[] = { + PEBS_EVENT_CONSTRAINT(0x00c0, 0xf), /* INSTR_RETIRED.ANY */ + PEBS_EVENT_CONSTRAINT(0xfec1, 0xf), /* X87_OPS_RETIRED.ANY */ + PEBS_EVENT_CONSTRAINT(0x00c5, 0xf), /* BR_INST_RETIRED.MISPRED */ + PEBS_EVENT_CONSTRAINT(0x1fc7, 0xf), /* SIMD_INST_RETURED.ANY */ + PEBS_EVENT_CONSTRAINT(0x01cb, 0xf), /* MEM_LOAD_RETIRED.L1D_MISS */ + PEBS_EVENT_CONSTRAINT(0x02cb, 0xf), /* MEM_LOAD_RETIRED.L1D_LINE_MISS */ + PEBS_EVENT_CONSTRAINT(0x04cb, 0xf), /* MEM_LOAD_RETIRED.L2_MISS */ + PEBS_EVENT_CONSTRAINT(0x08cb, 0xf), /* MEM_LOAD_RETIRED.L2_LINE_MISS */ + PEBS_EVENT_CONSTRAINT(0x10cb, 0xf), /* MEM_LOAD_RETIRED.DTLB_MISS */ + EVENT_CONSTRAINT_END +}; + +static struct event_constraint * +intel_pebs_constraints(struct perf_event *event) +{ + struct event_constraint *c; + + if (!event->attr.precise) + return NULL; + + if (x86_pmu.pebs_constraints) { + for_each_event_constraint(c, x86_pmu.pebs_constraints) { + if ((event->hw.config & c->cmask) == c->code) + return c; + } + } + + return &emptyconstraint; +} + +static void intel_pmu_pebs_enable(struct hw_perf_event *hwc) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + u64 val = cpuc->pebs_enabled; + + hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT; + + val |= 1ULL << hwc->idx; + wrmsrl(MSR_IA32_PEBS_ENABLE, val); +} + +static void intel_pmu_pebs_disable(struct hw_perf_event *hwc) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + u64 val = cpuc->pebs_enabled; + + val &= ~(1ULL << hwc->idx); + wrmsrl(MSR_IA32_PEBS_ENABLE, val); + + hwc->config |= ARCH_PERFMON_EVENTSEL_INT; +} + +static void intel_pmu_pebs_enable_all(void) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + + if (cpuc->pebs_enabled) + wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled); +} + +static void intel_pmu_pebs_disable_all(void) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + + if (cpuc->pebs_enabled) + wrmsrl(MSR_IA32_PEBS_ENABLE, 0); +} + +static int intel_pmu_save_and_restart(struct perf_event *event); +static void intel_pmu_disable_event(struct perf_event *event); + +static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + struct debug_store *ds = cpuc->ds; + struct perf_event *event = cpuc->events[0]; /* PMC0 only */ + struct pebs_record_core *at, *top; + struct perf_sample_data data; + struct pt_regs regs; + int n; + + if (!event || !ds || !x86_pmu.pebs) + return; + + intel_pmu_pebs_disable_all(); + + at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base; + top = (struct pebs_record_core *)(unsigned long)ds->pebs_index; + + if (top <= at) + goto out; + + ds->pebs_index = ds->pebs_buffer_base; + + if (!intel_pmu_save_and_restart(event)) + goto out; + + perf_sample_data_init(&data, 0); + data.period = event->hw.last_period; + + n = top - at; + + /* + * Should not happen, we program the threshold at 1 and do not + * set a reset value. + */ + WARN_ON_ONCE(n > 1); + + /* + * We use the interrupt regs as a base because the PEBS record + * does not contain a full regs set, specifically it seems to + * lack segment descriptors, which get used by things like + * user_mode(). + * + * In the simple case fix up only the IP and BP,SP regs, for + * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly. + * A possible PERF_SAMPLE_REGS will have to transfer all regs. + */ + regs = *iregs; + regs.ip = at->ip; + regs.bp = at->bp; + regs.sp = at->sp; + + if (perf_event_overflow(event, 1, &data, ®s)) + intel_pmu_disable_event(event); + +out: + intel_pmu_pebs_enable_all(); +} + +static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + struct debug_store *ds = cpuc->ds; + struct pebs_record_nhm *at, *top; + struct perf_sample_data data; + struct perf_event *event = NULL; + struct pt_regs regs; + int bit, n; + + if (!ds || !x86_pmu.pebs) + return; + + intel_pmu_pebs_disable_all(); + + at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base; + top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index; + + if (top <= at) + goto out; + + ds->pebs_index = ds->pebs_buffer_base; + + n = top - at; + + /* + * Should not happen, we program the threshold at 1 and do not + * set a reset value. + */ + WARN_ON_ONCE(n > MAX_PEBS_EVENTS); + + for ( ; at < top; at++) { + for_each_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) { + if (!cpuc->events[bit]->attr.precise) + continue; + + event = cpuc->events[bit]; + } + + if (!event) + continue; + + if (!intel_pmu_save_and_restart(event)) + continue; + + perf_sample_data_init(&data, 0); + data.period = event->hw.last_period; + + /* + * See the comment in intel_pmu_drain_pebs_core() + */ + regs = *iregs; + regs.ip = at->ip; + regs.bp = at->bp; + regs.sp = at->sp; + + if (perf_event_overflow(event, 1, &data, ®s)) + intel_pmu_disable_event(event); + } +out: + intel_pmu_pebs_enable_all(); +} + +/* + * BTS, PEBS probe and setup + */ + +static void intel_ds_init(void) +{ + /* + * No support for 32bit formats + */ + if (!boot_cpu_has(X86_FEATURE_DTES64)) + return; + + x86_pmu.bts = boot_cpu_has(X86_FEATURE_BTS); + x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS); + if (x86_pmu.pebs) { + int format = 0; + + if (x86_pmu.version > 1) { + u64 capabilities; + /* + * v2+ has a PEBS format field + */ + rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); + format = (capabilities >> 8) & 0xf; + } + + switch (format) { + case 0: + printk(KERN_CONT "PEBS v0, "); + x86_pmu.pebs_record_size = sizeof(struct pebs_record_core); + x86_pmu.drain_pebs = intel_pmu_drain_pebs_core; + x86_pmu.pebs_constraints = intel_core_pebs_events; + break; + + case 1: + printk(KERN_CONT "PEBS v1, "); + x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm); + x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + break; + + default: + printk(KERN_CONT "PEBS unknown format: %d, ", format); + x86_pmu.pebs = 0; + break; + } + } +} + +#else /* CONFIG_CPU_SUP_INTEL */ + +static int reseve_ds_buffers(void) +{ + return 0; +} + +static void release_ds_buffers(void) +{ +} + +#endif /* CONFIG_CPU_SUP_INTEL */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 80acbf3d5de1..42307b50c787 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -203,8 +203,9 @@ struct perf_event_attr { enable_on_exec : 1, /* next exec enables */ task : 1, /* trace fork/exit */ watermark : 1, /* wakeup_watermark */ + precise : 1, /* OoO invariant counter */ - __reserved_1 : 49; + __reserved_1 : 48; union { __u32 wakeup_events; /* wakeup every n events */ -- cgit v1.2.3-59-g8ed1b From caff2befffe899e63df5cc760b7ed01cfd902685 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 3 Mar 2010 12:02:30 +0100 Subject: perf, x86: Implement simple LBR support Implement simple suport Intel Last-Branch-Record, it supports all hardware that implements FREEZE_LBRS_ON_PMI, but does not (yet) implement the LBR config register. The Intel LBR is a FIFO of From,To addresses describing the last few branches the hardware took. This patch does not add perf interface to the LBR, but merely provides an interface for internal use. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <20100304140100.544191154@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 18 +++ arch/x86/kernel/cpu/perf_event_intel.c | 13 ++ arch/x86/kernel/cpu/perf_event_intel_lbr.c | 228 +++++++++++++++++++++++++++++ include/linux/perf_event.h | 11 ++ 4 files changed, 270 insertions(+) create mode 100644 arch/x86/kernel/cpu/perf_event_intel_lbr.c (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 0c03d5c1671f..1badff6b6b28 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -48,6 +48,8 @@ struct amd_nb { struct event_constraint event_constraints[X86_PMC_IDX_MAX]; }; +#define MAX_LBR_ENTRIES 16 + struct cpu_hw_events { /* * Generic x86 PMC bits @@ -69,6 +71,14 @@ struct cpu_hw_events { struct debug_store *ds; u64 pebs_enabled; + /* + * Intel LBR bits + */ + int lbr_users; + void *lbr_context; + struct perf_branch_stack lbr_stack; + struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES]; + /* * AMD specific bits */ @@ -159,6 +169,13 @@ struct x86_pmu { int pebs_record_size; void (*drain_pebs)(struct pt_regs *regs); struct event_constraint *pebs_constraints; + + /* + * Intel LBR + */ + unsigned long lbr_tos, lbr_from, lbr_to; /* MSR base regs */ + int lbr_nr; /* hardware stack size */ + int lbr_format; /* hardware format */ }; static struct x86_pmu x86_pmu __read_mostly; @@ -1237,6 +1254,7 @@ undo: #include "perf_event_amd.c" #include "perf_event_p6.c" +#include "perf_event_intel_lbr.c" #include "perf_event_intel_ds.c" #include "perf_event_intel.c" diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 11446412e4c7..44f6ed42a934 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -480,6 +480,7 @@ static void intel_pmu_disable_all(void) intel_pmu_disable_bts(); intel_pmu_pebs_disable_all(); + intel_pmu_lbr_disable_all(); } static void intel_pmu_enable_all(void) @@ -499,6 +500,7 @@ static void intel_pmu_enable_all(void) } intel_pmu_pebs_enable_all(); + intel_pmu_lbr_enable_all(); } static inline u64 intel_pmu_get_status(void) @@ -674,6 +676,8 @@ again: inc_irq_stat(apic_perf_irqs); ack = status; + intel_pmu_lbr_read(); + /* * PEBS overflow sets bit 62 in the global status register */ @@ -848,6 +852,8 @@ static __init int intel_pmu_init(void) memcpy(hw_cache_event_ids, core2_hw_cache_event_ids, sizeof(hw_cache_event_ids)); + intel_pmu_lbr_init_core(); + x86_pmu.event_constraints = intel_core2_event_constraints; pr_cont("Core2 events, "); break; @@ -857,13 +863,18 @@ static __init int intel_pmu_init(void) memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids, sizeof(hw_cache_event_ids)); + intel_pmu_lbr_init_nhm(); + x86_pmu.event_constraints = intel_nehalem_event_constraints; pr_cont("Nehalem/Corei7 events, "); break; + case 28: /* Atom */ memcpy(hw_cache_event_ids, atom_hw_cache_event_ids, sizeof(hw_cache_event_ids)); + intel_pmu_lbr_init_atom(); + x86_pmu.event_constraints = intel_gen_event_constraints; pr_cont("Atom events, "); break; @@ -873,6 +884,8 @@ static __init int intel_pmu_init(void) memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids, sizeof(hw_cache_event_ids)); + intel_pmu_lbr_init_nhm(); + x86_pmu.event_constraints = intel_westmere_event_constraints; pr_cont("Westmere events, "); break; diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c new file mode 100644 index 000000000000..ea3e99ed82ce --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -0,0 +1,228 @@ +#ifdef CONFIG_CPU_SUP_INTEL + +enum { + LBR_FORMAT_32 = 0x00, + LBR_FORMAT_LIP = 0x01, + LBR_FORMAT_EIP = 0x02, + LBR_FORMAT_EIP_FLAGS = 0x03, +}; + +/* + * We only support LBR implementations that have FREEZE_LBRS_ON_PMI + * otherwise it becomes near impossible to get a reliable stack. + */ + +#define X86_DEBUGCTL_LBR (1 << 0) +#define X86_DEBUGCTL_FREEZE_LBRS_ON_PMI (1 << 11) + +static void __intel_pmu_lbr_enable(void) +{ + u64 debugctl; + + rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); + debugctl |= (X86_DEBUGCTL_LBR | X86_DEBUGCTL_FREEZE_LBRS_ON_PMI); + wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); +} + +static void __intel_pmu_lbr_disable(void) +{ + u64 debugctl; + + rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); + debugctl &= ~(X86_DEBUGCTL_LBR | X86_DEBUGCTL_FREEZE_LBRS_ON_PMI); + wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); +} + +static void intel_pmu_lbr_reset_32(void) +{ + int i; + + for (i = 0; i < x86_pmu.lbr_nr; i++) + wrmsrl(x86_pmu.lbr_from + i, 0); +} + +static void intel_pmu_lbr_reset_64(void) +{ + int i; + + for (i = 0; i < x86_pmu.lbr_nr; i++) { + wrmsrl(x86_pmu.lbr_from + i, 0); + wrmsrl(x86_pmu.lbr_to + i, 0); + } +} + +static void intel_pmu_lbr_reset(void) +{ + if (x86_pmu.lbr_format == LBR_FORMAT_32) + intel_pmu_lbr_reset_32(); + else + intel_pmu_lbr_reset_64(); +} + +static void intel_pmu_lbr_enable(struct perf_event *event) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + + if (!x86_pmu.lbr_nr) + return; + + WARN_ON(cpuc->enabled); + + /* + * Reset the LBR stack if this is the first LBR user or + * we changed task context so as to avoid data leaks. + */ + + if (!cpuc->lbr_users || + (event->ctx->task && cpuc->lbr_context != event->ctx)) { + intel_pmu_lbr_reset(); + cpuc->lbr_context = event->ctx; + } + + cpuc->lbr_users++; +} + +static void intel_pmu_lbr_disable(struct perf_event *event) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + + if (!x86_pmu.lbr_nr) + return; + + cpuc->lbr_users--; + + BUG_ON(cpuc->lbr_users < 0); + WARN_ON(cpuc->enabled); +} + +static void intel_pmu_lbr_enable_all(void) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + + if (cpuc->lbr_users) + __intel_pmu_lbr_enable(); +} + +static void intel_pmu_lbr_disable_all(void) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + + if (cpuc->lbr_users) + __intel_pmu_lbr_disable(); +} + +static inline u64 intel_pmu_lbr_tos(void) +{ + u64 tos; + + rdmsrl(x86_pmu.lbr_tos, tos); + + return tos; +} + +static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) +{ + unsigned long mask = x86_pmu.lbr_nr - 1; + u64 tos = intel_pmu_lbr_tos(); + int i; + + for (i = 0; i < x86_pmu.lbr_nr; i++, tos--) { + unsigned long lbr_idx = (tos - i) & mask; + union { + struct { + u32 from; + u32 to; + }; + u64 lbr; + } msr_lastbranch; + + rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr); + + cpuc->lbr_entries[i].from = msr_lastbranch.from; + cpuc->lbr_entries[i].to = msr_lastbranch.to; + cpuc->lbr_entries[i].flags = 0; + } + cpuc->lbr_stack.nr = i; +} + +#define LBR_FROM_FLAG_MISPRED (1ULL << 63) + +/* + * Due to lack of segmentation in Linux the effective address (offset) + * is the same as the linear address, allowing us to merge the LIP and EIP + * LBR formats. + */ +static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) +{ + unsigned long mask = x86_pmu.lbr_nr - 1; + u64 tos = intel_pmu_lbr_tos(); + int i; + + for (i = 0; i < x86_pmu.lbr_nr; i++, tos--) { + unsigned long lbr_idx = (tos - i) & mask; + u64 from, to, flags = 0; + + rdmsrl(x86_pmu.lbr_from + lbr_idx, from); + rdmsrl(x86_pmu.lbr_to + lbr_idx, to); + + if (x86_pmu.lbr_format == LBR_FORMAT_EIP_FLAGS) { + flags = !!(from & LBR_FROM_FLAG_MISPRED); + from = (u64)((((s64)from) << 1) >> 1); + } + + cpuc->lbr_entries[i].from = from; + cpuc->lbr_entries[i].to = to; + cpuc->lbr_entries[i].flags = flags; + } + cpuc->lbr_stack.nr = i; +} + +static void intel_pmu_lbr_read(void) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + + if (!cpuc->lbr_users) + return; + + if (x86_pmu.lbr_format == LBR_FORMAT_32) + intel_pmu_lbr_read_32(cpuc); + else + intel_pmu_lbr_read_64(cpuc); +} + +static int intel_pmu_lbr_format(void) +{ + u64 capabilities; + + rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); + return capabilities & 0x1f; +} + +static void intel_pmu_lbr_init_core(void) +{ + x86_pmu.lbr_format = intel_pmu_lbr_format(); + x86_pmu.lbr_nr = 4; + x86_pmu.lbr_tos = 0x01c9; + x86_pmu.lbr_from = 0x40; + x86_pmu.lbr_to = 0x60; +} + +static void intel_pmu_lbr_init_nhm(void) +{ + x86_pmu.lbr_format = intel_pmu_lbr_format(); + x86_pmu.lbr_nr = 16; + x86_pmu.lbr_tos = 0x01c9; + x86_pmu.lbr_from = 0x680; + x86_pmu.lbr_to = 0x6c0; +} + +static void intel_pmu_lbr_init_atom(void) +{ + x86_pmu.lbr_format = intel_pmu_lbr_format(); + x86_pmu.lbr_nr = 8; + x86_pmu.lbr_tos = 0x01c9; + x86_pmu.lbr_from = 0x40; + x86_pmu.lbr_to = 0x60; +} + +#endif /* CONFIG_CPU_SUP_INTEL */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 42307b50c787..ab4fd9ede264 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -467,6 +467,17 @@ struct perf_raw_record { void *data; }; +struct perf_branch_entry { + __u64 from; + __u64 to; + __u64 flags; +}; + +struct perf_branch_stack { + __u64 nr; + struct perf_branch_entry entries[0]; +}; + struct task_struct; /** -- cgit v1.2.3-59-g8ed1b From ef21f683a045a79b6aa86ad81e5fdfc0d5ddd250 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 3 Mar 2010 13:12:23 +0100 Subject: perf, x86: use LBR for PEBS IP+1 fixup Use the LBR to fix up the PEBS IP+1 issue. As said, PEBS reports the next instruction, here we use the LBR to find the last branch and from that construct the actual IP. If the IP matches the LBR-TO, we use LBR-FROM, otherwise we use the LBR-TO address as the beginning of the last basic block and decode forward. Once we find a match to the current IP, we use the previous location. This patch introduces a new ABI element: PERF_RECORD_MISC_EXACT, which conveys that the reported IP (PERF_SAMPLE_IP) is the exact instruction that caused the event (barring CPU errata). The fixup can fail due to various reasons: 1) LBR contains invalid data (quite possible) 2) part of the basic block got paged out 3) the reported IP isn't part of the basic block (see 1) Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu Cc: "Zhang, Yanmin" Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <20100304140100.619375431@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event.h | 19 +++++++ arch/x86/kernel/cpu/perf_event.c | 70 +++++++++++++------------- arch/x86/kernel/cpu/perf_event_intel.c | 4 +- arch/x86/kernel/cpu/perf_event_intel_ds.c | 84 ++++++++++++++++++++++++++++++- include/linux/perf_event.h | 6 +++ 5 files changed, 144 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index db6109a885a7..a9038c951619 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -136,6 +136,25 @@ extern void perf_events_lapic_init(void); #define PERF_EVENT_INDEX_OFFSET 0 +/* + * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups. + * This flag is otherwise unused and ABI specified to be 0, so nobody should + * care what we do with it. + */ +#define PERF_EFLAGS_EXACT (1UL << 3) + +#define perf_misc_flags(regs) \ +({ int misc = 0; \ + if (user_mode(regs)) \ + misc |= PERF_RECORD_MISC_USER; \ + else \ + misc |= PERF_RECORD_MISC_KERNEL; \ + if (regs->flags & PERF_EFLAGS_EXACT) \ + misc |= PERF_RECORD_MISC_EXACT; \ + misc; }) + +#define perf_instruction_pointer(regs) ((regs)->ip) + #else static inline void init_hw_perf_events(void) { } static inline void perf_events_lapic_init(void) { } diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 1badff6b6b28..5cb4e8dcee4b 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -29,6 +29,41 @@ #include #include +/* + * best effort, GUP based copy_from_user() that assumes IRQ or NMI context + */ +static unsigned long +copy_from_user_nmi(void *to, const void __user *from, unsigned long n) +{ + unsigned long offset, addr = (unsigned long)from; + int type = in_nmi() ? KM_NMI : KM_IRQ0; + unsigned long size, len = 0; + struct page *page; + void *map; + int ret; + + do { + ret = __get_user_pages_fast(addr, 1, 0, &page); + if (!ret) + break; + + offset = addr & (PAGE_SIZE - 1); + size = min(PAGE_SIZE - offset, n - len); + + map = kmap_atomic(page, type); + memcpy(to, map+offset, size); + kunmap_atomic(map, type); + put_page(page); + + len += size; + to += size; + addr += size; + + } while (len < n); + + return len; +} + static u64 perf_event_mask __read_mostly; struct event_constraint { @@ -1550,41 +1585,6 @@ perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry); } -/* - * best effort, GUP based copy_from_user() that assumes IRQ or NMI context - */ -static unsigned long -copy_from_user_nmi(void *to, const void __user *from, unsigned long n) -{ - unsigned long offset, addr = (unsigned long)from; - int type = in_nmi() ? KM_NMI : KM_IRQ0; - unsigned long size, len = 0; - struct page *page; - void *map; - int ret; - - do { - ret = __get_user_pages_fast(addr, 1, 0, &page); - if (!ret) - break; - - offset = addr & (PAGE_SIZE - 1); - size = min(PAGE_SIZE - offset, n - len); - - map = kmap_atomic(page, type); - memcpy(to, map+offset, size); - kunmap_atomic(map, type); - put_page(page); - - len += size; - to += size; - addr += size; - - } while (len < n); - - return len; -} - static int copy_stack_frame(const void __user *fp, struct stack_frame *frame) { unsigned long bytes; diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 44f6ed42a934..7eb78be3b229 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -547,7 +547,7 @@ static void intel_pmu_disable_event(struct perf_event *event) x86_pmu_disable_event(event); if (unlikely(event->attr.precise)) - intel_pmu_pebs_disable(hwc); + intel_pmu_pebs_disable(event); } static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) @@ -600,7 +600,7 @@ static void intel_pmu_enable_event(struct perf_event *event) } if (unlikely(event->attr.precise)) - intel_pmu_pebs_enable(hwc); + intel_pmu_pebs_enable(event); __x86_pmu_enable_event(hwc); } diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 0d994ef213b9..50e6ff3281fc 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -331,26 +331,32 @@ intel_pebs_constraints(struct perf_event *event) return &emptyconstraint; } -static void intel_pmu_pebs_enable(struct hw_perf_event *hwc) +static void intel_pmu_pebs_enable(struct perf_event *event) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + struct hw_perf_event *hwc = &event->hw; u64 val = cpuc->pebs_enabled; hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT; val |= 1ULL << hwc->idx; wrmsrl(MSR_IA32_PEBS_ENABLE, val); + + intel_pmu_lbr_enable(event); } -static void intel_pmu_pebs_disable(struct hw_perf_event *hwc) +static void intel_pmu_pebs_disable(struct perf_event *event) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + struct hw_perf_event *hwc = &event->hw; u64 val = cpuc->pebs_enabled; val &= ~(1ULL << hwc->idx); wrmsrl(MSR_IA32_PEBS_ENABLE, val); hwc->config |= ARCH_PERFMON_EVENTSEL_INT; + + intel_pmu_lbr_disable(event); } static void intel_pmu_pebs_enable_all(void) @@ -369,6 +375,70 @@ static void intel_pmu_pebs_disable_all(void) wrmsrl(MSR_IA32_PEBS_ENABLE, 0); } +#include + +#define MAX_INSN_SIZE 16 + +static inline bool kernel_ip(unsigned long ip) +{ +#ifdef CONFIG_X86_32 + return ip > PAGE_OFFSET; +#else + return (long)ip < 0; +#endif +} + +static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + unsigned long from = cpuc->lbr_entries[0].from; + unsigned long old_to, to = cpuc->lbr_entries[0].to; + unsigned long ip = regs->ip; + + if (!cpuc->lbr_stack.nr || !from || !to) + return 0; + + if (ip < to) + return 0; + + /* + * We sampled a branch insn, rewind using the LBR stack + */ + if (ip == to) { + regs->ip = from; + return 1; + } + + do { + struct insn insn; + u8 buf[MAX_INSN_SIZE]; + void *kaddr; + + old_to = to; + if (!kernel_ip(ip)) { + int bytes, size = min_t(int, MAX_INSN_SIZE, ip - to); + + bytes = copy_from_user_nmi(buf, (void __user *)to, size); + if (bytes != size) + return 0; + + kaddr = buf; + } else + kaddr = (void *)to; + + kernel_insn_init(&insn, kaddr); + insn_get_length(&insn); + to += insn.length; + } while (to < ip); + + if (to == ip) { + regs->ip = old_to; + return 1; + } + + return 0; +} + static int intel_pmu_save_and_restart(struct perf_event *event); static void intel_pmu_disable_event(struct perf_event *event); @@ -424,6 +494,11 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) regs.bp = at->bp; regs.sp = at->sp; + if (intel_pmu_pebs_fixup_ip(®s)) + regs.flags |= PERF_EFLAGS_EXACT; + else + regs.flags &= ~PERF_EFLAGS_EXACT; + if (perf_event_overflow(event, 1, &data, ®s)) intel_pmu_disable_event(event); @@ -487,6 +562,11 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) regs.bp = at->bp; regs.sp = at->sp; + if (intel_pmu_pebs_fixup_ip(®s)) + regs.flags |= PERF_EFLAGS_EXACT; + else + regs.flags &= ~PERF_EFLAGS_EXACT; + if (perf_event_overflow(event, 1, &data, ®s)) intel_pmu_disable_event(event); } diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index ab4fd9ede264..be85f7c4a94f 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -294,6 +294,12 @@ struct perf_event_mmap_page { #define PERF_RECORD_MISC_USER (2 << 0) #define PERF_RECORD_MISC_HYPERVISOR (3 << 0) +#define PERF_RECORD_MISC_EXACT (1 << 14) +/* + * Reserve the last bit to indicate some extended misc field + */ +#define PERF_RECORD_MISC_EXT_RESERVED (1 << 15) + struct perf_event_header { __u32 type; __u16 misc; -- cgit v1.2.3-59-g8ed1b From 8db909a7e3c888b5d45aef7650d74ccebe3ce725 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 3 Mar 2010 17:07:40 +0100 Subject: perf, x86: Clean up IA32_PERF_CAPABILITIES usage Saner PERF_CAPABILITIES support, which also exposes pebs_trap. Use that latter to make PEBS's use of LBR conditional since a fault-like pebs should already report the correct IP. ( As of this writing there is no known hardware that implements !pebs_trap ) Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <20100304140100.770650663@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 15 +++++++++++++-- arch/x86/kernel/cpu/perf_event_intel.c | 10 ++++++++++ arch/x86/kernel/cpu/perf_event_intel_ds.c | 30 +++++++++++++++--------------- arch/x86/kernel/cpu/perf_event_intel_lbr.c | 18 ++++-------------- 4 files changed, 42 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 5cb4e8dcee4b..7b5430b2efe7 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -154,6 +154,17 @@ struct cpu_hw_events { #define for_each_event_constraint(e, c) \ for ((e) = (c); (e)->cmask; (e)++) +union perf_capabilities { + struct { + u64 lbr_format : 6; + u64 pebs_trap : 1; + u64 pebs_arch_reg : 1; + u64 pebs_format : 4; + u64 smm_freeze : 1; + }; + u64 capabilities; +}; + /* * struct x86_pmu - generic x86 pmu */ @@ -195,7 +206,8 @@ struct x86_pmu { /* * Intel Arch Perfmon v2+ */ - u64 intel_ctrl; + u64 intel_ctrl; + union perf_capabilities intel_cap; /* * Intel DebugStore bits @@ -210,7 +222,6 @@ struct x86_pmu { */ unsigned long lbr_tos, lbr_from, lbr_to; /* MSR base regs */ int lbr_nr; /* hardware stack size */ - int lbr_format; /* hardware format */ }; static struct x86_pmu x86_pmu __read_mostly; diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 7eb78be3b229..246c07238823 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -835,6 +835,16 @@ static __init int intel_pmu_init(void) if (version > 1) x86_pmu.num_events_fixed = max((int)edx.split.num_events_fixed, 3); + /* + * v2 and above have a perf capabilities MSR + */ + if (version > 1) { + u64 capabilities; + + rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); + x86_pmu.intel_cap.capabilities = capabilities; + } + intel_ds_init(); /* diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 50e6ff3281fc..5e4029441b2d 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -342,7 +342,8 @@ static void intel_pmu_pebs_enable(struct perf_event *event) val |= 1ULL << hwc->idx; wrmsrl(MSR_IA32_PEBS_ENABLE, val); - intel_pmu_lbr_enable(event); + if (x86_pmu.intel_cap.pebs_trap) + intel_pmu_lbr_enable(event); } static void intel_pmu_pebs_disable(struct perf_event *event) @@ -356,7 +357,8 @@ static void intel_pmu_pebs_disable(struct perf_event *event) hwc->config |= ARCH_PERFMON_EVENTSEL_INT; - intel_pmu_lbr_disable(event); + if (x86_pmu.intel_cap.pebs_trap) + intel_pmu_lbr_disable(event); } static void intel_pmu_pebs_enable_all(void) @@ -395,6 +397,12 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) unsigned long old_to, to = cpuc->lbr_entries[0].to; unsigned long ip = regs->ip; + /* + * We don't need to fixup if the PEBS assist is fault like + */ + if (!x86_pmu.intel_cap.pebs_trap) + return 1; + if (!cpuc->lbr_stack.nr || !from || !to) return 0; @@ -589,34 +597,26 @@ static void intel_ds_init(void) x86_pmu.bts = boot_cpu_has(X86_FEATURE_BTS); x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS); if (x86_pmu.pebs) { - int format = 0; - - if (x86_pmu.version > 1) { - u64 capabilities; - /* - * v2+ has a PEBS format field - */ - rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); - format = (capabilities >> 8) & 0xf; - } + char pebs_type = x86_pmu.intel_cap.pebs_trap ? '+' : '-'; + int format = x86_pmu.intel_cap.pebs_format; switch (format) { case 0: - printk(KERN_CONT "PEBS v0, "); + printk(KERN_CONT "PEBS fmt0%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_core); x86_pmu.drain_pebs = intel_pmu_drain_pebs_core; x86_pmu.pebs_constraints = intel_core_pebs_events; break; case 1: - printk(KERN_CONT "PEBS v1, "); + printk(KERN_CONT "PEBS fmt1%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; x86_pmu.pebs_constraints = intel_nehalem_pebs_events; break; default: - printk(KERN_CONT "PEBS unknown format: %d, ", format); + printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type); x86_pmu.pebs = 0; break; } diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index ea3e99ed82ce..4f3a124329c4 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -53,7 +53,7 @@ static void intel_pmu_lbr_reset_64(void) static void intel_pmu_lbr_reset(void) { - if (x86_pmu.lbr_format == LBR_FORMAT_32) + if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32) intel_pmu_lbr_reset_32(); else intel_pmu_lbr_reset_64(); @@ -155,6 +155,7 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) { unsigned long mask = x86_pmu.lbr_nr - 1; + int lbr_format = x86_pmu.intel_cap.lbr_format; u64 tos = intel_pmu_lbr_tos(); int i; @@ -165,7 +166,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) rdmsrl(x86_pmu.lbr_from + lbr_idx, from); rdmsrl(x86_pmu.lbr_to + lbr_idx, to); - if (x86_pmu.lbr_format == LBR_FORMAT_EIP_FLAGS) { + if (lbr_format == LBR_FORMAT_EIP_FLAGS) { flags = !!(from & LBR_FROM_FLAG_MISPRED); from = (u64)((((s64)from) << 1) >> 1); } @@ -184,23 +185,14 @@ static void intel_pmu_lbr_read(void) if (!cpuc->lbr_users) return; - if (x86_pmu.lbr_format == LBR_FORMAT_32) + if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32) intel_pmu_lbr_read_32(cpuc); else intel_pmu_lbr_read_64(cpuc); } -static int intel_pmu_lbr_format(void) -{ - u64 capabilities; - - rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); - return capabilities & 0x1f; -} - static void intel_pmu_lbr_init_core(void) { - x86_pmu.lbr_format = intel_pmu_lbr_format(); x86_pmu.lbr_nr = 4; x86_pmu.lbr_tos = 0x01c9; x86_pmu.lbr_from = 0x40; @@ -209,7 +201,6 @@ static void intel_pmu_lbr_init_core(void) static void intel_pmu_lbr_init_nhm(void) { - x86_pmu.lbr_format = intel_pmu_lbr_format(); x86_pmu.lbr_nr = 16; x86_pmu.lbr_tos = 0x01c9; x86_pmu.lbr_from = 0x680; @@ -218,7 +209,6 @@ static void intel_pmu_lbr_init_nhm(void) static void intel_pmu_lbr_init_atom(void) { - x86_pmu.lbr_format = intel_pmu_lbr_format(); x86_pmu.lbr_nr = 8; x86_pmu.lbr_tos = 0x01c9; x86_pmu.lbr_from = 0x40; -- cgit v1.2.3-59-g8ed1b From 7e1a40dda619b0483fbe0740494ed2c2a1f05289 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 4 Mar 2010 12:38:03 +0100 Subject: perf, x86: Expose the full PEBS record using PERF_SAMPLE_RAW Expose the full PEBS record using PERF_SAMPLE_RAW Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <20100304140100.847218224@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 5e4029441b2d..ef56f053ab31 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -457,6 +457,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) struct perf_event *event = cpuc->events[0]; /* PMC0 only */ struct pebs_record_core *at, *top; struct perf_sample_data data; + struct perf_raw_record raw; struct pt_regs regs; int n; @@ -479,6 +480,12 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) perf_sample_data_init(&data, 0); data.period = event->hw.last_period; + if (event->attr.sample_type & PERF_SAMPLE_RAW) { + raw.size = x86_pmu.pebs_record_size; + raw.data = at; + data.raw = &raw; + } + n = top - at; /* @@ -521,6 +528,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) struct pebs_record_nhm *at, *top; struct perf_sample_data data; struct perf_event *event = NULL; + struct perf_raw_record raw; struct pt_regs regs; int bit, n; @@ -562,6 +570,12 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) perf_sample_data_init(&data, 0); data.period = event->hw.last_period; + if (event->attr.sample_type & PERF_SAMPLE_RAW) { + raw.size = x86_pmu.pebs_record_size; + raw.data = at; + data.raw = &raw; + } + /* * See the comment in intel_pmu_drain_pebs_core() */ -- cgit v1.2.3-59-g8ed1b From 30a813ae035d3e220a89609adce878e045c49547 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 4 Mar 2010 13:49:21 +0100 Subject: x86: Move MAX_INSN_SIZE into asm/insn.h Since there's now two users for this, place it in a common header. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <20100304140100.923774125@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/insn.h | 2 ++ arch/x86/include/asm/kprobes.h | 2 +- arch/x86/kernel/cpu/perf_event_intel_ds.c | 2 -- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h index 96c2e0ad04ca..88c765e16410 100644 --- a/arch/x86/include/asm/insn.h +++ b/arch/x86/include/asm/insn.h @@ -68,6 +68,8 @@ struct insn { const insn_byte_t *next_byte; }; +#define MAX_INSN_SIZE 16 + #define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6) #define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3) #define X86_MODRM_RM(modrm) ((modrm) & 0x07) diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h index 4ffa345a8ccb..547882539157 100644 --- a/arch/x86/include/asm/kprobes.h +++ b/arch/x86/include/asm/kprobes.h @@ -24,6 +24,7 @@ #include #include #include +#include #define __ARCH_WANT_KPROBES_INSN_SLOT @@ -36,7 +37,6 @@ typedef u8 kprobe_opcode_t; #define RELATIVEJUMP_SIZE 5 #define RELATIVECALL_OPCODE 0xe8 #define RELATIVE_ADDR_SIZE 4 -#define MAX_INSN_SIZE 16 #define MAX_STACK_SIZE 64 #define MIN_STACK_SIZE(ADDR) \ (((MAX_STACK_SIZE) < (((unsigned long)current_thread_info()) + \ diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index ef56f053ab31..72453ac5fb7d 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -379,8 +379,6 @@ static void intel_pmu_pebs_disable_all(void) #include -#define MAX_INSN_SIZE 16 - static inline bool kernel_ip(unsigned long ip) { #ifdef CONFIG_X86_32 -- cgit v1.2.3-59-g8ed1b From 3adaebd69557615c1bf0365ce5e32d93ac7d82af Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 5 Mar 2010 12:09:29 +0100 Subject: perf, x86: Fix silly bug in data store buffer allocation Fix up the ds allocation error path, where we could free @buffer before we used it. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <20100305154128.813452402@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 72453ac5fb7d..a67fff14475e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -127,10 +127,8 @@ static int reserve_ds_buffers(void) err = -ENOMEM; ds = kzalloc(sizeof(*ds), GFP_KERNEL); - if (unlikely(!ds)) { - kfree(buffer); + if (unlikely(!ds)) break; - } per_cpu(cpu_hw_events, cpu).ds = ds; if (x86_pmu.bts) { -- cgit v1.2.3-59-g8ed1b From 3c44780b220e876b01e39d4028cd6f4205fbf5d6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 4 Mar 2010 21:49:01 +0100 Subject: perf, x86: Disable PEBS on clovertown chips This CPU has just too many handycaps to be really useful. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <20100305154128.890278662@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 4 ++++ arch/x86/kernel/cpu/perf_event_intel.c | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 7b5430b2efe7..335ee1d38b79 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -197,6 +197,7 @@ struct x86_pmu { void (*put_event_constraints)(struct cpu_hw_events *cpuc, struct perf_event *event); struct event_constraint *event_constraints; + void (*quirks)(void); void (*cpu_prepare)(int cpu); void (*cpu_starting)(int cpu); @@ -1373,6 +1374,9 @@ void __init init_hw_perf_events(void) pr_cont("%s PMU driver.\n", x86_pmu.name); + if (x86_pmu.quirks) + x86_pmu.quirks(); + if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) { WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", x86_pmu.num_events, X86_PMC_MAX_GENERIC); diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 246c07238823..224c952071f9 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -792,6 +792,32 @@ static __initconst struct x86_pmu intel_pmu = { .cpu_dying = fini_debug_store_on_cpu, }; +static void intel_clovertown_quirks(void) +{ + /* + * PEBS is unreliable due to: + * + * AJ67 - PEBS may experience CPL leaks + * AJ68 - PEBS PMI may be delayed by one event + * AJ69 - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12] + * AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS + * + * AJ67 could be worked around by restricting the OS/USR flags. + * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI. + * + * AJ106 could possibly be worked around by not allowing LBR + * usage from PEBS, including the fixup. + * AJ68 could possibly be worked around by always programming + * a pebs_event_reset[0] value and coping with the lost events. + * + * But taken together it might just make sense to not enable PEBS on + * these chips. + */ + printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); + x86_pmu.pebs = 0; + x86_pmu.pebs_constraints = NULL; +} + static __init int intel_pmu_init(void) { union cpuid10_edx edx; @@ -856,6 +882,7 @@ static __init int intel_pmu_init(void) break; case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */ + x86_pmu.quirks = intel_clovertown_quirks; case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */ case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */ case 29: /* six-core 45 nm xeon "Dunnington" */ -- cgit v1.2.3-59-g8ed1b From 74846d35b24b6efd61bb88a0a750b6bb257e6e78 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 5 Mar 2010 13:49:35 +0100 Subject: perf, x86: Clear the LBRs on init Some CPUs have errata where the LBR is not cleared on Power-On. So always clear the LBRs before use. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <20100305154128.966563424@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel.c | 18 ++++++++++++++++-- arch/x86/kernel/cpu/perf_event_intel_lbr.c | 3 +++ 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 224c952071f9..c135ed735b22 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -767,6 +767,20 @@ static __initconst struct x86_pmu core_pmu = { .event_constraints = intel_core_event_constraints, }; +static void intel_pmu_cpu_starting(int cpu) +{ + init_debug_store_on_cpu(cpu); + /* + * Deal with CPUs that don't clear their LBRs on power-up. + */ + intel_pmu_lbr_reset(); +} + +static void intel_pmu_cpu_dying(int cpu) +{ + fini_debug_store_on_cpu(cpu); +} + static __initconst struct x86_pmu intel_pmu = { .name = "Intel", .handle_irq = intel_pmu_handle_irq, @@ -788,8 +802,8 @@ static __initconst struct x86_pmu intel_pmu = { .max_period = (1ULL << 31) - 1, .get_event_constraints = intel_get_event_constraints, - .cpu_starting = init_debug_store_on_cpu, - .cpu_dying = fini_debug_store_on_cpu, + .cpu_starting = intel_pmu_cpu_starting, + .cpu_dying = intel_pmu_cpu_dying, }; static void intel_clovertown_quirks(void) diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index 4f3a124329c4..dcec765f8188 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -53,6 +53,9 @@ static void intel_pmu_lbr_reset_64(void) static void intel_pmu_lbr_reset(void) { + if (!x86_pmu.lbr_nr) + return; + if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32) intel_pmu_lbr_reset_32(); else -- cgit v1.2.3-59-g8ed1b From a562b1871f7f7d2f3a835c3c1e07fa58d473cfb7 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 5 Mar 2010 16:29:14 +0100 Subject: perf, x86: Robustify PEBS fixup It turns out the LBR is massively unreliable on certain CPUs, so code the fixup a little more defensive to avoid crashing the kernel. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <20100305154129.042271287@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index a67fff14475e..e7ac51770d4d 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -399,10 +399,23 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) if (!x86_pmu.intel_cap.pebs_trap) return 1; + /* + * No LBR entry, no basic block, no rewinding + */ if (!cpuc->lbr_stack.nr || !from || !to) return 0; - if (ip < to) + /* + * Basic blocks should never cross user/kernel boundaries + */ + if (kernel_ip(ip) != kernel_ip(to)) + return 0; + + /* + * unsigned math, either ip is before the start (impossible) or + * the basic block is larger than 1 page (sanity) + */ + if ((ip - to) > PAGE_SIZE) return 0; /* @@ -420,7 +433,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) old_to = to; if (!kernel_ip(ip)) { - int bytes, size = min_t(int, MAX_INSN_SIZE, ip - to); + int bytes, size = MAX_INSN_SIZE; bytes = copy_from_user_nmi(buf, (void __user *)to, size); if (bytes != size) @@ -440,6 +453,10 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) return 1; } + /* + * Even though we decoded the basic block, the instruction stream + * never matched the given IP, either the TO or the IP got corrupted. + */ return 0; } -- cgit v1.2.3-59-g8ed1b From cc7f00820b2f3be656569c41158d9323e425bcfe Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 8 Mar 2010 17:51:33 +0100 Subject: perf, x86: Avoid double disable on throttle vs ioctl(PERF_IOC_DISABLE) Calling ioctl(PERF_EVENT_IOC_DISABLE) on a thottled counter would result in a double disable, cure this by using x86_pmu_{start,stop} for throttle/unthrottle and teach x86_pmu_stop() to check ->active_mask. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index e7ac51770d4d..a7401e4167df 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -461,7 +461,6 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) } static int intel_pmu_save_and_restart(struct perf_event *event); -static void intel_pmu_disable_event(struct perf_event *event); static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) { @@ -528,7 +527,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) regs.flags &= ~PERF_EFLAGS_EXACT; if (perf_event_overflow(event, 1, &data, ®s)) - intel_pmu_disable_event(event); + x86_pmu_stop(event); out: intel_pmu_pebs_enable_all(); @@ -603,7 +602,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) regs.flags &= ~PERF_EFLAGS_EXACT; if (perf_event_overflow(event, 1, &data, ®s)) - intel_pmu_disable_event(event); + x86_pmu_stop(event); } out: intel_pmu_pebs_enable_all(); -- cgit v1.2.3-59-g8ed1b From 8f4aebd2be9892bf8fb79a2d8576d3f3ee7f00f6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 6 Mar 2010 13:26:11 +0100 Subject: perf, x86: Fix pebs drains I overlooked the perf_disable()/perf_enable() calls in intel_pmu_handle_irq(), (pointed out by Markus) so we should not explicitly disable_all/enable_all pebs counters in the drain functions, these are already disabled and enabling them early is confusing. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index a7401e4167df..66c6962f15f9 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -476,18 +476,16 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) if (!event || !ds || !x86_pmu.pebs) return; - intel_pmu_pebs_disable_all(); - at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base; top = (struct pebs_record_core *)(unsigned long)ds->pebs_index; if (top <= at) - goto out; + return; ds->pebs_index = ds->pebs_buffer_base; if (!intel_pmu_save_and_restart(event)) - goto out; + return; perf_sample_data_init(&data, 0); data.period = event->hw.last_period; @@ -528,9 +526,6 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) if (perf_event_overflow(event, 1, &data, ®s)) x86_pmu_stop(event); - -out: - intel_pmu_pebs_enable_all(); } static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) @@ -547,13 +542,11 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) if (!ds || !x86_pmu.pebs) return; - intel_pmu_pebs_disable_all(); - at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base; top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index; if (top <= at) - goto out; + return; ds->pebs_index = ds->pebs_buffer_base; @@ -604,8 +597,6 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) if (perf_event_overflow(event, 1, &data, ®s)) x86_pmu_stop(event); } -out: - intel_pmu_pebs_enable_all(); } /* -- cgit v1.2.3-59-g8ed1b From 4807e3d5dc7bb7057dd6ca3abb09f3da2eb8c323 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 6 Mar 2010 13:47:07 +0100 Subject: perf, x86: Fix PEBS enable/disable vs cpuc->enabled We should never call ->enable with the pmu enabled, and we _can_ have ->disable called with the pmu enabled. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 66c6962f15f9..9ad0e67b9c82 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -338,7 +338,7 @@ static void intel_pmu_pebs_enable(struct perf_event *event) hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT; val |= 1ULL << hwc->idx; - wrmsrl(MSR_IA32_PEBS_ENABLE, val); + WARN_ON_ONCE(cpuc->enabled); if (x86_pmu.intel_cap.pebs_trap) intel_pmu_lbr_enable(event); @@ -351,7 +351,8 @@ static void intel_pmu_pebs_disable(struct perf_event *event) u64 val = cpuc->pebs_enabled; val &= ~(1ULL << hwc->idx); - wrmsrl(MSR_IA32_PEBS_ENABLE, val); + if (cpuc->enabled) + wrmsrl(MSR_IA32_PEBS_ENABLE, val); hwc->config |= ARCH_PERFMON_EVENTSEL_INT; -- cgit v1.2.3-59-g8ed1b From 2df202bf7520eaffcbfb07e45dfa3cfb0aeee2c0 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 6 Mar 2010 13:48:54 +0100 Subject: perf, x86: Fix LBR enable/disable vs cpuc->enabled We should never call ->enable with the pmu enabled, and we _can_ have ->disable called with the pmu enabled. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_lbr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index dcec765f8188..0145f99f7a35 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -69,7 +69,7 @@ static void intel_pmu_lbr_enable(struct perf_event *event) if (!x86_pmu.lbr_nr) return; - WARN_ON(cpuc->enabled); + WARN_ON_ONCE(cpuc->enabled); /* * Reset the LBR stack if this is the first LBR user or @@ -93,9 +93,10 @@ static void intel_pmu_lbr_disable(struct perf_event *event) return; cpuc->lbr_users--; - BUG_ON(cpuc->lbr_users < 0); - WARN_ON(cpuc->enabled); + + if (cpuc->enabled && !cpuc->lbr_users) + __intel_pmu_lbr_disable(); } static void intel_pmu_lbr_enable_all(void) -- cgit v1.2.3-59-g8ed1b From d329527e47851f84b1e7944ed9601205f35f1b93 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 8 Mar 2010 13:57:14 +0100 Subject: perf, x86: Reorder intel_pmu_enable_all() The documentation says we have to enable PEBS before we enable the PMU proper. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index c135ed735b22..d3e2424069a7 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -487,6 +487,8 @@ static void intel_pmu_enable_all(void) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + intel_pmu_pebs_enable_all(); + intel_pmu_lbr_enable_all(); wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { @@ -498,9 +500,6 @@ static void intel_pmu_enable_all(void) intel_pmu_enable_bts(event->hw.config); } - - intel_pmu_pebs_enable_all(); - intel_pmu_lbr_enable_all(); } static inline u64 intel_pmu_get_status(void) -- cgit v1.2.3-59-g8ed1b From 12ab854d744f04bfc5c6c4db723b7e31fc03eb29 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 6 Mar 2010 18:57:38 +0100 Subject: perf, x86: Deal with multiple state bits for pebs-fmt1 Its unclear if the PEBS state record will have only a single bit set, in case it does not and accumulates bits, deal with that by only processing each event once. Also, robustify some of the code. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 9ad0e67b9c82..b4680daecf19 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -538,6 +538,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) struct perf_event *event = NULL; struct perf_raw_record raw; struct pt_regs regs; + u64 status = 0; int bit, n; if (!ds || !x86_pmu.pebs) @@ -561,13 +562,22 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) for ( ; at < top; at++) { for_each_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) { - if (!cpuc->events[bit]->attr.precise) + event = cpuc->events[bit]; + if (!test_bit(bit, cpuc->active_mask)) continue; - event = cpuc->events[bit]; + WARN_ON_ONCE(!event); + + if (!event->attr.precise) + continue; + + if (__test_and_set_bit(bit, (unsigned long *)&status)) + continue; + + break; } - if (!event) + if (!event || bit >= MAX_PEBS_EVENTS) continue; if (!intel_pmu_save_and_restart(event)) -- cgit v1.2.3-59-g8ed1b From ad0e6cfe2a2a61d7b5530188e571d508146cb43b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 6 Mar 2010 19:49:06 +0100 Subject: perf, x86: Fix silly bug in intel_pmu_pebs_{enable,disable} We need to use the actual cpuc->pebs_enabled value, not a local copy for the changes to take effect. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index b4680daecf19..242369488e72 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -333,11 +333,10 @@ static void intel_pmu_pebs_enable(struct perf_event *event) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct hw_perf_event *hwc = &event->hw; - u64 val = cpuc->pebs_enabled; hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT; - val |= 1ULL << hwc->idx; + cpuc->pebs_enabled |= 1ULL << hwc->idx; WARN_ON_ONCE(cpuc->enabled); if (x86_pmu.intel_cap.pebs_trap) @@ -348,11 +347,10 @@ static void intel_pmu_pebs_disable(struct perf_event *event) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct hw_perf_event *hwc = &event->hw; - u64 val = cpuc->pebs_enabled; - val &= ~(1ULL << hwc->idx); + cpuc->pebs_enabled &= ~(1ULL << hwc->idx); if (cpuc->enabled) - wrmsrl(MSR_IA32_PEBS_ENABLE, val); + wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled); hwc->config |= ARCH_PERFMON_EVENTSEL_INT; -- cgit v1.2.3-59-g8ed1b From b83a46e7da4a948cc852ba7805dfb1a392dec861 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 8 Mar 2010 13:51:12 +0100 Subject: perf, x86: Don't reset the LBR as frequently If we reset the LBR on each first counter, simple counter rotation which first deschedules all counters and then reschedules the new ones will lead to LBR reset, even though we're still in the same task context. Reduce this by not flushing on the first counter but only flushing on different task contexts. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_lbr.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index 0145f99f7a35..f278136bf918 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -72,12 +72,11 @@ static void intel_pmu_lbr_enable(struct perf_event *event) WARN_ON_ONCE(cpuc->enabled); /* - * Reset the LBR stack if this is the first LBR user or - * we changed task context so as to avoid data leaks. + * Reset the LBR stack if we changed task context to + * avoid data leaks. */ - if (!cpuc->lbr_users || - (event->ctx->task && cpuc->lbr_context != event->ctx)) { + if (event->ctx->task && cpuc->lbr_context != event->ctx) { intel_pmu_lbr_reset(); cpuc->lbr_context = event->ctx; } @@ -93,7 +92,7 @@ static void intel_pmu_lbr_disable(struct perf_event *event) return; cpuc->lbr_users--; - BUG_ON(cpuc->lbr_users < 0); + WARN_ON_ONCE(cpuc->lbr_users < 0); if (cpuc->enabled && !cpuc->lbr_users) __intel_pmu_lbr_disable(); -- cgit v1.2.3-59-g8ed1b From 7645a24cbd01cbf4865d1273d5ddaa8d8c2ccb3a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 8 Mar 2010 13:51:31 +0100 Subject: perf, x86: Remove checking_{wr,rd}msr() usage We don't need checking_{wr,rd}msr() calls, since we should know what cpu we're running on and not use blindly poke at msrs. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 24 ++++++++++++++++++------ arch/x86/kernel/cpu/perf_event_intel.c | 5 ++--- 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 335ee1d38b79..e24f6374f9f5 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -29,6 +29,17 @@ #include #include +#if 0 +#undef wrmsrl +#define wrmsrl(msr, val) \ +do { \ + trace_printk("wrmsrl(%lx, %lx)\n", (unsigned long)(msr),\ + (unsigned long)(val)); \ + native_write_msr((msr), (u32)((u64)(val)), \ + (u32)((u64)(val) >> 32)); \ +} while (0) +#endif + /* * best effort, GUP based copy_from_user() that assumes IRQ or NMI context */ @@ -821,14 +832,15 @@ void hw_perf_enable(void) static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc) { - (void)checking_wrmsrl(hwc->config_base + hwc->idx, + wrmsrl(hwc->config_base + hwc->idx, hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE); } static inline void x86_pmu_disable_event(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; - (void)checking_wrmsrl(hwc->config_base + hwc->idx, hwc->config); + + wrmsrl(hwc->config_base + hwc->idx, hwc->config); } static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); @@ -843,7 +855,7 @@ x86_perf_event_set_period(struct perf_event *event) struct hw_perf_event *hwc = &event->hw; s64 left = atomic64_read(&hwc->period_left); s64 period = hwc->sample_period; - int err, ret = 0, idx = hwc->idx; + int ret = 0, idx = hwc->idx; if (idx == X86_PMC_IDX_FIXED_BTS) return 0; @@ -881,8 +893,8 @@ x86_perf_event_set_period(struct perf_event *event) */ atomic64_set(&hwc->prev_count, (u64)-left); - err = checking_wrmsrl(hwc->event_base + idx, - (u64)(-left) & x86_pmu.event_mask); + wrmsrl(hwc->event_base + idx, + (u64)(-left) & x86_pmu.event_mask); perf_event_update_userpage(event); @@ -987,7 +999,7 @@ void perf_event_print_debug(void) pr_info("CPU#%d: fixed: %016llx\n", cpu, fixed); pr_info("CPU#%d: pebs: %016llx\n", cpu, pebs); } - pr_info("CPU#%d: active: %016llx\n", cpu, *(u64 *)cpuc->active_mask); + pr_info("CPU#%d: active: %016llx\n", cpu, *(u64 *)cpuc->active_mask); for (idx = 0; idx < x86_pmu.num_events; idx++) { rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl); diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index d3e2424069a7..971dc6e7d54b 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -525,7 +525,7 @@ static void intel_pmu_disable_fixed(struct hw_perf_event *hwc) rdmsrl(hwc->config_base, ctrl_val); ctrl_val &= ~mask; - (void)checking_wrmsrl(hwc->config_base, ctrl_val); + wrmsrl(hwc->config_base, ctrl_val); } static void intel_pmu_disable_event(struct perf_event *event) @@ -553,7 +553,6 @@ static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) { int idx = hwc->idx - X86_PMC_IDX_FIXED; u64 ctrl_val, bits, mask; - int err; /* * Enable IRQ generation (0x8), @@ -578,7 +577,7 @@ static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) rdmsrl(hwc->config_base, ctrl_val); ctrl_val &= ~mask; ctrl_val |= bits; - err = checking_wrmsrl(hwc->config_base, ctrl_val); + wrmsrl(hwc->config_base, ctrl_val); } static void intel_pmu_enable_event(struct perf_event *event) -- cgit v1.2.3-59-g8ed1b From d80c7502ff63aa0d99d8c0c5803d28bbef67a74e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 9 Mar 2010 11:41:02 +0100 Subject: perf, x86: Fixup the PEBS handler for Core2 cpus Pull the core handler in line with the nhm one, also make sure we always drain the buffer. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 38 +++++++++++++++++++------------ 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 242369488e72..1bfd59beb658 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -472,20 +472,39 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) struct pt_regs regs; int n; - if (!event || !ds || !x86_pmu.pebs) + if (!ds || !x86_pmu.pebs) return; at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base; top = (struct pebs_record_core *)(unsigned long)ds->pebs_index; - if (top <= at) + /* + * Whatever else happens, drain the thing + */ + ds->pebs_index = ds->pebs_buffer_base; + + if (!test_bit(0, cpuc->active_mask)) return; - ds->pebs_index = ds->pebs_buffer_base; + WARN_ON_ONCE(!event); + + if (!event->attr.precise) + return; + + n = top - at; + if (n <= 0) + return; if (!intel_pmu_save_and_restart(event)) return; + /* + * Should not happen, we program the threshold at 1 and do not + * set a reset value. + */ + WARN_ON_ONCE(n > 1); + at += n - 1; + perf_sample_data_init(&data, 0); data.period = event->hw.last_period; @@ -495,14 +514,6 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) data.raw = &raw; } - n = top - at; - - /* - * Should not happen, we program the threshold at 1 and do not - * set a reset value. - */ - WARN_ON_ONCE(n > 1); - /* * We use the interrupt regs as a base because the PEBS record * does not contain a full regs set, specifically it seems to @@ -545,12 +556,11 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base; top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index; - if (top <= at) - return; - ds->pebs_index = ds->pebs_buffer_base; n = top - at; + if (n <= 0) + return; /* * Should not happen, we program the threshold at 1 and do not -- cgit v1.2.3-59-g8ed1b From 63fb3f9b2312e131be5a0a2dddb63f2fb123db9b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 9 Mar 2010 11:51:02 +0100 Subject: perf, x86: Fix LBR read-out Don't decrement the TOS twice... Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_lbr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index f278136bf918..df4c98e26c5b 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -129,7 +129,7 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) u64 tos = intel_pmu_lbr_tos(); int i; - for (i = 0; i < x86_pmu.lbr_nr; i++, tos--) { + for (i = 0; i < x86_pmu.lbr_nr; i++) { unsigned long lbr_idx = (tos - i) & mask; union { struct { @@ -162,7 +162,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) u64 tos = intel_pmu_lbr_tos(); int i; - for (i = 0; i < x86_pmu.lbr_nr; i++, tos--) { + for (i = 0; i < x86_pmu.lbr_nr; i++) { unsigned long lbr_idx = (tos - i) & mask; u64 from, to, flags = 0; -- cgit v1.2.3-59-g8ed1b From ba7e4d13fc7e25af1d167d40e6f028298dfc55ad Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 6 Jun 2009 13:58:12 +0200 Subject: perf, x86: Add INSTRUCTION_DECODER config flag The PEBS+LBR decoding magic needs the insn_get_length() infrastructure to be able to decode x86 instruction length. So split it out of KPROBES dependency and make it enabled when either KPROBES or PERF_EVENTS is enabled. Cc: Peter Zijlstra Cc: Masami Hiramatsu Cc: Frederic Weisbecker Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 3 +++ arch/x86/lib/Makefile | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e98440371525..e1240f652a9b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -58,6 +58,9 @@ config X86 select HAVE_ARCH_KMEMCHECK select HAVE_USER_RETURN_NOTIFIER +config INSTRUCTION_DECODER + def_bool (KPROBES || PERF_EVENTS) + config OUTPUT_FORMAT string default "elf32-i386" if X86_32 diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 419386c24b82..cbaf8f2b83df 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -20,7 +20,7 @@ lib-y := delay.o lib-y += thunk_$(BITS).o lib-y += usercopy_$(BITS).o getuser.o putuser.o lib-y += memcpy_$(BITS).o -lib-$(CONFIG_KPROBES) += insn.o inat.o +lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o obj-y += msr.o msr-reg.o msr-reg-export.o -- cgit v1.2.3-59-g8ed1b From caa0142d84ceb0fc83e28f0475d0a7316cb6df77 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 6 Jun 2009 13:58:12 +0200 Subject: perf, x86: Fix the !CONFIG_CPU_SUP_INTEL build Fix typo. But the modularization here is ugly and should be improved. Cc: Peter Zijlstra Cc: Frederic Weisbecker Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 1bfd59beb658..c59678a14a2e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -661,7 +661,7 @@ static void intel_ds_init(void) #else /* CONFIG_CPU_SUP_INTEL */ -static int reseve_ds_buffers(void) +static int reserve_ds_buffers(void) { return 0; } -- cgit v1.2.3-59-g8ed1b From 938179b4f8cf8a4f11234ebf2dff2eb48400acfe Mon Sep 17 00:00:00 2001 From: Dimitri Sivanich Date: Fri, 5 Mar 2010 11:42:03 -0600 Subject: x86: Improve Intel microcode loader performance We've noticed that on large SGI UV system configurations, running microcode.ctl can take very long periods of time. This is due to the large number of vmalloc/vfree calls made by the Intel generic_load_microcode() logic. By reusing allocated space, the following patch reduces the time to run microcode.ctl on a 1024 cpu system from approximately 80 seconds down to 1 or 2 seconds. Signed-off-by: Dimitri Sivanich Acked-by: Dmitry Adamushko Cc: Avi Kivity Cc: Bill Davidsen LKML-Reference: <20100305174203.GA19638@sgi.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/microcode_intel.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index 85a343e28937..356170262a93 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c @@ -343,10 +343,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, int (*get_ucode_data)(void *, const void *, size_t)) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - u8 *ucode_ptr = data, *new_mc = NULL, *mc; + u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL; int new_rev = uci->cpu_sig.rev; unsigned int leftover = size; enum ucode_state state = UCODE_OK; + unsigned int curr_mc_size = 0; while (leftover) { struct microcode_header_intel mc_header; @@ -361,9 +362,15 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, break; } - mc = vmalloc(mc_size); - if (!mc) - break; + /* For performance reasons, reuse mc area when possible */ + if (!mc || mc_size > curr_mc_size) { + if (mc) + vfree(mc); + mc = vmalloc(mc_size); + if (!mc) + break; + curr_mc_size = mc_size; + } if (get_ucode_data(mc, ucode_ptr, mc_size) || microcode_sanity_check(mc) < 0) { @@ -376,13 +383,16 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, vfree(new_mc); new_rev = mc_header.rev; new_mc = mc; - } else - vfree(mc); + mc = NULL; /* trigger new vmalloc */ + } ucode_ptr += mc_size; leftover -= mc_size; } + if (mc) + vfree(mc); + if (leftover) { if (new_mc) vfree(new_mc); -- cgit v1.2.3-59-g8ed1b From 6f4edd69e40aba4f45bf9558c1e9a950d79ab4e4 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Wed, 10 Mar 2010 14:44:58 -0600 Subject: x86, UV: Clean up UV headers for MMR definitions Update UV mmr definitions header file. Eliminate definitions no longer needed. Move 2 definitions from tlb_uv.c into the header file where they belong. Signed-off-by: Jack Steiner LKML-Reference: <20100310204458.GA28835@sgi.com> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/uv/uv_mmrs.h | 528 ++++++-------------------------------- arch/x86/kernel/tlb_uv.c | 10 +- 2 files changed, 85 insertions(+), 453 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/uv/uv_mmrs.h b/arch/x86/include/asm/uv/uv_mmrs.h index 2cae46c7c8a2..b2f2d2e05cec 100644 --- a/arch/x86/include/asm/uv/uv_mmrs.h +++ b/arch/x86/include/asm/uv/uv_mmrs.h @@ -1,4 +1,3 @@ - /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -14,14 +13,26 @@ #define UV_MMR_ENABLE (1UL << 63) +/* ========================================================================= */ +/* UVH_BAU_DATA_BROADCAST */ +/* ========================================================================= */ +#define UVH_BAU_DATA_BROADCAST 0x61688UL +#define UVH_BAU_DATA_BROADCAST_32 0x0440 + +#define UVH_BAU_DATA_BROADCAST_ENABLE_SHFT 0 +#define UVH_BAU_DATA_BROADCAST_ENABLE_MASK 0x0000000000000001UL + +union uvh_bau_data_broadcast_u { + unsigned long v; + struct uvh_bau_data_broadcast_s { + unsigned long enable : 1; /* RW */ + unsigned long rsvd_1_63: 63; /* */ + } s; +}; + /* ========================================================================= */ /* UVH_BAU_DATA_CONFIG */ /* ========================================================================= */ -#define UVH_LB_BAU_MISC_CONTROL 0x320170UL -#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15 -#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16 -#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL -/* 1011 timebase 7 (168millisec) * 3 ticks -> 500ms */ #define UVH_BAU_DATA_CONFIG 0x61680UL #define UVH_BAU_DATA_CONFIG_32 0x0438 @@ -603,6 +614,68 @@ union uvh_lb_bau_intd_software_acknowledge_u { #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x0000000000320088UL #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0x0a70 +/* ========================================================================= */ +/* UVH_LB_BAU_MISC_CONTROL */ +/* ========================================================================= */ +#define UVH_LB_BAU_MISC_CONTROL 0x320170UL +#define UVH_LB_BAU_MISC_CONTROL_32 0x00a10 + +#define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 +#define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL +#define UVH_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8 +#define UVH_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL +#define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9 +#define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL +#define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 +#define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL +#define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_SHFT 11 +#define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL +#define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 +#define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL +#define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 +#define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL +#define UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16 +#define UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL +#define UVH_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20 +#define UVH_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL +#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21 +#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL +#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22 +#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL +#define UVH_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23 +#define UVH_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL +#define UVH_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24 +#define UVH_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL +#define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27 +#define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL +#define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 +#define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL +#define UVH_LB_BAU_MISC_CONTROL_FUN_SHFT 48 +#define UVH_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL + +union uvh_lb_bau_misc_control_u { + unsigned long v; + struct uvh_lb_bau_misc_control_s { + unsigned long rejection_delay : 8; /* RW */ + unsigned long apic_mode : 1; /* RW */ + unsigned long force_broadcast : 1; /* RW */ + unsigned long force_lock_nop : 1; /* RW */ + unsigned long csi_agent_presence_vector : 3; /* RW */ + unsigned long descriptor_fetch_mode : 1; /* RW */ + unsigned long enable_intd_soft_ack_mode : 1; /* RW */ + unsigned long intd_soft_ack_timeout_period : 4; /* RW */ + unsigned long enable_dual_mapping_mode : 1; /* RW */ + unsigned long vga_io_port_decode_enable : 1; /* RW */ + unsigned long vga_io_port_16_bit_decode : 1; /* RW */ + unsigned long suppress_dest_registration : 1; /* RW */ + unsigned long programmed_initial_priority : 3; /* RW */ + unsigned long use_incoming_priority : 1; /* RW */ + unsigned long enable_programmed_initial_priority : 1; /* RW */ + unsigned long rsvd_29_47 : 19; /* */ + unsigned long fun : 16; /* RW */ + } s; +}; + /* ========================================================================= */ /* UVH_LB_BAU_SB_ACTIVATION_CONTROL */ /* ========================================================================= */ @@ -680,334 +753,6 @@ union uvh_lb_bau_sb_descriptor_base_u { } s; }; -/* ========================================================================= */ -/* UVH_LB_MCAST_AOERR0_RPT_ENABLE */ -/* ========================================================================= */ -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE 0x50b20UL - -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_OBESE_MSG_SHFT 0 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_OBESE_MSG_MASK 0x0000000000000001UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_DATA_SB_ERR_SHFT 1 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_DATA_SB_ERR_MASK 0x0000000000000002UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_NACK_BUFF_PARITY_SHFT 2 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_NACK_BUFF_PARITY_MASK 0x0000000000000004UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_TIMEOUT_SHFT 3 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_TIMEOUT_MASK 0x0000000000000008UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_INACTIVE_REPLY_SHFT 4 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_INACTIVE_REPLY_MASK 0x0000000000000010UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_UPGRADE_ERROR_SHFT 5 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_UPGRADE_ERROR_MASK 0x0000000000000020UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REG_COUNT_UNDERFLOW_SHFT 6 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REG_COUNT_UNDERFLOW_MASK 0x0000000000000040UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REP_OBESE_MSG_SHFT 7 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REP_OBESE_MSG_MASK 0x0000000000000080UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_RUNT_MSG_SHFT 8 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_RUNT_MSG_MASK 0x0000000000000100UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_OBESE_MSG_SHFT 9 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_OBESE_MSG_MASK 0x0000000000000200UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_DATA_SB_ERR_SHFT 10 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_DATA_SB_ERR_MASK 0x0000000000000400UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_RUNT_MSG_SHFT 11 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_RUNT_MSG_MASK 0x0000000000000800UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_OBESE_MSG_SHFT 12 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_OBESE_MSG_MASK 0x0000000000001000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_DATA_SB_ERR_SHFT 13 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_DATA_SB_ERR_MASK 0x0000000000002000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_COMMAND_ERR_SHFT 14 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_COMMAND_ERR_MASK 0x0000000000004000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_PEND_TIMEOUT_SHFT 15 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_PEND_TIMEOUT_MASK 0x0000000000008000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_RUNT_MSG_SHFT 16 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_RUNT_MSG_MASK 0x0000000000010000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_OBESE_MSG_SHFT 17 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_OBESE_MSG_MASK 0x0000000000020000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_DATA_SB_ERR_SHFT 18 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_DATA_SB_ERR_MASK 0x0000000000040000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_RUNT_MSG_SHFT 19 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_RUNT_MSG_MASK 0x0000000000080000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_OBESE_MSG_SHFT 20 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_OBESE_MSG_MASK 0x0000000000100000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_DATA_SB_ERR_SHFT 21 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_DATA_SB_ERR_MASK 0x0000000000200000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_AMO_TIMEOUT_SHFT 22 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_AMO_TIMEOUT_MASK 0x0000000000400000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_PUT_TIMEOUT_SHFT 23 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_PUT_TIMEOUT_MASK 0x0000000000800000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_SPURIOUS_EVENT_SHFT 24 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_SPURIOUS_EVENT_MASK 0x0000000001000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IOH_DESTINATION_TABLE_PARITY_SHFT 25 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IOH_DESTINATION_TABLE_PARITY_MASK 0x0000000002000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_HAD_ERROR_REPLY_SHFT 26 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_HAD_ERROR_REPLY_MASK 0x0000000004000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_TIMEOUT_SHFT 27 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_TIMEOUT_MASK 0x0000000008000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_LOCK_MANAGER_HAD_ERROR_REPLY_SHFT 28 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_LOCK_MANAGER_HAD_ERROR_REPLY_MASK 0x0000000010000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_HAD_ERROR_REPLY_SHFT 29 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_HAD_ERROR_REPLY_MASK 0x0000000020000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_TIMEOUT_SHFT 30 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_TIMEOUT_MASK 0x0000000040000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SB_ACTIVATION_OVERRUN_SHFT 31 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SB_ACTIVATION_OVERRUN_MASK 0x0000000080000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_HAD_ERROR_REPLY_SHFT 32 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_HAD_ERROR_REPLY_MASK 0x0000000100000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_TIMEOUT_SHFT 33 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_TIMEOUT_MASK 0x0000000200000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_0_PARITY_SHFT 34 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_0_PARITY_MASK 0x0000000400000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_1_PARITY_SHFT 35 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_1_PARITY_MASK 0x0000000800000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SOCKET_DESTINATION_TABLE_PARITY_SHFT 36 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SOCKET_DESTINATION_TABLE_PARITY_MASK 0x0000001000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_BAU_REPLY_PAYLOAD_CORRUPTION_SHFT 37 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_BAU_REPLY_PAYLOAD_CORRUPTION_MASK 0x0000002000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IO_PORT_DESTINATION_TABLE_PARITY_SHFT 38 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IO_PORT_DESTINATION_TABLE_PARITY_MASK 0x0000004000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INTD_SOFT_ACK_TIMEOUT_SHFT 39 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INTD_SOFT_ACK_TIMEOUT_MASK 0x0000008000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_OBESE_MSG_SHFT 40 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_OBESE_MSG_MASK 0x0000010000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_COMMAND_ERR_SHFT 41 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_COMMAND_ERR_MASK 0x0000020000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_TIMEOUT_SHFT 42 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_TIMEOUT_MASK 0x0000040000000000UL - -union uvh_lb_mcast_aoerr0_rpt_enable_u { - unsigned long v; - struct uvh_lb_mcast_aoerr0_rpt_enable_s { - unsigned long mcast_obese_msg : 1; /* RW */ - unsigned long mcast_data_sb_err : 1; /* RW */ - unsigned long mcast_nack_buff_parity : 1; /* RW */ - unsigned long mcast_timeout : 1; /* RW */ - unsigned long mcast_inactive_reply : 1; /* RW */ - unsigned long mcast_upgrade_error : 1; /* RW */ - unsigned long mcast_reg_count_underflow : 1; /* RW */ - unsigned long mcast_rep_obese_msg : 1; /* RW */ - unsigned long ucache_req_runt_msg : 1; /* RW */ - unsigned long ucache_req_obese_msg : 1; /* RW */ - unsigned long ucache_req_data_sb_err : 1; /* RW */ - unsigned long ucache_rep_runt_msg : 1; /* RW */ - unsigned long ucache_rep_obese_msg : 1; /* RW */ - unsigned long ucache_rep_data_sb_err : 1; /* RW */ - unsigned long ucache_rep_command_err : 1; /* RW */ - unsigned long ucache_pend_timeout : 1; /* RW */ - unsigned long macc_req_runt_msg : 1; /* RW */ - unsigned long macc_req_obese_msg : 1; /* RW */ - unsigned long macc_req_data_sb_err : 1; /* RW */ - unsigned long macc_rep_runt_msg : 1; /* RW */ - unsigned long macc_rep_obese_msg : 1; /* RW */ - unsigned long macc_rep_data_sb_err : 1; /* RW */ - unsigned long macc_amo_timeout : 1; /* RW */ - unsigned long macc_put_timeout : 1; /* RW */ - unsigned long macc_spurious_event : 1; /* RW */ - unsigned long ioh_destination_table_parity : 1; /* RW */ - unsigned long get_had_error_reply : 1; /* RW */ - unsigned long get_timeout : 1; /* RW */ - unsigned long lock_manager_had_error_reply : 1; /* RW */ - unsigned long put_had_error_reply : 1; /* RW */ - unsigned long put_timeout : 1; /* RW */ - unsigned long sb_activation_overrun : 1; /* RW */ - unsigned long completed_gb_activation_had_error_reply : 1; /* RW */ - unsigned long completed_gb_activation_timeout : 1; /* RW */ - unsigned long descriptor_buffer_0_parity : 1; /* RW */ - unsigned long descriptor_buffer_1_parity : 1; /* RW */ - unsigned long socket_destination_table_parity : 1; /* RW */ - unsigned long bau_reply_payload_corruption : 1; /* RW */ - unsigned long io_port_destination_table_parity : 1; /* RW */ - unsigned long intd_soft_ack_timeout : 1; /* RW */ - unsigned long int_rep_obese_msg : 1; /* RW */ - unsigned long int_rep_command_err : 1; /* RW */ - unsigned long int_timeout : 1; /* RW */ - unsigned long rsvd_43_63 : 21; /* */ - } s; -}; - -/* ========================================================================= */ -/* UVH_LOCAL_INT0_CONFIG */ -/* ========================================================================= */ -#define UVH_LOCAL_INT0_CONFIG 0x61000UL - -#define UVH_LOCAL_INT0_CONFIG_VECTOR_SHFT 0 -#define UVH_LOCAL_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_LOCAL_INT0_CONFIG_DM_SHFT 8 -#define UVH_LOCAL_INT0_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_LOCAL_INT0_CONFIG_DESTMODE_SHFT 11 -#define UVH_LOCAL_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_LOCAL_INT0_CONFIG_STATUS_SHFT 12 -#define UVH_LOCAL_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_LOCAL_INT0_CONFIG_P_SHFT 13 -#define UVH_LOCAL_INT0_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_LOCAL_INT0_CONFIG_T_SHFT 15 -#define UVH_LOCAL_INT0_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_LOCAL_INT0_CONFIG_M_SHFT 16 -#define UVH_LOCAL_INT0_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_LOCAL_INT0_CONFIG_APIC_ID_SHFT 32 -#define UVH_LOCAL_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_local_int0_config_u { - unsigned long v; - struct uvh_local_int0_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_LOCAL_INT0_ENABLE */ -/* ========================================================================= */ -#define UVH_LOCAL_INT0_ENABLE 0x65000UL - -#define UVH_LOCAL_INT0_ENABLE_LB_HCERR_SHFT 0 -#define UVH_LOCAL_INT0_ENABLE_LB_HCERR_MASK 0x0000000000000001UL -#define UVH_LOCAL_INT0_ENABLE_GR0_HCERR_SHFT 1 -#define UVH_LOCAL_INT0_ENABLE_GR0_HCERR_MASK 0x0000000000000002UL -#define UVH_LOCAL_INT0_ENABLE_GR1_HCERR_SHFT 2 -#define UVH_LOCAL_INT0_ENABLE_GR1_HCERR_MASK 0x0000000000000004UL -#define UVH_LOCAL_INT0_ENABLE_LH_HCERR_SHFT 3 -#define UVH_LOCAL_INT0_ENABLE_LH_HCERR_MASK 0x0000000000000008UL -#define UVH_LOCAL_INT0_ENABLE_RH_HCERR_SHFT 4 -#define UVH_LOCAL_INT0_ENABLE_RH_HCERR_MASK 0x0000000000000010UL -#define UVH_LOCAL_INT0_ENABLE_XN_HCERR_SHFT 5 -#define UVH_LOCAL_INT0_ENABLE_XN_HCERR_MASK 0x0000000000000020UL -#define UVH_LOCAL_INT0_ENABLE_SI_HCERR_SHFT 6 -#define UVH_LOCAL_INT0_ENABLE_SI_HCERR_MASK 0x0000000000000040UL -#define UVH_LOCAL_INT0_ENABLE_LB_AOERR0_SHFT 7 -#define UVH_LOCAL_INT0_ENABLE_LB_AOERR0_MASK 0x0000000000000080UL -#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR0_SHFT 8 -#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR0_MASK 0x0000000000000100UL -#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR0_SHFT 9 -#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR0_MASK 0x0000000000000200UL -#define UVH_LOCAL_INT0_ENABLE_LH_AOERR0_SHFT 10 -#define UVH_LOCAL_INT0_ENABLE_LH_AOERR0_MASK 0x0000000000000400UL -#define UVH_LOCAL_INT0_ENABLE_RH_AOERR0_SHFT 11 -#define UVH_LOCAL_INT0_ENABLE_RH_AOERR0_MASK 0x0000000000000800UL -#define UVH_LOCAL_INT0_ENABLE_XN_AOERR0_SHFT 12 -#define UVH_LOCAL_INT0_ENABLE_XN_AOERR0_MASK 0x0000000000001000UL -#define UVH_LOCAL_INT0_ENABLE_SI_AOERR0_SHFT 13 -#define UVH_LOCAL_INT0_ENABLE_SI_AOERR0_MASK 0x0000000000002000UL -#define UVH_LOCAL_INT0_ENABLE_LB_AOERR1_SHFT 14 -#define UVH_LOCAL_INT0_ENABLE_LB_AOERR1_MASK 0x0000000000004000UL -#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR1_SHFT 15 -#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR1_MASK 0x0000000000008000UL -#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR1_SHFT 16 -#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR1_MASK 0x0000000000010000UL -#define UVH_LOCAL_INT0_ENABLE_LH_AOERR1_SHFT 17 -#define UVH_LOCAL_INT0_ENABLE_LH_AOERR1_MASK 0x0000000000020000UL -#define UVH_LOCAL_INT0_ENABLE_RH_AOERR1_SHFT 18 -#define UVH_LOCAL_INT0_ENABLE_RH_AOERR1_MASK 0x0000000000040000UL -#define UVH_LOCAL_INT0_ENABLE_XN_AOERR1_SHFT 19 -#define UVH_LOCAL_INT0_ENABLE_XN_AOERR1_MASK 0x0000000000080000UL -#define UVH_LOCAL_INT0_ENABLE_SI_AOERR1_SHFT 20 -#define UVH_LOCAL_INT0_ENABLE_SI_AOERR1_MASK 0x0000000000100000UL -#define UVH_LOCAL_INT0_ENABLE_RH_VPI_INT_SHFT 21 -#define UVH_LOCAL_INT0_ENABLE_RH_VPI_INT_MASK 0x0000000000200000UL -#define UVH_LOCAL_INT0_ENABLE_SYSTEM_SHUTDOWN_INT_SHFT 22 -#define UVH_LOCAL_INT0_ENABLE_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_0_SHFT 23 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_0_MASK 0x0000000000800000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_1_SHFT 24 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_1_MASK 0x0000000001000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_2_SHFT 25 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_2_MASK 0x0000000002000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_3_SHFT 26 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_3_MASK 0x0000000004000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_4_SHFT 27 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_4_MASK 0x0000000008000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_5_SHFT 28 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_5_MASK 0x0000000010000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_6_SHFT 29 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_6_MASK 0x0000000020000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_7_SHFT 30 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_7_MASK 0x0000000040000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_8_SHFT 31 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_8_MASK 0x0000000080000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_9_SHFT 32 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_9_MASK 0x0000000100000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_10_SHFT 33 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_10_MASK 0x0000000200000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_11_SHFT 34 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_11_MASK 0x0000000400000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_12_SHFT 35 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_12_MASK 0x0000000800000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_13_SHFT 36 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_13_MASK 0x0000001000000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_14_SHFT 37 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_14_MASK 0x0000002000000000UL -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_15_SHFT 38 -#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_15_MASK 0x0000004000000000UL -#define UVH_LOCAL_INT0_ENABLE_L1_NMI_INT_SHFT 39 -#define UVH_LOCAL_INT0_ENABLE_L1_NMI_INT_MASK 0x0000008000000000UL -#define UVH_LOCAL_INT0_ENABLE_STOP_CLOCK_SHFT 40 -#define UVH_LOCAL_INT0_ENABLE_STOP_CLOCK_MASK 0x0000010000000000UL -#define UVH_LOCAL_INT0_ENABLE_ASIC_TO_L1_SHFT 41 -#define UVH_LOCAL_INT0_ENABLE_ASIC_TO_L1_MASK 0x0000020000000000UL -#define UVH_LOCAL_INT0_ENABLE_L1_TO_ASIC_SHFT 42 -#define UVH_LOCAL_INT0_ENABLE_L1_TO_ASIC_MASK 0x0000040000000000UL -#define UVH_LOCAL_INT0_ENABLE_LTC_INT_SHFT 43 -#define UVH_LOCAL_INT0_ENABLE_LTC_INT_MASK 0x0000080000000000UL -#define UVH_LOCAL_INT0_ENABLE_LA_SEQ_TRIGGER_SHFT 44 -#define UVH_LOCAL_INT0_ENABLE_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL - -union uvh_local_int0_enable_u { - unsigned long v; - struct uvh_local_int0_enable_s { - unsigned long lb_hcerr : 1; /* RW */ - unsigned long gr0_hcerr : 1; /* RW */ - unsigned long gr1_hcerr : 1; /* RW */ - unsigned long lh_hcerr : 1; /* RW */ - unsigned long rh_hcerr : 1; /* RW */ - unsigned long xn_hcerr : 1; /* RW */ - unsigned long si_hcerr : 1; /* RW */ - unsigned long lb_aoerr0 : 1; /* RW */ - unsigned long gr0_aoerr0 : 1; /* RW */ - unsigned long gr1_aoerr0 : 1; /* RW */ - unsigned long lh_aoerr0 : 1; /* RW */ - unsigned long rh_aoerr0 : 1; /* RW */ - unsigned long xn_aoerr0 : 1; /* RW */ - unsigned long si_aoerr0 : 1; /* RW */ - unsigned long lb_aoerr1 : 1; /* RW */ - unsigned long gr0_aoerr1 : 1; /* RW */ - unsigned long gr1_aoerr1 : 1; /* RW */ - unsigned long lh_aoerr1 : 1; /* RW */ - unsigned long rh_aoerr1 : 1; /* RW */ - unsigned long xn_aoerr1 : 1; /* RW */ - unsigned long si_aoerr1 : 1; /* RW */ - unsigned long rh_vpi_int : 1; /* RW */ - unsigned long system_shutdown_int : 1; /* RW */ - unsigned long lb_irq_int_0 : 1; /* RW */ - unsigned long lb_irq_int_1 : 1; /* RW */ - unsigned long lb_irq_int_2 : 1; /* RW */ - unsigned long lb_irq_int_3 : 1; /* RW */ - unsigned long lb_irq_int_4 : 1; /* RW */ - unsigned long lb_irq_int_5 : 1; /* RW */ - unsigned long lb_irq_int_6 : 1; /* RW */ - unsigned long lb_irq_int_7 : 1; /* RW */ - unsigned long lb_irq_int_8 : 1; /* RW */ - unsigned long lb_irq_int_9 : 1; /* RW */ - unsigned long lb_irq_int_10 : 1; /* RW */ - unsigned long lb_irq_int_11 : 1; /* RW */ - unsigned long lb_irq_int_12 : 1; /* RW */ - unsigned long lb_irq_int_13 : 1; /* RW */ - unsigned long lb_irq_int_14 : 1; /* RW */ - unsigned long lb_irq_int_15 : 1; /* RW */ - unsigned long l1_nmi_int : 1; /* RW */ - unsigned long stop_clock : 1; /* RW */ - unsigned long asic_to_l1 : 1; /* RW */ - unsigned long l1_to_asic : 1; /* RW */ - unsigned long ltc_int : 1; /* RW */ - unsigned long la_seq_trigger : 1; /* RW */ - unsigned long rsvd_45_63 : 19; /* */ - } s; -}; - /* ========================================================================= */ /* UVH_NODE_ID */ /* ========================================================================= */ @@ -1111,26 +856,6 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u { } s; }; -/* ========================================================================= */ -/* UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR 0x1600020UL - -#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT 26 -#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL -#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -union uvh_rh_gam_cfg_overlay_config_mmr_u { - unsigned long v; - struct uvh_rh_gam_cfg_overlay_config_mmr_s { - unsigned long rsvd_0_25: 26; /* */ - unsigned long base : 20; /* RW */ - unsigned long rsvd_46_62: 17; /* */ - unsigned long enable : 1; /* RW */ - } s; -}; - /* ========================================================================= */ /* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */ /* ========================================================================= */ @@ -1262,101 +987,6 @@ union uvh_rtc1_int_config_u { } s; }; -/* ========================================================================= */ -/* UVH_RTC2_INT_CONFIG */ -/* ========================================================================= */ -#define UVH_RTC2_INT_CONFIG 0x61600UL - -#define UVH_RTC2_INT_CONFIG_VECTOR_SHFT 0 -#define UVH_RTC2_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_RTC2_INT_CONFIG_DM_SHFT 8 -#define UVH_RTC2_INT_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_RTC2_INT_CONFIG_DESTMODE_SHFT 11 -#define UVH_RTC2_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_RTC2_INT_CONFIG_STATUS_SHFT 12 -#define UVH_RTC2_INT_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_RTC2_INT_CONFIG_P_SHFT 13 -#define UVH_RTC2_INT_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_RTC2_INT_CONFIG_T_SHFT 15 -#define UVH_RTC2_INT_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_RTC2_INT_CONFIG_M_SHFT 16 -#define UVH_RTC2_INT_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_RTC2_INT_CONFIG_APIC_ID_SHFT 32 -#define UVH_RTC2_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_rtc2_int_config_u { - unsigned long v; - struct uvh_rtc2_int_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_RTC3_INT_CONFIG */ -/* ========================================================================= */ -#define UVH_RTC3_INT_CONFIG 0x61640UL - -#define UVH_RTC3_INT_CONFIG_VECTOR_SHFT 0 -#define UVH_RTC3_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_RTC3_INT_CONFIG_DM_SHFT 8 -#define UVH_RTC3_INT_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_RTC3_INT_CONFIG_DESTMODE_SHFT 11 -#define UVH_RTC3_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_RTC3_INT_CONFIG_STATUS_SHFT 12 -#define UVH_RTC3_INT_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_RTC3_INT_CONFIG_P_SHFT 13 -#define UVH_RTC3_INT_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_RTC3_INT_CONFIG_T_SHFT 15 -#define UVH_RTC3_INT_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_RTC3_INT_CONFIG_M_SHFT 16 -#define UVH_RTC3_INT_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_RTC3_INT_CONFIG_APIC_ID_SHFT 32 -#define UVH_RTC3_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_rtc3_int_config_u { - unsigned long v; - struct uvh_rtc3_int_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_RTC_INC_RATIO */ -/* ========================================================================= */ -#define UVH_RTC_INC_RATIO 0x350000UL - -#define UVH_RTC_INC_RATIO_FRACTION_SHFT 0 -#define UVH_RTC_INC_RATIO_FRACTION_MASK 0x00000000000fffffUL -#define UVH_RTC_INC_RATIO_RATIO_SHFT 20 -#define UVH_RTC_INC_RATIO_RATIO_MASK 0x0000000000700000UL - -union uvh_rtc_inc_ratio_u { - unsigned long v; - struct uvh_rtc_inc_ratio_s { - unsigned long fraction : 20; /* RW */ - unsigned long ratio : 3; /* RW */ - unsigned long rsvd_23_63: 41; /* */ - } s; -}; - /* ========================================================================= */ /* UVH_SI_ADDR_MAP_CONFIG */ /* ========================================================================= */ diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 364d015efebc..ef68ba48564b 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c @@ -20,6 +20,8 @@ #include #include +#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL + static struct bau_control **uv_bau_table_bases __read_mostly; static int uv_bau_retry_limit __read_mostly; @@ -478,16 +480,16 @@ static void uv_enable_timeouts(void) * To program the period, the SOFT_ACK_MODE must be off. */ mmr_image &= ~((unsigned long)1 << - UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT); + UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT); uv_write_global_mmr64 (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); /* * Set the 4-bit period. */ mmr_image &= ~((unsigned long)0xf << - UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT); + UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT); mmr_image |= (UV_INTD_SOFT_ACK_TIMEOUT_PERIOD << - UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT); + UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT); uv_write_global_mmr64 (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); /* @@ -496,7 +498,7 @@ static void uv_enable_timeouts(void) * indicated in bits 2:0 (7 causes all of them to timeout). */ mmr_image |= ((unsigned long)1 << - UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT); + UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT); uv_write_global_mmr64 (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); } -- cgit v1.2.3-59-g8ed1b From a072738e04f0eb26370e39ec679e9a0d65e49aea Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Thu, 11 Mar 2010 19:54:39 +0300 Subject: perf, x86: Implement initial P4 PMU driver The netburst PMU is way different from the "architectural perfomance monitoring" specification that current CPUs use. P4 uses a tuple of ESCR+CCCR+COUNTER MSR registers to handle perfomance monitoring events. A few implementational details: 1) We need a separate x86_pmu::hw_config helper in struct x86_pmu since register bit-fields are quite different from P6, Core and later cpu series. 2) For the same reason is a x86_pmu::schedule_events helper introduced. 3) hw_perf_event::config consists of packed ESCR+CCCR values. It's allowed since in reality both registers only use a half of their size. Of course before making a real write into a particular MSR we need to unpack the value and extend it to a proper size. 4) The tuple of packed ESCR+CCCR in hw_perf_event::config doesn't describe the memory address of ESCR MSR register so that we need to keep a mapping between these tuples used and available ESCR (various P4 events may use same ESCRs but not simultaneously), for this sake every active event has a per-cpu map of hw_perf_event::idx <--> ESCR addresses. 5) Since hw_perf_event::idx is an offset to counter/control register we need to lift X86_PMC_MAX_GENERIC up, otherwise kernel strips it down to 8 registers and event armed may never be turned off (ie the bit in active_mask is set but the loop never reaches this index to check), thanks to Peter Zijlstra Restrictions: - No cascaded counters support (do we ever need them?) - No dependent events support (so PERF_COUNT_HW_INSTRUCTIONS doesn't work for now) - There are events with same counters which can't work simultaneously (need to use intersected ones due to broken counter 1) - No PERF_COUNT_HW_CACHE_ events yet Todo: - Implement dependent events - Need proper hashing for event opcodes (no linear search, good for debugging stage but not in real loads) - Some events counted during a clock cycle -- need to set threshold for them and count every clock cycle just to get summary statistics (ie to behave the same way as other PMUs do) - Need to swicth to use event_constraints - To support RAW events we need to encode a global list of P4 events into p4_templates - Cache events need to be added Event support status matrix: Event status ----------------------------- cycles works cache-references works cache-misses works branch-misses works bus-cycles partially (does not work on 64bit cpu with HT enabled) instruction doesnt work (needs dependent event [mop tagging]) branches doesnt work Signed-off-by: Cyrill Gorcunov Signed-off-by: Lin Ming Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Stephane Eranian Cc: Robert Richter Cc: Frederic Weisbecker LKML-Reference: <20100311165439.GB5129@lenovo> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event.h | 2 +- arch/x86/include/asm/perf_event_p4.h | 707 +++++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/perf_event.c | 46 ++- arch/x86/kernel/cpu/perf_event_amd.c | 2 + arch/x86/kernel/cpu/perf_event_intel.c | 15 +- arch/x86/kernel/cpu/perf_event_p4.c | 607 ++++++++++++++++++++++++++++ arch/x86/kernel/cpu/perf_event_p6.c | 2 + 7 files changed, 1358 insertions(+), 23 deletions(-) create mode 100644 arch/x86/include/asm/perf_event_p4.h create mode 100644 arch/x86/kernel/cpu/perf_event_p4.c (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index a9038c951619..124dddd598f3 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -5,7 +5,7 @@ * Performance event hw details: */ -#define X86_PMC_MAX_GENERIC 8 +#define X86_PMC_MAX_GENERIC 32 #define X86_PMC_MAX_FIXED 3 #define X86_PMC_IDX_GENERIC 0 diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h new file mode 100644 index 000000000000..829f4711645f --- /dev/null +++ b/arch/x86/include/asm/perf_event_p4.h @@ -0,0 +1,707 @@ +/* + * Netburst Perfomance Events (P4, old Xeon) + */ + +#ifndef PERF_EVENT_P4_H +#define PERF_EVENT_P4_H + +#include +#include + +/* + * NetBurst has perfomance MSRs shared between + * threads if HT is turned on, ie for both logical + * processors (mem: in turn in Atom with HT support + * perf-MSRs are not shared and every thread has its + * own perf-MSRs set) + */ +#define ARCH_P4_TOTAL_ESCR (46) +#define ARCH_P4_RESERVED_ESCR (2) /* IQ_ESCR(0,1) not always present */ +#define ARCH_P4_MAX_ESCR (ARCH_P4_TOTAL_ESCR - ARCH_P4_RESERVED_ESCR) +#define ARCH_P4_MAX_CCCR (18) +#define ARCH_P4_MAX_COUNTER (ARCH_P4_MAX_CCCR / 2) + +#define P4_EVNTSEL_EVENT_MASK 0x7e000000U +#define P4_EVNTSEL_EVENT_SHIFT 25 +#define P4_EVNTSEL_EVENTMASK_MASK 0x01fffe00U +#define P4_EVNTSEL_EVENTMASK_SHIFT 9 +#define P4_EVNTSEL_TAG_MASK 0x000001e0U +#define P4_EVNTSEL_TAG_SHIFT 5 +#define P4_EVNTSEL_TAG_ENABLE 0x00000010U +#define P4_EVNTSEL_T0_OS 0x00000008U +#define P4_EVNTSEL_T0_USR 0x00000004U +#define P4_EVNTSEL_T1_OS 0x00000002U +#define P4_EVNTSEL_T1_USR 0x00000001U + +/* Non HT mask */ +#define P4_EVNTSEL_MASK \ + (P4_EVNTSEL_EVENT_MASK | \ + P4_EVNTSEL_EVENTMASK_MASK | \ + P4_EVNTSEL_TAG_MASK | \ + P4_EVNTSEL_TAG_ENABLE | \ + P4_EVNTSEL_T0_OS | \ + P4_EVNTSEL_T0_USR) + +/* HT mask */ +#define P4_EVNTSEL_MASK_HT \ + (P4_EVNTSEL_MASK | \ + P4_EVNTSEL_T1_OS | \ + P4_EVNTSEL_T1_USR) + +#define P4_CCCR_OVF 0x80000000U +#define P4_CCCR_CASCADE 0x40000000U +#define P4_CCCR_OVF_PMI_T0 0x04000000U +#define P4_CCCR_OVF_PMI_T1 0x08000000U +#define P4_CCCR_FORCE_OVF 0x02000000U +#define P4_CCCR_EDGE 0x01000000U +#define P4_CCCR_THRESHOLD_MASK 0x00f00000U +#define P4_CCCR_THRESHOLD_SHIFT 20 +#define P4_CCCR_THRESHOLD(v) ((v) << P4_CCCR_THRESHOLD_SHIFT) +#define P4_CCCR_COMPLEMENT 0x00080000U +#define P4_CCCR_COMPARE 0x00040000U +#define P4_CCCR_ESCR_SELECT_MASK 0x0000e000U +#define P4_CCCR_ESCR_SELECT_SHIFT 13 +#define P4_CCCR_ENABLE 0x00001000U +#define P4_CCCR_THREAD_SINGLE 0x00010000U +#define P4_CCCR_THREAD_BOTH 0x00020000U +#define P4_CCCR_THREAD_ANY 0x00030000U + +/* Non HT mask */ +#define P4_CCCR_MASK \ + (P4_CCCR_OVF | \ + P4_CCCR_CASCADE | \ + P4_CCCR_OVF_PMI_T0 | \ + P4_CCCR_FORCE_OVF | \ + P4_CCCR_EDGE | \ + P4_CCCR_THRESHOLD_MASK | \ + P4_CCCR_COMPLEMENT | \ + P4_CCCR_COMPARE | \ + P4_CCCR_ESCR_SELECT_MASK | \ + P4_CCCR_ENABLE) + +/* HT mask */ +#define P4_CCCR_MASK_HT \ + (P4_CCCR_MASK | \ + P4_CCCR_THREAD_ANY) + +/* + * format is 32 bit: ee ss aa aa + * where + * ee - 8 bit event + * ss - 8 bit selector + * aa aa - 16 bits reserved for tags/attributes + */ +#define P4_EVENT_PACK(event, selector) (((event) << 24) | ((selector) << 16)) +#define P4_EVENT_UNPACK_EVENT(packed) (((packed) >> 24) & 0xff) +#define P4_EVENT_UNPACK_SELECTOR(packed) (((packed) >> 16) & 0xff) +#define P4_EVENT_PACK_ATTR(attr) ((attr)) +#define P4_EVENT_UNPACK_ATTR(packed) ((packed) & 0xffff) +#define P4_MAKE_EVENT_ATTR(class, name, bit) class##_##name = (1 << bit) +#define P4_EVENT_ATTR(class, name) class##_##name +#define P4_EVENT_ATTR_STR(class, name) __stringify(class##_##name) + +/* + * config field is 64bit width and consists of + * HT << 63 | ESCR << 32 | CCCR + * where HT is HyperThreading bit (since ESCR + * has it reserved we may use it for own purpose) + * + * note that this is NOT the addresses of respective + * ESCR and CCCR but rather an only packed value should + * be unpacked and written to a proper addresses + * + * the base idea is to pack as much info as + * possible + */ +#define p4_config_pack_escr(v) (((u64)(v)) << 32) +#define p4_config_pack_cccr(v) (((u64)(v)) & 0xffffffffULL) +#define p4_config_unpack_escr(v) (((u64)(v)) >> 32) +#define p4_config_unpack_cccr(v) (((u64)(v)) & 0xffffffffULL) + +#define p4_config_unpack_emask(v) \ + ({ \ + u32 t = p4_config_unpack_escr((v)); \ + t &= P4_EVNTSEL_EVENTMASK_MASK; \ + t >>= P4_EVNTSEL_EVENTMASK_SHIFT; \ + t; \ + }) + +#define P4_CONFIG_HT_SHIFT 63 +#define P4_CONFIG_HT (1ULL << P4_CONFIG_HT_SHIFT) + +static inline u32 p4_config_unpack_opcode(u64 config) +{ + u32 e, s; + + /* + * we don't care about HT presence here since + * event opcode doesn't depend on it + */ + e = (p4_config_unpack_escr(config) & P4_EVNTSEL_EVENT_MASK) >> P4_EVNTSEL_EVENT_SHIFT; + s = (p4_config_unpack_cccr(config) & P4_CCCR_ESCR_SELECT_MASK) >> P4_CCCR_ESCR_SELECT_SHIFT; + + return P4_EVENT_PACK(e, s); +} + +static inline bool p4_is_event_cascaded(u64 config) +{ + u32 cccr = p4_config_unpack_cccr(config); + return !!(cccr & P4_CCCR_CASCADE); +} + +static inline int p4_ht_config_thread(u64 config) +{ + return !!(config & P4_CONFIG_HT); +} + +static inline u64 p4_set_ht_bit(u64 config) +{ + return config | P4_CONFIG_HT; +} + +static inline u64 p4_clear_ht_bit(u64 config) +{ + return config & ~P4_CONFIG_HT; +} + +static inline int p4_ht_active(void) +{ +#ifdef CONFIG_SMP + return smp_num_siblings > 1; +#endif + return 0; +} + +static inline int p4_ht_thread(int cpu) +{ +#ifdef CONFIG_SMP + if (smp_num_siblings == 2) + return cpu != cpumask_first(__get_cpu_var(cpu_sibling_map)); +#endif + return 0; +} + +static inline int p4_should_swap_ts(u64 config, int cpu) +{ + return p4_ht_config_thread(config) ^ p4_ht_thread(cpu); +} + +static inline u32 p4_default_cccr_conf(int cpu) +{ + /* + * Note that P4_CCCR_THREAD_ANY is "required" on + * non-HT machines (on HT machines we count TS events + * regardless the state of second logical processor + */ + u32 cccr = P4_CCCR_THREAD_ANY; + + if (!p4_ht_thread(cpu)) + cccr |= P4_CCCR_OVF_PMI_T0; + else + cccr |= P4_CCCR_OVF_PMI_T1; + + return cccr; +} + +static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr) +{ + u32 escr = 0; + + if (!p4_ht_thread(cpu)) { + if (!exclude_os) + escr |= P4_EVNTSEL_T0_OS; + if (!exclude_usr) + escr |= P4_EVNTSEL_T0_USR; + } else { + if (!exclude_os) + escr |= P4_EVNTSEL_T1_OS; + if (!exclude_usr) + escr |= P4_EVNTSEL_T1_USR; + } + + return escr; +} + +/* + * Comments below the event represent ESCR restriction + * for this event and counter index per ESCR + * + * MSR_P4_IQ_ESCR0 and MSR_P4_IQ_ESCR1 are available only on early + * processor builds (family 0FH, models 01H-02H). These MSRs + * are not available on later versions, so that we don't use + * them completely + * + * Also note that CCCR1 do not have P4_CCCR_ENABLE bit properly + * working so that we should not use this CCCR and respective + * counter as result + */ +#define P4_TC_DELIVER_MODE P4_EVENT_PACK(0x01, 0x01) + /* + * MSR_P4_TC_ESCR0: 4, 5 + * MSR_P4_TC_ESCR1: 6, 7 + */ + +#define P4_BPU_FETCH_REQUEST P4_EVENT_PACK(0x03, 0x00) + /* + * MSR_P4_BPU_ESCR0: 0, 1 + * MSR_P4_BPU_ESCR1: 2, 3 + */ + +#define P4_ITLB_REFERENCE P4_EVENT_PACK(0x18, 0x03) + /* + * MSR_P4_ITLB_ESCR0: 0, 1 + * MSR_P4_ITLB_ESCR1: 2, 3 + */ + +#define P4_MEMORY_CANCEL P4_EVENT_PACK(0x02, 0x05) + /* + * MSR_P4_DAC_ESCR0: 8, 9 + * MSR_P4_DAC_ESCR1: 10, 11 + */ + +#define P4_MEMORY_COMPLETE P4_EVENT_PACK(0x08, 0x02) + /* + * MSR_P4_SAAT_ESCR0: 8, 9 + * MSR_P4_SAAT_ESCR1: 10, 11 + */ + +#define P4_LOAD_PORT_REPLAY P4_EVENT_PACK(0x04, 0x02) + /* + * MSR_P4_SAAT_ESCR0: 8, 9 + * MSR_P4_SAAT_ESCR1: 10, 11 + */ + +#define P4_STORE_PORT_REPLAY P4_EVENT_PACK(0x05, 0x02) + /* + * MSR_P4_SAAT_ESCR0: 8, 9 + * MSR_P4_SAAT_ESCR1: 10, 11 + */ + +#define P4_MOB_LOAD_REPLAY P4_EVENT_PACK(0x03, 0x02) + /* + * MSR_P4_MOB_ESCR0: 0, 1 + * MSR_P4_MOB_ESCR1: 2, 3 + */ + +#define P4_PAGE_WALK_TYPE P4_EVENT_PACK(0x01, 0x04) + /* + * MSR_P4_PMH_ESCR0: 0, 1 + * MSR_P4_PMH_ESCR1: 2, 3 + */ + +#define P4_BSQ_CACHE_REFERENCE P4_EVENT_PACK(0x0c, 0x07) + /* + * MSR_P4_BSU_ESCR0: 0, 1 + * MSR_P4_BSU_ESCR1: 2, 3 + */ + +#define P4_IOQ_ALLOCATION P4_EVENT_PACK(0x03, 0x06) + /* + * MSR_P4_FSB_ESCR0: 0, 1 + * MSR_P4_FSB_ESCR1: 2, 3 + */ + +#define P4_IOQ_ACTIVE_ENTRIES P4_EVENT_PACK(0x1a, 0x06) + /* + * MSR_P4_FSB_ESCR1: 2, 3 + */ + +#define P4_FSB_DATA_ACTIVITY P4_EVENT_PACK(0x17, 0x06) + /* + * MSR_P4_FSB_ESCR0: 0, 1 + * MSR_P4_FSB_ESCR1: 2, 3 + */ + +#define P4_BSQ_ALLOCATION P4_EVENT_PACK(0x05, 0x07) + /* + * MSR_P4_BSU_ESCR0: 0, 1 + */ + +#define P4_BSQ_ACTIVE_ENTRIES P4_EVENT_PACK(0x06, 0x07) + /* + * MSR_P4_BSU_ESCR1: 2, 3 + */ + +#define P4_SSE_INPUT_ASSIST P4_EVENT_PACK(0x34, 0x01) + /* + * MSR_P4_FIRM_ESCR: 8, 9 + * MSR_P4_FIRM_ESCR: 10, 11 + */ + +#define P4_PACKED_SP_UOP P4_EVENT_PACK(0x08, 0x01) + /* + * MSR_P4_FIRM_ESCR0: 8, 9 + * MSR_P4_FIRM_ESCR1: 10, 11 + */ + +#define P4_PACKED_DP_UOP P4_EVENT_PACK(0x0c, 0x01) + /* + * MSR_P4_FIRM_ESCR0: 8, 9 + * MSR_P4_FIRM_ESCR1: 10, 11 + */ + +#define P4_SCALAR_SP_UOP P4_EVENT_PACK(0x0a, 0x01) + /* + * MSR_P4_FIRM_ESCR0: 8, 9 + * MSR_P4_FIRM_ESCR1: 10, 11 + */ + +#define P4_SCALAR_DP_UOP P4_EVENT_PACK(0x0e, 0x01) + /* + * MSR_P4_FIRM_ESCR0: 8, 9 + * MSR_P4_FIRM_ESCR1: 10, 11 + */ + +#define P4_64BIT_MMX_UOP P4_EVENT_PACK(0x02, 0x01) + /* + * MSR_P4_FIRM_ESCR0: 8, 9 + * MSR_P4_FIRM_ESCR1: 10, 11 + */ + +#define P4_128BIT_MMX_UOP P4_EVENT_PACK(0x1a, 0x01) + /* + * MSR_P4_FIRM_ESCR0: 8, 9 + * MSR_P4_FIRM_ESCR1: 10, 11 + */ + +#define P4_X87_FP_UOP P4_EVENT_PACK(0x04, 0x01) + /* + * MSR_P4_FIRM_ESCR0: 8, 9 + * MSR_P4_FIRM_ESCR1: 10, 11 + */ + +#define P4_TC_MISC P4_EVENT_PACK(0x06, 0x01) + /* + * MSR_P4_TC_ESCR0: 4, 5 + * MSR_P4_TC_ESCR1: 6, 7 + */ + +#define P4_GLOBAL_POWER_EVENTS P4_EVENT_PACK(0x13, 0x06) + /* + * MSR_P4_FSB_ESCR0: 0, 1 + * MSR_P4_FSB_ESCR1: 2, 3 + */ + +#define P4_TC_MS_XFER P4_EVENT_PACK(0x05, 0x00) + /* + * MSR_P4_MS_ESCR0: 4, 5 + * MSR_P4_MS_ESCR1: 6, 7 + */ + +#define P4_UOP_QUEUE_WRITES P4_EVENT_PACK(0x09, 0x00) + /* + * MSR_P4_MS_ESCR0: 4, 5 + * MSR_P4_MS_ESCR1: 6, 7 + */ + +#define P4_RETIRED_MISPRED_BRANCH_TYPE P4_EVENT_PACK(0x05, 0x02) + /* + * MSR_P4_TBPU_ESCR0: 4, 5 + * MSR_P4_TBPU_ESCR0: 6, 7 + */ + +#define P4_RETIRED_BRANCH_TYPE P4_EVENT_PACK(0x04, 0x02) + /* + * MSR_P4_TBPU_ESCR0: 4, 5 + * MSR_P4_TBPU_ESCR0: 6, 7 + */ + +#define P4_RESOURCE_STALL P4_EVENT_PACK(0x01, 0x01) + /* + * MSR_P4_ALF_ESCR0: 12, 13, 16 + * MSR_P4_ALF_ESCR1: 14, 15, 17 + */ + +#define P4_WC_BUFFER P4_EVENT_PACK(0x05, 0x05) + /* + * MSR_P4_DAC_ESCR0: 8, 9 + * MSR_P4_DAC_ESCR1: 10, 11 + */ + +#define P4_B2B_CYCLES P4_EVENT_PACK(0x16, 0x03) + /* + * MSR_P4_FSB_ESCR0: 0, 1 + * MSR_P4_FSB_ESCR1: 2, 3 + */ + +#define P4_BNR P4_EVENT_PACK(0x08, 0x03) + /* + * MSR_P4_FSB_ESCR0: 0, 1 + * MSR_P4_FSB_ESCR1: 2, 3 + */ + +#define P4_SNOOP P4_EVENT_PACK(0x06, 0x03) + /* + * MSR_P4_FSB_ESCR0: 0, 1 + * MSR_P4_FSB_ESCR1: 2, 3 + */ + +#define P4_RESPONSE P4_EVENT_PACK(0x04, 0x03) + /* + * MSR_P4_FSB_ESCR0: 0, 1 + * MSR_P4_FSB_ESCR1: 2, 3 + */ + +#define P4_FRONT_END_EVENT P4_EVENT_PACK(0x08, 0x05) + /* + * MSR_P4_CRU_ESCR2: 12, 13, 16 + * MSR_P4_CRU_ESCR3: 14, 15, 17 + */ + +#define P4_EXECUTION_EVENT P4_EVENT_PACK(0x0c, 0x05) + /* + * MSR_P4_CRU_ESCR2: 12, 13, 16 + * MSR_P4_CRU_ESCR3: 14, 15, 17 + */ + +#define P4_REPLAY_EVENT P4_EVENT_PACK(0x09, 0x05) + /* + * MSR_P4_CRU_ESCR2: 12, 13, 16 + * MSR_P4_CRU_ESCR3: 14, 15, 17 + */ + +#define P4_INSTR_RETIRED P4_EVENT_PACK(0x02, 0x04) + /* + * MSR_P4_CRU_ESCR2: 12, 13, 16 + * MSR_P4_CRU_ESCR3: 14, 15, 17 + */ + +#define P4_UOPS_RETIRED P4_EVENT_PACK(0x01, 0x04) + /* + * MSR_P4_CRU_ESCR2: 12, 13, 16 + * MSR_P4_CRU_ESCR3: 14, 15, 17 + */ + +#define P4_UOP_TYPE P4_EVENT_PACK(0x02, 0x02) + /* + * MSR_P4_RAT_ESCR0: 12, 13, 16 + * MSR_P4_RAT_ESCR1: 14, 15, 17 + */ + +#define P4_BRANCH_RETIRED P4_EVENT_PACK(0x06, 0x05) + /* + * MSR_P4_CRU_ESCR2: 12, 13, 16 + * MSR_P4_CRU_ESCR3: 14, 15, 17 + */ + +#define P4_MISPRED_BRANCH_RETIRED P4_EVENT_PACK(0x03, 0x04) + /* + * MSR_P4_CRU_ESCR0: 12, 13, 16 + * MSR_P4_CRU_ESCR1: 14, 15, 17 + */ + +#define P4_X87_ASSIST P4_EVENT_PACK(0x03, 0x05) + /* + * MSR_P4_CRU_ESCR2: 12, 13, 16 + * MSR_P4_CRU_ESCR3: 14, 15, 17 + */ + +#define P4_MACHINE_CLEAR P4_EVENT_PACK(0x02, 0x05) + /* + * MSR_P4_CRU_ESCR2: 12, 13, 16 + * MSR_P4_CRU_ESCR3: 14, 15, 17 + */ + +#define P4_INSTR_COMPLETED P4_EVENT_PACK(0x07, 0x04) + /* + * MSR_P4_CRU_ESCR0: 12, 13, 16 + * MSR_P4_CRU_ESCR1: 14, 15, 17 + */ + +/* + * a caller should use P4_EVENT_ATTR helper to + * pick the attribute needed, for example + * + * P4_EVENT_ATTR(P4_TC_DELIVER_MODE, DD) + */ +enum P4_EVENTS_ATTR { + P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, DD, 0), + P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, DB, 1), + P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, DI, 2), + P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, BD, 3), + P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, BB, 4), + P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, BI, 5), + P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, ID, 6), + + P4_MAKE_EVENT_ATTR(P4_BPU_FETCH_REQUEST, TCMISS, 0), + + P4_MAKE_EVENT_ATTR(P4_ITLB_REFERENCE, HIT, 0), + P4_MAKE_EVENT_ATTR(P4_ITLB_REFERENCE, MISS, 1), + P4_MAKE_EVENT_ATTR(P4_ITLB_REFERENCE, HIT_UK, 2), + + P4_MAKE_EVENT_ATTR(P4_MEMORY_CANCEL, ST_RB_FULL, 2), + P4_MAKE_EVENT_ATTR(P4_MEMORY_CANCEL, 64K_CONF, 3), + + P4_MAKE_EVENT_ATTR(P4_MEMORY_COMPLETE, LSC, 0), + P4_MAKE_EVENT_ATTR(P4_MEMORY_COMPLETE, SSC, 1), + + P4_MAKE_EVENT_ATTR(P4_LOAD_PORT_REPLAY, SPLIT_LD, 1), + + P4_MAKE_EVENT_ATTR(P4_STORE_PORT_REPLAY, SPLIT_ST, 1), + + P4_MAKE_EVENT_ATTR(P4_MOB_LOAD_REPLAY, NO_STA, 1), + P4_MAKE_EVENT_ATTR(P4_MOB_LOAD_REPLAY, NO_STD, 3), + P4_MAKE_EVENT_ATTR(P4_MOB_LOAD_REPLAY, PARTIAL_DATA, 4), + P4_MAKE_EVENT_ATTR(P4_MOB_LOAD_REPLAY, UNALGN_ADDR, 5), + + P4_MAKE_EVENT_ATTR(P4_PAGE_WALK_TYPE, DTMISS, 0), + P4_MAKE_EVENT_ATTR(P4_PAGE_WALK_TYPE, ITMISS, 1), + + P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITS, 0), + P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITE, 1), + P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITM, 2), + P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITS, 3), + P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITE, 4), + P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITM, 5), + P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_MISS, 8), + P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_MISS, 9), + P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, WR_2ndL_MISS, 10), + + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, DEFAULT, 0), + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, ALL_READ, 5), + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, ALL_WRITE, 6), + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, MEM_UC, 7), + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, MEM_WC, 8), + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, MEM_WT, 9), + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, MEM_WP, 10), + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, MEM_WB, 11), + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, OWN, 13), + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, OTHER, 14), + P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, PREFETCH, 15), + + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, DEFAULT, 0), + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, ALL_READ, 5), + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, ALL_WRITE, 6), + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, MEM_UC, 7), + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, MEM_WC, 8), + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, MEM_WT, 9), + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, MEM_WP, 10), + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, MEM_WB, 11), + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, OWN, 13), + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, OTHER, 14), + P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, PREFETCH, 15), + + P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_DRV, 0), + P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_OWN, 1), + P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_OTHER, 2), + P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DBSY_DRV, 3), + P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DBSY_OWN, 4), + P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DBSY_OTHER, 5), + + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_TYPE0, 0), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_TYPE1, 1), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_LEN0, 2), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_LEN1, 3), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_IO_TYPE, 5), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_LOCK_TYPE, 6), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_CACHE_TYPE, 7), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_SPLIT_TYPE, 8), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_DEM_TYPE, 9), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_ORD_TYPE, 10), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, MEM_TYPE0, 11), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, MEM_TYPE1, 12), + P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, MEM_TYPE2, 13), + + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_TYPE0, 0), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_TYPE1, 1), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_LEN0, 2), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_LEN1, 3), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE, 5), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE, 6), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE, 7), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE, 8), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE, 9), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE, 10), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, MEM_TYPE0, 11), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, MEM_TYPE1, 12), + P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, MEM_TYPE2, 13), + + P4_MAKE_EVENT_ATTR(P4_SSE_INPUT_ASSIST, ALL, 15), + + P4_MAKE_EVENT_ATTR(P4_PACKED_SP_UOP, ALL, 15), + + P4_MAKE_EVENT_ATTR(P4_PACKED_DP_UOP, ALL, 15), + + P4_MAKE_EVENT_ATTR(P4_SCALAR_SP_UOP, ALL, 15), + + P4_MAKE_EVENT_ATTR(P4_SCALAR_DP_UOP, ALL, 15), + + P4_MAKE_EVENT_ATTR(P4_64BIT_MMX_UOP, ALL, 15), + + P4_MAKE_EVENT_ATTR(P4_128BIT_MMX_UOP, ALL, 15), + + P4_MAKE_EVENT_ATTR(P4_X87_FP_UOP, ALL, 15), + + P4_MAKE_EVENT_ATTR(P4_TC_MISC, FLUSH, 4), + + P4_MAKE_EVENT_ATTR(P4_GLOBAL_POWER_EVENTS, RUNNING, 0), + + P4_MAKE_EVENT_ATTR(P4_TC_MS_XFER, CISC, 0), + + P4_MAKE_EVENT_ATTR(P4_UOP_QUEUE_WRITES, FROM_TC_BUILD, 0), + P4_MAKE_EVENT_ATTR(P4_UOP_QUEUE_WRITES, FROM_TC_DELIVER, 1), + P4_MAKE_EVENT_ATTR(P4_UOP_QUEUE_WRITES, FROM_ROM, 2), + + P4_MAKE_EVENT_ATTR(P4_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL, 1), + P4_MAKE_EVENT_ATTR(P4_RETIRED_MISPRED_BRANCH_TYPE, CALL, 2), + P4_MAKE_EVENT_ATTR(P4_RETIRED_MISPRED_BRANCH_TYPE, RETURN, 3), + P4_MAKE_EVENT_ATTR(P4_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT, 4), + + P4_MAKE_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CONDITIONAL, 1), + P4_MAKE_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CALL, 2), + P4_MAKE_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, RETURN, 3), + P4_MAKE_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, INDIRECT, 4), + + P4_MAKE_EVENT_ATTR(P4_RESOURCE_STALL, SBFULL, 5), + + P4_MAKE_EVENT_ATTR(P4_WC_BUFFER, WCB_EVICTS, 0), + P4_MAKE_EVENT_ATTR(P4_WC_BUFFER, WCB_FULL_EVICTS, 1), + + P4_MAKE_EVENT_ATTR(P4_FRONT_END_EVENT, NBOGUS, 0), + P4_MAKE_EVENT_ATTR(P4_FRONT_END_EVENT, BOGUS, 1), + + P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, NBOGUS0, 0), + P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, NBOGUS1, 1), + P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, NBOGUS2, 2), + P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, NBOGUS3, 3), + P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, BOGUS0, 4), + P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, BOGUS1, 5), + P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, BOGUS2, 6), + P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, BOGUS3, 7), + + P4_MAKE_EVENT_ATTR(P4_REPLAY_EVENT, NBOGUS, 0), + P4_MAKE_EVENT_ATTR(P4_REPLAY_EVENT, BOGUS, 1), + + P4_MAKE_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSNTAG, 0), + P4_MAKE_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSTAG, 1), + P4_MAKE_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSNTAG, 2), + P4_MAKE_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSTAG, 3), + + P4_MAKE_EVENT_ATTR(P4_UOPS_RETIRED, NBOGUS, 0), + P4_MAKE_EVENT_ATTR(P4_UOPS_RETIRED, BOGUS, 1), + + P4_MAKE_EVENT_ATTR(P4_UOP_TYPE, TAGLOADS, 1), + P4_MAKE_EVENT_ATTR(P4_UOP_TYPE, TAGSTORES, 2), + + P4_MAKE_EVENT_ATTR(P4_BRANCH_RETIRED, MMNP, 0), + P4_MAKE_EVENT_ATTR(P4_BRANCH_RETIRED, MMNM, 1), + P4_MAKE_EVENT_ATTR(P4_BRANCH_RETIRED, MMTP, 2), + P4_MAKE_EVENT_ATTR(P4_BRANCH_RETIRED, MMTM, 3), + + P4_MAKE_EVENT_ATTR(P4_MISPRED_BRANCH_RETIRED, NBOGUS, 0), + + P4_MAKE_EVENT_ATTR(P4_X87_ASSIST, FPSU, 0), + P4_MAKE_EVENT_ATTR(P4_X87_ASSIST, FPSO, 1), + P4_MAKE_EVENT_ATTR(P4_X87_ASSIST, POAO, 2), + P4_MAKE_EVENT_ATTR(P4_X87_ASSIST, POAU, 3), + P4_MAKE_EVENT_ATTR(P4_X87_ASSIST, PREA, 4), + + P4_MAKE_EVENT_ATTR(P4_MACHINE_CLEAR, CLEAR, 0), + P4_MAKE_EVENT_ATTR(P4_MACHINE_CLEAR, MOCLEAR, 1), + P4_MAKE_EVENT_ATTR(P4_MACHINE_CLEAR, SMCLEAR, 2), + + P4_MAKE_EVENT_ATTR(P4_INSTR_COMPLETED, NBOGUS, 0), + P4_MAKE_EVENT_ATTR(P4_INSTR_COMPLETED, BOGUS, 1), +}; + +#endif /* PERF_EVENT_P4_H */ diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index e24f6374f9f5..e6a3f5f81c96 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -190,6 +190,8 @@ struct x86_pmu { void (*enable_all)(void); void (*enable)(struct perf_event *); void (*disable)(struct perf_event *); + int (*hw_config)(struct perf_event_attr *attr, struct hw_perf_event *hwc); + int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign); unsigned eventsel; unsigned perfctr; u64 (*event_map)(int); @@ -415,6 +417,25 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event_attr *attr) return 0; } +static int x86_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc) +{ + /* + * Generate PMC IRQs: + * (keep 'enabled' bit clear for now) + */ + hwc->config = ARCH_PERFMON_EVENTSEL_INT; + + /* + * Count user and OS events unless requested not to + */ + if (!attr->exclude_user) + hwc->config |= ARCH_PERFMON_EVENTSEL_USR; + if (!attr->exclude_kernel) + hwc->config |= ARCH_PERFMON_EVENTSEL_OS; + + return 0; +} + /* * Setup the hardware configuration for a given attr_type */ @@ -446,23 +467,13 @@ static int __hw_perf_event_init(struct perf_event *event) event->destroy = hw_perf_event_destroy; - /* - * Generate PMC IRQs: - * (keep 'enabled' bit clear for now) - */ - hwc->config = ARCH_PERFMON_EVENTSEL_INT; - hwc->idx = -1; hwc->last_cpu = -1; hwc->last_tag = ~0ULL; - /* - * Count user and OS events unless requested not to. - */ - if (!attr->exclude_user) - hwc->config |= ARCH_PERFMON_EVENTSEL_USR; - if (!attr->exclude_kernel) - hwc->config |= ARCH_PERFMON_EVENTSEL_OS; + /* Processor specifics */ + if (x86_pmu.hw_config(attr, hwc)) + return -EOPNOTSUPP; if (!hwc->sample_period) { hwc->sample_period = x86_pmu.max_period; @@ -517,7 +528,7 @@ static int __hw_perf_event_init(struct perf_event *event) return -EOPNOTSUPP; /* BTS is currently only allowed for user-mode. */ - if (hwc->config & ARCH_PERFMON_EVENTSEL_OS) + if (!attr->exclude_kernel) return -EOPNOTSUPP; } @@ -931,7 +942,7 @@ static int x86_pmu_enable(struct perf_event *event) if (n < 0) return n; - ret = x86_schedule_events(cpuc, n, assign); + ret = x86_pmu.schedule_events(cpuc, n, assign); if (ret) return ret; /* @@ -1263,7 +1274,7 @@ int hw_perf_group_sched_in(struct perf_event *leader, if (n0 < 0) return n0; - ret = x86_schedule_events(cpuc, n0, assign); + ret = x86_pmu.schedule_events(cpuc, n0, assign); if (ret) return ret; @@ -1313,6 +1324,7 @@ undo: #include "perf_event_amd.c" #include "perf_event_p6.c" +#include "perf_event_p4.c" #include "perf_event_intel_lbr.c" #include "perf_event_intel_ds.c" #include "perf_event_intel.c" @@ -1515,7 +1527,7 @@ static int validate_group(struct perf_event *event) fake_cpuc->n_events = n; - ret = x86_schedule_events(fake_cpuc, n, NULL); + ret = x86_pmu.schedule_events(fake_cpuc, n, NULL); out_free: kfree(fake_cpuc); diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 573458f1caf2..358a8e3d05f8 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -363,6 +363,8 @@ static __initconst struct x86_pmu amd_pmu = { .enable_all = x86_pmu_enable_all, .enable = x86_pmu_enable_event, .disable = x86_pmu_disable_event, + .hw_config = x86_hw_config, + .schedule_events = x86_schedule_events, .eventsel = MSR_K7_EVNTSEL0, .perfctr = MSR_K7_PERFCTR0, .event_map = amd_pmu_event_map, diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 971dc6e7d54b..044b8436b19d 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -749,6 +749,8 @@ static __initconst struct x86_pmu core_pmu = { .enable_all = x86_pmu_enable_all, .enable = x86_pmu_enable_event, .disable = x86_pmu_disable_event, + .hw_config = x86_hw_config, + .schedule_events = x86_schedule_events, .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, .perfctr = MSR_ARCH_PERFMON_PERFCTR0, .event_map = intel_pmu_event_map, @@ -786,6 +788,8 @@ static __initconst struct x86_pmu intel_pmu = { .enable_all = intel_pmu_enable_all, .enable = intel_pmu_enable_event, .disable = intel_pmu_disable_event, + .hw_config = x86_hw_config, + .schedule_events = x86_schedule_events, .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, .perfctr = MSR_ARCH_PERFMON_PERFCTR0, .event_map = intel_pmu_event_map, @@ -839,12 +843,13 @@ static __init int intel_pmu_init(void) int version; if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - /* check for P6 processor family */ - if (boot_cpu_data.x86 == 6) { - return p6_pmu_init(); - } else { + switch (boot_cpu_data.x86) { + case 0x6: + return p6_pmu_init(); + case 0xf: + return p4_pmu_init(); + } return -ENODEV; - } } /* diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c new file mode 100644 index 000000000000..381f593e8297 --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -0,0 +1,607 @@ +/* + * Netburst Perfomance Events (P4, old Xeon) + * + * Copyright (C) 2010 Parallels, Inc., Cyrill Gorcunov + * Copyright (C) 2010 Intel Corporation, Lin Ming + * + * For licencing details see kernel-base/COPYING + */ + +#ifdef CONFIG_CPU_SUP_INTEL + +#include + +/* + * array indices: 0,1 - HT threads, used with HT enabled cpu + */ +struct p4_event_template { + u32 opcode; /* ESCR event + CCCR selector */ + u64 config; /* packed predefined bits */ + int dep; /* upstream dependency event index */ + unsigned int emask; /* ESCR EventMask */ + unsigned int escr_msr[2]; /* ESCR MSR for this event */ + unsigned int cntr[2]; /* counter index (offset) */ +}; + +struct p4_pmu_res { + /* maps hw_conf::idx into template for ESCR sake */ + struct p4_event_template *tpl[ARCH_P4_MAX_CCCR]; +}; + +static DEFINE_PER_CPU(struct p4_pmu_res, p4_pmu_config); + +/* + * WARN: CCCR1 doesn't have a working enable bit so try to not + * use it if possible + * + * Also as only we start to support raw events we will need to + * append _all_ P4_EVENT_PACK'ed events here + */ +struct p4_event_template p4_templates[] = { + [0] = { + .opcode = P4_UOP_TYPE, + .config = 0, + .dep = -1, + .emask = + P4_EVENT_ATTR(P4_UOP_TYPE, TAGLOADS) | + P4_EVENT_ATTR(P4_UOP_TYPE, TAGSTORES), + .escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 }, + .cntr = { 16, 17 }, + }, + [1] = { + .opcode = P4_GLOBAL_POWER_EVENTS, + .config = 0, + .dep = -1, + .emask = + P4_EVENT_ATTR(P4_GLOBAL_POWER_EVENTS, RUNNING), + .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, + .cntr = { 0, 2 }, + }, + [2] = { + .opcode = P4_INSTR_RETIRED, + .config = 0, + .dep = 0, /* needs front-end tagging */ + .emask = + P4_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSNTAG) | + P4_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSTAG) | + P4_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSNTAG) | + P4_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSTAG), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, + .cntr = { 12, 14 }, + }, + [3] = { + .opcode = P4_BSQ_CACHE_REFERENCE, + .config = 0, + .dep = -1, + .emask = + P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) | + P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) | + P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITM) | + P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITS) | + P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITE) | + P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITM), + .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 }, + .cntr = { 0, 2 }, + }, + [4] = { + .opcode = P4_BSQ_CACHE_REFERENCE, + .config = 0, + .dep = -1, + .emask = + P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) | + P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) | + P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, WR_2ndL_MISS), + .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 }, + .cntr = { 0, 3 }, + }, + [5] = { + .opcode = P4_RETIRED_BRANCH_TYPE, + .config = 0, + .dep = -1, + .emask = + P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CONDITIONAL) | + P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CALL) | + P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, RETURN) | + P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, INDIRECT), + .escr_msr = { MSR_P4_TBPU_ESCR0, MSR_P4_TBPU_ESCR1 }, + .cntr = { 4, 6 }, + }, + [6] = { + .opcode = P4_MISPRED_BRANCH_RETIRED, + .config = 0, + .dep = -1, + .emask = + P4_EVENT_ATTR(P4_MISPRED_BRANCH_RETIRED, NBOGUS), + .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, + .cntr = { 12, 14 }, + }, + [7] = { + .opcode = P4_FSB_DATA_ACTIVITY, + .config = p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE), + .dep = -1, + .emask = + P4_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_DRV) | + P4_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_OWN), + .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, + .cntr = { 0, 2 }, + }, +}; + +static struct p4_event_template *p4_event_map[PERF_COUNT_HW_MAX] = { + /* non-halted CPU clocks */ + [PERF_COUNT_HW_CPU_CYCLES] = &p4_templates[1], + + /* retired instructions: dep on tagging the FSB */ + [PERF_COUNT_HW_INSTRUCTIONS] = &p4_templates[2], + + /* cache hits */ + [PERF_COUNT_HW_CACHE_REFERENCES] = &p4_templates[3], + + /* cache misses */ + [PERF_COUNT_HW_CACHE_MISSES] = &p4_templates[4], + + /* branch instructions retired */ + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = &p4_templates[5], + + /* mispredicted branches retired */ + [PERF_COUNT_HW_BRANCH_MISSES] = &p4_templates[6], + + /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN): */ + [PERF_COUNT_HW_BUS_CYCLES] = &p4_templates[7], +}; + +static u64 p4_pmu_event_map(int hw_event) +{ + struct p4_event_template *tpl; + u64 config; + + if (hw_event > ARRAY_SIZE(p4_event_map)) { + printk_once(KERN_ERR "PMU: Incorrect event index\n"); + return 0; + } + tpl = p4_event_map[hw_event]; + + /* + * fill config up according to + * a predefined event template + */ + config = tpl->config; + config |= p4_config_pack_escr(P4_EVENT_UNPACK_EVENT(tpl->opcode) << P4_EVNTSEL_EVENT_SHIFT); + config |= p4_config_pack_escr(tpl->emask << P4_EVNTSEL_EVENTMASK_SHIFT); + config |= p4_config_pack_cccr(P4_EVENT_UNPACK_SELECTOR(tpl->opcode) << P4_CCCR_ESCR_SELECT_SHIFT); + + /* on HT machine we need a special bit */ + if (p4_ht_active() && p4_ht_thread(raw_smp_processor_id())) + config = p4_set_ht_bit(config); + + return config; +} + +/* + * Note that we still have 5 events (from global events SDM list) + * intersected in opcode+emask bits so we will need another + * scheme there do distinguish templates. + */ +static inline int p4_pmu_emask_match(unsigned int dst, unsigned int src) +{ + return dst & src; +} + +static struct p4_event_template *p4_pmu_template_lookup(u64 config) +{ + u32 opcode = p4_config_unpack_opcode(config); + unsigned int emask = p4_config_unpack_emask(config); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(p4_templates); i++) { + if (opcode == p4_templates[i].opcode && + p4_pmu_emask_match(emask, p4_templates[i].emask)) + return &p4_templates[i]; + } + + return NULL; +} + +/* + * We don't control raw events so it's up to the caller + * to pass sane values (and we don't count the thread number + * on HT machine but allow HT-compatible specifics to be + * passed on) + */ +static u64 p4_pmu_raw_event(u64 hw_event) +{ + return hw_event & + (p4_config_pack_escr(P4_EVNTSEL_MASK_HT) | + p4_config_pack_cccr(P4_CCCR_MASK_HT)); +} + +static int p4_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc) +{ + int cpu = raw_smp_processor_id(); + + /* + * the reason we use cpu that early is that: if we get scheduled + * first time on the same cpu -- we will not need swap thread + * specific flags in config (and will save some cpu cycles) + */ + + /* CCCR by default */ + hwc->config = p4_config_pack_cccr(p4_default_cccr_conf(cpu)); + + /* Count user and OS events unless not requested to */ + hwc->config |= p4_config_pack_escr(p4_default_escr_conf(cpu, attr->exclude_kernel, + attr->exclude_user)); + return 0; +} + +static inline void p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc) +{ + unsigned long dummy; + + rdmsrl(hwc->config_base + hwc->idx, dummy); + if (dummy & P4_CCCR_OVF) { + (void)checking_wrmsrl(hwc->config_base + hwc->idx, + ((u64)dummy) & ~P4_CCCR_OVF); + } +} + +static inline void p4_pmu_disable_event(struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + /* + * If event gets disabled while counter is in overflowed + * state we need to clear P4_CCCR_OVF, otherwise interrupt get + * asserted again and again + */ + (void)checking_wrmsrl(hwc->config_base + hwc->idx, + (u64)(p4_config_unpack_cccr(hwc->config)) & + ~P4_CCCR_ENABLE & ~P4_CCCR_OVF); +} + +static void p4_pmu_disable_all(void) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + int idx; + + for (idx = 0; idx < x86_pmu.num_events; idx++) { + struct perf_event *event = cpuc->events[idx]; + if (!test_bit(idx, cpuc->active_mask)) + continue; + p4_pmu_disable_event(event); + } +} + +static void p4_pmu_enable_event(struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + int thread = p4_ht_config_thread(hwc->config); + u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config)); + u64 escr_base; + struct p4_event_template *tpl; + struct p4_pmu_res *c; + + /* + * some preparation work from per-cpu private fields + * since we need to find out which ESCR to use + */ + c = &__get_cpu_var(p4_pmu_config); + tpl = c->tpl[hwc->idx]; + if (!tpl) { + pr_crit("%s: Wrong index: %d\n", __func__, hwc->idx); + return; + } + escr_base = (u64)tpl->escr_msr[thread]; + + /* + * - we dont support cascaded counters yet + * - and counter 1 is broken (erratum) + */ + WARN_ON_ONCE(p4_is_event_cascaded(hwc->config)); + WARN_ON_ONCE(hwc->idx == 1); + + (void)checking_wrmsrl(escr_base, escr_conf); + (void)checking_wrmsrl(hwc->config_base + hwc->idx, + (u64)(p4_config_unpack_cccr(hwc->config)) | P4_CCCR_ENABLE); +} + +static void p4_pmu_enable_all(void) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + int idx; + + for (idx = 0; idx < x86_pmu.num_events; idx++) { + struct perf_event *event = cpuc->events[idx]; + if (!test_bit(idx, cpuc->active_mask)) + continue; + p4_pmu_enable_event(event); + } +} + +static int p4_pmu_handle_irq(struct pt_regs *regs) +{ + struct perf_sample_data data; + struct cpu_hw_events *cpuc; + struct perf_event *event; + struct hw_perf_event *hwc; + int idx, handled = 0; + u64 val; + + data.addr = 0; + data.raw = NULL; + + cpuc = &__get_cpu_var(cpu_hw_events); + + for (idx = 0; idx < x86_pmu.num_events; idx++) { + + if (!test_bit(idx, cpuc->active_mask)) + continue; + + event = cpuc->events[idx]; + hwc = &event->hw; + + WARN_ON_ONCE(hwc->idx != idx); + + /* + * FIXME: Redundant call, actually not needed + * but just to check if we're screwed + */ + p4_pmu_clear_cccr_ovf(hwc); + + val = x86_perf_event_update(event); + if (val & (1ULL << (x86_pmu.event_bits - 1))) + continue; + + /* + * event overflow + */ + handled = 1; + data.period = event->hw.last_period; + + if (!x86_perf_event_set_period(event)) + continue; + if (perf_event_overflow(event, 1, &data, regs)) + p4_pmu_disable_event(event); + } + + if (handled) { + /* p4 quirk: unmask it again */ + apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); + inc_irq_stat(apic_perf_irqs); + } + + return handled; +} + +/* + * swap thread specific fields according to a thread + * we are going to run on + */ +static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu) +{ + u32 escr, cccr; + + /* + * we either lucky and continue on same cpu or no HT support + */ + if (!p4_should_swap_ts(hwc->config, cpu)) + return; + + /* + * the event is migrated from an another logical + * cpu, so we need to swap thread specific flags + */ + + escr = p4_config_unpack_escr(hwc->config); + cccr = p4_config_unpack_cccr(hwc->config); + + if (p4_ht_thread(cpu)) { + cccr &= ~P4_CCCR_OVF_PMI_T0; + cccr |= P4_CCCR_OVF_PMI_T1; + if (escr & P4_EVNTSEL_T0_OS) { + escr &= ~P4_EVNTSEL_T0_OS; + escr |= P4_EVNTSEL_T1_OS; + } + if (escr & P4_EVNTSEL_T0_USR) { + escr &= ~P4_EVNTSEL_T0_USR; + escr |= P4_EVNTSEL_T1_USR; + } + hwc->config = p4_config_pack_escr(escr); + hwc->config |= p4_config_pack_cccr(cccr); + hwc->config |= P4_CONFIG_HT; + } else { + cccr &= ~P4_CCCR_OVF_PMI_T1; + cccr |= P4_CCCR_OVF_PMI_T0; + if (escr & P4_EVNTSEL_T1_OS) { + escr &= ~P4_EVNTSEL_T1_OS; + escr |= P4_EVNTSEL_T0_OS; + } + if (escr & P4_EVNTSEL_T1_USR) { + escr &= ~P4_EVNTSEL_T1_USR; + escr |= P4_EVNTSEL_T0_USR; + } + hwc->config = p4_config_pack_escr(escr); + hwc->config |= p4_config_pack_cccr(cccr); + hwc->config &= ~P4_CONFIG_HT; + } +} + +/* ESCRs are not sequential in memory so we need a map */ +static unsigned int p4_escr_map[ARCH_P4_TOTAL_ESCR] = { + MSR_P4_ALF_ESCR0, /* 0 */ + MSR_P4_ALF_ESCR1, /* 1 */ + MSR_P4_BPU_ESCR0, /* 2 */ + MSR_P4_BPU_ESCR1, /* 3 */ + MSR_P4_BSU_ESCR0, /* 4 */ + MSR_P4_BSU_ESCR1, /* 5 */ + MSR_P4_CRU_ESCR0, /* 6 */ + MSR_P4_CRU_ESCR1, /* 7 */ + MSR_P4_CRU_ESCR2, /* 8 */ + MSR_P4_CRU_ESCR3, /* 9 */ + MSR_P4_CRU_ESCR4, /* 10 */ + MSR_P4_CRU_ESCR5, /* 11 */ + MSR_P4_DAC_ESCR0, /* 12 */ + MSR_P4_DAC_ESCR1, /* 13 */ + MSR_P4_FIRM_ESCR0, /* 14 */ + MSR_P4_FIRM_ESCR1, /* 15 */ + MSR_P4_FLAME_ESCR0, /* 16 */ + MSR_P4_FLAME_ESCR1, /* 17 */ + MSR_P4_FSB_ESCR0, /* 18 */ + MSR_P4_FSB_ESCR1, /* 19 */ + MSR_P4_IQ_ESCR0, /* 20 */ + MSR_P4_IQ_ESCR1, /* 21 */ + MSR_P4_IS_ESCR0, /* 22 */ + MSR_P4_IS_ESCR1, /* 23 */ + MSR_P4_ITLB_ESCR0, /* 24 */ + MSR_P4_ITLB_ESCR1, /* 25 */ + MSR_P4_IX_ESCR0, /* 26 */ + MSR_P4_IX_ESCR1, /* 27 */ + MSR_P4_MOB_ESCR0, /* 28 */ + MSR_P4_MOB_ESCR1, /* 29 */ + MSR_P4_MS_ESCR0, /* 30 */ + MSR_P4_MS_ESCR1, /* 31 */ + MSR_P4_PMH_ESCR0, /* 32 */ + MSR_P4_PMH_ESCR1, /* 33 */ + MSR_P4_RAT_ESCR0, /* 34 */ + MSR_P4_RAT_ESCR1, /* 35 */ + MSR_P4_SAAT_ESCR0, /* 36 */ + MSR_P4_SAAT_ESCR1, /* 37 */ + MSR_P4_SSU_ESCR0, /* 38 */ + MSR_P4_SSU_ESCR1, /* 39 */ + MSR_P4_TBPU_ESCR0, /* 40 */ + MSR_P4_TBPU_ESCR1, /* 41 */ + MSR_P4_TC_ESCR0, /* 42 */ + MSR_P4_TC_ESCR1, /* 43 */ + MSR_P4_U2L_ESCR0, /* 44 */ + MSR_P4_U2L_ESCR1, /* 45 */ +}; + +static int p4_get_escr_idx(unsigned int addr) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(p4_escr_map); i++) { + if (addr == p4_escr_map[i]) + return i; + } + + return -1; +} + +static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) +{ + unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; + unsigned long escr_mask[BITS_TO_LONGS(ARCH_P4_TOTAL_ESCR)]; + + struct hw_perf_event *hwc; + struct p4_event_template *tpl; + struct p4_pmu_res *c; + int cpu = raw_smp_processor_id(); + int escr_idx, thread, i, num; + + bitmap_zero(used_mask, X86_PMC_IDX_MAX); + bitmap_zero(escr_mask, ARCH_P4_TOTAL_ESCR); + + c = &__get_cpu_var(p4_pmu_config); + /* + * Firstly find out which resource events are going + * to use, if ESCR+CCCR tuple is already borrowed + * then get out of here + */ + for (i = 0, num = n; i < n; i++, num--) { + hwc = &cpuc->event_list[i]->hw; + tpl = p4_pmu_template_lookup(hwc->config); + if (!tpl) + goto done; + thread = p4_ht_thread(cpu); + escr_idx = p4_get_escr_idx(tpl->escr_msr[thread]); + if (escr_idx == -1) + goto done; + + /* already allocated and remains on the same cpu */ + if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) { + if (assign) + assign[i] = hwc->idx; + /* upstream dependent event */ + if (unlikely(tpl->dep != -1)) + printk_once(KERN_WARNING "PMU: Dep events are " + "not implemented yet\n"); + goto reserve; + } + + /* it may be already borrowed */ + if (test_bit(tpl->cntr[thread], used_mask) || + test_bit(escr_idx, escr_mask)) + goto done; + + /* + * ESCR+CCCR+COUNTERs are available to use lets swap + * thread specific bits, push assigned bits + * back and save template into per-cpu + * area (which will allow us to find out the ESCR + * to be used at moment of "enable event via real MSR") + */ + p4_pmu_swap_config_ts(hwc, cpu); + if (assign) { + assign[i] = tpl->cntr[thread]; + c->tpl[assign[i]] = tpl; + } +reserve: + set_bit(tpl->cntr[thread], used_mask); + set_bit(escr_idx, escr_mask); + } + +done: + return num ? -ENOSPC : 0; +} + +static __initconst struct x86_pmu p4_pmu = { + .name = "Netburst P4/Xeon", + .handle_irq = p4_pmu_handle_irq, + .disable_all = p4_pmu_disable_all, + .enable_all = p4_pmu_enable_all, + .enable = p4_pmu_enable_event, + .disable = p4_pmu_disable_event, + .eventsel = MSR_P4_BPU_CCCR0, + .perfctr = MSR_P4_BPU_PERFCTR0, + .event_map = p4_pmu_event_map, + .raw_event = p4_pmu_raw_event, + .max_events = ARRAY_SIZE(p4_event_map), + .get_event_constraints = x86_get_event_constraints, + /* + * IF HT disabled we may need to use all + * ARCH_P4_MAX_CCCR counters simulaneously + * though leave it restricted at moment assuming + * HT is on + */ + .num_events = ARCH_P4_MAX_CCCR, + .apic = 1, + .event_bits = 40, + .event_mask = (1ULL << 40) - 1, + .max_period = (1ULL << 39) - 1, + .hw_config = p4_hw_config, + .schedule_events = p4_pmu_schedule_events, +}; + +static __init int p4_pmu_init(void) +{ + unsigned int low, high; + + /* If we get stripped -- indexig fails */ + BUILD_BUG_ON(ARCH_P4_MAX_CCCR > X86_PMC_MAX_GENERIC); + + rdmsr(MSR_IA32_MISC_ENABLE, low, high); + if (!(low & (1 << 7))) { + pr_cont("unsupported Netburst CPU model %d ", + boot_cpu_data.x86_model); + return -ENODEV; + } + + pr_cont("Netburst events, "); + + x86_pmu = p4_pmu; + + return 0; +} + +#endif /* CONFIG_CPU_SUP_INTEL */ diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index a330485d14da..6ff4d01d880f 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -109,6 +109,8 @@ static __initconst struct x86_pmu p6_pmu = { .enable_all = p6_pmu_enable_all, .enable = p6_pmu_enable_event, .disable = p6_pmu_disable_event, + .hw_config = x86_hw_config, + .schedule_events = x86_schedule_events, .eventsel = MSR_P6_EVNTSEL0, .perfctr = MSR_P6_PERFCTR0, .event_map = p6_pmu_event_map, -- cgit v1.2.3-59-g8ed1b From 0b861225a5890f22445f08ca9cc7a87cff276ff7 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Fri, 12 Mar 2010 00:50:16 +0300 Subject: x86, perf: Fix NULL deref on not assigned x86_pmu In case of not assigned x86_pmu and software events NULL dereference may being hit via x86_pmu::schedule_events method. Fix it by checking if x86_pmu is initialized at all. Signed-off-by: Cyrill Gorcunov Cc: Lin Ming Cc: Arnaldo Carvalho de Melo Cc: Stephane Eranian Cc: Robert Richter Cc: Frederic Weisbecker Cc: Peter Zijlstra LKML-Reference: <20100311215016.GG25162@lenovo> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index e6a3f5f81c96..5586a02067d8 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1269,6 +1269,9 @@ int hw_perf_group_sched_in(struct perf_event *leader, int assign[X86_PMC_IDX_MAX]; int n0, n1, ret; + if (!x86_pmu_initialized()) + return 0; + /* n0 = total number of events */ n0 = collect_events(cpuc, leader, true); if (n0 < 0) -- cgit v1.2.3-59-g8ed1b From aa9b88ee80d3985ebae9567a8f4e0d07ce15b5a7 Mon Sep 17 00:00:00 2001 From: Miguel Aguilar Date: Thu, 11 Mar 2010 09:33:40 -0600 Subject: DaVinci: DM365: Voice Codec support for the DM365 EVM The DM365 EVM has two codecs: the Audio Codec (AIC3x) and the Voice Codec, the idea is to have both enabled in the same kernel simultaneously. However, the current soc-core doesn't support simultaneous codecs, once that support will have added, a patch will be posted to enable both codecs in the DM365 EVM. Signed-off-by: Miguel Aguilar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-davinci/board-dm365-evm.c | 4 +++ sound/soc/davinci/Kconfig | 24 ++++++++++++++++-- sound/soc/davinci/davinci-evm.c | 45 +++++++++++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index d15beceb632e..512174a874a1 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -604,7 +604,11 @@ static __init void dm365_evm_init(void) /* maybe setup mmc1/etc ... _after_ mmc0 */ evm_init_cpld(); +#ifdef CONFIG_SND_DM365_AIC3X_CODEC dm365_init_asp(&dm365_evm_snd_data); +#elif defined(CONFIG_SND_DM365_VOICE_CODEC) + dm365_init_vc(&dm365_evm_snd_data); +#endif dm365_init_rtc(); dm365_init_ks(&dm365evm_ks_data); diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 47e7ccecc577..6bbf001f6591 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -18,12 +18,32 @@ config SND_DAVINCI_SOC_VCIF config SND_DAVINCI_SOC_EVM tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" depends on SND_DAVINCI_SOC - depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM + depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM select SND_DAVINCI_SOC_I2S select SND_SOC_TLV320AIC3X help Say Y if you want to add support for SoC audio on TI - DaVinci DM6446 or DM355 EVM platforms. + DaVinci DM6446, DM355 or DM365 EVM platforms. + +choice + prompt "DM365 codec select" + depends on SND_DAVINCI_SOC_EVM + depends on MACH_DAVINCI_DM365_EVM + default SND_DM365_EXTERNAL_CODEC + +config SND_DM365_AIC3X_CODEC + bool "Audio Codec - AIC3101" + help + Say Y if you want to add support for AIC3101 audio codec + +config SND_DM365_VOICE_CODEC + bool "Voice Codec - CQ93VC" + select MFD_DAVINCI_VOICECODEC + select SND_DAVINCI_SOC_VCIF + select SND_SOC_CQ0093VC + help + Say Y if you want to add support for SoC On-chip voice codec +endchoice config SND_DM6467_SOC_EVM tristate "SoC Audio support for DaVinci DM6467 EVM" diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index dba6651547c1..97f74d6a33e6 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -28,10 +28,12 @@ #include #include "../codecs/tlv320aic3x.h" +#include "../codecs/cq93vc.h" #include "../codecs/spdif_transciever.h" #include "davinci-pcm.h" #include "davinci-i2s.h" #include "davinci-mcasp.h" +#include "davinci-vcif.h" #define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) @@ -165,6 +167,22 @@ static struct snd_soc_dai_link evm_dai = { .ops = &evm_ops, }; +static struct snd_soc_dai_link dm365_evm_dai = { +#ifdef CONFIG_SND_DM365_AIC3X_CODEC + .name = "TLV320AIC3X", + .stream_name = "AIC3X", + .cpu_dai = &davinci_i2s_dai, + .codec_dai = &aic3x_dai, + .init = evm_aic3x_init, + .ops = &evm_ops, +#elif defined(CONFIG_SND_DM365_VOICE_CODEC) + .name = "Voice Codec - CQ93VC", + .stream_name = "CQ93", + .cpu_dai = &davinci_vcif_dai, + .codec_dai = &cq93vc_dai, +#endif +}; + static struct snd_soc_dai_link dm6467_evm_dai[] = { { .name = "TLV320AIC3X", @@ -191,7 +209,7 @@ static struct snd_soc_dai_link da8xx_evm_dai = { .ops = &evm_ops, }; -/* davinci dm6446, dm355 or dm365 evm audio machine driver */ +/* davinci dm6446, dm355 evm audio machine driver */ static struct snd_soc_card snd_soc_card_evm = { .name = "DaVinci EVM", .platform = &davinci_soc_platform, @@ -199,6 +217,15 @@ static struct snd_soc_card snd_soc_card_evm = { .num_links = 1, }; +/* davinci dm365 evm audio machine driver */ +static struct snd_soc_card dm365_snd_soc_card_evm = { + .name = "DaVinci DM365 EVM", + .platform = &davinci_soc_platform, + .dai_link = &dm365_evm_dai, + .num_links = 1, +}; + + /* davinci dm6467 evm audio machine driver */ static struct snd_soc_card dm6467_snd_soc_card_evm = { .name = "DaVinci DM6467 EVM", @@ -230,6 +257,17 @@ static struct snd_soc_device evm_snd_devdata = { .codec_data = &aic3x_setup, }; +/* evm audio subsystem */ +static struct snd_soc_device dm365_evm_snd_devdata = { + .card = &dm365_snd_soc_card_evm, +#ifdef CONFIG_SND_DM365_AIC3X_CODEC + .codec_dev = &soc_codec_dev_aic3x, + .codec_data = &aic3x_setup, +#elif defined(CONFIG_SND_DM365_VOICE_CODEC) + .codec_dev = &soc_codec_dev_cq93vc, +#endif +}; + /* evm audio subsystem */ static struct snd_soc_device dm6467_evm_snd_devdata = { .card = &dm6467_snd_soc_card_evm, @@ -258,12 +296,15 @@ static int __init evm_init(void) int index; int ret; - if (machine_is_davinci_evm() || machine_is_davinci_dm365_evm()) { + if (machine_is_davinci_evm()) { evm_snd_dev_data = &evm_snd_devdata; index = 0; } else if (machine_is_davinci_dm355_evm()) { evm_snd_dev_data = &evm_snd_devdata; index = 1; + } else if (machine_is_davinci_dm365_evm()) { + evm_snd_dev_data = &dm365_evm_snd_devdata; + index = 0; } else if (machine_is_davinci_dm6467_evm()) { evm_snd_dev_data = &dm6467_evm_snd_devdata; index = 0; -- cgit v1.2.3-59-g8ed1b From 7dc976ed38a927fc9880bd3dc498a6a903d1ba74 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 3 Mar 2010 15:08:08 +0200 Subject: OMAP3: McBSP: Add interface for FIFO caused delay query New functions for querying the FIFO caused delay on both TX and RX path. On TX path the return value shows the number of used locations in the FIFO. On RX papth it returns the number of locations to be filled to reach the threshold value (DMA will be triggered to read the data out from the FIFO). Signed-off-by: Peter Ujfalusi Acked-by: Tony Lindgren Acked-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/plat/mcbsp.h | 6 ++++ arch/arm/plat-omap/mcbsp.c | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h index 39748354ce45..1bd7021336c2 100644 --- a/arch/arm/plat-omap/include/plat/mcbsp.h +++ b/arch/arm/plat-omap/include/plat/mcbsp.h @@ -149,6 +149,8 @@ #define OMAP_MCBSP_REG_WAKEUPEN 0xA8 #define OMAP_MCBSP_REG_XCCR 0xAC #define OMAP_MCBSP_REG_RCCR 0xB0 +#define OMAP_MCBSP_REG_XBUFFSTAT 0xB4 +#define OMAP_MCBSP_REG_RBUFFSTAT 0xB8 #define OMAP_MCBSP_REG_SSELCR 0xBC #define OMAP_ST_REG_REV 0x00 @@ -471,6 +473,8 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); +u16 omap_mcbsp_get_tx_delay(unsigned int id); +u16 omap_mcbsp_get_rx_delay(unsigned int id); int omap_mcbsp_get_dma_op_mode(unsigned int id); #else static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) @@ -479,6 +483,8 @@ static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) { } static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } +static inline u16 omap_mcbsp_get_tx_delay(unsigned int id) { return 0; } +static inline u16 omap_mcbsp_get_rx_delay(unsigned int id) { return 0; } static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; } #endif int omap_mcbsp_request(unsigned int id); diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index e47686e0a633..5e6d3096c725 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -561,6 +561,61 @@ u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) } EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); +#define MCBSP2_FIFO_SIZE 0x500 /* 1024 + 256 locations */ +#define MCBSP1345_FIFO_SIZE 0x80 /* 128 locations */ +/* + * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO + */ +u16 omap_mcbsp_get_tx_delay(unsigned int id) +{ + struct omap_mcbsp *mcbsp; + u16 buffstat; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + mcbsp = id_to_mcbsp_ptr(id); + + /* Returns the number of free locations in the buffer */ + buffstat = MCBSP_READ(mcbsp, XBUFFSTAT); + + /* Number of slots are different in McBSP ports */ + if (mcbsp->id == 2) + return MCBSP2_FIFO_SIZE - buffstat; + else + return MCBSP1345_FIFO_SIZE - buffstat; +} +EXPORT_SYMBOL(omap_mcbsp_get_tx_delay); + +/* + * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO + * to reach the threshold value (when the DMA will be triggered to read it) + */ +u16 omap_mcbsp_get_rx_delay(unsigned int id) +{ + struct omap_mcbsp *mcbsp; + u16 buffstat, threshold; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + mcbsp = id_to_mcbsp_ptr(id); + + /* Returns the number of used locations in the buffer */ + buffstat = MCBSP_READ(mcbsp, RBUFFSTAT); + /* RX threshold */ + threshold = MCBSP_READ(mcbsp, THRSH1); + + /* Return the number of location till we reach the threshold limit */ + if (threshold <= buffstat) + return 0; + else + return threshold - buffstat; +} +EXPORT_SYMBOL(omap_mcbsp_get_rx_delay); + /* * omap_mcbsp_get_dma_op_mode just return the current configured * operating mode for the mcbsp channel -- cgit v1.2.3-59-g8ed1b From c4507257764ae0387f0d8c2ca57808f37e4c9439 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 11 Mar 2010 14:04:47 -0800 Subject: time: Clean up direct xtime usage in xen Cleanup xen's direct use of internal timekeeping values. Signed-off-by: John Stultz Acked-by: Jeremy Fitzhardinge Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner --- arch/x86/xen/time.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 0d3f07cd1b5f..6365df925cb1 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -475,6 +475,7 @@ void xen_timer_resume(void) __init void xen_time_init(void) { int cpu = smp_processor_id(); + struct timespec tp; clocksource_register(&xen_clocksource); @@ -486,9 +487,8 @@ __init void xen_time_init(void) } /* Set initial system time with full resolution */ - xen_read_wallclock(&xtime); - set_normalized_timespec(&wall_to_monotonic, - -xtime.tv_sec, -xtime.tv_nsec); + xen_read_wallclock(&tp); + do_settimeofday(&tp); setup_force_cpu_cap(X86_FEATURE_TSC); -- cgit v1.2.3-59-g8ed1b From 104f9c471ffb425fd081074ef31521b38d77592a Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 11 Mar 2010 14:11:39 -0800 Subject: xtensa: Fix unnecessary setting of xtime xtensa supports read_persisitent_clock(), so there is no reason for the arch specific code to be setting xtime. Setting xtime will be done by the generic timekeeping code. Signed-off-by: John Stultz Cc: Chris Zankel Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner --- arch/xtensa/kernel/time.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 19f7df30937f..19df764f6399 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -60,11 +60,6 @@ static struct irqaction timer_irqaction = { void __init time_init(void) { - /* FIXME: xtime&wall_to_monotonic are set in timekeeping_init. */ - read_persistent_clock(&xtime); - set_normalized_timespec(&wall_to_monotonic, - -xtime.tv_sec, -xtime.tv_nsec); - #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT printk("Calibrating CPU frequency "); platform_calibrate_ccount(); -- cgit v1.2.3-59-g8ed1b From 1e871be1aa97babb467a929d6adcb1960659928b Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:16 -0800 Subject: alpha: Convert alpha to use read/update_persistent_clock This patch converts the alpha architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. I have not built or tested this patch, so help from arch maintainers would be appreciated. igned-off-by: John Stultz Cc: Richard Henderson Cc: Andrew Morton LKML-Reference: <1267675049-12337-2-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- arch/alpha/Kconfig | 3 ++ arch/alpha/kernel/time.c | 101 ++++++++++++++++++++++------------------------- 2 files changed, 50 insertions(+), 54 deletions(-) (limited to 'arch') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index bd7261ea8f94..75fff7e5a0db 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -54,6 +54,9 @@ config ARCH_USES_GETTIMEOFFSET bool default y +config GENERIC_CMOS_UPDATE + def_bool y + config ZONE_DMA bool default y diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 5d0826654c61..5465e932e568 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -75,8 +75,6 @@ static struct { __u32 last_time; /* ticks/cycle * 2^48 */ unsigned long scaled_ticks_per_cycle; - /* last time the CMOS clock got updated */ - time_t last_rtc_update; /* partial unused tick */ unsigned long partial_tick; } state; @@ -91,6 +89,52 @@ static inline __u32 rpcc(void) return result; } +int update_persistent_clock(struct timespec now) +{ + return set_rtc_mmss(now.tv_sec); +} + +void read_persistent_clock(struct timespec *ts) +{ + unsigned int year, mon, day, hour, min, sec, epoch; + + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); + + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + sec = bcd2bin(sec); + min = bcd2bin(min); + hour = bcd2bin(hour); + day = bcd2bin(day); + mon = bcd2bin(mon); + year = bcd2bin(year); + } + + /* PC-like is standard; used for year >= 70 */ + epoch = 1900; + if (year < 20) + epoch = 2000; + else if (year >= 20 && year < 48) + /* NT epoch */ + epoch = 1980; + else if (year >= 48 && year < 70) + /* Digital UNIX epoch */ + epoch = 1952; + + printk(KERN_INFO "Using epoch = %d\n", epoch); + + if ((year += epoch) < 1970) + year += 100; + + ts->tv_sec = mktime(year, mon, day, hour, min, sec); +} + + + /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick @@ -123,19 +167,6 @@ irqreturn_t timer_interrupt(int irq, void *dev) if (nticks) do_timer(nticks); - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - if (ntp_synced() - && xtime.tv_sec > state.last_rtc_update + 660 - && xtime.tv_nsec >= 500000 - ((unsigned) TICK_SIZE) / 2 - && xtime.tv_nsec <= 500000 + ((unsigned) TICK_SIZE) / 2) { - int tmp = set_rtc_mmss(xtime.tv_sec); - state.last_rtc_update = xtime.tv_sec - (tmp ? 600 : 0); - } - write_sequnlock(&xtime_lock); #ifndef CONFIG_SMP @@ -304,7 +335,7 @@ rpcc_after_update_in_progress(void) void __init time_init(void) { - unsigned int year, mon, day, hour, min, sec, cc1, cc2, epoch; + unsigned int cc1, cc2; unsigned long cycle_freq, tolerance; long diff; @@ -348,43 +379,6 @@ time_init(void) bogomips yet, but this is close on a 500Mhz box. */ __delay(1000000); - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - sec = bcd2bin(sec); - min = bcd2bin(min); - hour = bcd2bin(hour); - day = bcd2bin(day); - mon = bcd2bin(mon); - year = bcd2bin(year); - } - - /* PC-like is standard; used for year >= 70 */ - epoch = 1900; - if (year < 20) - epoch = 2000; - else if (year >= 20 && year < 48) - /* NT epoch */ - epoch = 1980; - else if (year >= 48 && year < 70) - /* Digital UNIX epoch */ - epoch = 1952; - - printk(KERN_INFO "Using epoch = %d\n", epoch); - - if ((year += epoch) < 1970) - year += 100; - - xtime.tv_sec = mktime(year, mon, day, hour, min, sec); - xtime.tv_nsec = 0; - - wall_to_monotonic.tv_sec -= xtime.tv_sec; - wall_to_monotonic.tv_nsec = 0; if (HZ > (1<<16)) { extern void __you_loose (void); @@ -394,7 +388,6 @@ time_init(void) state.last_time = cc1; state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; - state.last_rtc_update = 0; state.partial_tick = 0L; /* Startup the timer source. */ -- cgit v1.2.3-59-g8ed1b From f7a56575fa4e62e94a644f72ef8c5d423c073982 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:17 -0800 Subject: mn10300: Convert mn10300 to use read/update_persistent_clock This patch converts the mn10300 architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. I have not built or tested this patch, so help from arch maintainers would be appreciated. Signed-off-by: John Stultz Cc: David Howells Cc: Koichi Yasutake Cc: Andrew Morton LKML-Reference: <1267675049-12337-3-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- arch/mn10300/Kconfig | 3 +++ arch/mn10300/kernel/rtc.c | 27 +++++---------------------- arch/mn10300/kernel/time.c | 4 ---- 3 files changed, 8 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 89faacad5d17..1c4565a9102b 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -37,6 +37,9 @@ config GENERIC_HARDIRQS_NO__DO_IRQ config GENERIC_CALIBRATE_DELAY def_bool y +config GENERIC_CMOS_UPDATE + def_bool y + config GENERIC_FIND_NEXT_BIT def_bool y diff --git a/arch/mn10300/kernel/rtc.c b/arch/mn10300/kernel/rtc.c index 7978470b5749..815a933aafa8 100644 --- a/arch/mn10300/kernel/rtc.c +++ b/arch/mn10300/kernel/rtc.c @@ -26,17 +26,15 @@ static long last_rtc_update; /* time for RTC to update itself in ioclks */ static unsigned long mn10300_rtc_update_period; -/* - * read the current RTC time - */ -unsigned long __init get_initial_rtc_time(void) +void read_persistent_clock(struct timespec *ts) { struct rtc_time tm; get_rtc_time(&tm); - return mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, + ts->tv_sec = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); + ts->tv_nsec = 0; } /* @@ -110,24 +108,9 @@ static int set_rtc_mmss(unsigned long nowtime) return retval; } -void check_rtc_time(void) +int update_persistent_clock(struct timespec now) { - /* the RTC clock just finished ticking over again this second - * - if we have an externally synchronized Linux clock, then update - * RTC clock accordingly every ~11 minutes. set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - if ((time_status & STA_UNSYNC) == 0 && - xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_nsec / 1000 >= 500000 - ((unsigned) TICK_SIZE) / 2 && - xtime.tv_nsec / 1000 <= 500000 + ((unsigned) TICK_SIZE) / 2 - ) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* do it again in 60s */ - last_rtc_update = xtime.tv_sec - 600; - } + return set_rtc_mms(now.tv_sec); } /* diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c index 395caf01b909..8f7f6d22783d 100644 --- a/arch/mn10300/kernel/time.c +++ b/arch/mn10300/kernel/time.c @@ -111,7 +111,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) /* advance the kernel's time tracking system */ profile_tick(CPU_PROFILING); do_timer(1); - check_rtc_time(); } write_sequnlock(&xtime_lock); @@ -139,9 +138,6 @@ void __init time_init(void) " (calibrated against RTC)\n", MN10300_TSCCLK / 1000000, (MN10300_TSCCLK / 10000) % 100); - xtime.tv_sec = get_initial_rtc_time(); - xtime.tv_nsec = 0; - mn10300_last_tsc = TMTSCBC; /* use timer 0 & 1 cascaded to tick at as close to HZ as possible */ -- cgit v1.2.3-59-g8ed1b From 739b27116a0e6903d6c85d6769e69f43d8fa4128 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:18 -0800 Subject: frv: Convert frv to use read/update_persistent_clock This patch converts the frv architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. I have not built or tested this patch, so help from arch maintainers would be appreciated. Signed-off-by: John Stultz Cc: David Howells Cc: Andrew Morton LKML-Reference: <1267675049-12337-4-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- arch/frv/kernel/time.c | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c index fb0ce7577225..0ddbbae83cb2 100644 --- a/arch/frv/kernel/time.c +++ b/arch/frv/kernel/time.c @@ -48,20 +48,12 @@ static struct irqaction timer_irq = { .name = "timer", }; -static inline int set_rtc_mmss(unsigned long nowtime) -{ - return -1; -} - /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ static irqreturn_t timer_interrupt(int irq, void *dummy) { - /* last time the cmos clock got updated */ - static long last_rtc_update = 0; - profile_tick(CPU_PROFILING); /* * Here we are in the timer irq handler. We just have irqs locally @@ -74,22 +66,6 @@ static irqreturn_t timer_interrupt(int irq, void *dummy) do_timer(1); - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - if (ntp_synced() && - xtime.tv_sec > last_rtc_update + 660 && - (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && - (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2 - ) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ - } - #ifdef CONFIG_HEARTBEAT static unsigned short n; n++; @@ -119,7 +95,8 @@ void time_divisor_init(void) __set_TCSR_DATA(0, base >> 8); } -void time_init(void) + +void read_persistent_clock(struct timespec *ts) { unsigned int year, mon, day, hour, min, sec; @@ -135,9 +112,12 @@ void time_init(void) if ((year += 1900) < 1970) year += 100; - xtime.tv_sec = mktime(year, mon, day, hour, min, sec); - xtime.tv_nsec = 0; + ts->tv_sec = mktime(year, mon, day, hour, min, sec); + ts->tv_nsec = 0; +} +void time_init(void) +{ /* install scheduling interrupt handler */ setup_irq(IRQ_CPU_TIMER0, &timer_irq); -- cgit v1.2.3-59-g8ed1b From 12833c1e373ad2b12667ca159d335fae29968473 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:20 -0800 Subject: h8300: Convert h8300 to use read/update_persistent_clock This patch converts the h8300 architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. I have not built or tested this patch, so help from arch maintainers would be appreciated. Signed-off-by: John Stultz Cc: Yoshinori Sato Cc: Andrew Morton LKML-Reference: <1267675049-12337-6-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- arch/h8300/kernel/time.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c index 7f2d6cfbb4b6..165005aff9df 100644 --- a/arch/h8300/kernel/time.c +++ b/arch/h8300/kernel/time.c @@ -41,7 +41,7 @@ void h8300_timer_tick(void) update_process_times(user_mode(get_irq_regs())); } -void __init time_init(void) +void read_persistent_clock(struct timespec *ts) { unsigned int year, mon, day, hour, min, sec; @@ -56,8 +56,12 @@ void __init time_init(void) #endif if ((year += 1900) < 1970) year += 100; - xtime.tv_sec = mktime(year, mon, day, hour, min, sec); - xtime.tv_nsec = 0; + ts->tv_sec = mktime(year, mon, day, hour, min, sec); + ts->tv_nsec = 0; +} + +void __init time_init(void) +{ h8300_timer_setup(); } -- cgit v1.2.3-59-g8ed1b From e2032a4a7237e97cd2ee36e2d806c5742ace189f Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:21 -0800 Subject: avr32: Convert avr32 to use read/update_persistent_clock This patch converts the avr32 architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. I have not built or tested this patch, so help from arch maintainers would be appreciated. Signed-off-by: John Stultz Cc: Haavard Skinnemoen Cc: Andrew Morton LKML-Reference: <1267675049-12337-7-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- arch/avr32/kernel/time.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c index f27aa3b259fa..a047d69d17e2 100644 --- a/arch/avr32/kernel/time.c +++ b/arch/avr32/kernel/time.c @@ -110,17 +110,17 @@ static struct clock_event_device comparator = { .set_mode = comparator_mode, }; +void read_persistent_clock(struct timespec *ts) +{ + ts->tv.sec = mktime(2007, 1, 1, 0, 0, 0); + ts->tv_nsec = 0; +} + void __init time_init(void) { unsigned long counter_hz; int ret; - xtime.tv_sec = mktime(2007, 1, 1, 0, 0, 0); - xtime.tv_nsec = 0; - - set_normalized_timespec(&wall_to_monotonic, - -xtime.tv_sec, -xtime.tv_nsec); - /* figure rate for counter */ counter_hz = clk_get_rate(boot_cpu_data.clk); counter.mult = clocksource_hz2mult(counter_hz, counter.shift); -- cgit v1.2.3-59-g8ed1b From 6ffdc5774a9ef80e58db398a8307d5b2db2644ce Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:22 -0800 Subject: ia64: Convert ia64 to use read/update_persistent_clock This patch converts the ia64 architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. I have not built or tested this patch, so help from arch maintainers would be appreciated. Signed-off-by: John Stultz Cc: Tony Luck Cc: Fenghua Yu Cc: Andrew Morton LKML-Reference: <1267675049-12337-8-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- arch/ia64/kernel/time.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 47a192781b0a..653b3c46ea82 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -430,18 +430,16 @@ static int __init rtc_init(void) } module_init(rtc_init); +void read_persistent_clock(struct timespec *ts) +{ + efi_gettimeofday(ts); +} + void __init time_init (void) { register_percpu_irq(IA64_TIMER_VECTOR, &timer_irqaction); - efi_gettimeofday(&xtime); ia64_init_itm(); - - /* - * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the - * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC). - */ - set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); } /* -- cgit v1.2.3-59-g8ed1b From cb0e996378900fa05d5c779d6bfa52d55ebc3407 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:24 -0800 Subject: blackfin: Convert blackfin to use read/update_persistent_clock This patch converts the blackfin architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. I have not built or tested this patch, so help from arch maintainers would be appreciated. Signed-off-by: John Stultz Cc: Mike Frysinger Cc: Andrew Morton LKML-Reference: <1267675049-12337-10-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- arch/blackfin/kernel/time-ts.c | 13 +++++++------ arch/blackfin/kernel/time.c | 39 ++++++--------------------------------- 2 files changed, 13 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 17c38c5b5b22..08dd3e83c187 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -348,9 +348,15 @@ static int __init bfin_clockevent_init(void) return 0; } -void __init time_init(void) +void read_persistent_clock(struct timespec *ts) { time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */ + ts->tv_sec = secs_since_1970; + ts->tv_nsec = 0; +} + +void __init time_init(void) +{ #ifdef CONFIG_RTC_DRV_BFIN /* [#2663] hack to filter junk RTC values that would cause @@ -363,11 +369,6 @@ void __init time_init(void) } #endif - /* Initialize xtime. From now on, xtime is updated with timer interrupts */ - xtime.tv_sec = secs_since_1970; - xtime.tv_nsec = 0; - set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); - bfin_cs_cycles_init(); bfin_cs_gptimer0_init(); bfin_clockevent_init(); diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c index 13c1ee3e6408..c9113619029f 100644 --- a/arch/blackfin/kernel/time.c +++ b/arch/blackfin/kernel/time.c @@ -112,11 +112,6 @@ u32 arch_gettimeoffset(void) } #endif -static inline int set_rtc_mmss(unsigned long nowtime) -{ - return 0; -} - /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick @@ -126,29 +121,8 @@ __attribute__((l1_text)) #endif irqreturn_t timer_interrupt(int irq, void *dummy) { - /* last time the cmos clock got updated */ - static long last_rtc_update; - write_seqlock(&xtime_lock); do_timer(1); - - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - if (ntp_synced() && - xtime.tv_sec > last_rtc_update + 660 && - (xtime.tv_nsec / NSEC_PER_USEC) >= - 500000 - ((unsigned)TICK_SIZE) / 2 - && (xtime.tv_nsec / NSEC_PER_USEC) <= - 500000 + ((unsigned)TICK_SIZE) / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* Do it again in 60s. */ - last_rtc_update = xtime.tv_sec - 600; - } write_sequnlock(&xtime_lock); #ifdef CONFIG_IPIPE @@ -161,10 +135,15 @@ irqreturn_t timer_interrupt(int irq, void *dummy) return IRQ_HANDLED; } -void __init time_init(void) +void read_persistent_clock(struct timespec *ts) { time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */ + ts->tv_sec = secs_since_1970; + ts->tv_nsec = 0; +} +void __init time_init(void) +{ #ifdef CONFIG_RTC_DRV_BFIN /* [#2663] hack to filter junk RTC values that would cause * userspace to have to deal with time values greater than @@ -176,11 +155,5 @@ void __init time_init(void) } #endif - /* Initialize xtime. From now on, xtime is updated with timer interrupts */ - xtime.tv_sec = secs_since_1970; - xtime.tv_nsec = 0; - - wall_to_monotonic.tv_sec = -xtime.tv_sec; - time_sched_init(timer_interrupt); } -- cgit v1.2.3-59-g8ed1b From 944694716d6ea3c274a73c830bf33e194bad4bcd Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:25 -0800 Subject: m32r: Convert m32r to use read/update_peristent_clock This patch converts the m32r architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. I have not built or tested this patch, so help from arch maintainers would be appreciated. Signed-off-by: John Stultz Cc: Hirokazu Takata Cc: Andrew Morton LKML-Reference: <1267675049-12337-11-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- arch/m32r/kernel/time.c | 47 +++++++---------------------------------------- 1 file changed, 7 insertions(+), 40 deletions(-) (limited to 'arch') diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c index 9cedcef11575..bda86820bffd 100644 --- a/arch/m32r/kernel/time.c +++ b/arch/m32r/kernel/time.c @@ -105,24 +105,6 @@ u32 arch_gettimeoffset(void) return elapsed_time * 1000; } -/* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be - * called 500 ms after the second nowtime has started, because when - * nowtime is written into the registers of the CMOS clock, it will - * jump to the next second precisely 500 ms later. Check the Motorola - * MC146818A or Dallas DS12887 data sheet for details. - * - * BUG: This routine does not handle hour overflow properly; it just - * sets the minutes. Usually you won't notice until after reboot! - */ -static inline int set_rtc_mmss(unsigned long nowtime) -{ - return 0; -} - -/* last time the cmos clock got updated */ -static long last_rtc_update = 0; - /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick @@ -138,23 +120,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - write_seqlock(&xtime_lock); - if (ntp_synced() - && xtime.tv_sec > last_rtc_update + 660 - && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2 - && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned)TICK_SIZE) / 2) - { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else /* do it again in 60 s */ - last_rtc_update = xtime.tv_sec - 600; - } - write_sequnlock(&xtime_lock); /* As we return to user mode fire off the other CPU schedulers.. this is basically because we don't yet share IRQ's around. This message is rigged to be safe on the 386 - basically it's @@ -174,7 +139,7 @@ static struct irqaction irq0 = { .name = "MFT2", }; -void __init time_init(void) +void read_persistent_clock(struct timespec *ts) { unsigned int epoch, year, mon, day, hour, min, sec; @@ -194,11 +159,13 @@ void __init time_init(void) epoch = 1952; year += epoch; - xtime.tv_sec = mktime(year, mon, day, hour, min, sec); - xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); - set_normalized_timespec(&wall_to_monotonic, - -xtime.tv_sec, -xtime.tv_nsec); + ts->tv_sec = mktime(year, mon, day, hour, min, sec); + ts->tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); +} + +void __init time_init(void) +{ #if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \ || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \ || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104) -- cgit v1.2.3-59-g8ed1b From ffbcad49e79cd82428010b44a87401446ea7f370 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:26 -0800 Subject: m68k: Convert m68k to use read/update_persistent_clock This patch converts the m68k architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. I have not built or tested this patch, so help from arch maintainers would be appreciated. Signed-off-by: John Stultz Cc: Geert Uytterhoeven Cc: Andrew Morton LKML-Reference: <1267675049-12337-12-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- arch/m68k/kernel/time.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index 17dc2a31a7ca..4926b3856c15 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c @@ -73,21 +73,24 @@ static irqreturn_t timer_interrupt(int irq, void *dummy) return IRQ_HANDLED; } -void __init time_init(void) +void read_persistent_clock(struct timespec *ts) { struct rtc_time time; + ts->tv_sec = 0; + ts->tv_nsec = 0; if (mach_hwclk) { mach_hwclk(0, &time); if ((time.tm_year += 1900) < 1970) time.tm_year += 100; - xtime.tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday, + ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec); - xtime.tv_nsec = 0; } - wall_to_monotonic.tv_sec = -xtime.tv_sec; +} +void __init time_init(void) +{ mach_sched_init(timer_interrupt); } -- cgit v1.2.3-59-g8ed1b From 8eff8a5c1d3a1de7a2d173e0effc6cc9bcbb5177 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:28 -0800 Subject: cris: Convert cris to use read/update_persistent_clock This patch converts the cris architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. I have not built or tested this patch, so help from arch maintainers would be appreciated. Signed-off-by: John Stultz Cc: Mikael Starvik Cc: Jesper Nilsson Cc: Andrew Morton LKML-Reference: <1267675049-12337-14-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- arch/cris/Kconfig | 3 +++ arch/cris/arch-v10/kernel/time.c | 37 ++----------------------------------- arch/cris/arch-v32/kernel/time.c | 40 ++-------------------------------------- arch/cris/kernel/time.c | 20 +++++++++++--------- 4 files changed, 18 insertions(+), 82 deletions(-) (limited to 'arch') diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 059eac6abda1..e25bf4440b51 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -23,6 +23,9 @@ config RWSEM_XCHGADD_ALGORITHM config GENERIC_TIME def_bool y +config GENERIC_CMOS_UPDATE + def_bool y + config ARCH_USES_GETTIMEOFFSET def_bool y diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index 31ca1418d5a7..30adae594aef 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -26,7 +26,6 @@ /* it will make jiffies at 96 hz instead of 100 hz though */ #undef USE_CASCADE_TIMERS -extern void update_xtime_from_cmos(void); extern int set_rtc_mmss(unsigned long nowtime); extern int have_rtc; @@ -188,8 +187,6 @@ stop_watchdog(void) #endif } -/* last time the cmos clock got updated */ -static long last_rtc_update = 0; /* * timer_interrupt() needs to keep up the real-time clock, @@ -232,24 +229,6 @@ timer_interrupt(int irq, void *dev_id) do_timer(1); cris_do_profile(regs); /* Save profiling information */ - - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - * - * The division here is not time critical since it will run once in - * 11 minutes - */ - if (ntp_synced() && - xtime.tv_sec > last_rtc_update + 660 && - (xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 && - (xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ - } return IRQ_HANDLED; } @@ -274,22 +253,10 @@ time_init(void) */ loops_per_usec = 50; - if(RTC_INIT() < 0) { - /* no RTC, start at 1980 */ - xtime.tv_sec = 0; - xtime.tv_nsec = 0; + if(RTC_INIT() < 0) have_rtc = 0; - } else { - /* get the current time */ + else have_rtc = 1; - update_xtime_from_cmos(); - } - - /* - * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the - * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC). - */ - set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); /* Setup the etrax timers * Base frequency is 25000 hz, divider 250 -> 100 HZ diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c index b1920d8de403..1ee0e1010228 100644 --- a/arch/cris/arch-v32/kernel/time.c +++ b/arch/cris/arch-v32/kernel/time.c @@ -44,7 +44,6 @@ unsigned long timer_regs[NR_CPUS] = #endif }; -extern void update_xtime_from_cmos(void); extern int set_rtc_mmss(unsigned long nowtime); extern int have_rtc; @@ -198,9 +197,6 @@ handle_watchdog_bite(struct pt_regs* regs) #endif } -/* Last time the cmos clock got updated. */ -static long last_rtc_update = 0; - /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick. @@ -238,25 +234,6 @@ timer_interrupt(int irq, void *dev_id) /* Call the real timer interrupt handler */ do_timer(1); - - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - * - * The division here is not time critical since it will run once in - * 11 minutes - */ - if ((time_status & STA_UNSYNC) == 0 && - xtime.tv_sec > last_rtc_update + 660 && - (xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 && - (xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* Do it again in 60 s */ - last_rtc_update = xtime.tv_sec - 600; - } return IRQ_HANDLED; } @@ -309,23 +286,10 @@ time_init(void) */ loops_per_usec = 50; - if(RTC_INIT() < 0) { - /* No RTC, start at 1980 */ - xtime.tv_sec = 0; - xtime.tv_nsec = 0; + if(RTC_INIT() < 0) have_rtc = 0; - } else { - /* Get the current time */ + else have_rtc = 1; - update_xtime_from_cmos(); - } - - /* - * Initialize wall_to_monotonic such that adding it to - * xtime will yield zero, the tv_nsec field must be normalized - * (i.e., 0 <= nsec < NSEC_PER_SEC). - */ - set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); /* Start CPU local timer. */ cris_timer_init(); diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c index a05dd31f3efb..c72730d20ef6 100644 --- a/arch/cris/kernel/time.c +++ b/arch/cris/kernel/time.c @@ -98,6 +98,8 @@ unsigned long get_cmos_time(void) { unsigned int year, mon, day, hour, min, sec; + if(!have_rtc) + return 0; sec = CMOS_READ(RTC_SECONDS); min = CMOS_READ(RTC_MINUTES); @@ -119,19 +121,19 @@ get_cmos_time(void) return mktime(year, mon, day, hour, min, sec); } -/* update xtime from the CMOS settings. used when /dev/rtc gets a SET_TIME. - * TODO: this doesn't reset the fancy NTP phase stuff as do_settimeofday does. - */ -void -update_xtime_from_cmos(void) +int update_persistent_clock(struct timespec now) { - if(have_rtc) { - xtime.tv_sec = get_cmos_time(); - xtime.tv_nsec = 0; - } + return set_rtc_mmss(now.tv_sec); } +void read_persistent_clock(struct timespec *ts) +{ + ts->tv_sec = get_cmos_time(); + ts->tv_nsec = 0; +} + + extern void cris_profile_sample(struct pt_regs* regs); void -- cgit v1.2.3-59-g8ed1b From f5c9c9be267f73eda6a668ac81ddde56ed7fa793 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 3 Mar 2010 19:57:27 -0800 Subject: sparc: Convert sparc to use read/update_persistent_clock This patch converts the sparc architecture to use the generic read_persistent_clock and update_persistent_clock interfaces, reducing the amount of arch specific code we have to maintain, and allowing for further cleanups in the future. [ davem: compile fix: Here's a version that compiles, you have to get rid of the now unused variably last_rtc_update since we build with -Werror ] Signed-off-by: John Stultz Acked-by: David S. Miller Cc: Andrew Morton Cc: sparclinux@vger.kernel.org Signed-off-by: Thomas Gleixner --- arch/sparc/Kconfig | 2 +- arch/sparc/kernel/time_32.c | 18 +++++------------- 2 files changed, 6 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 4097f6a10860..0e8ec2ad8477 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -72,7 +72,7 @@ config ARCH_USES_GETTIMEOFFSET config GENERIC_CMOS_UPDATE bool - default y if SPARC64 + default y config GENERIC_CLOCKEVENTS bool diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 0d4c09b15efc..4453003032b5 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -78,6 +78,11 @@ __volatile__ unsigned int *master_l10_counter; u32 (*do_arch_gettimeoffset)(void); +int update_persistent_clock(struct timespec now) +{ + return set_rtc_mmss(now.tv_sec); +} + /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick @@ -87,9 +92,6 @@ u32 (*do_arch_gettimeoffset)(void); static irqreturn_t timer_interrupt(int dummy, void *dev_id) { - /* last time the cmos clock got updated */ - static long last_rtc_update; - #ifndef CONFIG_SMP profile_tick(CPU_PROFILING); #endif @@ -101,16 +103,6 @@ static irqreturn_t timer_interrupt(int dummy, void *dev_id) do_timer(1); - /* Determine when to update the Mostek clock. */ - if (ntp_synced() && - xtime.tv_sec > last_rtc_update + 660 && - (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && - (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ - } write_sequnlock(&xtime_lock); #ifndef CONFIG_SMP -- cgit v1.2.3-59-g8ed1b From 32cbd7dfce93382a70f155bf539871b4c55bed29 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Sat, 13 Mar 2010 16:28:42 +0800 Subject: crypto: aesni-intel - Fix CTR optimization build failure with gas 2.16.1 Andrew Morton reported that AES-NI CTR optimization failed to compile with gas 2.16.1, the error message is as follow: arch/x86/crypto/aesni-intel_asm.S: Assembler messages: arch/x86/crypto/aesni-intel_asm.S:752: Error: suffix or operands invalid for `movq' arch/x86/crypto/aesni-intel_asm.S:753: Error: suffix or operands invalid for `movq' To fix this, a gas macro is defined to assemble movq with 64bit general purpose registers and XMM registers. The macro will generate the raw .byte sequence for needed instructions. Reported-by: Andrew Morton Signed-off-by: Huang Ying Signed-off-by: Herbert Xu --- arch/x86/crypto/aesni-intel_asm.S | 4 +- arch/x86/include/asm/inst.h | 96 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index 822846a9eba9..ff16756a51c1 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S @@ -749,8 +749,8 @@ _aesni_inc_init: movaps IV, CTR PSHUFB_XMM BSWAP_MASK CTR mov $1, TCTR_LOW - movq TCTR_LOW, INC - movq CTR, TCTR_LOW + MOVQ_R64_XMM TCTR_LOW INC + MOVQ_R64_XMM CTR TCTR_LOW ret /* diff --git a/arch/x86/include/asm/inst.h b/arch/x86/include/asm/inst.h index 14cf526091f9..840a399701b2 100644 --- a/arch/x86/include/asm/inst.h +++ b/arch/x86/include/asm/inst.h @@ -7,7 +7,66 @@ #ifdef __ASSEMBLY__ +#define REG_NUM_INVALID 100 + +#define REG_TYPE_R64 0 +#define REG_TYPE_XMM 1 +#define REG_TYPE_INVALID 100 + + .macro R64_NUM opd r64 + \opd = REG_NUM_INVALID + .ifc \r64,%rax + \opd = 0 + .endif + .ifc \r64,%rcx + \opd = 1 + .endif + .ifc \r64,%rdx + \opd = 2 + .endif + .ifc \r64,%rbx + \opd = 3 + .endif + .ifc \r64,%rsp + \opd = 4 + .endif + .ifc \r64,%rbp + \opd = 5 + .endif + .ifc \r64,%rsi + \opd = 6 + .endif + .ifc \r64,%rdi + \opd = 7 + .endif + .ifc \r64,%r8 + \opd = 8 + .endif + .ifc \r64,%r9 + \opd = 9 + .endif + .ifc \r64,%r10 + \opd = 10 + .endif + .ifc \r64,%r11 + \opd = 11 + .endif + .ifc \r64,%r12 + \opd = 12 + .endif + .ifc \r64,%r13 + \opd = 13 + .endif + .ifc \r64,%r14 + \opd = 14 + .endif + .ifc \r64,%r15 + \opd = 15 + .endif + .endm + .macro XMM_NUM opd xmm + \opd = REG_NUM_INVALID .ifc \xmm,%xmm0 \opd = 0 .endif @@ -58,13 +117,25 @@ .endif .endm + .macro REG_TYPE type reg + R64_NUM reg_type_r64 \reg + XMM_NUM reg_type_xmm \reg + .if reg_type_r64 != REG_NUM_INVALID + \type = REG_TYPE_R64 + .elseif reg_type_xmm != REG_NUM_INVALID + \type = REG_TYPE_XMM + .else + \type = REG_TYPE_INVALID + .endif + .endm + .macro PFX_OPD_SIZE .byte 0x66 .endm - .macro PFX_REX opd1 opd2 - .if (\opd1 | \opd2) & 8 - .byte 0x40 | ((\opd1 & 8) >> 3) | ((\opd2 & 8) >> 1) + .macro PFX_REX opd1 opd2 W=0 + .if ((\opd1 | \opd2) & 8) || \W + .byte 0x40 | ((\opd1 & 8) >> 3) | ((\opd2 & 8) >> 1) | (\W << 3) .endif .endm @@ -145,6 +216,25 @@ .byte 0x0f, 0x38, 0xdf MODRM 0xc0 aesdeclast_opd1 aesdeclast_opd2 .endm + + .macro MOVQ_R64_XMM opd1 opd2 + REG_TYPE movq_r64_xmm_opd1_type \opd1 + .if movq_r64_xmm_opd1_type == REG_TYPE_XMM + XMM_NUM movq_r64_xmm_opd1 \opd1 + R64_NUM movq_r64_xmm_opd2 \opd2 + .else + R64_NUM movq_r64_xmm_opd1 \opd1 + XMM_NUM movq_r64_xmm_opd2 \opd2 + .endif + PFX_OPD_SIZE + PFX_REX movq_r64_xmm_opd1 movq_r64_xmm_opd2 1 + .if movq_r64_xmm_opd1_type == REG_TYPE_XMM + .byte 0x0f, 0x7e + .else + .byte 0x0f, 0x6e + .endif + MODRM 0xc0 movq_r64_xmm_opd1 movq_r64_xmm_opd2 + .endm #endif #endif -- cgit v1.2.3-59-g8ed1b From 8576e1971663ffdb6139041de97cdd2e1d4791cc Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 13 Mar 2010 11:11:16 +0300 Subject: x86, perf: Unmask LVTPC only if we have APIC supported Ingo reported: | | There's a build failure on -tip with the P4 driver, on UP 32-bit, if | PERF_EVENTS is enabled but UP_APIC is disabled: | | arch/x86/built-in.o: In function `p4_pmu_handle_irq': | perf_event.c:(.text+0xa756): undefined reference to `apic' | perf_event.c:(.text+0xa76e): undefined reference to `apic' | So we have to unmask LVTPC only if we're configured to have one. Reported-by: Ingo Molnar Signed-off-by: Cyrill Gorcunov CC: Lin Ming CC: Peter Zijlstra LKML-Reference: <20100313081116.GA5179@lenovo> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_p4.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 381f593e8297..ef861da1c8ab 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -365,8 +365,10 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) } if (handled) { +#ifdef CONFIG_X86_LOCAL_APIC /* p4 quirk: unmask it again */ apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); +#endif inc_irq_stat(apic_perf_irqs); } -- cgit v1.2.3-59-g8ed1b From e4495262826d1eabca3529fa6ac22394eb348132 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 15 Mar 2010 12:58:22 +0800 Subject: perf, x86: Enable not tagged retired instruction counting on P4s This should turn on instruction counting on P4s, which was missing in the first version of the new PMU driver. It's inaccurate for now, we still need dependant event to tag mops before we can count them precisely. The result is that the number of instruction may be lifted up. Signed-off-by: Cyrill Gorcunov Signed-off-by: Lin Ming Cc: Peter Zijlstra LKML-Reference: <1268629102.3355.11.camel@minggr.sh.intel.com> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event_p4.h | 8 ++++---- arch/x86/kernel/cpu/perf_event_p4.c | 8 +++----- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index 829f4711645f..b47b9e9ac13f 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h @@ -324,8 +324,8 @@ static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr) #define P4_SSE_INPUT_ASSIST P4_EVENT_PACK(0x34, 0x01) /* - * MSR_P4_FIRM_ESCR: 8, 9 - * MSR_P4_FIRM_ESCR: 10, 11 + * MSR_P4_FIRM_ESCR0: 8, 9 + * MSR_P4_FIRM_ESCR1: 10, 11 */ #define P4_PACKED_SP_UOP P4_EVENT_PACK(0x08, 0x01) @@ -462,8 +462,8 @@ static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr) #define P4_INSTR_RETIRED P4_EVENT_PACK(0x02, 0x04) /* - * MSR_P4_CRU_ESCR2: 12, 13, 16 - * MSR_P4_CRU_ESCR3: 14, 15, 17 + * MSR_P4_CRU_ESCR0: 12, 13, 16 + * MSR_P4_CRU_ESCR1: 14, 15, 17 */ #define P4_UOPS_RETIRED P4_EVENT_PACK(0x01, 0x04) diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index ef861da1c8ab..a11ce73a93c9 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -60,13 +60,11 @@ struct p4_event_template p4_templates[] = { [2] = { .opcode = P4_INSTR_RETIRED, .config = 0, - .dep = 0, /* needs front-end tagging */ + .dep = -1, /* needs front-end tagging */ .emask = P4_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSNTAG) | - P4_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSTAG) | - P4_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSNTAG) | - P4_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSTAG), - .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, + P4_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSNTAG), + .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, .cntr = { 12, 14 }, }, [3] = { -- cgit v1.2.3-59-g8ed1b From 1d199b1ad606ae8b88acebd295b101c4e1cf2a57 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 16 Mar 2010 01:05:02 +0100 Subject: perf: Fix unexported generic perf_arch_fetch_caller_regs perf_arch_fetch_caller_regs() is exported for the overriden x86 version, but not for the generic weak version. As a general rule, weak functions should not have their symbol exported in the same file they are defined. So let's export it on trace_event_perf.c as it is used by trace events only. This fixes: ERROR: ".perf_arch_fetch_caller_regs" [fs/xfs/xfs.ko] undefined! ERROR: ".perf_arch_fetch_caller_regs" [arch/powerpc/platforms/cell/spufs/spufs.ko] undefined! -v2: And also only build it if trace events are enabled. -v3: Fix changelog mistake Reported-by: Stephen Rothwell Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Xiao Guangrong Cc: Paul Mackerras LKML-Reference: <1268697902-9518-1-git-send-regression-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 3 ++- kernel/perf_event.c | 2 ++ kernel/trace/trace_event_perf.c | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 978d297170a1..0d3466cf7f57 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1695,6 +1695,7 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) return entry; } +#ifdef CONFIG_EVENT_TRACING void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) { regs->ip = ip; @@ -1706,4 +1707,4 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski regs->cs = __KERNEL_CS; local_save_flags(regs->flags); } -EXPORT_SYMBOL_GPL(perf_arch_fetch_caller_regs); +#endif diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 8bf61273c58b..455393e71cab 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -2790,10 +2790,12 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) return NULL; } +#ifdef CONFIG_EVENT_TRACING __weak void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) { } +#endif /* * Output diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 0709e4f75114..7d79a10c3cde 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -12,6 +12,8 @@ DEFINE_PER_CPU(struct pt_regs, perf_trace_regs); EXPORT_PER_CPU_SYMBOL_GPL(perf_trace_regs); +EXPORT_SYMBOL_GPL(perf_arch_fetch_caller_regs); + static char *perf_trace_buf; static char *perf_trace_buf_nmi; -- cgit v1.2.3-59-g8ed1b From 8ea7f544100844307072cae2f5fc108afdef999a Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Tue, 16 Mar 2010 10:12:36 +0800 Subject: x86, perf: Fix comments in Pentium-4 PMU definitions Reported-by: Cyrill Gorcunov Signed-off-by: Lin Ming Cc: Peter Zijlstra Cc: Mike Galbraith Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker LKML-Reference: <1268705556.3379.8.camel@minggr.sh.intel.com> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event_p4.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index b47b9e9ac13f..b842b3238e46 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h @@ -319,6 +319,7 @@ static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr) #define P4_BSQ_ACTIVE_ENTRIES P4_EVENT_PACK(0x06, 0x07) /* + * NOTE: no ESCR name in docs, it's guessed * MSR_P4_BSU_ESCR1: 2, 3 */ @@ -468,8 +469,8 @@ static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr) #define P4_UOPS_RETIRED P4_EVENT_PACK(0x01, 0x04) /* - * MSR_P4_CRU_ESCR2: 12, 13, 16 - * MSR_P4_CRU_ESCR3: 14, 15, 17 + * MSR_P4_CRU_ESCR0: 12, 13, 16 + * MSR_P4_CRU_ESCR1: 14, 15, 17 */ #define P4_UOP_TYPE P4_EVENT_PACK(0x02, 0x02) -- cgit v1.2.3-59-g8ed1b From 5cc718b9dad682329a60e73547c6e708faa5bbe4 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 15 Mar 2010 13:00:54 -0400 Subject: kprobes: Hide CONFIG_OPTPROBES and set if arch supports optimized kprobes Hide CONFIG_OPTPROBES and set if the arch supports optimized kprobes (IOW, HAVE_OPTPROBES=y), since this option doesn't change the major behavior of kprobes, and workarounds for minor changes are documented. Signed-off-by: Masami Hiramatsu Cc: systemtap Cc: DLE Cc: Dieter Ries Cc: Ananth N Mavinakayanahalli Cc: OGAWA Hirofumi Cc: Peter Zijlstra Cc: Mike Galbraith Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker LKML-Reference: <20100315170054.31593.3153.stgit@localhost6.localdomain6> Signed-off-by: Ingo Molnar --- Documentation/kprobes.txt | 10 ++-------- arch/Kconfig | 9 ++------- 2 files changed, 4 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt index 2f9115c0ae62..61c291cddf18 100644 --- a/Documentation/kprobes.txt +++ b/Documentation/kprobes.txt @@ -165,8 +165,8 @@ the user entry_handler invocation is also skipped. 1.4 How Does Jump Optimization Work? -If you configured your kernel with CONFIG_OPTPROBES=y (currently -this option is supported on x86/x86-64, non-preemptive kernel) and +If your kernel is built with CONFIG_OPTPROBES=y (currently this flag +is automatically set 'y' on x86/x86-64, non-preemptive kernel) and the "debug.kprobes_optimization" kernel parameter is set to 1 (see sysctl(8)), Kprobes tries to reduce probe-hit overhead by using a jump instruction instead of a breakpoint instruction at each probepoint. @@ -271,8 +271,6 @@ tweak the kernel's execution path, you need to suppress optimization, using one of the following techniques: - Specify an empty function for the kprobe's post_handler or break_handler. or -- Config CONFIG_OPTPROBES=n. - or - Execute 'sysctl -w debug.kprobes_optimization=n' 2. Architectures Supported @@ -307,10 +305,6 @@ it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO), so you can use "objdump -d -l vmlinux" to see the source-to-object code mapping. -If you want to reduce probing overhead, set "Kprobes jump optimization -support" (CONFIG_OPTPROBES) to "y". You can find this option under the -"Kprobes" line. - 4. API Reference The Kprobes API includes a "register" function and an "unregister" diff --git a/arch/Kconfig b/arch/Kconfig index e5eb1337a537..f06010fb4838 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -42,15 +42,10 @@ config KPROBES If in doubt, say "N". config OPTPROBES - bool "Kprobes jump optimization support (EXPERIMENTAL)" - default y - depends on KPROBES + def_bool y + depends on KPROBES && HAVE_OPTPROBES depends on !PREEMPT - depends on HAVE_OPTPROBES select KALLSYMS_ALL - help - This option will allow kprobes to optimize breakpoint to - a jump for reducing its overhead. config HAVE_EFFICIENT_UNALIGNED_ACCESS bool -- cgit v1.2.3-59-g8ed1b From 984763cb90d4b5444baa0c3e43feff7926bf1834 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 16 Mar 2010 17:07:33 +0100 Subject: perf, x86: Report error code that returned from x86_pmu.hw_config() If x86_pmu.hw_config() fails a fixed error code (-EOPNOTSUPP) is returned even if a different error was reported. This patch fixes this. Signed-off-by: Robert Richter Acked-by: Cyrill Gorcunov Acked-by: Lin Ming Cc: acme@redhat.com Cc: eranian@google.com Cc: gorcunov@openvz.org Cc: peterz@infradead.org Cc: fweisbec@gmail.com LKML-Reference: <20100316160733.GR1585@erda.amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 0d3466cf7f57..5dacf63f913e 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -472,8 +472,9 @@ static int __hw_perf_event_init(struct perf_event *event) hwc->last_tag = ~0ULL; /* Processor specifics */ - if (x86_pmu.hw_config(attr, hwc)) - return -EOPNOTSUPP; + err = x86_pmu.hw_config(attr, hwc); + if (err) + return err; if (!hwc->sample_period) { hwc->sample_period = x86_pmu.max_period; -- cgit v1.2.3-59-g8ed1b From b27ea29c6267889be255f2217fa7a6106e6a8b04 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 17 Mar 2010 12:49:10 +0100 Subject: perf/core, x86: Reduce number of CONFIG_X86_LOCAL_APIC macros The function reserve_pmc_hardware() and release_pmc_hardware() were hard to read. This patch improves readability of the code by removing most of the CONFIG_X86_LOCAL_APIC macros. Signed-off-by: Robert Richter Cc: Stephane Eranian Cc: Peter Zijlstra LKML-Reference: <1268826553-19518-2-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 5dacf63f913e..793e63f6c420 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -313,9 +313,10 @@ again: static atomic_t active_events; static DEFINE_MUTEX(pmc_reserve_mutex); +#ifdef CONFIG_X86_LOCAL_APIC + static bool reserve_pmc_hardware(void) { -#ifdef CONFIG_X86_LOCAL_APIC int i; if (nmi_watchdog == NMI_LOCAL_APIC) @@ -330,11 +331,9 @@ static bool reserve_pmc_hardware(void) if (!reserve_evntsel_nmi(x86_pmu.eventsel + i)) goto eventsel_fail; } -#endif return true; -#ifdef CONFIG_X86_LOCAL_APIC eventsel_fail: for (i--; i >= 0; i--) release_evntsel_nmi(x86_pmu.eventsel + i); @@ -349,12 +348,10 @@ perfctr_fail: enable_lapic_nmi_watchdog(); return false; -#endif } static void release_pmc_hardware(void) { -#ifdef CONFIG_X86_LOCAL_APIC int i; for (i = 0; i < x86_pmu.num_events; i++) { @@ -364,9 +361,15 @@ static void release_pmc_hardware(void) if (nmi_watchdog == NMI_LOCAL_APIC) enable_lapic_nmi_watchdog(); -#endif } +#else + +static bool reserve_pmc_hardware(void) { return true; } +static void release_pmc_hardware(void) {} + +#endif + static int reserve_ds_buffers(void); static void release_ds_buffers(void); -- cgit v1.2.3-59-g8ed1b From 10f1014d86fd4fe5087080d609b51183396c5e4c Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 17 Mar 2010 12:49:12 +0100 Subject: perf/core, x86: Remove cpu_hw_events.interrupts This member in the struct is not used anymore and can be removed. Signed-off-by: Robert Richter Cc: Stephane Eranian Cc: Peter Zijlstra LKML-Reference: <1268826553-19518-4-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 793e63f6c420..104292a58c2b 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -102,7 +102,6 @@ struct cpu_hw_events { */ struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */ unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; - unsigned long interrupts; int enabled; int n_events; -- cgit v1.2.3-59-g8ed1b From d6dc0b4ead6e8720096ecfa3d9e899b47ddbc8ed Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 17 Mar 2010 12:49:13 +0100 Subject: perf/core, x86: Remove duplicate perf_event_mask variable The same information is stored also in x86_pmu.intel_ctrl. This patch removes perf_event_mask and instead uses x86_pmu.intel_ctrl directly. Signed-off-by: Robert Richter Cc: Stephane Eranian Cc: Peter Zijlstra LKML-Reference: <1268826553-19518-5-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 104292a58c2b..c97d5b52d12a 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -75,8 +75,6 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) return len; } -static u64 perf_event_mask __read_mostly; - struct event_constraint { union { unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; @@ -1406,7 +1404,7 @@ void __init init_hw_perf_events(void) x86_pmu.num_events, X86_PMC_MAX_GENERIC); x86_pmu.num_events = X86_PMC_MAX_GENERIC; } - perf_event_mask = (1 << x86_pmu.num_events) - 1; + x86_pmu.intel_ctrl = (1 << x86_pmu.num_events) - 1; perf_max_events = x86_pmu.num_events; if (x86_pmu.num_events_fixed > X86_PMC_MAX_FIXED) { @@ -1415,9 +1413,8 @@ void __init init_hw_perf_events(void) x86_pmu.num_events_fixed = X86_PMC_MAX_FIXED; } - perf_event_mask |= + x86_pmu.intel_ctrl |= ((1LL << x86_pmu.num_events_fixed)-1) << X86_PMC_IDX_FIXED; - x86_pmu.intel_ctrl = perf_event_mask; perf_events_lapic_init(); register_die_notifier(&perf_event_nmi_notifier); @@ -1442,7 +1439,7 @@ void __init init_hw_perf_events(void) pr_info("... value mask: %016Lx\n", x86_pmu.event_mask); pr_info("... max period: %016Lx\n", x86_pmu.max_period); pr_info("... fixed-purpose events: %d\n", x86_pmu.num_events_fixed); - pr_info("... event mask: %016Lx\n", perf_event_mask); + pr_info("... event mask: %016Lx\n", x86_pmu.intel_ctrl); perf_cpu_notifier(x86_pmu_notifier); } -- cgit v1.2.3-59-g8ed1b From 2acebe9ecb2b77876e87a1480729cfb2db4570dd Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Wed, 17 Mar 2010 10:40:38 -0500 Subject: x86, UV: Delete unneeded boot messages SGI:UV: Delete extra boot messages that describe the system topology. These messages are no longer useful. Signed-off-by: Jack Steiner LKML-Reference: <20100317154038.GA29346@sgi.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/x2apic_uv_x.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 3740c8a4eae7..9a93b07fa141 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -736,9 +736,6 @@ void __init uv_system_init(void) uv_node_to_blade[nid] = blade; uv_cpu_to_blade[cpu] = blade; max_pnode = max(pnode, max_pnode); - - printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n", - cpu, apicid, pnode, nid, lcpu, blade); } /* Add blade/pnode info for nodes without cpus */ -- cgit v1.2.3-59-g8ed1b From d674cd1963129b70bc5f631c51fb30fb73213fb2 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 17 Mar 2010 13:37:00 +0300 Subject: x86, apic: Allow to use certain functions without APIC built-in support In case even if the kernel is configured so that no APIC support is built-in we still may allow to use certain apic functions as dummy calls. In particular we start using it in perf-events code. Note that this is not that same as NOOP apic driver (which is used if APIC support is present but no physical APIC is available), this is for the case when we don't have apic code compiled in at all. Signed-off-by: Cyrill Gorcunov Cc: H. Peter Anvin Cc: Yinghai Lu Cc: Yinghai Lu LKML-Reference: <20100317104356.011052632@openvz.org> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index b4ac2cdcb64f..1fa03e04ae44 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -373,6 +373,7 @@ extern atomic_t init_deasserted; extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip); #endif +#ifdef CONFIG_X86_LOCAL_APIC static inline u32 apic_read(u32 reg) { return apic->read(reg); @@ -403,10 +404,19 @@ static inline u32 safe_apic_wait_icr_idle(void) return apic->safe_wait_icr_idle(); } +#else /* CONFIG_X86_LOCAL_APIC */ + +static inline u32 apic_read(u32 reg) { return 0; } +static inline void apic_write(u32 reg, u32 val) { } +static inline u64 apic_icr_read(void) { return 0; } +static inline void apic_icr_write(u32 low, u32 high) { } +static inline void apic_wait_icr_idle(void) { } +static inline u32 safe_apic_wait_icr_idle(void) { return 0; } + +#endif /* CONFIG_X86_LOCAL_APIC */ static inline void ack_APIC_irq(void) { -#ifdef CONFIG_X86_LOCAL_APIC /* * ack_APIC_irq() actually gets compiled as a single instruction * ... yummie. @@ -414,7 +424,6 @@ static inline void ack_APIC_irq(void) /* Docs say use 0 for future compatibility */ apic_write(APIC_EOI, 0); -#endif } static inline unsigned default_get_apic_id(unsigned long x) -- cgit v1.2.3-59-g8ed1b From 7335f75e9ca166044e38a96abad422d8e6e364b5 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 17 Mar 2010 13:37:01 +0300 Subject: x86, perf: Use apic_write unconditionally Since apic_write() maps to a plain noop in the !CONFIG_X86_LOCAL_APIC case we're safe to remove this conditional compilation and clean up the code a bit. Signed-off-by: Cyrill Gorcunov Cc: fweisbec@gmail.com Cc: acme@redhat.com Cc: eranian@google.com Cc: peterz@infradead.org LKML-Reference: <20100317104356.232371479@openvz.org> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 4 ---- arch/x86/kernel/cpu/perf_event_p4.c | 2 -- 2 files changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index c97d5b52d12a..14eca80918dc 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1136,7 +1136,6 @@ void set_perf_event_pending(void) void perf_events_lapic_init(void) { -#ifdef CONFIG_X86_LOCAL_APIC if (!x86_pmu.apic || !x86_pmu_initialized()) return; @@ -1144,7 +1143,6 @@ void perf_events_lapic_init(void) * Always use NMI for PMU */ apic_write(APIC_LVTPC, APIC_DM_NMI); -#endif } static int __kprobes @@ -1168,9 +1166,7 @@ perf_event_nmi_handler(struct notifier_block *self, regs = args->regs; -#ifdef CONFIG_X86_LOCAL_APIC apic_write(APIC_LVTPC, APIC_DM_NMI); -#endif /* * Can't rely on the handled return value to say it was our NMI, two * events could trigger 'simultaneously' raising two back-to-back NMIs. diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index a11ce73a93c9..0367889b4ae0 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -363,10 +363,8 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) } if (handled) { -#ifdef CONFIG_X86_LOCAL_APIC /* p4 quirk: unmask it again */ apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); -#endif inc_irq_stat(apic_perf_irqs); } -- cgit v1.2.3-59-g8ed1b From f34edbc1cdb0f8f83d94e1d668dd6e41abf0defb Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 18 Mar 2010 18:33:07 +0800 Subject: perf, x86: Add a key to simplify template lookup in Pentium-4 PMU Currently, we use opcode(Event and Event-Selector) + emask to look up template in p4_templates. But cache events (L1-dcache-load-misses, LLC-load-misses, etc) use the same event(P4_REPLAY_EVENT) to do the counting, ie, they have the same opcode and emask. So we can not use current lookup mechanism to find the template for cache events. This patch introduces a "key", which is the index into p4_templates. The low 12 bits of CCCR are reserved, so we can hide the "key" in the low 12 bits of hwc->config. We extract the key from hwc->config and then quickly find the template. Signed-off-by: Lin Ming Reviewed-by: Cyrill Gorcunov Cc: Peter Zijlstra LKML-Reference: <1268908387.13901.127.camel@minggr.sh.intel.com> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event_p4.h | 5 ++- arch/x86/kernel/cpu/perf_event_p4.c | 86 ++++++++++++++---------------------- 2 files changed, 38 insertions(+), 53 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index b842b3238e46..7d3406a2773c 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h @@ -65,6 +65,7 @@ #define P4_CCCR_THREAD_SINGLE 0x00010000U #define P4_CCCR_THREAD_BOTH 0x00020000U #define P4_CCCR_THREAD_ANY 0x00030000U +#define P4_CCCR_RESERVED 0x00000fffU /* Non HT mask */ #define P4_CCCR_MASK \ @@ -116,7 +117,7 @@ #define p4_config_pack_escr(v) (((u64)(v)) << 32) #define p4_config_pack_cccr(v) (((u64)(v)) & 0xffffffffULL) #define p4_config_unpack_escr(v) (((u64)(v)) >> 32) -#define p4_config_unpack_cccr(v) (((u64)(v)) & 0xffffffffULL) +#define p4_config_unpack_cccr(v) (((u64)(v)) & 0xfffff000ULL) #define p4_config_unpack_emask(v) \ ({ \ @@ -126,6 +127,8 @@ t; \ }) +#define p4_config_unpack_key(v) (((u64)(v)) & P4_CCCR_RESERVED) + #define P4_CONFIG_HT_SHIFT 63 #define P4_CONFIG_HT (1ULL << P4_CONFIG_HT_SHIFT) diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 0367889b4ae0..3e97ed3904cc 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -18,6 +18,7 @@ struct p4_event_template { u32 opcode; /* ESCR event + CCCR selector */ u64 config; /* packed predefined bits */ int dep; /* upstream dependency event index */ + int key; /* index into p4_templates */ unsigned int emask; /* ESCR EventMask */ unsigned int escr_msr[2]; /* ESCR MSR for this event */ unsigned int cntr[2]; /* counter index (offset) */ @@ -39,38 +40,31 @@ static DEFINE_PER_CPU(struct p4_pmu_res, p4_pmu_config); */ struct p4_event_template p4_templates[] = { [0] = { - .opcode = P4_UOP_TYPE, - .config = 0, - .dep = -1, - .emask = - P4_EVENT_ATTR(P4_UOP_TYPE, TAGLOADS) | - P4_EVENT_ATTR(P4_UOP_TYPE, TAGSTORES), - .escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 }, - .cntr = { 16, 17 }, - }, - [1] = { .opcode = P4_GLOBAL_POWER_EVENTS, .config = 0, .dep = -1, + .key = 0, .emask = P4_EVENT_ATTR(P4_GLOBAL_POWER_EVENTS, RUNNING), .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, .cntr = { 0, 2 }, }, - [2] = { + [1] = { .opcode = P4_INSTR_RETIRED, .config = 0, .dep = -1, /* needs front-end tagging */ + .key = 1, .emask = P4_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSNTAG) | P4_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSNTAG), .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, .cntr = { 12, 14 }, }, - [3] = { + [2] = { .opcode = P4_BSQ_CACHE_REFERENCE, .config = 0, .dep = -1, + .key = 2, .emask = P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) | P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) | @@ -81,10 +75,11 @@ struct p4_event_template p4_templates[] = { .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 }, .cntr = { 0, 2 }, }, - [4] = { + [3] = { .opcode = P4_BSQ_CACHE_REFERENCE, .config = 0, .dep = -1, + .key = 3, .emask = P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) | P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) | @@ -92,10 +87,11 @@ struct p4_event_template p4_templates[] = { .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 }, .cntr = { 0, 3 }, }, - [5] = { + [4] = { .opcode = P4_RETIRED_BRANCH_TYPE, .config = 0, .dep = -1, + .key = 4, .emask = P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CONDITIONAL) | P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CALL) | @@ -104,48 +100,38 @@ struct p4_event_template p4_templates[] = { .escr_msr = { MSR_P4_TBPU_ESCR0, MSR_P4_TBPU_ESCR1 }, .cntr = { 4, 6 }, }, - [6] = { + [5] = { .opcode = P4_MISPRED_BRANCH_RETIRED, .config = 0, .dep = -1, + .key = 5, .emask = P4_EVENT_ATTR(P4_MISPRED_BRANCH_RETIRED, NBOGUS), .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, .cntr = { 12, 14 }, }, - [7] = { + [6] = { .opcode = P4_FSB_DATA_ACTIVITY, .config = p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE), .dep = -1, + .key = 6, .emask = P4_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_DRV) | P4_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_OWN), .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, .cntr = { 0, 2 }, }, -}; - -static struct p4_event_template *p4_event_map[PERF_COUNT_HW_MAX] = { - /* non-halted CPU clocks */ - [PERF_COUNT_HW_CPU_CYCLES] = &p4_templates[1], - - /* retired instructions: dep on tagging the FSB */ - [PERF_COUNT_HW_INSTRUCTIONS] = &p4_templates[2], - - /* cache hits */ - [PERF_COUNT_HW_CACHE_REFERENCES] = &p4_templates[3], - - /* cache misses */ - [PERF_COUNT_HW_CACHE_MISSES] = &p4_templates[4], - - /* branch instructions retired */ - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = &p4_templates[5], - - /* mispredicted branches retired */ - [PERF_COUNT_HW_BRANCH_MISSES] = &p4_templates[6], - - /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN): */ - [PERF_COUNT_HW_BUS_CYCLES] = &p4_templates[7], + [7] = { + .opcode = P4_UOP_TYPE, + .config = 0, + .dep = -1, + .key = 7, + .emask = + P4_EVENT_ATTR(P4_UOP_TYPE, TAGLOADS) | + P4_EVENT_ATTR(P4_UOP_TYPE, TAGSTORES), + .escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 }, + .cntr = { 16, 17 }, + }, }; static u64 p4_pmu_event_map(int hw_event) @@ -153,11 +139,11 @@ static u64 p4_pmu_event_map(int hw_event) struct p4_event_template *tpl; u64 config; - if (hw_event > ARRAY_SIZE(p4_event_map)) { + if (hw_event > ARRAY_SIZE(p4_templates)) { printk_once(KERN_ERR "PMU: Incorrect event index\n"); return 0; } - tpl = p4_event_map[hw_event]; + tpl = &p4_templates[hw_event]; /* * fill config up according to @@ -167,6 +153,7 @@ static u64 p4_pmu_event_map(int hw_event) config |= p4_config_pack_escr(P4_EVENT_UNPACK_EVENT(tpl->opcode) << P4_EVNTSEL_EVENT_SHIFT); config |= p4_config_pack_escr(tpl->emask << P4_EVNTSEL_EVENTMASK_SHIFT); config |= p4_config_pack_cccr(P4_EVENT_UNPACK_SELECTOR(tpl->opcode) << P4_CCCR_ESCR_SELECT_SHIFT); + config |= p4_config_pack_cccr(hw_event & P4_CCCR_RESERVED); /* on HT machine we need a special bit */ if (p4_ht_active() && p4_ht_thread(raw_smp_processor_id())) @@ -187,17 +174,12 @@ static inline int p4_pmu_emask_match(unsigned int dst, unsigned int src) static struct p4_event_template *p4_pmu_template_lookup(u64 config) { - u32 opcode = p4_config_unpack_opcode(config); - unsigned int emask = p4_config_unpack_emask(config); - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(p4_templates); i++) { - if (opcode == p4_templates[i].opcode && - p4_pmu_emask_match(emask, p4_templates[i].emask)) - return &p4_templates[i]; - } + int key = p4_config_unpack_key(config); - return NULL; + if (key < ARRAY_SIZE(p4_templates)) + return &p4_templates[key]; + else + return NULL; } /* @@ -564,7 +546,7 @@ static __initconst struct x86_pmu p4_pmu = { .perfctr = MSR_P4_BPU_PERFCTR0, .event_map = p4_pmu_event_map, .raw_event = p4_pmu_raw_event, - .max_events = ARRAY_SIZE(p4_event_map), + .max_events = ARRAY_SIZE(p4_templates), .get_event_constraints = x86_get_event_constraints, /* * IF HT disabled we may need to use all -- cgit v1.2.3-59-g8ed1b From cb7d6b5053e86598735d9af19930f5929f007b7f Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 18 Mar 2010 18:33:12 +0800 Subject: perf, x86: Add cache events for the Pentium-4 PMU Move the HT bit setting code from p4_pmu_event_map to p4_hw_config. So the cache events can get HT bit set correctly. Tested on my P4 desktop, below 6 cache events work: L1-dcache-load-misses LLC-load-misses dTLB-load-misses dTLB-store-misses iTLB-loads iTLB-load-misses Signed-off-by: Lin Ming Reviewed-by: Cyrill Gorcunov Cc: Peter Zijlstra LKML-Reference: <1268908392.13901.128.camel@minggr.sh.intel.com> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/msr-index.h | 2 + arch/x86/include/asm/perf_event_p4.h | 10 +++ arch/x86/kernel/cpu/perf_event_p4.c | 153 +++++++++++++++++++++++++++++++++-- 3 files changed, 159 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 1cd58cdbc03f..aef562c0a647 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -357,6 +357,8 @@ #define MSR_P4_U2L_ESCR0 0x000003b0 #define MSR_P4_U2L_ESCR1 0x000003b1 +#define MSR_P4_PEBS_MATRIX_VERT 0x000003f2 + /* Intel Core-based CPU performance counters */ #define MSR_CORE_PERF_FIXED_CTR0 0x00000309 #define MSR_CORE_PERF_FIXED_CTR1 0x0000030a diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index 7d3406a2773c..871249cf4d2b 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h @@ -708,4 +708,14 @@ enum P4_EVENTS_ATTR { P4_MAKE_EVENT_ATTR(P4_INSTR_COMPLETED, BOGUS, 1), }; +enum { + KEY_P4_L1D_OP_READ_RESULT_MISS, + KEY_P4_LL_OP_READ_RESULT_MISS, + KEY_P4_DTLB_OP_READ_RESULT_MISS, + KEY_P4_DTLB_OP_WRITE_RESULT_MISS, + KEY_P4_ITLB_OP_READ_RESULT_ACCESS, + KEY_P4_ITLB_OP_READ_RESULT_MISS, + KEY_P4_UOP_TYPE, +}; + #endif /* PERF_EVENT_P4_H */ diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 3e97ed3904cc..b7bf9911198c 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -19,6 +19,11 @@ struct p4_event_template { u64 config; /* packed predefined bits */ int dep; /* upstream dependency event index */ int key; /* index into p4_templates */ + u64 msr; /* + * the high 32 bits set into MSR_IA32_PEBS_ENABLE and + * the low 32 bits set into MSR_P4_PEBS_MATRIX_VERT + * for cache events + */ unsigned int emask; /* ESCR EventMask */ unsigned int escr_msr[2]; /* ESCR MSR for this event */ unsigned int cntr[2]; /* counter index (offset) */ @@ -31,6 +36,67 @@ struct p4_pmu_res { static DEFINE_PER_CPU(struct p4_pmu_res, p4_pmu_config); +#define P4_CACHE_EVENT_CONFIG(event, bit) \ + p4_config_pack_escr(P4_EVENT_UNPACK_EVENT(event) << P4_EVNTSEL_EVENT_SHIFT) | \ + p4_config_pack_escr((event##_##bit) << P4_EVNTSEL_EVENTMASK_SHIFT) | \ + p4_config_pack_cccr(P4_EVENT_UNPACK_SELECTOR(event) << P4_CCCR_ESCR_SELECT_SHIFT) + +static __initconst u64 p4_hw_cache_event_ids + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = +{ + [ C(L1D ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + /* 1stL_cache_load_miss_retired */ + [ C(RESULT_MISS) ] = P4_CACHE_EVENT_CONFIG(P4_REPLAY_EVENT, NBOGUS) + | KEY_P4_L1D_OP_READ_RESULT_MISS, + }, + }, + [ C(LL ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + /* 2ndL_cache_load_miss_retired */ + [ C(RESULT_MISS) ] = P4_CACHE_EVENT_CONFIG(P4_REPLAY_EVENT, NBOGUS) + | KEY_P4_LL_OP_READ_RESULT_MISS, + }, + }, + [ C(DTLB) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + /* DTLB_load_miss_retired */ + [ C(RESULT_MISS) ] = P4_CACHE_EVENT_CONFIG(P4_REPLAY_EVENT, NBOGUS) + | KEY_P4_DTLB_OP_READ_RESULT_MISS, + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + /* DTLB_store_miss_retired */ + [ C(RESULT_MISS) ] = P4_CACHE_EVENT_CONFIG(P4_REPLAY_EVENT, NBOGUS) + | KEY_P4_DTLB_OP_WRITE_RESULT_MISS, + }, + }, + [ C(ITLB) ] = { + [ C(OP_READ) ] = { + /* ITLB_reference.HIT */ + [ C(RESULT_ACCESS) ] = P4_CACHE_EVENT_CONFIG(P4_ITLB_REFERENCE, HIT) + | KEY_P4_ITLB_OP_READ_RESULT_ACCESS, + + /* ITLB_reference.MISS */ + [ C(RESULT_MISS) ] = P4_CACHE_EVENT_CONFIG(P4_ITLB_REFERENCE, MISS) + | KEY_P4_ITLB_OP_READ_RESULT_MISS, + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + }, +}; + /* * WARN: CCCR1 doesn't have a working enable bit so try to not * use it if possible @@ -121,11 +187,77 @@ struct p4_event_template p4_templates[] = { .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, .cntr = { 0, 2 }, }, - [7] = { + [KEY_P4_L1D_OP_READ_RESULT_MISS] = { + .opcode = P4_REPLAY_EVENT, + .config = 0, + .dep = -1, + .msr = (u64)(1 << 0 | 1 << 24) << 32 | (1 << 0), + .key = KEY_P4_L1D_OP_READ_RESULT_MISS, + .emask = + P4_EVENT_ATTR(P4_REPLAY_EVENT, NBOGUS), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR2 }, + .cntr = { 16, 17 }, + }, + [KEY_P4_LL_OP_READ_RESULT_MISS] = { + .opcode = P4_REPLAY_EVENT, + .config = 0, + .dep = -1, + .msr = (u64)(1 << 1 | 1 << 24) << 32 | (1 << 0), + .key = KEY_P4_LL_OP_READ_RESULT_MISS, + .emask = + P4_EVENT_ATTR(P4_REPLAY_EVENT, NBOGUS), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR2 }, + .cntr = { 16, 17 }, + }, + [KEY_P4_DTLB_OP_READ_RESULT_MISS] = { + .opcode = P4_REPLAY_EVENT, + .config = 0, + .dep = -1, + .msr = (u64)(1 << 2 | 1 << 24) << 32 | (1 << 0), + .key = KEY_P4_DTLB_OP_READ_RESULT_MISS, + .emask = + P4_EVENT_ATTR(P4_REPLAY_EVENT, NBOGUS), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR2 }, + .cntr = { 16, 17 }, + }, + [KEY_P4_DTLB_OP_WRITE_RESULT_MISS] = { + .opcode = P4_REPLAY_EVENT, + .config = 0, + .dep = -1, + .msr = (u64)(1 << 2 | 1 << 24) << 32 | (1 << 1), + .key = KEY_P4_DTLB_OP_WRITE_RESULT_MISS, + .emask = + P4_EVENT_ATTR(P4_REPLAY_EVENT, NBOGUS), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR2 }, + .cntr = { 16, 17 }, + }, + [KEY_P4_ITLB_OP_READ_RESULT_ACCESS] = { + .opcode = P4_ITLB_REFERENCE, + .config = 0, + .dep = -1, + .msr = 0, + .key = KEY_P4_ITLB_OP_READ_RESULT_ACCESS, + .emask = + P4_EVENT_ATTR(P4_ITLB_REFERENCE, HIT), + .escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 }, + .cntr = { 0, 2 }, + }, + [KEY_P4_ITLB_OP_READ_RESULT_MISS] = { + .opcode = P4_ITLB_REFERENCE, + .config = 0, + .dep = -1, + .msr = 0, + .key = KEY_P4_ITLB_OP_READ_RESULT_MISS, + .emask = + P4_EVENT_ATTR(P4_ITLB_REFERENCE, MISS), + .escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 }, + .cntr = { 0, 2 }, + }, + [KEY_P4_UOP_TYPE] = { .opcode = P4_UOP_TYPE, .config = 0, .dep = -1, - .key = 7, + .key = KEY_P4_UOP_TYPE, .emask = P4_EVENT_ATTR(P4_UOP_TYPE, TAGLOADS) | P4_EVENT_ATTR(P4_UOP_TYPE, TAGSTORES), @@ -155,10 +287,6 @@ static u64 p4_pmu_event_map(int hw_event) config |= p4_config_pack_cccr(P4_EVENT_UNPACK_SELECTOR(tpl->opcode) << P4_CCCR_ESCR_SELECT_SHIFT); config |= p4_config_pack_cccr(hw_event & P4_CCCR_RESERVED); - /* on HT machine we need a special bit */ - if (p4_ht_active() && p4_ht_thread(raw_smp_processor_id())) - config = p4_set_ht_bit(config); - return config; } @@ -211,6 +339,10 @@ static int p4_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc) /* Count user and OS events unless not requested to */ hwc->config |= p4_config_pack_escr(p4_default_escr_conf(cpu, attr->exclude_kernel, attr->exclude_user)); + /* on HT machine we need a special bit */ + if (p4_ht_active() && p4_ht_thread(cpu)) + hwc->config = p4_set_ht_bit(hwc->config); + return 0; } @@ -271,6 +403,12 @@ static void p4_pmu_enable_event(struct perf_event *event) pr_crit("%s: Wrong index: %d\n", __func__, hwc->idx); return; } + + if (tpl->msr) { + (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, tpl->msr >> 32); + (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, tpl->msr & 0xffffffff); + } + escr_base = (u64)tpl->escr_msr[thread]; /* @@ -577,6 +715,9 @@ static __init int p4_pmu_init(void) return -ENODEV; } + memcpy(hw_cache_event_ids, p4_hw_cache_event_ids, + sizeof(hw_cache_event_ids)); + pr_cont("Netburst events, "); x86_pmu = p4_pmu; -- cgit v1.2.3-59-g8ed1b From 4b24a88b35e15e04bd8f2c5dda65b5dc8ebca05f Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Wed, 17 Mar 2010 23:21:01 +0200 Subject: perf_events: Fix resource leak in x86 __hw_perf_event_init() If reserve_pmc_hardware() succeeds but reserve_ds_buffers() fails, then we need to release_pmc_hardware. It won't be done by the destroy() callback because we return before setting it in case of error. Signed-off-by: Stephane Eranian Cc: Cc: peterz@infradead.org Cc: paulus@samba.org Cc: davem@davemloft.net Cc: fweisbec@gmail.com Cc: robert.richter@amd.com Cc: perfmon2-devel@lists.sf.net LKML-Reference: <4ba1568b.15185e0a.182a.7802@mx.google.com> Signed-off-by: Ingo Molnar -- arch/x86/kernel/cpu/perf_event.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) --- arch/x86/kernel/cpu/perf_event.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 14eca80918dc..f571f514de2a 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -455,8 +455,11 @@ static int __hw_perf_event_init(struct perf_event *event) if (atomic_read(&active_events) == 0) { if (!reserve_pmc_hardware()) err = -EBUSY; - else + else { err = reserve_ds_buffers(); + if (err) + release_pmc_hardware(); + } } if (!err) atomic_inc(&active_events); -- cgit v1.2.3-59-g8ed1b From 5b00f40f90e7b17c11cf388680f43e8466b3666d Mon Sep 17 00:00:00 2001 From: San Mehat Date: Sat, 21 Nov 2009 09:22:14 -0800 Subject: msm: Add 'execute' datamover callback Based on a patch from Brent DeGraaf: "The datamover supports channels which can be shared amongst devices. As a result, the actual data transfer may occur some time after the request is queued up. Some devices such as mmc host controllers will timeout if a command is issued too far in advance of the actual transfer, so if dma to other devices on the same channel is already in progress or queued up, the added delay can cause pending transfers to fail before they start. This change extends the api to allow a user callback to be invoked just before the actual transfer takes place, thus allowing actions directly associated with the dma transfer, such as device commands, to be invoked with precise timing. Without this mechanism, there is no way for a driver to realize this timing. Also adds a user pointer to the command structure for use by the caller to reference information that may be needed by the callback routine for proper identification and processing associated with that specific request. This change is necessary to fix problems associated with excessive command timeouts and race conditions in the mmc driver." This patch also fixes all the callers of msm_dmov_enqueue_cmd() to ensure their callback function is NULL. Signed-off-by: San Mehat Cc: Brent DeGraaf Cc: Brian Swetland Signed-off-by: Daniel Walker --- arch/arm/mach-msm/dma.c | 5 +++++ arch/arm/mach-msm/include/mach/dma.h | 2 ++ drivers/mmc/host/msm_sdcc.c | 1 + 3 files changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index f5420f9585c5..8df798ac70c7 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c @@ -63,6 +63,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) writel(DMOV_CONFIG_IRQ_EN, DMOV_CONFIG(id)); } #endif + if (cmd->execute_func) + cmd->execute_func(cmd); PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status); list_add_tail(&cmd->list, &active_commands[id]); if (!channel_active) @@ -108,6 +110,7 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) cmd.dmov_cmd.cmdptr = cmdptr; cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func; + cmd.dmov_cmd.execute_func = NULL; cmd.id = id; init_completion(&cmd.complete); @@ -210,6 +213,8 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) cmd = list_entry(ready_commands[id].next, typeof(*cmd), list); list_del(&cmd->list); list_add_tail(&cmd->list, &active_commands[id]); + if (cmd->execute_func) + cmd->execute_func(cmd); PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id); writel(cmd->cmdptr, DMOV_CMD_PTR(id)); } diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h index 5ab5bdffab07..78b0ffdf27e8 100644 --- a/arch/arm/mach-msm/include/mach/dma.h +++ b/arch/arm/mach-msm/include/mach/dma.h @@ -28,6 +28,8 @@ struct msm_dmov_cmd { void (*complete_func)(struct msm_dmov_cmd *cmd, unsigned int result, struct msm_dmov_errdata *err); + void (*execute_func)(struct msm_dmov_cmd *cmd); + void *data; }; void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd); diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index f4f7883271f0..02bec7c739e0 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -299,6 +299,7 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data) host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(host->dma.cmdptr_busaddr); host->dma.hdr.complete_func = msmsdcc_dma_complete_func; + host->dma.hdr.execute_func = NULL; return 0; } -- cgit v1.2.3-59-g8ed1b From 9c8c6bad3137112d2c7bf3d215b736ee4215fa74 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Fri, 19 Mar 2010 00:12:56 +0300 Subject: x86, perf: Fix few cosmetic dabs for P4 pmu (comments and constantify) - A few ESCR have escaped fixing at previous attempt. - p4_escr_map is read only, make it const. Nothing serious. Signed-off-by: Cyrill Gorcunov Cc: Lin Ming LKML-Reference: <20100318211256.GH5062@lenovo> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event_p4.h | 4 ++-- arch/x86/kernel/cpu/perf_event_p4.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index 871249cf4d2b..2a1a57f71539 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h @@ -401,13 +401,13 @@ static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr) #define P4_RETIRED_MISPRED_BRANCH_TYPE P4_EVENT_PACK(0x05, 0x02) /* * MSR_P4_TBPU_ESCR0: 4, 5 - * MSR_P4_TBPU_ESCR0: 6, 7 + * MSR_P4_TBPU_ESCR1: 6, 7 */ #define P4_RETIRED_BRANCH_TYPE P4_EVENT_PACK(0x04, 0x02) /* * MSR_P4_TBPU_ESCR0: 4, 5 - * MSR_P4_TBPU_ESCR0: 6, 7 + * MSR_P4_TBPU_ESCR1: 6, 7 */ #define P4_RESOURCE_STALL P4_EVENT_PACK(0x01, 0x01) diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index b7bf9911198c..b8a811ab7609 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -545,7 +545,7 @@ static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu) } /* ESCRs are not sequential in memory so we need a map */ -static unsigned int p4_escr_map[ARCH_P4_TOTAL_ESCR] = { +static const unsigned int p4_escr_map[ARCH_P4_TOTAL_ESCR] = { MSR_P4_ALF_ESCR0, /* 0 */ MSR_P4_ALF_ESCR1, /* 1 */ MSR_P4_BPU_ESCR0, /* 2 */ -- cgit v1.2.3-59-g8ed1b From 40b7e05e17eef31ff30fe08dfc2424ef653a792c Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Fri, 19 Mar 2010 15:28:58 +0800 Subject: perf, x86: Fix key indexing in Pentium-4 PMU Index 0-6 in p4_templates are reserved for common hardware events. So p4_templates is arranged as below: 0 - 6: common hardware events 7 - N: cache events N+1 - ...: other raw events Reported-by: Cyrill Gorcunov Signed-off-by: Lin Ming Acked-by: Cyrill Gorcunov Cc: Peter Zijlstra LKML-Reference: <1268983738.13901.142.camel@minggr.sh.intel.com> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event_p4.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index 2a1a57f71539..facf96186b26 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h @@ -709,7 +709,7 @@ enum P4_EVENTS_ATTR { }; enum { - KEY_P4_L1D_OP_READ_RESULT_MISS, + KEY_P4_L1D_OP_READ_RESULT_MISS = PERF_COUNT_HW_MAX, KEY_P4_LL_OP_READ_RESULT_MISS, KEY_P4_DTLB_OP_READ_RESULT_MISS, KEY_P4_DTLB_OP_WRITE_RESULT_MISS, -- cgit v1.2.3-59-g8ed1b From 0deac0bf66110fe70507c5dcec661c9e85fa07ca Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 15 Mar 2010 20:36:22 +0000 Subject: ARM: Arrange for COMMON_CLKDEV to select HAVE_CLK If support for COMMON_CLKDEV is enabled, we have CLK support. Signed-off-by: Russell King --- arch/arm/Kconfig | 14 -------------- arch/arm/common/Kconfig | 1 + 2 files changed, 1 insertion(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5408bf1bf43..bcaa8c83e522 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -238,7 +238,6 @@ config ARCH_INTEGRATOR bool "ARM Ltd. Integrator family" select ARM_AMBA select ARCH_HAS_CPUFREQ - select HAVE_CLK select COMMON_CLKDEV select ICST525 help @@ -247,7 +246,6 @@ config ARCH_INTEGRATOR config ARCH_REALVIEW bool "ARM Ltd. RealView family" select ARM_AMBA - select HAVE_CLK select COMMON_CLKDEV select ICST307 select GENERIC_TIME @@ -260,7 +258,6 @@ config ARCH_VERSATILE bool "ARM Ltd. Versatile family" select ARM_AMBA select ARM_VIC - select HAVE_CLK select COMMON_CLKDEV select ICST307 select GENERIC_TIME @@ -321,7 +318,6 @@ config ARCH_EP93XX select ARM_AMBA select ARM_VIC select GENERIC_GPIO - select HAVE_CLK select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_HOLES_MEMORYMODEL @@ -341,7 +337,6 @@ config ARCH_MXC select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB - select HAVE_CLK select COMMON_CLKDEV help Support for Freescale MXC/iMX-based family of processors @@ -349,7 +344,6 @@ config ARCH_MXC config ARCH_STMP3XXX bool "Freescale STMP3xxx" select CPU_ARM926T - select HAVE_CLK select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select GENERIC_TIME @@ -516,7 +510,6 @@ config ARCH_MMP depends on MMU select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB - select HAVE_CLK select COMMON_CLKDEV select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -552,7 +545,6 @@ config ARCH_W90X900 select CPU_ARM926T select ARCH_REQUIRE_GPIOLIB select GENERIC_GPIO - select HAVE_CLK select COMMON_CLKDEV select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -568,7 +560,6 @@ config ARCH_W90X900 config ARCH_NUC93X bool "Nuvoton NUC93X CPU" select CPU_ARM926T - select HAVE_CLK select COMMON_CLKDEV help Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a @@ -577,7 +568,6 @@ config ARCH_NUC93X config ARCH_PNX4008 bool "Philips Nexperia PNX4008 Mobile" select CPU_ARM926T - select HAVE_CLK select COMMON_CLKDEV help This enables support for Philips PNX4008 mobile platform. @@ -588,7 +578,6 @@ config ARCH_PXA select ARCH_MTD_XIP select ARCH_HAS_CPUFREQ select GENERIC_GPIO - select HAVE_CLK select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select GENERIC_TIME @@ -743,7 +732,6 @@ config ARCH_U300 select ARM_VIC select GENERIC_TIME select GENERIC_CLOCKEVENTS - select HAVE_CLK select COMMON_CLKDEV select GENERIC_GPIO help @@ -764,7 +752,6 @@ config ARCH_NOMADIK select ARM_AMBA select ARM_VIC select CPU_ARM926T - select HAVE_CLK select COMMON_CLKDEV select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -780,7 +767,6 @@ config ARCH_DAVINCI select GENERIC_CLOCKEVENTS select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB - select HAVE_CLK select ZONE_DMA select HAVE_IDE select COMMON_CLKDEV diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 4efbb9df0444..b64bb78d784c 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -40,3 +40,4 @@ config SHARP_SCOOP config COMMON_CLKDEV bool + select HAVE_CLK -- cgit v1.2.3-59-g8ed1b From e4bf5becccf4685754c4d8e4485bb2ff7d28147f Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Tue, 9 Mar 2010 11:54:30 +0100 Subject: ARM: 5979/1: CLKDEV: return from clk_find as soon as we get maching clk clk_find function looks for clock with matching dev_id and con_id. We should return from clk_find as soon as we get a clock with matching dev_id and con_id. This can be done by comparing variable "match" with 3. Acked-by: Uwe Kleine-Konig Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/common/clkdev.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/clkdev.c b/arch/arm/common/clkdev.c index 6416d5b5020d..4f8390dd6cac 100644 --- a/arch/arm/common/clkdev.c +++ b/arch/arm/common/clkdev.c @@ -52,12 +52,13 @@ static struct clk *clk_find(const char *dev_id, const char *con_id) continue; match += 1; } - if (match == 0) - continue; if (match > best) { clk = p->clk; - best = match; + if (match != 3) + best = match; + else + break; } } return clk; -- cgit v1.2.3-59-g8ed1b From 3a5e854e09b77c49c8030c7dfd3a3f506571a89a Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 3 Mar 2010 04:46:58 +0100 Subject: ARM: 5969/1: nomadik: move gpio to plat-nomadik Move the Nomadik GPIO driver to plat-nomadik so that it can also be used on the Ux500 platform. The mach-nomadik include/mach/gpio.h is replaced by one that includes the one now in plat-nomadik, so that code doesn't need to include the one in plat specifically, and can instead use as usual. Acked-by: Alessandro Rubini Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-nomadik/Kconfig | 1 + arch/arm/mach-nomadik/Makefile | 2 +- arch/arm/mach-nomadik/gpio.c | 396 ------------------------------ arch/arm/mach-nomadik/include/mach/gpio.h | 67 +---- arch/arm/plat-nomadik/Kconfig | 5 + arch/arm/plat-nomadik/Makefile | 1 + arch/arm/plat-nomadik/gpio.c | 396 ++++++++++++++++++++++++++++++ arch/arm/plat-nomadik/include/plat/gpio.h | 71 ++++++ 8 files changed, 476 insertions(+), 463 deletions(-) delete mode 100644 arch/arm/mach-nomadik/gpio.c create mode 100644 arch/arm/plat-nomadik/gpio.c create mode 100644 arch/arm/plat-nomadik/include/plat/gpio.h (limited to 'arch') diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig index 3c5e0f522e9c..71f3ea623974 100644 --- a/arch/arm/mach-nomadik/Kconfig +++ b/arch/arm/mach-nomadik/Kconfig @@ -6,6 +6,7 @@ config MACH_NOMADIK_8815NHK bool "ST 8815 Nomadik Hardware Kit (evaluation board)" select NOMADIK_8815 select HAS_MTU + select NOMADIK_GPIO endmenu diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile index 36f67fb207d2..a6bbd1a7b4e7 100644 --- a/arch/arm/mach-nomadik/Makefile +++ b/arch/arm/mach-nomadik/Makefile @@ -7,7 +7,7 @@ # Object file lists. -obj-y += clock.o gpio.o +obj-y += clock.o # Cpu revision obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c deleted file mode 100644 index 9a09b2791e03..000000000000 --- a/arch/arm/mach-nomadik/gpio.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Generic GPIO driver for logic cells found in the Nomadik SoC - * - * Copyright (C) 2008,2009 STMicroelectronics - * Copyright (C) 2009 Alessandro Rubini - * Rewritten based on work by Prafulla WADASKAR - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* - * The GPIO module in the Nomadik family of Systems-on-Chip is an - * AMBA device, managing 32 pins and alternate functions. The logic block - * is currently only used in the Nomadik. - * - * Symbols in this file are called "nmk_gpio" for "nomadik gpio" - */ - -#define NMK_GPIO_PER_CHIP 32 -struct nmk_gpio_chip { - struct gpio_chip chip; - void __iomem *addr; - unsigned int parent_irq; - spinlock_t *lock; - /* Keep track of configured edges */ - u32 edge_rising; - u32 edge_falling; -}; - -/* Mode functions */ -int nmk_gpio_set_mode(int gpio, int gpio_mode) -{ - struct nmk_gpio_chip *nmk_chip; - unsigned long flags; - u32 afunc, bfunc, bit; - - nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); - if (!nmk_chip) - return -EINVAL; - - bit = 1 << (gpio - nmk_chip->chip.base); - - spin_lock_irqsave(&nmk_chip->lock, flags); - afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit; - bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit; - if (gpio_mode & NMK_GPIO_ALT_A) - afunc |= bit; - if (gpio_mode & NMK_GPIO_ALT_B) - bfunc |= bit; - writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA); - writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB); - spin_unlock_irqrestore(&nmk_chip->lock, flags); - - return 0; -} -EXPORT_SYMBOL(nmk_gpio_set_mode); - -int nmk_gpio_get_mode(int gpio) -{ - struct nmk_gpio_chip *nmk_chip; - u32 afunc, bfunc, bit; - - nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); - if (!nmk_chip) - return -EINVAL; - - bit = 1 << (gpio - nmk_chip->chip.base); - - afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit; - bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit; - - return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0); -} -EXPORT_SYMBOL(nmk_gpio_get_mode); - - -/* IRQ functions */ -static inline int nmk_gpio_get_bitmask(int gpio) -{ - return 1 << (gpio % 32); -} - -static void nmk_gpio_irq_ack(unsigned int irq) -{ - int gpio; - struct nmk_gpio_chip *nmk_chip; - - gpio = NOMADIK_IRQ_TO_GPIO(irq); - nmk_chip = get_irq_chip_data(irq); - if (!nmk_chip) - return; - writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); -} - -static void nmk_gpio_irq_mask(unsigned int irq) -{ - int gpio; - struct nmk_gpio_chip *nmk_chip; - unsigned long flags; - u32 bitmask, reg; - - gpio = NOMADIK_IRQ_TO_GPIO(irq); - nmk_chip = get_irq_chip_data(irq); - bitmask = nmk_gpio_get_bitmask(gpio); - if (!nmk_chip) - return; - - /* we must individually clear the two edges */ - spin_lock_irqsave(&nmk_chip->lock, flags); - if (nmk_chip->edge_rising & bitmask) { - reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); - reg &= ~bitmask; - writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC); - } - if (nmk_chip->edge_falling & bitmask) { - reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); - reg &= ~bitmask; - writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC); - } - spin_unlock_irqrestore(&nmk_chip->lock, flags); -}; - -static void nmk_gpio_irq_unmask(unsigned int irq) -{ - int gpio; - struct nmk_gpio_chip *nmk_chip; - unsigned long flags; - u32 bitmask, reg; - - gpio = NOMADIK_IRQ_TO_GPIO(irq); - nmk_chip = get_irq_chip_data(irq); - bitmask = nmk_gpio_get_bitmask(gpio); - if (!nmk_chip) - return; - - /* we must individually set the two edges */ - spin_lock_irqsave(&nmk_chip->lock, flags); - if (nmk_chip->edge_rising & bitmask) { - reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); - reg |= bitmask; - writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC); - } - if (nmk_chip->edge_falling & bitmask) { - reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); - reg |= bitmask; - writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC); - } - spin_unlock_irqrestore(&nmk_chip->lock, flags); -} - -static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) -{ - int gpio; - struct nmk_gpio_chip *nmk_chip; - unsigned long flags; - u32 bitmask; - - gpio = NOMADIK_IRQ_TO_GPIO(irq); - nmk_chip = get_irq_chip_data(irq); - bitmask = nmk_gpio_get_bitmask(gpio); - if (!nmk_chip) - return -EINVAL; - - if (type & IRQ_TYPE_LEVEL_HIGH) - return -EINVAL; - if (type & IRQ_TYPE_LEVEL_LOW) - return -EINVAL; - - spin_lock_irqsave(&nmk_chip->lock, flags); - - nmk_chip->edge_rising &= ~bitmask; - if (type & IRQ_TYPE_EDGE_RISING) - nmk_chip->edge_rising |= bitmask; - writel(nmk_chip->edge_rising, nmk_chip->addr + NMK_GPIO_RIMSC); - - nmk_chip->edge_falling &= ~bitmask; - if (type & IRQ_TYPE_EDGE_FALLING) - nmk_chip->edge_falling |= bitmask; - writel(nmk_chip->edge_falling, nmk_chip->addr + NMK_GPIO_FIMSC); - - spin_unlock_irqrestore(&nmk_chip->lock, flags); - - nmk_gpio_irq_unmask(irq); - - return 0; -} - -static struct irq_chip nmk_gpio_irq_chip = { - .name = "Nomadik-GPIO", - .ack = nmk_gpio_irq_ack, - .mask = nmk_gpio_irq_mask, - .unmask = nmk_gpio_irq_unmask, - .set_type = nmk_gpio_irq_set_type, -}; - -static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) -{ - struct nmk_gpio_chip *nmk_chip; - struct irq_chip *host_chip; - unsigned int gpio_irq; - u32 pending; - unsigned int first_irq; - - nmk_chip = get_irq_data(irq); - first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); - while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) { - gpio_irq = first_irq + __ffs(pending); - generic_handle_irq(gpio_irq); - } - if (0) {/* don't ack parent irq, as ack == disable */ - host_chip = get_irq_chip(irq); - host_chip->ack(irq); - } -} - -static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) -{ - unsigned int first_irq; - int i; - - first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); - for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) { - set_irq_chip(i, &nmk_gpio_irq_chip); - set_irq_handler(i, handle_edge_irq); - set_irq_flags(i, IRQF_VALID); - set_irq_chip_data(i, nmk_chip); - } - set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); - set_irq_data(nmk_chip->parent_irq, nmk_chip); - return 0; -} - -/* I/O Functions */ -static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset) -{ - struct nmk_gpio_chip *nmk_chip = - container_of(chip, struct nmk_gpio_chip, chip); - - writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); - return 0; -} - -static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, - int val) -{ - struct nmk_gpio_chip *nmk_chip = - container_of(chip, struct nmk_gpio_chip, chip); - - writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); - return 0; -} - -static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset) -{ - struct nmk_gpio_chip *nmk_chip = - container_of(chip, struct nmk_gpio_chip, chip); - u32 bit = 1 << offset; - - return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0; -} - -static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, - int val) -{ - struct nmk_gpio_chip *nmk_chip = - container_of(chip, struct nmk_gpio_chip, chip); - u32 bit = 1 << offset; - - if (val) - writel(bit, nmk_chip->addr + NMK_GPIO_DATS); - else - writel(bit, nmk_chip->addr + NMK_GPIO_DATC); -} - -/* This structure is replicated for each GPIO block allocated at probe time */ -static struct gpio_chip nmk_gpio_template = { - .direction_input = nmk_gpio_make_input, - .get = nmk_gpio_get_input, - .direction_output = nmk_gpio_make_output, - .set = nmk_gpio_set_output, - .ngpio = NMK_GPIO_PER_CHIP, - .can_sleep = 0, -}; - -static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id) -{ - struct nmk_gpio_platform_data *pdata; - struct nmk_gpio_chip *nmk_chip; - struct gpio_chip *chip; - int ret; - - pdata = dev->dev.platform_data; - ret = amba_request_regions(dev, pdata->name); - if (ret) - return ret; - - nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); - if (!nmk_chip) { - ret = -ENOMEM; - goto out_amba; - } - /* - * The virt address in nmk_chip->addr is in the nomadik register space, - * so we can simply convert the resource address, without remapping - */ - nmk_chip->addr = io_p2v(dev->res.start); - nmk_chip->chip = nmk_gpio_template; - nmk_chip->parent_irq = pdata->parent_irq; - - chip = &nmk_chip->chip; - chip->base = pdata->first_gpio; - chip->label = pdata->name; - chip->dev = &dev->dev; - chip->owner = THIS_MODULE; - - ret = gpiochip_add(&nmk_chip->chip); - if (ret) - goto out_free; - - amba_set_drvdata(dev, nmk_chip); - - nmk_gpio_init_irq(nmk_chip); - - dev_info(&dev->dev, "Bits %i-%i at address %p\n", - nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr); - return 0; - - out_free: - kfree(nmk_chip); - out_amba: - amba_release_regions(dev); - dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret, - pdata->first_gpio, pdata->first_gpio+31); - return ret; -} - -static int nmk_gpio_remove(struct amba_device *dev) -{ - struct nmk_gpio_chip *nmk_chip; - - nmk_chip = amba_get_drvdata(dev); - gpiochip_remove(&nmk_chip->chip); - kfree(nmk_chip); - amba_release_regions(dev); - return 0; -} - - -/* We have 0x1f080060 and 0x1f180060, accept both using the mask */ -static struct amba_id nmk_gpio_ids[] = { - { - .id = 0x1f080060, - .mask = 0xffefffff, - }, - {0, 0}, -}; - -static struct amba_driver nmk_gpio_driver = { - .drv = { - .owner = THIS_MODULE, - .name = "gpio", - }, - .probe = nmk_gpio_probe, - .remove = nmk_gpio_remove, - .suspend = NULL, /* to be done */ - .resume = NULL, - .id_table = nmk_gpio_ids, -}; - -static int __init nmk_gpio_init(void) -{ - return amba_driver_register(&nmk_gpio_driver); -} - -arch_initcall(nmk_gpio_init); - -MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini"); -MODULE_DESCRIPTION("Nomadik GPIO Driver"); -MODULE_LICENSE("GPL"); - - diff --git a/arch/arm/mach-nomadik/include/mach/gpio.h b/arch/arm/mach-nomadik/include/mach/gpio.h index 61577c9f9a7d..7a81a0420343 100644 --- a/arch/arm/mach-nomadik/include/mach/gpio.h +++ b/arch/arm/mach-nomadik/include/mach/gpio.h @@ -1,71 +1,6 @@ -/* - * Structures and registers for GPIO access in the Nomadik SoC - * - * Copyright (C) 2008 STMicroelectronics - * Author: Prafulla WADASKAR - * Copyright (C) 2009 Alessandro Rubini - * - * 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. - */ #ifndef __ASM_ARCH_GPIO_H #define __ASM_ARCH_GPIO_H -#include - -/* - * These currently cause a function call to happen, they may be optimized - * if needed by adding cpu-specific defines to identify blocks - * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc) - */ -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value -#define gpio_cansleep __gpio_cansleep -#define gpio_to_irq __gpio_to_irq - -/* - * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving - * the "gpio" namespace for generic and cross-machine functions - */ - -/* Register in the logic block */ -#define NMK_GPIO_DAT 0x00 -#define NMK_GPIO_DATS 0x04 -#define NMK_GPIO_DATC 0x08 -#define NMK_GPIO_PDIS 0x0c -#define NMK_GPIO_DIR 0x10 -#define NMK_GPIO_DIRS 0x14 -#define NMK_GPIO_DIRC 0x18 -#define NMK_GPIO_SLPC 0x1c -#define NMK_GPIO_AFSLA 0x20 -#define NMK_GPIO_AFSLB 0x24 - -#define NMK_GPIO_RIMSC 0x40 -#define NMK_GPIO_FIMSC 0x44 -#define NMK_GPIO_IS 0x48 -#define NMK_GPIO_IC 0x4c -#define NMK_GPIO_RWIMSC 0x50 -#define NMK_GPIO_FWIMSC 0x54 -#define NMK_GPIO_WKS 0x58 - -/* Alternate functions: function C is set in hw by setting both A and B */ -#define NMK_GPIO_ALT_GPIO 0 -#define NMK_GPIO_ALT_A 1 -#define NMK_GPIO_ALT_B 2 -#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B) - -extern int nmk_gpio_set_mode(int gpio, int gpio_mode); -extern int nmk_gpio_get_mode(int gpio); - -/* - * Platform data to register a block: only the initial gpio/irq number. - */ -struct nmk_gpio_platform_data { - char *name; - int first_gpio; - int first_irq; - int parent_irq; -}; +#include #endif /* __ASM_ARCH_GPIO_H */ diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig index 159daf583f85..5da3f97c537b 100644 --- a/arch/arm/plat-nomadik/Kconfig +++ b/arch/arm/plat-nomadik/Kconfig @@ -19,4 +19,9 @@ config HAS_MTU to multiple interrupt generating programmable 32-bit free running decrementing counters. +config NOMADIK_GPIO + bool + help + Support for the Nomadik GPIO controller. + endif diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile index 37c7cdd0f8f0..c33547361bd7 100644 --- a/arch/arm/plat-nomadik/Makefile +++ b/arch/arm/plat-nomadik/Makefile @@ -3,3 +3,4 @@ # Licensed under GPLv2 obj-$(CONFIG_HAS_MTU) += timer.o +obj-$(CONFIG_NOMADIK_GPIO) += gpio.o diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c new file mode 100644 index 000000000000..9a09b2791e03 --- /dev/null +++ b/arch/arm/plat-nomadik/gpio.c @@ -0,0 +1,396 @@ +/* + * Generic GPIO driver for logic cells found in the Nomadik SoC + * + * Copyright (C) 2008,2009 STMicroelectronics + * Copyright (C) 2009 Alessandro Rubini + * Rewritten based on work by Prafulla WADASKAR + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + * The GPIO module in the Nomadik family of Systems-on-Chip is an + * AMBA device, managing 32 pins and alternate functions. The logic block + * is currently only used in the Nomadik. + * + * Symbols in this file are called "nmk_gpio" for "nomadik gpio" + */ + +#define NMK_GPIO_PER_CHIP 32 +struct nmk_gpio_chip { + struct gpio_chip chip; + void __iomem *addr; + unsigned int parent_irq; + spinlock_t *lock; + /* Keep track of configured edges */ + u32 edge_rising; + u32 edge_falling; +}; + +/* Mode functions */ +int nmk_gpio_set_mode(int gpio, int gpio_mode) +{ + struct nmk_gpio_chip *nmk_chip; + unsigned long flags; + u32 afunc, bfunc, bit; + + nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); + if (!nmk_chip) + return -EINVAL; + + bit = 1 << (gpio - nmk_chip->chip.base); + + spin_lock_irqsave(&nmk_chip->lock, flags); + afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit; + bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit; + if (gpio_mode & NMK_GPIO_ALT_A) + afunc |= bit; + if (gpio_mode & NMK_GPIO_ALT_B) + bfunc |= bit; + writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA); + writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB); + spin_unlock_irqrestore(&nmk_chip->lock, flags); + + return 0; +} +EXPORT_SYMBOL(nmk_gpio_set_mode); + +int nmk_gpio_get_mode(int gpio) +{ + struct nmk_gpio_chip *nmk_chip; + u32 afunc, bfunc, bit; + + nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); + if (!nmk_chip) + return -EINVAL; + + bit = 1 << (gpio - nmk_chip->chip.base); + + afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit; + bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit; + + return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0); +} +EXPORT_SYMBOL(nmk_gpio_get_mode); + + +/* IRQ functions */ +static inline int nmk_gpio_get_bitmask(int gpio) +{ + return 1 << (gpio % 32); +} + +static void nmk_gpio_irq_ack(unsigned int irq) +{ + int gpio; + struct nmk_gpio_chip *nmk_chip; + + gpio = NOMADIK_IRQ_TO_GPIO(irq); + nmk_chip = get_irq_chip_data(irq); + if (!nmk_chip) + return; + writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); +} + +static void nmk_gpio_irq_mask(unsigned int irq) +{ + int gpio; + struct nmk_gpio_chip *nmk_chip; + unsigned long flags; + u32 bitmask, reg; + + gpio = NOMADIK_IRQ_TO_GPIO(irq); + nmk_chip = get_irq_chip_data(irq); + bitmask = nmk_gpio_get_bitmask(gpio); + if (!nmk_chip) + return; + + /* we must individually clear the two edges */ + spin_lock_irqsave(&nmk_chip->lock, flags); + if (nmk_chip->edge_rising & bitmask) { + reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); + reg &= ~bitmask; + writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC); + } + if (nmk_chip->edge_falling & bitmask) { + reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); + reg &= ~bitmask; + writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC); + } + spin_unlock_irqrestore(&nmk_chip->lock, flags); +}; + +static void nmk_gpio_irq_unmask(unsigned int irq) +{ + int gpio; + struct nmk_gpio_chip *nmk_chip; + unsigned long flags; + u32 bitmask, reg; + + gpio = NOMADIK_IRQ_TO_GPIO(irq); + nmk_chip = get_irq_chip_data(irq); + bitmask = nmk_gpio_get_bitmask(gpio); + if (!nmk_chip) + return; + + /* we must individually set the two edges */ + spin_lock_irqsave(&nmk_chip->lock, flags); + if (nmk_chip->edge_rising & bitmask) { + reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); + reg |= bitmask; + writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC); + } + if (nmk_chip->edge_falling & bitmask) { + reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); + reg |= bitmask; + writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC); + } + spin_unlock_irqrestore(&nmk_chip->lock, flags); +} + +static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) +{ + int gpio; + struct nmk_gpio_chip *nmk_chip; + unsigned long flags; + u32 bitmask; + + gpio = NOMADIK_IRQ_TO_GPIO(irq); + nmk_chip = get_irq_chip_data(irq); + bitmask = nmk_gpio_get_bitmask(gpio); + if (!nmk_chip) + return -EINVAL; + + if (type & IRQ_TYPE_LEVEL_HIGH) + return -EINVAL; + if (type & IRQ_TYPE_LEVEL_LOW) + return -EINVAL; + + spin_lock_irqsave(&nmk_chip->lock, flags); + + nmk_chip->edge_rising &= ~bitmask; + if (type & IRQ_TYPE_EDGE_RISING) + nmk_chip->edge_rising |= bitmask; + writel(nmk_chip->edge_rising, nmk_chip->addr + NMK_GPIO_RIMSC); + + nmk_chip->edge_falling &= ~bitmask; + if (type & IRQ_TYPE_EDGE_FALLING) + nmk_chip->edge_falling |= bitmask; + writel(nmk_chip->edge_falling, nmk_chip->addr + NMK_GPIO_FIMSC); + + spin_unlock_irqrestore(&nmk_chip->lock, flags); + + nmk_gpio_irq_unmask(irq); + + return 0; +} + +static struct irq_chip nmk_gpio_irq_chip = { + .name = "Nomadik-GPIO", + .ack = nmk_gpio_irq_ack, + .mask = nmk_gpio_irq_mask, + .unmask = nmk_gpio_irq_unmask, + .set_type = nmk_gpio_irq_set_type, +}; + +static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + struct nmk_gpio_chip *nmk_chip; + struct irq_chip *host_chip; + unsigned int gpio_irq; + u32 pending; + unsigned int first_irq; + + nmk_chip = get_irq_data(irq); + first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); + while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) { + gpio_irq = first_irq + __ffs(pending); + generic_handle_irq(gpio_irq); + } + if (0) {/* don't ack parent irq, as ack == disable */ + host_chip = get_irq_chip(irq); + host_chip->ack(irq); + } +} + +static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) +{ + unsigned int first_irq; + int i; + + first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); + for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) { + set_irq_chip(i, &nmk_gpio_irq_chip); + set_irq_handler(i, handle_edge_irq); + set_irq_flags(i, IRQF_VALID); + set_irq_chip_data(i, nmk_chip); + } + set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); + set_irq_data(nmk_chip->parent_irq, nmk_chip); + return 0; +} + +/* I/O Functions */ +static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset) +{ + struct nmk_gpio_chip *nmk_chip = + container_of(chip, struct nmk_gpio_chip, chip); + + writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); + return 0; +} + +static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, + int val) +{ + struct nmk_gpio_chip *nmk_chip = + container_of(chip, struct nmk_gpio_chip, chip); + + writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); + return 0; +} + +static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset) +{ + struct nmk_gpio_chip *nmk_chip = + container_of(chip, struct nmk_gpio_chip, chip); + u32 bit = 1 << offset; + + return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0; +} + +static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, + int val) +{ + struct nmk_gpio_chip *nmk_chip = + container_of(chip, struct nmk_gpio_chip, chip); + u32 bit = 1 << offset; + + if (val) + writel(bit, nmk_chip->addr + NMK_GPIO_DATS); + else + writel(bit, nmk_chip->addr + NMK_GPIO_DATC); +} + +/* This structure is replicated for each GPIO block allocated at probe time */ +static struct gpio_chip nmk_gpio_template = { + .direction_input = nmk_gpio_make_input, + .get = nmk_gpio_get_input, + .direction_output = nmk_gpio_make_output, + .set = nmk_gpio_set_output, + .ngpio = NMK_GPIO_PER_CHIP, + .can_sleep = 0, +}; + +static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id) +{ + struct nmk_gpio_platform_data *pdata; + struct nmk_gpio_chip *nmk_chip; + struct gpio_chip *chip; + int ret; + + pdata = dev->dev.platform_data; + ret = amba_request_regions(dev, pdata->name); + if (ret) + return ret; + + nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); + if (!nmk_chip) { + ret = -ENOMEM; + goto out_amba; + } + /* + * The virt address in nmk_chip->addr is in the nomadik register space, + * so we can simply convert the resource address, without remapping + */ + nmk_chip->addr = io_p2v(dev->res.start); + nmk_chip->chip = nmk_gpio_template; + nmk_chip->parent_irq = pdata->parent_irq; + + chip = &nmk_chip->chip; + chip->base = pdata->first_gpio; + chip->label = pdata->name; + chip->dev = &dev->dev; + chip->owner = THIS_MODULE; + + ret = gpiochip_add(&nmk_chip->chip); + if (ret) + goto out_free; + + amba_set_drvdata(dev, nmk_chip); + + nmk_gpio_init_irq(nmk_chip); + + dev_info(&dev->dev, "Bits %i-%i at address %p\n", + nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr); + return 0; + + out_free: + kfree(nmk_chip); + out_amba: + amba_release_regions(dev); + dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret, + pdata->first_gpio, pdata->first_gpio+31); + return ret; +} + +static int nmk_gpio_remove(struct amba_device *dev) +{ + struct nmk_gpio_chip *nmk_chip; + + nmk_chip = amba_get_drvdata(dev); + gpiochip_remove(&nmk_chip->chip); + kfree(nmk_chip); + amba_release_regions(dev); + return 0; +} + + +/* We have 0x1f080060 and 0x1f180060, accept both using the mask */ +static struct amba_id nmk_gpio_ids[] = { + { + .id = 0x1f080060, + .mask = 0xffefffff, + }, + {0, 0}, +}; + +static struct amba_driver nmk_gpio_driver = { + .drv = { + .owner = THIS_MODULE, + .name = "gpio", + }, + .probe = nmk_gpio_probe, + .remove = nmk_gpio_remove, + .suspend = NULL, /* to be done */ + .resume = NULL, + .id_table = nmk_gpio_ids, +}; + +static int __init nmk_gpio_init(void) +{ + return amba_driver_register(&nmk_gpio_driver); +} + +arch_initcall(nmk_gpio_init); + +MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini"); +MODULE_DESCRIPTION("Nomadik GPIO Driver"); +MODULE_LICENSE("GPL"); + + diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h new file mode 100644 index 000000000000..1d665a0abb87 --- /dev/null +++ b/arch/arm/plat-nomadik/include/plat/gpio.h @@ -0,0 +1,71 @@ +/* + * Structures and registers for GPIO access in the Nomadik SoC + * + * Copyright (C) 2008 STMicroelectronics + * Author: Prafulla WADASKAR + * Copyright (C) 2009 Alessandro Rubini + * + * 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. + */ +#ifndef __ASM_PLAT_GPIO_H +#define __ASM_PLAT_GPIO_H + +#include + +/* + * These currently cause a function call to happen, they may be optimized + * if needed by adding cpu-specific defines to identify blocks + * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc) + */ +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep +#define gpio_to_irq __gpio_to_irq + +/* + * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving + * the "gpio" namespace for generic and cross-machine functions + */ + +/* Register in the logic block */ +#define NMK_GPIO_DAT 0x00 +#define NMK_GPIO_DATS 0x04 +#define NMK_GPIO_DATC 0x08 +#define NMK_GPIO_PDIS 0x0c +#define NMK_GPIO_DIR 0x10 +#define NMK_GPIO_DIRS 0x14 +#define NMK_GPIO_DIRC 0x18 +#define NMK_GPIO_SLPC 0x1c +#define NMK_GPIO_AFSLA 0x20 +#define NMK_GPIO_AFSLB 0x24 + +#define NMK_GPIO_RIMSC 0x40 +#define NMK_GPIO_FIMSC 0x44 +#define NMK_GPIO_IS 0x48 +#define NMK_GPIO_IC 0x4c +#define NMK_GPIO_RWIMSC 0x50 +#define NMK_GPIO_FWIMSC 0x54 +#define NMK_GPIO_WKS 0x58 + +/* Alternate functions: function C is set in hw by setting both A and B */ +#define NMK_GPIO_ALT_GPIO 0 +#define NMK_GPIO_ALT_A 1 +#define NMK_GPIO_ALT_B 2 +#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B) + +extern int nmk_gpio_set_mode(int gpio, int gpio_mode); +extern int nmk_gpio_get_mode(int gpio); + +/* + * Platform data to register a block: only the initial gpio/irq number. + */ +struct nmk_gpio_platform_data { + char *name; + int first_gpio; + int first_irq; + int parent_irq; +}; + +#endif /* __ASM_PLAT_GPIO_H */ -- cgit v1.2.3-59-g8ed1b From c0fcb8dba829421fe20652a376a2bedaf168238f Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 3 Mar 2010 04:48:54 +0100 Subject: ARM: 5970/1: nomadik-gpio: fix spinlock usage Fix the incorrect spinlock usage which leads to these compiler warnings: arch/arm/plat-nomadik/gpio.c:60: warning: passing argument 1 of `spinlock_check' from incompatible pointer type arch/arm/plat-nomadik/gpio.c:69: warning: passing argument 1 of `spin_unlock_irqrestore' from incompatible pointer type Acked-by: Alessandro Rubini Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/plat-nomadik/gpio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 9a09b2791e03..a9ee9889a833 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -36,7 +36,7 @@ struct nmk_gpio_chip { struct gpio_chip chip; void __iomem *addr; unsigned int parent_irq; - spinlock_t *lock; + spinlock_t lock; /* Keep track of configured edges */ u32 edge_rising; u32 edge_falling; @@ -321,6 +321,7 @@ static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id) nmk_chip->addr = io_p2v(dev->res.start); nmk_chip->chip = nmk_gpio_template; nmk_chip->parent_irq = pdata->parent_irq; + spin_lock_init(&nmk_chip->lock); chip = &nmk_chip->chip; chip->base = pdata->first_gpio; -- cgit v1.2.3-59-g8ed1b From aaedaa2b5c610ae97f863078075d8d3c6ef91575 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 3 Mar 2010 04:50:27 +0100 Subject: ARM: 5971/1: nomadik-gpio: mask/ack/unmask the parent irq Since we register as a chained handler, we need to take care of acking the parent irq. Current code had the acking disabled because just acking the interrupt disables it on some interrupt controllers (like the VIC used on Nomadik). However, not acking at all is incorrect because interrupt controllers like the GIC need an EOI indication, which is done in the ack routine. Solve this by maskacking and unmasking it appropriately, similar to how handle_level_irq operates. Acked-by: Alessandro Rubini Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/plat-nomadik/gpio.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index a9ee9889a833..4c3ea1a922ac 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -211,21 +211,27 @@ static struct irq_chip nmk_gpio_irq_chip = { static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { struct nmk_gpio_chip *nmk_chip; - struct irq_chip *host_chip; + struct irq_chip *host_chip = get_irq_chip(irq); unsigned int gpio_irq; u32 pending; unsigned int first_irq; + if (host_chip->mask_ack) + host_chip->mask_ack(irq); + else { + host_chip->mask(irq); + if (host_chip->ack) + host_chip->ack(irq); + } + nmk_chip = get_irq_data(irq); first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) { gpio_irq = first_irq + __ffs(pending); generic_handle_irq(gpio_irq); } - if (0) {/* don't ack parent irq, as ack == disable */ - host_chip = get_irq_chip(irq); - host_chip->ack(irq); - } + + host_chip->unmask(irq); } static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) -- cgit v1.2.3-59-g8ed1b From 3e3c62ca5395df48319b808379bc9fd487ff3c29 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 3 Mar 2010 04:52:34 +0100 Subject: ARM: 5972/1: nomadik-gpio: convert to platform driver On the U8500 platform there are four GPIO blocks, each with a 4K address space, including the peripheral identification. However, each of these blocks have a varying number of banks, each of which have 32 GPIOs and an interrupt line. The current nomadik-gpio driver implementation can handle each of these sub-banks easily with one instance each, but cannot as-is be hooked up to them because it is an AMBA driver and it expects to see a peripheral with the appropriate peripheral ids but having only one bank and only one interrupt. Solve this by converting the driver to a platform driver. Acked-by: Alessandro Rubini Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-nomadik/cpu-8815.c | 83 +++++++++++++++++-------------- arch/arm/plat-nomadik/gpio.c | 74 +++++++++++++++------------ arch/arm/plat-nomadik/include/plat/gpio.h | 1 - 3 files changed, 90 insertions(+), 68 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index 9bf33b30a025..91c3c901b469 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -30,60 +31,66 @@ #include #include +#define __MEM_4K_RESOURCE(x) \ + .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} + /* The 8815 has 4 GPIO blocks, let's register them immediately */ + +#define GPIO_RESOURCE(block) \ + { \ + .start = NOMADIK_GPIO##block##_BASE, \ + .end = NOMADIK_GPIO##block##_BASE + SZ_4K - 1, \ + .flags = IORESOURCE_MEM, \ + }, \ + { \ + .start = IRQ_GPIO##block, \ + .end = IRQ_GPIO##block, \ + .flags = IORESOURCE_IRQ, \ + } + +#define GPIO_DEVICE(block) \ + { \ + .name = "gpio", \ + .id = block, \ + .num_resources = 2, \ + .resource = &cpu8815_gpio_resources[block * 2], \ + .dev = { \ + .platform_data = &cpu8815_gpio[block], \ + }, \ + } + static struct nmk_gpio_platform_data cpu8815_gpio[] = { { .name = "GPIO-0-31", .first_gpio = 0, .first_irq = NOMADIK_GPIO_TO_IRQ(0), - .parent_irq = IRQ_GPIO0, }, { .name = "GPIO-32-63", .first_gpio = 32, .first_irq = NOMADIK_GPIO_TO_IRQ(32), - .parent_irq = IRQ_GPIO1, }, { .name = "GPIO-64-95", .first_gpio = 64, .first_irq = NOMADIK_GPIO_TO_IRQ(64), - .parent_irq = IRQ_GPIO2, }, { .name = "GPIO-96-127", /* 124..127 not routed to pin */ .first_gpio = 96, .first_irq = NOMADIK_GPIO_TO_IRQ(96), - .parent_irq = IRQ_GPIO3, } }; -#define __MEM_4K_RESOURCE(x) \ - .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} +static struct resource cpu8815_gpio_resources[] = { + GPIO_RESOURCE(0), + GPIO_RESOURCE(1), + GPIO_RESOURCE(2), + GPIO_RESOURCE(3), +}; -static struct amba_device cpu8815_amba_gpio[] = { - { - .dev = { - .init_name = "gpio0", - .platform_data = cpu8815_gpio + 0, - }, - __MEM_4K_RESOURCE(NOMADIK_GPIO0_BASE), - }, { - .dev = { - .init_name = "gpio1", - .platform_data = cpu8815_gpio + 1, - }, - __MEM_4K_RESOURCE(NOMADIK_GPIO1_BASE), - }, { - .dev = { - .init_name = "gpio2", - .platform_data = cpu8815_gpio + 2, - }, - __MEM_4K_RESOURCE(NOMADIK_GPIO2_BASE), - }, { - .dev = { - .init_name = "gpio3", - .platform_data = cpu8815_gpio + 3, - }, - __MEM_4K_RESOURCE(NOMADIK_GPIO3_BASE), - }, +static struct platform_device cpu8815_platform_gpio[] = { + GPIO_DEVICE(0), + GPIO_DEVICE(1), + GPIO_DEVICE(2), + GPIO_DEVICE(3), }; static struct amba_device cpu8815_amba_rng = { @@ -93,11 +100,14 @@ static struct amba_device cpu8815_amba_rng = { __MEM_4K_RESOURCE(NOMADIK_RNG_BASE), }; +static struct platform_device *platform_devs[] __initdata = { + cpu8815_platform_gpio + 0, + cpu8815_platform_gpio + 1, + cpu8815_platform_gpio + 2, + cpu8815_platform_gpio + 3, +}; + static struct amba_device *amba_devs[] __initdata = { - cpu8815_amba_gpio + 0, - cpu8815_amba_gpio + 1, - cpu8815_amba_gpio + 2, - cpu8815_amba_gpio + 3, &cpu8815_amba_rng }; @@ -105,6 +115,7 @@ static int __init cpu8815_init(void) { int i; + platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) amba_device_register(amba_devs[i], &iomem_resource); return 0; diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 4c3ea1a922ac..092f380063b3 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -303,30 +303,48 @@ static struct gpio_chip nmk_gpio_template = { .can_sleep = 0, }; -static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id) +static int __init nmk_gpio_probe(struct platform_device *dev) { - struct nmk_gpio_platform_data *pdata; + struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; struct nmk_gpio_chip *nmk_chip; struct gpio_chip *chip; + struct resource *res; + int irq; int ret; - pdata = dev->dev.platform_data; - ret = amba_request_regions(dev, pdata->name); - if (ret) - return ret; + if (!pdata) + return -ENODEV; + + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENOENT; + goto out; + } + + irq = platform_get_irq(dev, 0); + if (irq < 0) { + ret = irq; + goto out; + } + + if (request_mem_region(res->start, resource_size(res), + dev_name(&dev->dev)) == NULL) { + ret = -EBUSY; + goto out; + } nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); if (!nmk_chip) { ret = -ENOMEM; - goto out_amba; + goto out_release; } /* * The virt address in nmk_chip->addr is in the nomadik register space, * so we can simply convert the resource address, without remapping */ - nmk_chip->addr = io_p2v(dev->res.start); + nmk_chip->addr = io_p2v(res->start); nmk_chip->chip = nmk_gpio_template; - nmk_chip->parent_irq = pdata->parent_irq; + nmk_chip->parent_irq = irq; spin_lock_init(&nmk_chip->lock); chip = &nmk_chip->chip; @@ -339,7 +357,7 @@ static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id) if (ret) goto out_free; - amba_set_drvdata(dev, nmk_chip); + platform_set_drvdata(dev, nmk_chip); nmk_gpio_init_irq(nmk_chip); @@ -347,51 +365,45 @@ static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id) nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr); return 0; - out_free: +out_free: kfree(nmk_chip); - out_amba: - amba_release_regions(dev); +out_release: + release_mem_region(res->start, resource_size(res)); +out: dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret, pdata->first_gpio, pdata->first_gpio+31); return ret; } -static int nmk_gpio_remove(struct amba_device *dev) +static int __exit nmk_gpio_remove(struct platform_device *dev) { struct nmk_gpio_chip *nmk_chip; + struct resource *res; + + res = platform_get_resource(dev, IORESOURCE_MEM, 0); - nmk_chip = amba_get_drvdata(dev); + nmk_chip = platform_get_drvdata(dev); gpiochip_remove(&nmk_chip->chip); kfree(nmk_chip); - amba_release_regions(dev); + release_mem_region(res->start, resource_size(res)); return 0; } -/* We have 0x1f080060 and 0x1f180060, accept both using the mask */ -static struct amba_id nmk_gpio_ids[] = { - { - .id = 0x1f080060, - .mask = 0xffefffff, - }, - {0, 0}, -}; - -static struct amba_driver nmk_gpio_driver = { - .drv = { +static struct platform_driver nmk_gpio_driver = { + .driver = { .owner = THIS_MODULE, .name = "gpio", }, .probe = nmk_gpio_probe, - .remove = nmk_gpio_remove, + .remove = __exit_p(nmk_gpio_remove), .suspend = NULL, /* to be done */ .resume = NULL, - .id_table = nmk_gpio_ids, }; static int __init nmk_gpio_init(void) { - return amba_driver_register(&nmk_gpio_driver); + return platform_driver_register(&nmk_gpio_driver); } arch_initcall(nmk_gpio_init); diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h index 1d665a0abb87..4200811249ca 100644 --- a/arch/arm/plat-nomadik/include/plat/gpio.h +++ b/arch/arm/plat-nomadik/include/plat/gpio.h @@ -65,7 +65,6 @@ struct nmk_gpio_platform_data { char *name; int first_gpio; int first_irq; - int parent_irq; }; #endif /* __ASM_PLAT_GPIO_H */ -- cgit v1.2.3-59-g8ed1b From cc2c13342508d52cf08ea81f639b5de69607fd5d Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 1 Mar 2010 05:03:31 +0100 Subject: ARM: 5962/1: ux500: move system timer to cpu file There is nothing board-specific about the system timer, so move it to the CPU file. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/board-mop500.c | 18 ------------------ arch/arm/mach-ux500/cpu-u8500.c | 20 ++++++++++++++++++++ arch/arm/mach-ux500/include/mach/setup.h | 3 +++ 3 files changed, 23 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 803aec1d6728..c2b4a35cf01b 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -17,11 +17,9 @@ #include #include -#include #include #include -#include #include #include @@ -201,22 +199,6 @@ static struct platform_device *platform_devs[] __initdata = { &i2c_controller3, }; -static void __init u8500_timer_init(void) -{ -#ifdef CONFIG_LOCAL_TIMERS - /* Setup the local timer base */ - twd_base = __io_address(U8500_TWD_BASE); -#endif - /* Setup the MTU base */ - mtu_base = __io_address(U8500_MTU0_BASE); - - nmdk_timer_init(); -} - -static struct sys_timer u8500_timer = { - .init = u8500_timer_init, -}; - static void __init u8500_init_machine(void) { int i; diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index 397bc1f9ed94..588b0596a635 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -14,10 +14,14 @@ #include #include #include +#include +#include #include #include +#include #include +#include /* add any platform devices here - TODO */ static struct platform_device *platform_devs[] __initdata = { @@ -63,3 +67,19 @@ void __init u8500_init_devices(void) return ; } + +static void __init u8500_timer_init(void) +{ +#ifdef CONFIG_LOCAL_TIMERS + /* Setup the local timer base */ + twd_base = __io_address(U8500_TWD_BASE); +#endif + /* Setup the MTU base */ + mtu_base = __io_address(U8500_MTU0_BASE); + + nmdk_timer_init(); +} + +struct sys_timer u8500_timer = { + .init = u8500_timer_init, +}; diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index cf0ce1687f24..65112bfd7a0c 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -20,4 +20,7 @@ extern void u8500_init_irq(void); /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); +struct sys_timer; +extern struct sys_timer u8500_timer; + #endif /* __ASM_ARCH_SETUP_H */ -- cgit v1.2.3-59-g8ed1b From 75a36ee01e860be693220f1c40e2c04fb6cc69ba Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 1 Mar 2010 05:05:56 +0100 Subject: ARM: 5963/1: ux500: add support for u8500 v1 revision Add cpu_is_u8500{ed/v1}() functions to determine the variant based on the CPU id, add the changed peripheral addresses, and fixup the MTU address. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/cpu-u8500.c | 19 +++++++++++++++++-- arch/arm/mach-ux500/include/mach/hardware.h | 29 ++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index 588b0596a635..f368504d2af7 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -40,15 +40,27 @@ static struct map_desc u8500_io_desc[] __initdata = { __IO_DEV_DESC(U8500_UART2_BASE, SZ_4K), __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K), __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K), - __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K), __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), }; +static struct map_desc u8500ed_io_desc[] __initdata = { + __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K), +}; + +static struct map_desc u8500v1_io_desc[] __initdata = { + __IO_DEV_DESC(U8500_MTU0_BASE_V1, SZ_4K), +}; + void __init u8500_map_io(void) { iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); + + if (cpu_is_u8500ed()) + iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc)); + else + iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); } void __init u8500_init_irq(void) @@ -75,7 +87,10 @@ static void __init u8500_timer_init(void) twd_base = __io_address(U8500_TWD_BASE); #endif /* Setup the MTU base */ - mtu_base = __io_address(U8500_MTU0_BASE); + if (cpu_is_u8500ed()) + mtu_base = __io_address(U8500_MTU0_BASE_ED); + else + mtu_base = __io_address(U8500_MTU0_BASE_V1); nmdk_timer_init(); } diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 04ea836969b3..f29a43d9d45a 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h @@ -56,16 +56,19 @@ #define U8500_TWD_SIZE 0x100 /* per7 base addressess */ -#define U8500_CR_BASE (U8500_PER7_BASE + 0x8000) -#define U8500_MTU0_BASE (U8500_PER7_BASE + 0xa000) -#define U8500_MTU1_BASE (U8500_PER7_BASE + 0xb000) -#define U8500_TZPC0_BASE (U8500_PER7_BASE + 0xc000) -#define U8500_CLKRST7_BASE (U8500_PER7_BASE + 0xf000) +#define U8500_CR_BASE_ED (U8500_PER7_BASE + 0x8000) +#define U8500_MTU0_BASE_ED (U8500_PER7_BASE + 0xa000) +#define U8500_MTU1_BASE_ED (U8500_PER7_BASE + 0xb000) +#define U8500_TZPC0_BASE_ED (U8500_PER7_BASE + 0xc000) +#define U8500_CLKRST7_BASE_ED (U8500_PER7_BASE + 0xf000) /* per6 base addressess */ #define U8500_RNG_BASE (U8500_PER6_BASE + 0x0000) #define U8500_PKA_BASE (U8500_PER6_BASE + 0x1000) #define U8500_PKAM_BASE (U8500_PER6_BASE + 0x2000) +#define U8500_MTU0_BASE_V1 (U8500_PER6_BASE + 0x6000) +#define U8500_MTU1_BASE_V1 (U8500_PER6_BASE + 0x7000) +#define U8500_CR_BASE_V1 (U8500_PER6_BASE + 0x8000) #define U8500_CRYPTO0_BASE (U8500_PER6_BASE + 0xa000) #define U8500_CRYPTO1_BASE (U8500_PER6_BASE + 0xb000) #define U8500_CLKRST6_BASE (U8500_PER6_BASE + 0xf000) @@ -128,4 +131,20 @@ /* ST-Ericsson modified pl022 id */ #define SSP_PER_ID 0x01080022 +#ifndef __ASSEMBLY__ + +#include + +static inline bool cpu_is_u8500ed(void) +{ + return (read_cpuid_id() & 15) == 0; +} + +static inline bool cpu_is_u8500v1(void) +{ + return (read_cpuid_id() & 15) == 1; +} + +#endif + #endif /* __MACH_HARDWARE_H */ -- cgit v1.2.3-59-g8ed1b From 1df20afce51e7af2a587425d1aafca2608fe0066 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 1 Mar 2010 05:07:47 +0100 Subject: ARM: 5964/1: ux500: support clock gating Implement clock gating support for the u8500 clocks. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/board-mop500.c | 2 +- arch/arm/mach-ux500/clock.c | 491 ++++++++++++++++++++++++++++++++++--- arch/arm/mach-ux500/clock.h | 125 ++++++++++ arch/arm/mach-ux500/cpu-u8500.c | 7 + 4 files changed, 590 insertions(+), 35 deletions(-) create mode 100644 arch/arm/mach-ux500/clock.h (limited to 'arch') diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index c2b4a35cf01b..4335186135e4 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -94,7 +94,7 @@ static struct pl022_ssp_controller ssp0_platform_data = { static struct amba_device pl022_device = { .dev = { .coherent_dma_mask = ~0, - .init_name = "pl022", + .init_name = "ssp0", .platform_data = &ssp0_platform_data, }, .res = { diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 8359a73d0041..d16b8b5ca8c7 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2009 ST-Ericsson - * heavily based on realview platform + * Copyright (C) 2009 STMicroelectronics * * 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 @@ -12,33 +12,130 @@ #include #include #include -#include +#include #include -/* currently the clk structure - * just supports rate. This would - * be extended as and when new devices are - * added - TODO - */ -struct clk { - unsigned long rate; -}; +#include +#include "clock.h" + +#define PRCC_PCKEN 0x00 +#define PRCC_PCKDIS 0x04 +#define PRCC_KCKEN 0x08 +#define PRCC_KCKDIS 0x0C + +#define PRCM_YYCLKEN0_MGT_SET 0x510 +#define PRCM_YYCLKEN1_MGT_SET 0x514 +#define PRCM_YYCLKEN0_MGT_CLR 0x518 +#define PRCM_YYCLKEN1_MGT_CLR 0x51C +#define PRCM_YYCLKEN0_MGT_VAL 0x520 +#define PRCM_YYCLKEN1_MGT_VAL 0x524 + +#define PRCM_SVAMMDSPCLK_MGT 0x008 +#define PRCM_SIAMMDSPCLK_MGT 0x00C +#define PRCM_SGACLK_MGT 0x014 +#define PRCM_UARTCLK_MGT 0x018 +#define PRCM_MSP02CLK_MGT 0x01C +#define PRCM_MSP1CLK_MGT 0x288 +#define PRCM_I2CCLK_MGT 0x020 +#define PRCM_SDMMCCLK_MGT 0x024 +#define PRCM_SLIMCLK_MGT 0x028 +#define PRCM_PER1CLK_MGT 0x02C +#define PRCM_PER2CLK_MGT 0x030 +#define PRCM_PER3CLK_MGT 0x034 +#define PRCM_PER5CLK_MGT 0x038 +#define PRCM_PER6CLK_MGT 0x03C +#define PRCM_PER7CLK_MGT 0x040 +#define PRCM_LCDCLK_MGT 0x044 +#define PRCM_BMLCLK_MGT 0x04C +#define PRCM_HSITXCLK_MGT 0x050 +#define PRCM_HSIRXCLK_MGT 0x054 +#define PRCM_HDMICLK_MGT 0x058 +#define PRCM_APEATCLK_MGT 0x05C +#define PRCM_APETRACECLK_MGT 0x060 +#define PRCM_MCDECLK_MGT 0x064 +#define PRCM_IPI2CCLK_MGT 0x068 +#define PRCM_DSIALTCLK_MGT 0x06C +#define PRCM_DMACLK_MGT 0x074 +#define PRCM_B2R2CLK_MGT 0x078 +#define PRCM_TVCLK_MGT 0x07C +#define PRCM_UNIPROCLK_MGT 0x278 +#define PRCM_SSPCLK_MGT 0x280 +#define PRCM_RNGCLK_MGT 0x284 +#define PRCM_UICCCLK_MGT 0x27C + +#define PRCM_MGT_ENABLE (1 << 8) + +static DEFINE_SPINLOCK(clocks_lock); + +static void __clk_enable(struct clk *clk) +{ + if (clk->enabled++ == 0) { + if (clk->parent_cluster) + __clk_enable(clk->parent_cluster); + + if (clk->parent_periph) + __clk_enable(clk->parent_periph); + + if (clk->ops && clk->ops->enable) + clk->ops->enable(clk); + } +} int clk_enable(struct clk *clk) { + unsigned long flags; + + spin_lock_irqsave(&clocks_lock, flags); + __clk_enable(clk); + spin_unlock_irqrestore(&clocks_lock, flags); + return 0; } EXPORT_SYMBOL(clk_enable); +static void __clk_disable(struct clk *clk) +{ + if (--clk->enabled == 0) { + if (clk->ops && clk->ops->disable) + clk->ops->disable(clk); + + if (clk->parent_periph) + __clk_disable(clk->parent_periph); + + if (clk->parent_cluster) + __clk_disable(clk->parent_cluster); + } +} + void clk_disable(struct clk *clk) { + unsigned long flags; + + WARN_ON(!clk->enabled); + + spin_lock_irqsave(&clocks_lock, flags); + __clk_disable(clk); + spin_unlock_irqrestore(&clocks_lock, flags); } EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { - return clk->rate; + unsigned long rate; + + if (clk->ops && clk->ops->get_rate) + return clk->ops->get_rate(clk); + + rate = clk->rate; + if (!rate) { + if (clk->parent_periph) + rate = clk_get_rate(clk->parent_periph); + else if (clk->parent_cluster) + rate = clk_get_rate(clk->parent_cluster); + } + + return rate; } EXPORT_SYMBOL(clk_get_rate); @@ -56,37 +153,363 @@ int clk_set_rate(struct clk *clk, unsigned long rate) } EXPORT_SYMBOL(clk_set_rate); -/* ssp clock */ -static struct clk ssp_clk = { - .rate = 48000000, +static void clk_prcmu_enable(struct clk *clk) +{ + void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE) + + PRCM_YYCLKEN0_MGT_SET + clk->prcmu_cg_off; + + writel(1 << clk->prcmu_cg_bit, cg_set_reg); +} + +static void clk_prcmu_disable(struct clk *clk) +{ + void __iomem *cg_clr_reg = __io_address(U8500_PRCMU_BASE) + + PRCM_YYCLKEN0_MGT_CLR + clk->prcmu_cg_off; + + writel(1 << clk->prcmu_cg_bit, cg_clr_reg); +} + +/* ED doesn't have the combined set/clr registers */ +static void clk_prcmu_ed_enable(struct clk *clk) +{ + void __iomem *addr = __io_address(U8500_PRCMU_BASE) + + clk->prcmu_cg_mgt; + + writel(readl(addr) | PRCM_MGT_ENABLE, addr); +} + +static void clk_prcmu_ed_disable(struct clk *clk) +{ + void __iomem *addr = __io_address(U8500_PRCMU_BASE) + + clk->prcmu_cg_mgt; + + writel(readl(addr) & ~PRCM_MGT_ENABLE, addr); +} + +static struct clkops clk_prcmu_ops = { + .enable = clk_prcmu_enable, + .disable = clk_prcmu_disable, }; -/* fixed clock */ -static struct clk f38_clk = { - .rate = 38400000, +static unsigned int clkrst_base[] = { + [1] = U8500_CLKRST1_BASE, + [2] = U8500_CLKRST2_BASE, + [3] = U8500_CLKRST3_BASE, + [5] = U8500_CLKRST5_BASE, + [6] = U8500_CLKRST6_BASE, + [7] = U8500_CLKRST7_BASE_ED, }; -static struct clk_lookup lookups[] = { - { - /* UART0 */ - .dev_id = "uart0", - .clk = &f38_clk, - }, { /* UART1 */ - .dev_id = "uart1", - .clk = &f38_clk, - }, { /* UART2 */ - .dev_id = "uart2", - .clk = &f38_clk, - }, { /* SSP */ - .dev_id = "pl022", - .clk = &ssp_clk, - } +static void clk_prcc_enable(struct clk *clk) +{ + void __iomem *addr = __io_address(clkrst_base[clk->cluster]); + + if (clk->prcc_kernel != -1) + writel(1 << clk->prcc_kernel, addr + PRCC_KCKEN); + + if (clk->prcc_bus != -1) + writel(1 << clk->prcc_bus, addr + PRCC_PCKEN); +} + +static void clk_prcc_disable(struct clk *clk) +{ + void __iomem *addr = __io_address(clkrst_base[clk->cluster]); + + if (clk->prcc_bus != -1) + writel(1 << clk->prcc_bus, addr + PRCC_PCKDIS); + + if (clk->prcc_kernel != -1) + writel(1 << clk->prcc_kernel, addr + PRCC_KCKDIS); +} + +static struct clkops clk_prcc_ops = { + .enable = clk_prcc_enable, + .disable = clk_prcc_disable, +}; + +static struct clk clk_32khz = { + .rate = 32000, +}; + +/* + * PRCMU level clock gating + */ + +/* Bank 0 */ +static DEFINE_PRCMU_CLK(svaclk, 0x0, 2, SVAMMDSPCLK); +static DEFINE_PRCMU_CLK(siaclk, 0x0, 3, SIAMMDSPCLK); +static DEFINE_PRCMU_CLK(sgaclk, 0x0, 4, SGACLK); +static DEFINE_PRCMU_CLK_RATE(uartclk, 0x0, 5, UARTCLK, 38400000); +static DEFINE_PRCMU_CLK(msp02clk, 0x0, 6, MSP02CLK); +static DEFINE_PRCMU_CLK(msp1clk, 0x0, 7, MSP1CLK); /* v1 */ +static DEFINE_PRCMU_CLK_RATE(i2cclk, 0x0, 8, I2CCLK, 48000000); +static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 50000000); +static DEFINE_PRCMU_CLK(slimclk, 0x0, 10, SLIMCLK); +static DEFINE_PRCMU_CLK(per1clk, 0x0, 11, PER1CLK); +static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK); +static DEFINE_PRCMU_CLK(per3clk, 0x0, 13, PER3CLK); +static DEFINE_PRCMU_CLK(per5clk, 0x0, 14, PER5CLK); +static DEFINE_PRCMU_CLK_RATE(per6clk, 0x0, 15, PER6CLK, 133330000); +static DEFINE_PRCMU_CLK_RATE(per7clk, 0x0, 16, PER7CLK, 100000000); +static DEFINE_PRCMU_CLK(lcdclk, 0x0, 17, LCDCLK); +static DEFINE_PRCMU_CLK(bmlclk, 0x0, 18, BMLCLK); +static DEFINE_PRCMU_CLK(hsitxclk, 0x0, 19, HSITXCLK); +static DEFINE_PRCMU_CLK(hsirxclk, 0x0, 20, HSIRXCLK); +static DEFINE_PRCMU_CLK(hdmiclk, 0x0, 21, HDMICLK); +static DEFINE_PRCMU_CLK(apeatclk, 0x0, 22, APEATCLK); +static DEFINE_PRCMU_CLK(apetraceclk, 0x0, 23, APETRACECLK); +static DEFINE_PRCMU_CLK(mcdeclk, 0x0, 24, MCDECLK); +static DEFINE_PRCMU_CLK(ipi2clk, 0x0, 25, IPI2CCLK); +static DEFINE_PRCMU_CLK(dsialtclk, 0x0, 26, DSIALTCLK); /* v1 */ +static DEFINE_PRCMU_CLK(dmaclk, 0x0, 27, DMACLK); +static DEFINE_PRCMU_CLK(b2r2clk, 0x0, 28, B2R2CLK); +static DEFINE_PRCMU_CLK(tvclk, 0x0, 29, TVCLK); +static DEFINE_PRCMU_CLK(uniproclk, 0x0, 30, UNIPROCLK); /* v1 */ +static DEFINE_PRCMU_CLK_RATE(sspclk, 0x0, 31, SSPCLK, 48000000); /* v1 */ + +/* Bank 1 */ +static DEFINE_PRCMU_CLK(rngclk, 0x4, 0, RNGCLK); /* v1 */ +static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */ + +/* + * PRCC level clock gating + * Format: per#, clk, PCKEN bit, KCKEN bit, parent + */ + +/* Peripheral Cluster #1 */ +static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk); +static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL); +static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk); +static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL); +static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL); +static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk); +static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk); +static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk); +static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk); +static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk); +static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk); +static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk); +static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk); + +/* Peripheral Cluster #2 */ + +static DEFINE_PRCC_CLK(2, gpio1_ed, 12, -1, NULL); +static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL); +static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL); +static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL); +static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk); +static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk); +static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk); +static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk); +static DEFINE_PRCC_CLK(2, pwl_ed, 3, 1, NULL); +static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL); +static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL); +static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk); + +static DEFINE_PRCC_CLK(2, gpio1_v1, 11, -1, NULL); +static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL); +static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL); +static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL); +static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk); +static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk); +static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk); +static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk); +static DEFINE_PRCC_CLK(2, pwl_v1, 3, 1, NULL); +static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL); +static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL); +static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk); + +/* Peripheral Cluster #3 */ +static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL); +static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk); +static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk); +static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz); +static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk); +static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk); +static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk); +static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk); +static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk); +static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk); +static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL); + +/* Peripheral Cluster #4 is in the always on domain */ + +/* Peripheral Cluster #5 */ +static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL); +static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk); +static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL); + +/* Peripheral Cluster #6 */ + +static DEFINE_PRCC_CLK(6, mtu1_v1, 8, -1, NULL); +static DEFINE_PRCC_CLK(6, mtu0_v1, 7, -1, NULL); +static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); +static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL); +static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); +static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk); +static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL); +static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL); +static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL); +static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL); +static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk); +static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk); + +/* Peripheral Cluster #7 */ + +static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL); +static DEFINE_PRCC_CLK(7, mtu1_ed, 3, -1, NULL); +static DEFINE_PRCC_CLK(7, mtu0_ed, 2, -1, NULL); +static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL); +static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); + +static struct clk_lookup u8500_common_clks[] = { + /* Peripheral Cluster #1 */ + CLK(gpio0, "gpioblock0", NULL), + CLK(slimbus0, "slimbus0", NULL), + CLK(i2c2, "nmk-i2c.2", NULL), + CLK(sdi0, "sdi0", NULL), + CLK(msp0, "msp0", NULL), + CLK(i2c1, "nmk-i2c.1", NULL), + CLK(uart1, "uart1", NULL), + CLK(uart0, "uart0", NULL), + + /* Peripheral Cluster #3 */ + CLK(gpio2, "gpioblock2", NULL), + CLK(sdi5, "sdi5", NULL), + CLK(uart2, "uart2", NULL), + CLK(ske, "ske", NULL), + CLK(sdi2, "sdi2", NULL), + CLK(i2c0, "nmk-i2c.0", NULL), + CLK(fsmc, "fsmc", NULL), + + /* Peripheral Cluster #5 */ + CLK(gpio3, "gpioblock3", NULL), + + /* Peripheral Cluster #6 */ + CLK(hash1, "hash1", NULL), + CLK(pka, "pka", NULL), + CLK(hash0, "hash0", NULL), + CLK(cryp0, "cryp0", NULL), + + /* PRCMU level clock gating */ + + /* Bank 0 */ + CLK(svaclk, "sva", NULL), + CLK(siaclk, "sia", NULL), + CLK(sgaclk, "sga", NULL), + CLK(slimclk, "slim", NULL), + CLK(lcdclk, "lcd", NULL), + CLK(bmlclk, "bml", NULL), + CLK(hsitxclk, "stm-hsi.0", NULL), + CLK(hsirxclk, "stm-hsi.1", NULL), + CLK(hdmiclk, "hdmi", NULL), + CLK(apeatclk, "apeat", NULL), + CLK(apetraceclk, "apetrace", NULL), + CLK(mcdeclk, "mcde", NULL), + CLK(ipi2clk, "ipi2", NULL), + CLK(dmaclk, "dma40", NULL), + CLK(b2r2clk, "b2r2", NULL), + CLK(tvclk, "tv", NULL), +}; + +static struct clk_lookup u8500_ed_clks[] = { + /* Peripheral Cluster #1 */ + CLK(spi3_ed, "spi3", NULL), + CLK(msp1_ed, "msp1", NULL), + + /* Peripheral Cluster #2 */ + CLK(gpio1_ed, "gpioblock1", NULL), + CLK(ssitx_ed, "ssitx", NULL), + CLK(ssirx_ed, "ssirx", NULL), + CLK(spi0_ed, "spi0", NULL), + CLK(sdi3_ed, "sdi3", NULL), + CLK(sdi1_ed, "sdi1", NULL), + CLK(msp2_ed, "msp2", NULL), + CLK(sdi4_ed, "sdi4", NULL), + CLK(pwl_ed, "pwl", NULL), + CLK(spi1_ed, "spi1", NULL), + CLK(spi2_ed, "spi2", NULL), + CLK(i2c3_ed, "nmk-i2c.3", NULL), + + /* Peripheral Cluster #3 */ + CLK(ssp1_ed, "ssp1", NULL), + CLK(ssp0_ed, "ssp0", NULL), + + /* Peripheral Cluster #5 */ + CLK(usb_ed, "musb_hdrc.0", "usb"), + + /* Peripheral Cluster #6 */ + CLK(dmc_ed, "dmc", NULL), + CLK(cryp1_ed, "cryp1", NULL), + CLK(rng_ed, "rng", NULL), + + /* Peripheral Cluster #7 */ + CLK(tzpc0_ed, "tzpc0", NULL), + CLK(mtu1_ed, "mtu1", NULL), + CLK(mtu0_ed, "mtu0", NULL), + CLK(wdg_ed, "wdg", NULL), + CLK(cfgreg_ed, "cfgreg", NULL), +}; + +static struct clk_lookup u8500_v1_clks[] = { + /* Peripheral Cluster #1 */ + CLK(i2c4, "nmk-i2c.4", NULL), + CLK(spi3_v1, "spi3", NULL), + CLK(msp1_v1, "msp1", NULL), + + /* Peripheral Cluster #2 */ + CLK(gpio1_v1, "gpioblock1", NULL), + CLK(ssitx_v1, "ssitx", NULL), + CLK(ssirx_v1, "ssirx", NULL), + CLK(spi0_v1, "spi0", NULL), + CLK(sdi3_v1, "sdi3", NULL), + CLK(sdi1_v1, "sdi1", NULL), + CLK(msp2_v1, "msp2", NULL), + CLK(sdi4_v1, "sdi4", NULL), + CLK(pwl_v1, "pwl", NULL), + CLK(spi1_v1, "spi1", NULL), + CLK(spi2_v1, "spi2", NULL), + CLK(i2c3_v1, "nmk-i2c.3", NULL), + + /* Peripheral Cluster #3 */ + CLK(ssp1_v1, "ssp1", NULL), + CLK(ssp0_v1, "ssp0", NULL), + + /* Peripheral Cluster #5 */ + CLK(usb_v1, "musb_hdrc.0", "usb"), + + /* Peripheral Cluster #6 */ + CLK(mtu1_v1, "mtu1", NULL), + CLK(mtu0_v1, "mtu0", NULL), + CLK(cfgreg_v1, "cfgreg", NULL), + CLK(hash1, "hash1", NULL), + CLK(unipro_v1, "unipro", NULL), + CLK(rng_v1, "rng", NULL), + + /* PRCMU level clock gating */ + + /* Bank 0 */ + CLK(uniproclk, "uniproclk", NULL), + CLK(dsialtclk, "dsialt", NULL), + + /* Bank 1 */ + CLK(rngclk, "rng", NULL), + CLK(uiccclk, "uicc", NULL), }; static int __init clk_init(void) { - /* register the clock lookups */ - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + if (cpu_is_u8500ed()) { + clk_prcmu_ops.enable = clk_prcmu_ed_enable; + clk_prcmu_ops.disable = clk_prcmu_ed_disable; + } + + clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); + if (cpu_is_u8500ed()) + clkdev_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks)); + else + clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); + return 0; } arch_initcall(clk_init); diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h new file mode 100644 index 000000000000..e4f99b65026f --- /dev/null +++ b/arch/arm/mach-ux500/clock.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2010 ST-Ericsson + * Copyright (C) 2009 STMicroelectronics + * + * 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. + */ + +/** + * struct clkops - ux500 clock operations + * @enable: function to enable the clock + * @disable: function to disable the clock + * @get_rate: function to get the current clock rate + * + * This structure contains function pointers to functions that will be used to + * control the clock. All of these functions are optional. If get_rate is + * NULL, the rate in the struct clk will be used. + */ +struct clkops { + void (*enable) (struct clk *); + void (*disable) (struct clk *); + unsigned long (*get_rate) (struct clk *); +}; + +/** + * struct clk - ux500 clock structure + * @ops: pointer to clkops struct used to control this clock + * @name: name, for debugging + * @enabled: refcount. positive if enabled, zero if disabled + * @rate: fixed rate for clocks which don't implement + * ops->getrate + * @prcmu_cg_off: address offset of the combined enable/disable register + * (used on u8500v1) + * @prcmu_cg_bit: bit in the combined enable/disable register (used on + * u8500v1) + * @prcmu_cg_mgt: address of the enable/disable register (used on + * u8500ed) + * @cluster: peripheral cluster number + * @prcc_bus: bit for the bus clock in the peripheral's CLKRST + * @prcc_kernel: bit for the kernel clock in the peripheral's CLKRST. + * -1 if no kernel clock exists. + * @parent_cluster: pointer to parent's cluster clk struct + * @parent_periph: pointer to parent's peripheral clk struct + * + * Peripherals are organised into clusters, and each cluster has an associated + * bus clock. Some peripherals also have a parent peripheral clock. + * + * In order to enable a clock for a peripheral, we need to enable: + * (1) the parent cluster (bus) clock at the PRCMU level + * (2) the parent peripheral clock (if any) at the PRCMU level + * (3) the peripheral's bus & kernel clock at the PRCC level + * + * (1) and (2) are handled by defining clk structs (DEFINE_PRCMU_CLK) for each + * of the cluster and peripheral clocks, and hooking these as the parents of + * the individual peripheral clocks. + * + * (3) is handled by specifying the bits in the PRCC control registers required + * to enable these clocks and modifying them in the ->enable and + * ->disable callbacks of the peripheral clocks (DEFINE_PRCC_CLK). + * + * This structure describes both the PRCMU-level clocks and PRCC-level clocks. + * The prcmu_* fields are only used for the PRCMU clocks, and the cluster, + * prcc, and parent pointers are only used for the PRCC-level clocks. + */ +struct clk { + const struct clkops *ops; + const char *name; + unsigned int enabled; + + unsigned long rate; + struct list_head list; + + /* These three are only for PRCMU clks */ + + unsigned int prcmu_cg_off; + unsigned int prcmu_cg_bit; + unsigned int prcmu_cg_mgt; + + /* The rest are only for PRCC clks */ + + int cluster; + unsigned int prcc_bus; + unsigned int prcc_kernel; + + struct clk *parent_cluster; + struct clk *parent_periph; +}; + +#define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \ +struct clk clk_##_name = { \ + .name = #_name, \ + .ops = &clk_prcmu_ops, \ + .prcmu_cg_off = _cg_off, \ + .prcmu_cg_bit = _cg_bit, \ + .prcmu_cg_mgt = PRCM_##_reg##_MGT \ + } + +#define DEFINE_PRCMU_CLK_RATE(_name, _cg_off, _cg_bit, _reg, _rate) \ +struct clk clk_##_name = { \ + .name = #_name, \ + .ops = &clk_prcmu_ops, \ + .prcmu_cg_off = _cg_off, \ + .prcmu_cg_bit = _cg_bit, \ + .rate = _rate, \ + .prcmu_cg_mgt = PRCM_##_reg##_MGT \ + } + +#define DEFINE_PRCC_CLK(_pclust, _name, _bus_en, _kernel_en, _kernclk) \ +struct clk clk_##_name = { \ + .name = #_name, \ + .ops = &clk_prcc_ops, \ + .cluster = _pclust, \ + .prcc_bus = _bus_en, \ + .prcc_kernel = _kernel_en, \ + .parent_cluster = &clk_per##_pclust##clk, \ + .parent_periph = _kernclk \ + } + +#define CLK(_clk, _devname, _conname) \ + { \ + .clk = &clk_##_clk, \ + .dev_id = _devname, \ + .con_id = _conname, \ + } diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index f368504d2af7..09bcba1ccef1 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -43,10 +43,17 @@ static struct map_desc u8500_io_desc[] __initdata = { __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K), __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), + __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST1_BASE, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST2_BASE, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K), }; static struct map_desc u8500ed_io_desc[] __initdata = { __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K), }; static struct map_desc u8500v1_io_desc[] __initdata = { -- cgit v1.2.3-59-g8ed1b From 94bdc0e2d76c5f2467346bf14e7e16d6d8e0395d Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 3 Mar 2010 04:54:37 +0100 Subject: ARM: 5973/1: ux500: add gpio support Add support for the GPIOs on the U8500, using the plat-nomadik GPIO driver. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/cpu-u8500.c | 82 ++++++++++++++++++++++++++++- arch/arm/mach-ux500/include/mach/gpio.h | 12 +++++ arch/arm/mach-ux500/include/mach/hardware.h | 12 +++++ arch/arm/mach-ux500/include/mach/irqs.h | 8 ++- 6 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-ux500/include/mach/gpio.h (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5408bf1bf43..540f85922113 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -756,6 +756,7 @@ config ARCH_U8500 select GENERIC_TIME select GENERIC_CLOCKEVENTS select COMMON_CLKDEV + select ARCH_REQUIRE_GPIOLIB help Support for ST-Ericsson's Ux500 architecture diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 03625d744857..cd412a3e0ab8 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -8,6 +8,7 @@ config MACH_U8500_MOP default y select ARM_GIC select HAS_MTU + select NOMADIK_GPIO help Include support for mop500 development platform based on U8500 architecture. The platform is based diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index 09bcba1ccef1..5fb44661adaf 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -23,9 +24,82 @@ #include #include -/* add any platform devices here - TODO */ +#define GPIO_RESOURCE(block) \ + { \ + .start = U8500_GPIOBANK##block##_BASE, \ + .end = U8500_GPIOBANK##block##_BASE + 127, \ + .flags = IORESOURCE_MEM, \ + }, \ + { \ + .start = IRQ_GPIO##block, \ + .end = IRQ_GPIO##block, \ + .flags = IORESOURCE_IRQ, \ + } + +#define GPIO_DEVICE(block) \ + { \ + .name = "gpio", \ + .id = block, \ + .num_resources = 2, \ + .resource = &u8500_gpio_resources[block * 2], \ + .dev = { \ + .platform_data = &u8500_gpio_data[block], \ + }, \ + } + +#define GPIO_DATA(_name, first) \ + { \ + .name = _name, \ + .first_gpio = first, \ + .first_irq = NOMADIK_GPIO_TO_IRQ(first), \ + } + +static struct nmk_gpio_platform_data u8500_gpio_data[] = { + GPIO_DATA("GPIO-0-31", 0), + GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */ + GPIO_DATA("GPIO-64-95", 64), + GPIO_DATA("GPIO-96-127", 96), /* 97..127 not routed to pin */ + GPIO_DATA("GPIO-128-159", 128), + GPIO_DATA("GPIO-160-191", 160), /* 172..191 not routed to pin */ + GPIO_DATA("GPIO-192-223", 192), + GPIO_DATA("GPIO-224-255", 224), /* 231..255 not routed to pin */ + GPIO_DATA("GPIO-256-288", 256), /* 258..288 not routed to pin */ +}; + +static struct resource u8500_gpio_resources[] = { + GPIO_RESOURCE(0), + GPIO_RESOURCE(1), + GPIO_RESOURCE(2), + GPIO_RESOURCE(3), + GPIO_RESOURCE(4), + GPIO_RESOURCE(5), + GPIO_RESOURCE(6), + GPIO_RESOURCE(7), + GPIO_RESOURCE(8), +}; + +static struct platform_device u8500_gpio_devs[] = { + GPIO_DEVICE(0), + GPIO_DEVICE(1), + GPIO_DEVICE(2), + GPIO_DEVICE(3), + GPIO_DEVICE(4), + GPIO_DEVICE(5), + GPIO_DEVICE(6), + GPIO_DEVICE(7), + GPIO_DEVICE(8), +}; + static struct platform_device *platform_devs[] __initdata = { - /* yet to be added, add i2c0, gpio.. */ + &u8500_gpio_devs[0], + &u8500_gpio_devs[1], + &u8500_gpio_devs[2], + &u8500_gpio_devs[3], + &u8500_gpio_devs[4], + &u8500_gpio_devs[5], + &u8500_gpio_devs[6], + &u8500_gpio_devs[7], + &u8500_gpio_devs[8], }; #define __IO_DEV_DESC(x, sz) { \ @@ -49,6 +123,10 @@ static struct map_desc u8500_io_desc[] __initdata = { __IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K), __IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K), __IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO5_BASE, SZ_4K), }; static struct map_desc u8500ed_io_desc[] __initdata = { diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h new file mode 100644 index 000000000000..3c4cd31ad9f7 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/gpio.h @@ -0,0 +1,12 @@ +#ifndef __ASM_ARCH_GPIO_H +#define __ASM_ARCH_GPIO_H + +/* + * 288 (#267 is the highest one actually hooked up) onchip GPIOs, plus enough + * room for a couple of GPIO expanders. + */ +#define ARCH_NR_GPIOS 350 + +#include + +#endif /* __ASM_ARCH_GPIO_H */ diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index f29a43d9d45a..99ca89fe9b30 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h @@ -23,6 +23,8 @@ /* typesafe io address */ #define __io_address(n) __io(IO_ADDRESS(n)) +/* used by some plat-nomadik code */ +#define io_p2v(n) __io_address(n) /* * Base address definitions for U8500 Onchip IPs. All the @@ -128,6 +130,16 @@ #define U8500_GPIO1_BASE (U8500_PER1_BASE + 0xe000) #define U8500_CLKRST1_BASE (U8500_PER1_BASE + 0xf000) +#define U8500_GPIOBANK0_BASE U8500_GPIO1_BASE +#define U8500_GPIOBANK1_BASE (U8500_GPIO1_BASE + 0x80) +#define U8500_GPIOBANK2_BASE U8500_GPIO3_BASE +#define U8500_GPIOBANK3_BASE (U8500_GPIO3_BASE + 0x80) +#define U8500_GPIOBANK4_BASE (U8500_GPIO3_BASE + 0x100) +#define U8500_GPIOBANK5_BASE (U8500_GPIO3_BASE + 0x180) +#define U8500_GPIOBANK6_BASE U8500_GPIO2_BASE +#define U8500_GPIOBANK7_BASE (U8500_GPIO2_BASE + 0x80) +#define U8500_GPIOBANK8_BASE U8500_GPIO5_BASE + /* ST-Ericsson modified pl022 id */ #define SSP_PER_ID 0x01080022 diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h index 394b5dd2200f..8a1f6976c245 100644 --- a/arch/arm/mach-ux500/include/mach/irqs.h +++ b/arch/arm/mach-ux500/include/mach/irqs.h @@ -66,6 +66,12 @@ /* There are 128 shared peripheral interrupts assigned to * INTID[160:32]. The first 32 interrupts are reserved. */ -#define NR_IRQS 161 +#define U8500_SOC_NR_IRQS 161 + +/* After chip-specific IRQ numbers we have the GPIO ones */ +#define NOMADIK_NR_GPIO 288 +#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + U8500_SOC_NR_IRQS) +#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - U8500_SOC_NR_IRQS) +#define NR_IRQS NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO) #endif /*ASM_ARCH_IRQS_H*/ -- cgit v1.2.3-59-g8ed1b From b102c01faed5e0083a4e6d29a2d61f6b57716e94 Mon Sep 17 00:00:00 2001 From: Alessandro Rubini Date: Fri, 5 Mar 2010 12:38:51 +0100 Subject: ARM: 5978/1: plat-nomadik: use one-shot clock events This is a complete rewrite of the MTU driver, using one-shot for events and a free-running timer for stamping. It allows CONFIG_NO_HZ and CONFIG_HIGH_RES_TIMERS to work on Nomadik and Ux500. Signed-off-by: Alessandro Rubini Acked-by: Linus Walleij Acked-by: Andrea Gallo Signed-off-by: Russell King --- arch/arm/plat-nomadik/timer.c | 125 +++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 62 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index fa7cb3a57cbf..db67402518a6 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c @@ -2,7 +2,7 @@ * linux/arch/arm/mach-nomadik/timer.c * * Copyright (C) 2008 STMicroelectronics - * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x + * Copyright (C) 2010 Alessandro Rubini * * 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 @@ -18,123 +18,124 @@ #include -static u32 nmdk_count; /* accumulated count */ -static u32 nmdk_cycle; /* write-once */ +void __iomem *mtu_base; /* ssigned by machine code */ -/* setup by the platform code */ -void __iomem *mtu_base; - -/* - * clocksource: the MTU device is a decrementing counters, so we negate - * the value being read. - */ +/* clocksource: MTU decrements, so we negate the value being read. */ static cycle_t nmdk_read_timer(struct clocksource *cs) { - u32 count = readl(mtu_base + MTU_VAL(0)); - return nmdk_count + nmdk_cycle - count; - + return -readl(mtu_base + MTU_VAL(0)); } static struct clocksource nmdk_clksrc = { .name = "mtu_0", - .rating = 120, + .rating = 200, .read = nmdk_read_timer, + .mask = CLOCKSOURCE_MASK(32), .shift = 20, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -/* - * Clockevent device: currently only periodic mode is supported - */ +/* Clockevent device: use one-shot mode */ static void nmdk_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) { + u32 cr; + switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - /* count current value? */ - writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC); + pr_err("%s: periodic mode not supported\n", __func__); break; case CLOCK_EVT_MODE_ONESHOT: - BUG(); /* Not supported, yet */ - /* FALLTHROUGH */ + /* Load highest value, enable device, enable interrupts */ + cr = readl(mtu_base + MTU_CR(1)); + writel(0, mtu_base + MTU_LR(1)); + writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); + writel(0x2, mtu_base + MTU_IMSC); + break; case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: - writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC); + /* disable irq */ + writel(0, mtu_base + MTU_IMSC); break; case CLOCK_EVT_MODE_RESUME: break; } } +static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev) +{ + /* writing the value has immediate effect */ + writel(evt, mtu_base + MTU_LR(1)); + return 0; +} + static struct clock_event_device nmdk_clkevt = { - .name = "mtu_0", - .features = CLOCK_EVT_FEAT_PERIODIC, + .name = "mtu_1", + .features = CLOCK_EVT_FEAT_ONESHOT, .shift = 32, - .rating = 100, + .rating = 200, .set_mode = nmdk_clkevt_mode, + .set_next_event = nmdk_clkevt_next, }; /* - * IRQ Handler for the timer 0 of the MTU block. The irq is not shared - * as we are the only users of mtu0 by now. + * IRQ Handler for timer 1 of the MTU block. */ static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id) { - /* ack: "interrupt clear register" */ - writel(1 << 0, mtu_base + MTU_ICR); - - /* we can't count lost ticks, unfortunately */ - nmdk_count += nmdk_cycle; - nmdk_clkevt.event_handler(&nmdk_clkevt); + struct clock_event_device *evdev = dev_id; + writel(1 << 1, mtu_base + MTU_ICR); /* Interrupt clear reg */ + evdev->event_handler(evdev); return IRQ_HANDLED; } -/* - * Set up timer interrupt, and return the current time in seconds. - */ static struct irqaction nmdk_timer_irq = { .name = "Nomadik Timer Tick", .flags = IRQF_DISABLED | IRQF_TIMER, .handler = nmdk_timer_interrupt, + .dev_id = &nmdk_clkevt, }; -static void nmdk_timer_reset(void) -{ - u32 cr; - - writel(0, mtu_base + MTU_CR(0)); /* off */ - - /* configure load and background-load, and fire it up */ - writel(nmdk_cycle, mtu_base + MTU_LR(0)); - writel(nmdk_cycle, mtu_base + MTU_BGLR(0)); - cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS; - writel(cr, mtu_base + MTU_CR(0)); - writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); -} - void __init nmdk_timer_init(void) { unsigned long rate; - int bits; - - rate = CLOCK_TICK_RATE; /* 2.4MHz */ - nmdk_cycle = (rate + HZ/2) / HZ; + u32 cr = MTU_CRn_32BITS;; + + /* + * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500: + * use a divide-by-16 counter if it's more than 16MHz + */ + rate = CLOCK_TICK_RATE; + if (rate > 16 << 20) { + rate /= 16; + cr |= MTU_CRn_PRESCALE_16; + } else { + cr |= MTU_CRn_PRESCALE_1; + } - /* Init the timer and register clocksource */ - nmdk_timer_reset(); + /* Timer 0 is the free running clocksource */ + writel(cr, mtu_base + MTU_CR(0)); + writel(0, mtu_base + MTU_LR(0)); + writel(0, mtu_base + MTU_BGLR(0)); + writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift); - bits = 8*sizeof(nmdk_count); - nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits); if (clocksource_register(&nmdk_clksrc)) - printk(KERN_ERR "timer: failed to initialize clock " - "source %s\n", nmdk_clksrc.name); + pr_err("timer: failed to initialize clock source %s\n", + nmdk_clksrc.name); + + /* Timer 1 is used for events, fix according to rate */ + writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ + nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift); + nmdk_clkevt.max_delta_ns = + clockevent_delta2ns(0xffffffff, &nmdk_clkevt); + nmdk_clkevt.min_delta_ns = + clockevent_delta2ns(0x00000002, &nmdk_clkevt); + nmdk_clkevt.cpumask = cpumask_of(0); /* Register irq and clockevents */ setup_irq(IRQ_MTU0, &nmdk_timer_irq); - nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift); - nmdk_clkevt.cpumask = cpumask_of(0); clockevents_register_device(&nmdk_clkevt); } -- cgit v1.2.3-59-g8ed1b From 4bd96a7a8185755b091233b16034c7436cbf57af Mon Sep 17 00:00:00 2001 From: Shane Wang Date: Wed, 10 Mar 2010 14:36:10 +0800 Subject: x86, tboot: Add support for S3 memory integrity protection This patch adds support for S3 memory integrity protection within an Intel(R) TXT launched kernel, for all kernel and userspace memory. All RAM used by the kernel and userspace, as indicated by memory ranges of type E820_RAM and E820_RESERVED_KERN in the e820 table, will be integrity protected. The MAINTAINERS file is also updated to reflect the maintainers of the TXT-related code. All MACing is done in tboot, based on a complexity analysis and tradeoff. v3: Compared with v2, this patch adds a check of array size in tboot.c, and a note to specify which c/s of tboot supports this kind of MACing in intel_txt.txt. Signed-off-by: Shane Wang LKML-Reference: <4B973DDA.6050902@intel.com> Signed-off-by: Joseph Cihula Acked-by: Pavel Machek Acked-by: Rafael J. Wysocki Signed-off-by: H. Peter Anvin --- Documentation/intel_txt.txt | 16 +++++++++------- MAINTAINERS | 11 +++++++++++ arch/x86/include/asm/e820.h | 7 ++++++- arch/x86/kernel/tboot.c | 20 +++++++++++--------- 4 files changed, 37 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/Documentation/intel_txt.txt b/Documentation/intel_txt.txt index f40a1f030019..87c8990dbbd9 100644 --- a/Documentation/intel_txt.txt +++ b/Documentation/intel_txt.txt @@ -161,13 +161,15 @@ o In order to put a system into any of the sleep states after a TXT has been restored, it will restore the TPM PCRs and then transfer control back to the kernel's S3 resume vector. In order to preserve system integrity across S3, the kernel - provides tboot with a set of memory ranges (kernel - code/data/bss, S3 resume code, and AP trampoline) that tboot - will calculate a MAC (message authentication code) over and then - seal with the TPM. On resume and once the measured environment - has been re-established, tboot will re-calculate the MAC and - verify it against the sealed value. Tboot's policy determines - what happens if the verification fails. + provides tboot with a set of memory ranges (RAM and RESERVED_KERN + in the e820 table, but not any memory that BIOS might alter over + the S3 transition) that tboot will calculate a MAC (message + authentication code) over and then seal with the TPM. On resume + and once the measured environment has been re-established, tboot + will re-calculate the MAC and verify it against the sealed value. + Tboot's policy determines what happens if the verification fails. + Note that the c/s 194 of tboot which has the new MAC code supports + this. That's pretty much it for TXT support. diff --git a/MAINTAINERS b/MAINTAINERS index 47cc449d89d8..d3072cb8805d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2940,6 +2940,17 @@ S: Odd Fixes F: Documentation/networking/README.ipw2200 F: drivers/net/wireless/ipw2x00/ipw2200.* +INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT) +M: Joseph Cihula +M: Shane Wang +L: tboot-devel@lists.sourceforge.net +W: http://tboot.sourceforge.net +T: Mercurial http://www.bughost.org/repos.hg/tboot.hg +S: Supported +F: Documentation/intel_txt.txt +F: include/linux/tboot.h +F: arch/x86/kernel/tboot.c + INTEL WIRELESS WIMAX CONNECTION 2400 M: Inaky Perez-Gonzalez M: linux-wimax@intel.com diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index 0e22296790d3..ec8a52d14ab1 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h @@ -45,7 +45,12 @@ #define E820_NVS 4 #define E820_UNUSABLE 5 -/* reserved RAM used by kernel itself */ +/* + * reserved RAM used by kernel itself + * if CONFIG_INTEL_TXT is enabled, memory of this type will be + * included in the S3 integrity calculation and so should not include + * any memory that BIOS might alter over the S3 transition + */ #define E820_RESERVED_KERN 128 #ifndef __ASSEMBLY__ diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 86c9f91b48ae..cc2c60474fd0 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c @@ -175,6 +175,9 @@ static void add_mac_region(phys_addr_t start, unsigned long size) struct tboot_mac_region *mr; phys_addr_t end = start + size; + if (tboot->num_mac_regions >= MAX_TB_MAC_REGIONS) + panic("tboot: Too many MAC regions\n"); + if (start && size) { mr = &tboot->mac_regions[tboot->num_mac_regions++]; mr->start = round_down(start, PAGE_SIZE); @@ -184,18 +187,17 @@ static void add_mac_region(phys_addr_t start, unsigned long size) static int tboot_setup_sleep(void) { + int i; + tboot->num_mac_regions = 0; - /* S3 resume code */ - add_mac_region(acpi_wakeup_address, WAKEUP_SIZE); + for (i = 0; i < e820.nr_map; i++) { + if ((e820.map[i].type != E820_RAM) + && (e820.map[i].type != E820_RESERVED_KERN)) + continue; -#ifdef CONFIG_X86_TRAMPOLINE - /* AP trampoline code */ - add_mac_region(virt_to_phys(trampoline_base), TRAMPOLINE_SIZE); -#endif - - /* kernel code + data + bss */ - add_mac_region(virt_to_phys(_text), _end - _text); + add_mac_region(e820.map[i].addr, e820.map[i].size); + } tboot->acpi_sinfo.kernel_s3_resume_vector = acpi_wakeup_address; -- cgit v1.2.3-59-g8ed1b From 4bab9d426e6dbd9ea09330919a33d35d5faab400 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Mar 2010 04:46:38 +0000 Subject: dmaengine: shdma: Remove sh_dmae_slave_chan_id enum This patch replaces the sh_dmae_slave_chan_id enum with an unsigned int. The purpose of this chainge is to make it possible to separate the slave id enums from the dmaengine header. The slave id enums varies with processor model, so in the future it makes sense to put these in the processor specific headers together with the pinmux enums. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/dmaengine.h | 6 +++--- arch/sh/include/asm/siu.h | 8 ++++---- drivers/dma/shdma.c | 8 ++++---- drivers/serial/sh-sci.c | 4 ++-- include/linux/serial_sci.h | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/dmaengine.h b/arch/sh/include/asm/dmaengine.h index bf2f30cf0a27..568e991442b0 100644 --- a/arch/sh/include/asm/dmaengine.h +++ b/arch/sh/include/asm/dmaengine.h @@ -17,7 +17,7 @@ #define SH_DMAC_MAX_CHANNELS 6 -enum sh_dmae_slave_chan_id { +enum { SHDMA_SLAVE_SCIF0_TX, SHDMA_SLAVE_SCIF0_RX, SHDMA_SLAVE_SCIF1_TX, @@ -38,7 +38,7 @@ enum sh_dmae_slave_chan_id { }; struct sh_dmae_slave_config { - enum sh_dmae_slave_chan_id slave_id; + unsigned int slave_id; dma_addr_t addr; u32 chcr; char mid_rid; @@ -68,7 +68,7 @@ struct device; /* Used by slave DMA clients to request DMA to/from a specific peripheral */ struct sh_dmae_slave { - enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */ + unsigned int slave_id; /* Set by the platform */ struct device *dma_dev; /* Set by the platform */ struct sh_dmae_slave_config *config; /* Set by the driver */ }; diff --git a/arch/sh/include/asm/siu.h b/arch/sh/include/asm/siu.h index f1b1e6944a5f..e8d4142baf59 100644 --- a/arch/sh/include/asm/siu.h +++ b/arch/sh/include/asm/siu.h @@ -17,10 +17,10 @@ struct device; struct siu_platform { struct device *dma_dev; - enum sh_dmae_slave_chan_id dma_slave_tx_a; - enum sh_dmae_slave_chan_id dma_slave_rx_a; - enum sh_dmae_slave_chan_id dma_slave_tx_b; - enum sh_dmae_slave_chan_id dma_slave_rx_b; + unsigned int dma_slave_tx_a; + unsigned int dma_slave_rx_a; + unsigned int dma_slave_tx_b; + unsigned int dma_slave_rx_b; }; #endif /* ASM_SIU_H */ diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 5d17e09cb625..e5588f4868ca 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -266,7 +266,7 @@ static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan) } static struct sh_dmae_slave_config *sh_dmae_find_slave( - struct sh_dmae_chan *sh_chan, enum sh_dmae_slave_chan_id slave_id) + struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *param) { struct dma_device *dma_dev = sh_chan->common.device; struct sh_dmae_device *shdev = container_of(dma_dev, @@ -274,11 +274,11 @@ static struct sh_dmae_slave_config *sh_dmae_find_slave( struct sh_dmae_pdata *pdata = shdev->pdata; int i; - if ((unsigned)slave_id >= SHDMA_SLAVE_NUMBER) + if (param->slave_id >= SHDMA_SLAVE_NUMBER) return NULL; for (i = 0; i < pdata->slave_num; i++) - if (pdata->slave[i].slave_id == slave_id) + if (pdata->slave[i].slave_id == param->slave_id) return pdata->slave + i; return NULL; @@ -299,7 +299,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) if (param) { struct sh_dmae_slave_config *cfg; - cfg = sh_dmae_find_slave(sh_chan, param->slave_id); + cfg = sh_dmae_find_slave(sh_chan, param); if (!cfg) return -EINVAL; diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index f7b9aff88f4a..2d9a06db83b5 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -90,8 +90,8 @@ struct sci_port { struct dma_chan *chan_rx; #ifdef CONFIG_SERIAL_SH_SCI_DMA struct device *dma_dev; - enum sh_dmae_slave_chan_id slave_tx; - enum sh_dmae_slave_chan_id slave_rx; + unsigned int slave_tx; + unsigned int slave_rx; struct dma_async_tx_descriptor *desc_tx; struct dma_async_tx_descriptor *desc_rx[2]; dma_cookie_t cookie_tx; diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 193d4bfe42ff..f5364a1de68b 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -33,8 +33,8 @@ struct plat_sci_port { char *clk; /* clock string */ struct device *dma_dev; #ifdef CONFIG_SERIAL_SH_SCI_DMA - enum sh_dmae_slave_chan_id dma_slave_tx; - enum sh_dmae_slave_chan_id dma_slave_rx; + unsigned int dma_slave_tx; + unsigned int dma_slave_rx; #endif }; -- cgit v1.2.3-59-g8ed1b From 02ca5083f60521d09f13224596564a405108bc4c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Mar 2010 04:46:47 +0000 Subject: dmaengine: shdma: Common SH_DMA_SLAVE_NUMBER Move SHDMA_SLAVE_NUMBER from asm/dmaengine.h to shdma.h. Set it to 256 to support a wide range of processors. The amount of memory consumed by this change is limited to 256 bits. While at it, rename to SH_DMA_SLAVE_NUMBER to match with the rest of the file. Signed-off-by: Magnus Damm Acked-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/include/asm/dmaengine.h | 1 - drivers/dma/shdma.c | 4 ++-- drivers/dma/shdma.h | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/dmaengine.h b/arch/sh/include/asm/dmaengine.h index 568e991442b0..abb8d660b6fb 100644 --- a/arch/sh/include/asm/dmaengine.h +++ b/arch/sh/include/asm/dmaengine.h @@ -34,7 +34,6 @@ enum { SHDMA_SLAVE_SIUA_RX, SHDMA_SLAVE_SIUB_TX, SHDMA_SLAVE_SIUB_RX, - SHDMA_SLAVE_NUMBER, /* Must stay last */ }; struct sh_dmae_slave_config { diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index e5588f4868ca..83605389fb56 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -44,7 +44,7 @@ enum sh_dmae_desc_status { #define LOG2_DEFAULT_XFER_SIZE 2 /* A bitmask with bits enough for enum sh_dmae_slave_chan_id */ -static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)]; +static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SH_DMA_SLAVE_NUMBER)]; static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all); @@ -274,7 +274,7 @@ static struct sh_dmae_slave_config *sh_dmae_find_slave( struct sh_dmae_pdata *pdata = shdev->pdata; int i; - if (param->slave_id >= SHDMA_SLAVE_NUMBER) + if (param->slave_id >= SH_DMA_SLAVE_NUMBER) return NULL; for (i = 0; i < pdata->slave_num; i++) diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h index 153609a1e96c..d7ddf6f47154 100644 --- a/drivers/dma/shdma.h +++ b/drivers/dma/shdma.h @@ -19,6 +19,7 @@ #include +#define SH_DMA_SLAVE_NUMBER 256 #define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ struct device; -- cgit v1.2.3-59-g8ed1b From b2623a61cfd3c6badb8396dc85ab5a70f4a05f61 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Mar 2010 04:47:10 +0000 Subject: dmaengine: shdma: Introduce include/linux/sh_dma.h Create a common platform data header file for the shdma dmaengine driver. This is done by moving common structures from sh asm/dmaengine.h to linux/sh_dma.h. DMA registers are also copied from sh asm/dma-register.h to make the code architecture independent. The sh header file asm/dmaengine.h is still kept with the slave id enum. This allows us to keep the old processor specific code as is and slowly move over to slave id enums in per-processor headers. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/dmaengine.h | 60 +----------------------- drivers/dma/shdma.c | 3 +- drivers/dma/shdma.h | 3 +- include/linux/sh_dma.h | 101 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 63 deletions(-) create mode 100644 include/linux/sh_dma.h (limited to 'arch') diff --git a/arch/sh/include/asm/dmaengine.h b/arch/sh/include/asm/dmaengine.h index abb8d660b6fb..2a02b611a9ad 100644 --- a/arch/sh/include/asm/dmaengine.h +++ b/arch/sh/include/asm/dmaengine.h @@ -10,12 +10,7 @@ #ifndef ASM_DMAENGINE_H #define ASM_DMAENGINE_H -#include -#include - -#include - -#define SH_DMAC_MAX_CHANNELS 6 +#include enum { SHDMA_SLAVE_SCIF0_TX, @@ -36,57 +31,4 @@ enum { SHDMA_SLAVE_SIUB_RX, }; -struct sh_dmae_slave_config { - unsigned int slave_id; - dma_addr_t addr; - u32 chcr; - char mid_rid; -}; - -struct sh_dmae_channel { - unsigned int offset; - unsigned int dmars; - unsigned int dmars_bit; -}; - -struct sh_dmae_pdata { - struct sh_dmae_slave_config *slave; - int slave_num; - struct sh_dmae_channel *channel; - int channel_num; - unsigned int ts_low_shift; - unsigned int ts_low_mask; - unsigned int ts_high_shift; - unsigned int ts_high_mask; - unsigned int *ts_shift; - int ts_shift_num; - u16 dmaor_init; -}; - -struct device; - -/* Used by slave DMA clients to request DMA to/from a specific peripheral */ -struct sh_dmae_slave { - unsigned int slave_id; /* Set by the platform */ - struct device *dma_dev; /* Set by the platform */ - struct sh_dmae_slave_config *config; /* Set by the driver */ -}; - -struct sh_dmae_regs { - u32 sar; /* SAR / source address */ - u32 dar; /* DAR / destination address */ - u32 tcr; /* TCR / transfer count */ -}; - -struct sh_desc { - struct sh_dmae_regs hw; - struct list_head node; - struct dma_async_tx_descriptor async_tx; - enum dma_data_direction direction; - dma_cookie_t cookie; - size_t partial; - int chunks; - int mark; -}; - #endif diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 83605389fb56..7a18b580f626 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -25,8 +25,7 @@ #include #include #include - -#include +#include #include "shdma.h" diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h index d7ddf6f47154..4021275a0a43 100644 --- a/drivers/dma/shdma.h +++ b/drivers/dma/shdma.h @@ -17,8 +17,7 @@ #include #include -#include - +#define SH_DMAC_MAX_CHANNELS 6 #define SH_DMA_SLAVE_NUMBER 256 #define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h new file mode 100644 index 000000000000..cdaaff424211 --- /dev/null +++ b/include/linux/sh_dma.h @@ -0,0 +1,101 @@ +/* + * Header for the new SH dmaengine driver + * + * Copyright (C) 2010 Guennadi Liakhovetski + * + * 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. + */ +#ifndef SH_DMA_H +#define SH_DMA_H + +#include +#include + +/* Used by slave DMA clients to request DMA to/from a specific peripheral */ +struct sh_dmae_slave { + unsigned int slave_id; /* Set by the platform */ + struct device *dma_dev; /* Set by the platform */ + struct sh_dmae_slave_config *config; /* Set by the driver */ +}; + +struct sh_dmae_regs { + u32 sar; /* SAR / source address */ + u32 dar; /* DAR / destination address */ + u32 tcr; /* TCR / transfer count */ +}; + +struct sh_desc { + struct sh_dmae_regs hw; + struct list_head node; + struct dma_async_tx_descriptor async_tx; + enum dma_data_direction direction; + dma_cookie_t cookie; + size_t partial; + int chunks; + int mark; +}; +struct sh_dmae_slave_config { + unsigned int slave_id; + dma_addr_t addr; + u32 chcr; + char mid_rid; +}; + +struct sh_dmae_channel { + unsigned int offset; + unsigned int dmars; + unsigned int dmars_bit; +}; + +struct sh_dmae_pdata { + struct sh_dmae_slave_config *slave; + int slave_num; + struct sh_dmae_channel *channel; + int channel_num; + unsigned int ts_low_shift; + unsigned int ts_low_mask; + unsigned int ts_high_shift; + unsigned int ts_high_mask; + unsigned int *ts_shift; + int ts_shift_num; + u16 dmaor_init; +}; + +/* DMA register */ +#define SAR 0x00 +#define DAR 0x04 +#define TCR 0x08 +#define CHCR 0x0C +#define DMAOR 0x40 + +/* DMAOR definitions */ +#define DMAOR_AE 0x00000004 +#define DMAOR_NMIF 0x00000002 +#define DMAOR_DME 0x00000001 + +/* Definitions for the SuperH DMAC */ +#define REQ_L 0x00000000 +#define REQ_E 0x00080000 +#define RACK_H 0x00000000 +#define RACK_L 0x00040000 +#define ACK_R 0x00000000 +#define ACK_W 0x00020000 +#define ACK_H 0x00000000 +#define ACK_L 0x00010000 +#define DM_INC 0x00004000 +#define DM_DEC 0x00008000 +#define DM_FIX 0x0000c000 +#define SM_INC 0x00001000 +#define SM_DEC 0x00002000 +#define SM_FIX 0x00003000 +#define RS_IN 0x00000200 +#define RS_OUT 0x00000300 +#define TS_BLK 0x00000040 +#define TM_BUR 0x00000020 +#define CHCR_DE 0x00000001 +#define CHCR_TE 0x00000002 +#define CHCR_IE 0x00000004 + +#endif -- cgit v1.2.3-59-g8ed1b From 5cfc8ee0bb5134e1204e1ec5843e164f24315021 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 24 Mar 2010 00:22:36 +0000 Subject: ARM: convert arm to arch_gettimeoffset() Convert arm to use GENERIC_TIME via the arch_getoffset() infrastructure, reducing the amount of arch specific code we need to maintain. The arm architecture is the last arch that need to be converted. Signed-off-by: John Stultz Signed-off-by: Russell King Cc: Andrew Morton --- arch/arm/Kconfig | 23 +++++++++++++ arch/arm/include/asm/mach/time.h | 2 +- arch/arm/kernel/time.c | 70 ++++------------------------------------ arch/arm/mach-at91/Kconfig | 1 + 4 files changed, 31 insertions(+), 65 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bcaa8c83e522..bf856f492eb5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -42,6 +42,11 @@ config GENERIC_GPIO config GENERIC_TIME bool + default y + +config ARCH_USES_GETTIMEOFFSET + bool + default n config GENERIC_CLOCKEVENTS bool @@ -231,6 +236,7 @@ config ARCH_AAEC2000 select CPU_ARM920T select ARM_AMBA select HAVE_CLK + select ARCH_USES_GETTIMEOFFSET help This enables support for systems based on the Agilent AAEC-2000 @@ -271,6 +277,7 @@ config ARCH_AT91 select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select HAVE_CLK + select ARCH_USES_GETTIMEOFFSET help This enables support for systems based on the Atmel AT91RM9200, AT91SAM9 and AT91CAP9 processors. @@ -290,6 +297,7 @@ config ARCH_BCMRING config ARCH_CLPS711X bool "Cirrus Logic CLPS711x/EP721x-based" select CPU_ARM720T + select ARCH_USES_GETTIMEOFFSET help Support for Cirrus Logic 711x/721x based boards. @@ -298,6 +306,7 @@ config ARCH_GEMINI select CPU_FA526 select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB + select ARCH_USES_GETTIMEOFFSET help Support for the Cortina Systems Gemini family SoCs @@ -306,6 +315,7 @@ config ARCH_EBSA110 select CPU_SA110 select ISA select NO_IOPORT + select ARCH_USES_GETTIMEOFFSET help This is an evaluation board for the StrongARM processor available from Digital. It has limited hardware on-board, including an @@ -321,6 +331,7 @@ config ARCH_EP93XX select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_HOLES_MEMORYMODEL + select ARCH_USES_GETTIMEOFFSET help This enables support for the Cirrus EP93xx series of CPUs. @@ -328,6 +339,7 @@ config ARCH_FOOTBRIDGE bool "FootBridge" select CPU_SA110 select FOOTBRIDGE + select ARCH_USES_GETTIMEOFFSET help Support for systems based on the DC21285 companion chip ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder. @@ -366,6 +378,7 @@ config ARCH_H720X bool "Hynix HMS720x-based" select CPU_ARM720T select ISA_DMA_API + select ARCH_USES_GETTIMEOFFSET help This enables support for systems based on the Hynix HMS720x @@ -408,6 +421,7 @@ config ARCH_IXP23XX depends on MMU select CPU_XSC3 select PCI + select ARCH_USES_GETTIMEOFFSET help Support for Intel's IXP23xx (XScale) family of processors. @@ -416,6 +430,7 @@ config ARCH_IXP2000 depends on MMU select CPU_XSCALE select PCI + select ARCH_USES_GETTIMEOFFSET help Support for Intel's IXP2400/2800 (XScale) family of processors. @@ -434,6 +449,7 @@ config ARCH_L7200 bool "LinkUp-L7200" select CPU_ARM720T select FIQ + select ARCH_USES_GETTIMEOFFSET help Say Y here if you intend to run this kernel on a LinkUp Systems L7200 Software Development Board which uses an ARM720T processor. @@ -523,6 +539,7 @@ config ARCH_KS8695 select CPU_ARM922T select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB + select ARCH_USES_GETTIMEOFFSET help Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based System-on-Chip devices. @@ -569,6 +586,7 @@ config ARCH_PNX4008 bool "Philips Nexperia PNX4008 Mobile" select CPU_ARM926T select COMMON_CLKDEV + select ARCH_USES_GETTIMEOFFSET help This enables support for Philips PNX4008 mobile platform. @@ -613,6 +631,7 @@ config ARCH_RPC select ISA_DMA_API select NO_IOPORT select ARCH_SPARSEMEM_ENABLE + select ARCH_USES_GETTIMEOFFSET help On the Acorn Risc-PC, Linux can support the internal IDE disk and CD-ROM interface, serial and parallel port, and the floppy drive. @@ -639,6 +658,7 @@ config ARCH_S3C2410 select GENERIC_GPIO select ARCH_HAS_CPUFREQ select HAVE_CLK + select ARCH_USES_GETTIMEOFFSET help Samsung S3C2410X CPU based systems, such as the Simtec Electronics BAST (), the IPAQ 1940 or @@ -652,6 +672,7 @@ config ARCH_S3C64XX select ARM_VIC select HAVE_CLK select NO_IOPORT + select ARCH_USES_GETTIMEOFFSET select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB select SAMSUNG_CLKSRC @@ -708,6 +729,7 @@ config ARCH_SHARK select ISA_DMA select ZONE_DMA select PCI + select ARCH_USES_GETTIMEOFFSET help Support for the StrongARM based Digital DNARD machine, also known as "Shark" (). @@ -717,6 +739,7 @@ config ARCH_LH7A40X select CPU_ARM922T select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM + select ARCH_USES_GETTIMEOFFSET help Say Y here for systems based on one of the Sharp LH7A40X System on a Chip processors. These CPUs include an ARM922T diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h index 8bffc3ff3acf..35d408f6dccf 100644 --- a/arch/arm/include/asm/mach/time.h +++ b/arch/arm/include/asm/mach/time.h @@ -38,7 +38,7 @@ struct sys_timer { void (*init)(void); void (*suspend)(void); void (*resume)(void); -#ifndef CONFIG_GENERIC_TIME +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET unsigned long (*offset)(void); #endif }; diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 28753805d2d1..38c261f9951c 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -72,12 +72,15 @@ unsigned long profile_pc(struct pt_regs *regs) EXPORT_SYMBOL(profile_pc); #endif -#ifndef CONFIG_GENERIC_TIME -static unsigned long dummy_gettimeoffset(void) +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET +u32 arch_gettimeoffset(void) { + if (system_timer->offset != NULL) + return system_timer->offset() * 1000; + return 0; } -#endif +#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */ #ifdef CONFIG_LEDS_TIMER static inline void do_leds(void) @@ -93,63 +96,6 @@ static inline void do_leds(void) #define do_leds() #endif -#ifndef CONFIG_GENERIC_TIME -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - unsigned long seq; - unsigned long usec, sec; - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - usec = system_timer->offset(); - sec = xtime.tv_sec; - usec += xtime.tv_nsec / 1000; - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - /* usec may have gone up a lot: be safe */ - while (usec >= 1000000) { - usec -= 1000000; - sec++; - } - - tv->tv_sec = sec; - tv->tv_usec = usec; -} - -EXPORT_SYMBOL(do_gettimeofday); - -int do_settimeofday(struct timespec *tv) -{ - time_t wtm_sec, sec = tv->tv_sec; - long wtm_nsec, nsec = tv->tv_nsec; - - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) - return -EINVAL; - - write_seqlock_irq(&xtime_lock); - /* - * This is revolting. We need to set "xtime" correctly. However, the - * value in this location is the value at the most recent update of - * wall time. Discover what correction gettimeofday() would have - * done, and then undo it! - */ - nsec -= system_timer->offset() * NSEC_PER_USEC; - - wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); - wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); - - set_normalized_timespec(&xtime, sec, nsec); - set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - - ntp_clear(); - write_sequnlock_irq(&xtime_lock); - clock_was_set(); - return 0; -} - -EXPORT_SYMBOL(do_settimeofday); -#endif /* !CONFIG_GENERIC_TIME */ #ifndef CONFIG_GENERIC_CLOCKEVENTS /* @@ -214,10 +160,6 @@ device_initcall(timer_init_sysfs); void __init time_init(void) { -#ifndef CONFIG_GENERIC_TIME - if (system_timer->offset == NULL) - system_timer->offset = dummy_gettimeoffset; -#endif system_timer->init(); } diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 2db43a5ddd9b..8a5e8e9fe448 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -97,6 +97,7 @@ config ARCH_AT572D940HF config ARCH_AT91X40 bool "AT91x40" + select ARCH_USES_GETTIMEOFFSET endchoice -- cgit v1.2.3-59-g8ed1b From 62e7bec49479e0c61e8cfd914f722a9ca6fd52e5 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Wed, 24 Mar 2010 21:37:57 +0800 Subject: crypto: aesni-intel - Fix another CTR build failure with gas 2.16.1 The previous AES-NI CTR optimization compiling failure gas 2.16.1 fix introduces another compiling failure by itself. This patch fixes that. Reported-by: Andrew Morton Signed-off-by: Huang Ying Signed-off-by: Herbert Xu --- arch/x86/include/asm/inst.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/inst.h b/arch/x86/include/asm/inst.h index 840a399701b2..280bf7fb6aba 100644 --- a/arch/x86/include/asm/inst.h +++ b/arch/x86/include/asm/inst.h @@ -120,9 +120,9 @@ .macro REG_TYPE type reg R64_NUM reg_type_r64 \reg XMM_NUM reg_type_xmm \reg - .if reg_type_r64 != REG_NUM_INVALID + .if reg_type_r64 <> REG_NUM_INVALID \type = REG_TYPE_R64 - .elseif reg_type_xmm != REG_NUM_INVALID + .elseif reg_type_xmm <> REG_NUM_INVALID \type = REG_TYPE_XMM .else \type = REG_TYPE_INVALID -- cgit v1.2.3-59-g8ed1b From d814f30105798b6677ecb73ed61d691ff96dada9 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 24 Mar 2010 12:09:26 +0800 Subject: x86, perf: Add raw events support for the P4 PMU The adding of raw event support lead to complete code refactoring. I hope is became more readable then it was. The list of changes: 1) The 64bit config field is enough to hold all information we need to track event details. To achieve it we used *own* enum for events selection in ESCR register and map this key into proper value at moment of event enabling. For the same reason we use 12LSB bits in CCCR register -- to track which exactly cache trace event was requested. And we cear this bits at real 'write' moment. 2) There is no per-cpu area reserved for P4 PMU anymore. We don't need it. All is held by config. 3) Now we may use any available counter, ie we try to grab any possible counter. v2: - Lin Ming reported the lack of ESCR selector in CCCR for cache events v3: - Don't loose cache event codes at config unpacking procedure, we may need it one day so no obscure hack behind our back, better to clear reserved bits explicitly when needed (thanks Ming for pointing out) - Lin Ming fixed misplaced opcodes in cache events Signed-off-by: Cyrill Gorcunov Tested-by: Lin Ming Signed-off-by: Lin Ming Cc: Arnaldo Carvalho de Melo Cc: Stephane Eranian Cc: Robert Richter Cc: Frederic Weisbecker Cc: Cyrill Gorcunov Cc: Peter Zijlstra LKML-Reference: <1269403766.3409.6.camel@minggr.sh.intel.com> [ v4: did a few whitespace fixlets ] Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event_p4.h | 691 +++++++++++++++++--------------- arch/x86/kernel/cpu/perf_event_p4.c | 746 ++++++++++++++++++++--------------- 2 files changed, 806 insertions(+), 631 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index facf96186b26..b05400a542ff 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h @@ -15,38 +15,40 @@ * perf-MSRs are not shared and every thread has its * own perf-MSRs set) */ -#define ARCH_P4_TOTAL_ESCR (46) -#define ARCH_P4_RESERVED_ESCR (2) /* IQ_ESCR(0,1) not always present */ -#define ARCH_P4_MAX_ESCR (ARCH_P4_TOTAL_ESCR - ARCH_P4_RESERVED_ESCR) -#define ARCH_P4_MAX_CCCR (18) -#define ARCH_P4_MAX_COUNTER (ARCH_P4_MAX_CCCR / 2) - -#define P4_EVNTSEL_EVENT_MASK 0x7e000000U -#define P4_EVNTSEL_EVENT_SHIFT 25 -#define P4_EVNTSEL_EVENTMASK_MASK 0x01fffe00U -#define P4_EVNTSEL_EVENTMASK_SHIFT 9 -#define P4_EVNTSEL_TAG_MASK 0x000001e0U -#define P4_EVNTSEL_TAG_SHIFT 5 -#define P4_EVNTSEL_TAG_ENABLE 0x00000010U -#define P4_EVNTSEL_T0_OS 0x00000008U -#define P4_EVNTSEL_T0_USR 0x00000004U -#define P4_EVNTSEL_T1_OS 0x00000002U -#define P4_EVNTSEL_T1_USR 0x00000001U +#define ARCH_P4_TOTAL_ESCR (46) +#define ARCH_P4_RESERVED_ESCR (2) /* IQ_ESCR(0,1) not always present */ +#define ARCH_P4_MAX_ESCR (ARCH_P4_TOTAL_ESCR - ARCH_P4_RESERVED_ESCR) +#define ARCH_P4_MAX_CCCR (18) +#define ARCH_P4_MAX_COUNTER (ARCH_P4_MAX_CCCR / 2) + +#define P4_ESCR_EVENT_MASK 0x7e000000U +#define P4_ESCR_EVENT_SHIFT 25 +#define P4_ESCR_EVENTMASK_MASK 0x01fffe00U +#define P4_ESCR_EVENTMASK_SHIFT 9 +#define P4_ESCR_TAG_MASK 0x000001e0U +#define P4_ESCR_TAG_SHIFT 5 +#define P4_ESCR_TAG_ENABLE 0x00000010U +#define P4_ESCR_T0_OS 0x00000008U +#define P4_ESCR_T0_USR 0x00000004U +#define P4_ESCR_T1_OS 0x00000002U +#define P4_ESCR_T1_USR 0x00000001U + +#define P4_ESCR_EVENT(v) ((v) << P4_ESCR_EVENT_SHIFT) +#define P4_ESCR_EMASK(v) ((v) << P4_ESCR_EVENTMASK_SHIFT) +#define P4_ESCR_TAG(v) ((v) << P4_ESCR_TAG_SHIFT) /* Non HT mask */ -#define P4_EVNTSEL_MASK \ - (P4_EVNTSEL_EVENT_MASK | \ - P4_EVNTSEL_EVENTMASK_MASK | \ - P4_EVNTSEL_TAG_MASK | \ - P4_EVNTSEL_TAG_ENABLE | \ - P4_EVNTSEL_T0_OS | \ - P4_EVNTSEL_T0_USR) +#define P4_ESCR_MASK \ + (P4_ESCR_EVENT_MASK | \ + P4_ESCR_EVENTMASK_MASK | \ + P4_ESCR_TAG_MASK | \ + P4_ESCR_TAG_ENABLE | \ + P4_ESCR_T0_OS | \ + P4_ESCR_T0_USR) /* HT mask */ -#define P4_EVNTSEL_MASK_HT \ - (P4_EVNTSEL_MASK | \ - P4_EVNTSEL_T1_OS | \ - P4_EVNTSEL_T1_USR) +#define P4_ESCR_MASK_HT \ + (P4_ESCR_MASK | P4_ESCR_T1_OS | P4_ESCR_T1_USR) #define P4_CCCR_OVF 0x80000000U #define P4_CCCR_CASCADE 0x40000000U @@ -56,7 +58,6 @@ #define P4_CCCR_EDGE 0x01000000U #define P4_CCCR_THRESHOLD_MASK 0x00f00000U #define P4_CCCR_THRESHOLD_SHIFT 20 -#define P4_CCCR_THRESHOLD(v) ((v) << P4_CCCR_THRESHOLD_SHIFT) #define P4_CCCR_COMPLEMENT 0x00080000U #define P4_CCCR_COMPARE 0x00040000U #define P4_CCCR_ESCR_SELECT_MASK 0x0000e000U @@ -67,6 +68,13 @@ #define P4_CCCR_THREAD_ANY 0x00030000U #define P4_CCCR_RESERVED 0x00000fffU +#define P4_CCCR_THRESHOLD(v) ((v) << P4_CCCR_THRESHOLD_SHIFT) +#define P4_CCCR_ESEL(v) ((v) << P4_CCCR_ESCR_SELECT_SHIFT) + +/* Custom bits in reerved CCCR area */ +#define P4_CCCR_CACHE_OPS_MASK 0x0000003fU + + /* Non HT mask */ #define P4_CCCR_MASK \ (P4_CCCR_OVF | \ @@ -81,25 +89,11 @@ P4_CCCR_ENABLE) /* HT mask */ -#define P4_CCCR_MASK_HT \ - (P4_CCCR_MASK | \ - P4_CCCR_THREAD_ANY) +#define P4_CCCR_MASK_HT (P4_CCCR_MASK | P4_CCCR_THREAD_ANY) -/* - * format is 32 bit: ee ss aa aa - * where - * ee - 8 bit event - * ss - 8 bit selector - * aa aa - 16 bits reserved for tags/attributes - */ -#define P4_EVENT_PACK(event, selector) (((event) << 24) | ((selector) << 16)) -#define P4_EVENT_UNPACK_EVENT(packed) (((packed) >> 24) & 0xff) -#define P4_EVENT_UNPACK_SELECTOR(packed) (((packed) >> 16) & 0xff) -#define P4_EVENT_PACK_ATTR(attr) ((attr)) -#define P4_EVENT_UNPACK_ATTR(packed) ((packed) & 0xffff) -#define P4_MAKE_EVENT_ATTR(class, name, bit) class##_##name = (1 << bit) -#define P4_EVENT_ATTR(class, name) class##_##name -#define P4_EVENT_ATTR_STR(class, name) __stringify(class##_##name) +#define P4_GEN_ESCR_EMASK(class, name, bit) \ + class##__##name = ((1 << bit) << P4_ESCR_EVENTMASK_SHIFT) +#define P4_ESCR_EMASK_BIT(class, name) class##__##name /* * config field is 64bit width and consists of @@ -117,35 +111,29 @@ #define p4_config_pack_escr(v) (((u64)(v)) << 32) #define p4_config_pack_cccr(v) (((u64)(v)) & 0xffffffffULL) #define p4_config_unpack_escr(v) (((u64)(v)) >> 32) -#define p4_config_unpack_cccr(v) (((u64)(v)) & 0xfffff000ULL) +#define p4_config_unpack_cccr(v) (((u64)(v)) & 0xffffffffULL) #define p4_config_unpack_emask(v) \ ({ \ u32 t = p4_config_unpack_escr((v)); \ - t &= P4_EVNTSEL_EVENTMASK_MASK; \ - t >>= P4_EVNTSEL_EVENTMASK_SHIFT; \ + t = t & P4_ESCR_EVENTMASK_MASK; \ + t = t >> P4_ESCR_EVENTMASK_SHIFT; \ + t; \ + }) + +#define p4_config_unpack_event(v) \ + ({ \ + u32 t = p4_config_unpack_escr((v)); \ + t = t & P4_ESCR_EVENT_MASK; \ + t = t >> P4_ESCR_EVENT_SHIFT; \ t; \ }) -#define p4_config_unpack_key(v) (((u64)(v)) & P4_CCCR_RESERVED) +#define p4_config_unpack_cache_event(v) (((u64)(v)) & P4_CCCR_CACHE_OPS_MASK) #define P4_CONFIG_HT_SHIFT 63 #define P4_CONFIG_HT (1ULL << P4_CONFIG_HT_SHIFT) -static inline u32 p4_config_unpack_opcode(u64 config) -{ - u32 e, s; - - /* - * we don't care about HT presence here since - * event opcode doesn't depend on it - */ - e = (p4_config_unpack_escr(config) & P4_EVNTSEL_EVENT_MASK) >> P4_EVNTSEL_EVENT_SHIFT; - s = (p4_config_unpack_cccr(config) & P4_CCCR_ESCR_SELECT_MASK) >> P4_CCCR_ESCR_SELECT_SHIFT; - - return P4_EVENT_PACK(e, s); -} - static inline bool p4_is_event_cascaded(u64 config) { u32 cccr = p4_config_unpack_cccr(config); @@ -212,19 +200,73 @@ static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr) if (!p4_ht_thread(cpu)) { if (!exclude_os) - escr |= P4_EVNTSEL_T0_OS; + escr |= P4_ESCR_T0_OS; if (!exclude_usr) - escr |= P4_EVNTSEL_T0_USR; + escr |= P4_ESCR_T0_USR; } else { if (!exclude_os) - escr |= P4_EVNTSEL_T1_OS; + escr |= P4_ESCR_T1_OS; if (!exclude_usr) - escr |= P4_EVNTSEL_T1_USR; + escr |= P4_ESCR_T1_USR; } return escr; } +enum P4_EVENTS { + P4_EVENT_TC_DELIVER_MODE, + P4_EVENT_BPU_FETCH_REQUEST, + P4_EVENT_ITLB_REFERENCE, + P4_EVENT_MEMORY_CANCEL, + P4_EVENT_MEMORY_COMPLETE, + P4_EVENT_LOAD_PORT_REPLAY, + P4_EVENT_STORE_PORT_REPLAY, + P4_EVENT_MOB_LOAD_REPLAY, + P4_EVENT_PAGE_WALK_TYPE, + P4_EVENT_BSQ_CACHE_REFERENCE, + P4_EVENT_IOQ_ALLOCATION, + P4_EVENT_IOQ_ACTIVE_ENTRIES, + P4_EVENT_FSB_DATA_ACTIVITY, + P4_EVENT_BSQ_ALLOCATION, + P4_EVENT_BSQ_ACTIVE_ENTRIES, + P4_EVENT_SSE_INPUT_ASSIST, + P4_EVENT_PACKED_SP_UOP, + P4_EVENT_PACKED_DP_UOP, + P4_EVENT_SCALAR_SP_UOP, + P4_EVENT_SCALAR_DP_UOP, + P4_EVENT_64BIT_MMX_UOP, + P4_EVENT_128BIT_MMX_UOP, + P4_EVENT_X87_FP_UOP, + P4_EVENT_TC_MISC, + P4_EVENT_GLOBAL_POWER_EVENTS, + P4_EVENT_TC_MS_XFER, + P4_EVENT_UOP_QUEUE_WRITES, + P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, + P4_EVENT_RETIRED_BRANCH_TYPE, + P4_EVENT_RESOURCE_STALL, + P4_EVENT_WC_BUFFER, + P4_EVENT_B2B_CYCLES, + P4_EVENT_BNR, + P4_EVENT_SNOOP, + P4_EVENT_RESPONSE, + P4_EVENT_FRONT_END_EVENT, + P4_EVENT_EXECUTION_EVENT, + P4_EVENT_REPLAY_EVENT, + P4_EVENT_INSTR_RETIRED, + P4_EVENT_UOPS_RETIRED, + P4_EVENT_UOP_TYPE, + P4_EVENT_BRANCH_RETIRED, + P4_EVENT_MISPRED_BRANCH_RETIRED, + P4_EVENT_X87_ASSIST, + P4_EVENT_MACHINE_CLEAR, + P4_EVENT_INSTR_COMPLETED, +}; + +#define P4_OPCODE(event) event##_OPCODE +#define P4_OPCODE_ESEL(opcode) ((opcode & 0x00ff) >> 0) +#define P4_OPCODE_EVNT(opcode) ((opcode & 0xff00) >> 8) +#define P4_OPCODE_PACK(event, sel) (((event) << 8) | sel) + /* * Comments below the event represent ESCR restriction * for this event and counter index per ESCR @@ -238,484 +280,515 @@ static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr) * working so that we should not use this CCCR and respective * counter as result */ -#define P4_TC_DELIVER_MODE P4_EVENT_PACK(0x01, 0x01) +enum P4_EVENT_OPCODES { + P4_OPCODE(P4_EVENT_TC_DELIVER_MODE) = P4_OPCODE_PACK(0x01, 0x01), /* * MSR_P4_TC_ESCR0: 4, 5 * MSR_P4_TC_ESCR1: 6, 7 */ -#define P4_BPU_FETCH_REQUEST P4_EVENT_PACK(0x03, 0x00) + P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST) = P4_OPCODE_PACK(0x03, 0x00), /* * MSR_P4_BPU_ESCR0: 0, 1 * MSR_P4_BPU_ESCR1: 2, 3 */ -#define P4_ITLB_REFERENCE P4_EVENT_PACK(0x18, 0x03) + P4_OPCODE(P4_EVENT_ITLB_REFERENCE) = P4_OPCODE_PACK(0x18, 0x03), /* * MSR_P4_ITLB_ESCR0: 0, 1 * MSR_P4_ITLB_ESCR1: 2, 3 */ -#define P4_MEMORY_CANCEL P4_EVENT_PACK(0x02, 0x05) + P4_OPCODE(P4_EVENT_MEMORY_CANCEL) = P4_OPCODE_PACK(0x02, 0x05), /* * MSR_P4_DAC_ESCR0: 8, 9 * MSR_P4_DAC_ESCR1: 10, 11 */ -#define P4_MEMORY_COMPLETE P4_EVENT_PACK(0x08, 0x02) + P4_OPCODE(P4_EVENT_MEMORY_COMPLETE) = P4_OPCODE_PACK(0x08, 0x02), /* * MSR_P4_SAAT_ESCR0: 8, 9 * MSR_P4_SAAT_ESCR1: 10, 11 */ -#define P4_LOAD_PORT_REPLAY P4_EVENT_PACK(0x04, 0x02) + P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY) = P4_OPCODE_PACK(0x04, 0x02), /* * MSR_P4_SAAT_ESCR0: 8, 9 * MSR_P4_SAAT_ESCR1: 10, 11 */ -#define P4_STORE_PORT_REPLAY P4_EVENT_PACK(0x05, 0x02) + P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY) = P4_OPCODE_PACK(0x05, 0x02), /* * MSR_P4_SAAT_ESCR0: 8, 9 * MSR_P4_SAAT_ESCR1: 10, 11 */ -#define P4_MOB_LOAD_REPLAY P4_EVENT_PACK(0x03, 0x02) + P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY) = P4_OPCODE_PACK(0x03, 0x02), /* * MSR_P4_MOB_ESCR0: 0, 1 * MSR_P4_MOB_ESCR1: 2, 3 */ -#define P4_PAGE_WALK_TYPE P4_EVENT_PACK(0x01, 0x04) + P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE) = P4_OPCODE_PACK(0x01, 0x04), /* * MSR_P4_PMH_ESCR0: 0, 1 * MSR_P4_PMH_ESCR1: 2, 3 */ -#define P4_BSQ_CACHE_REFERENCE P4_EVENT_PACK(0x0c, 0x07) + P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE) = P4_OPCODE_PACK(0x0c, 0x07), /* * MSR_P4_BSU_ESCR0: 0, 1 * MSR_P4_BSU_ESCR1: 2, 3 */ -#define P4_IOQ_ALLOCATION P4_EVENT_PACK(0x03, 0x06) + P4_OPCODE(P4_EVENT_IOQ_ALLOCATION) = P4_OPCODE_PACK(0x03, 0x06), /* * MSR_P4_FSB_ESCR0: 0, 1 * MSR_P4_FSB_ESCR1: 2, 3 */ -#define P4_IOQ_ACTIVE_ENTRIES P4_EVENT_PACK(0x1a, 0x06) + P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES) = P4_OPCODE_PACK(0x1a, 0x06), /* * MSR_P4_FSB_ESCR1: 2, 3 */ -#define P4_FSB_DATA_ACTIVITY P4_EVENT_PACK(0x17, 0x06) + P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY) = P4_OPCODE_PACK(0x17, 0x06), /* * MSR_P4_FSB_ESCR0: 0, 1 * MSR_P4_FSB_ESCR1: 2, 3 */ -#define P4_BSQ_ALLOCATION P4_EVENT_PACK(0x05, 0x07) + P4_OPCODE(P4_EVENT_BSQ_ALLOCATION) = P4_OPCODE_PACK(0x05, 0x07), /* * MSR_P4_BSU_ESCR0: 0, 1 */ -#define P4_BSQ_ACTIVE_ENTRIES P4_EVENT_PACK(0x06, 0x07) + P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES) = P4_OPCODE_PACK(0x06, 0x07), /* * NOTE: no ESCR name in docs, it's guessed * MSR_P4_BSU_ESCR1: 2, 3 */ -#define P4_SSE_INPUT_ASSIST P4_EVENT_PACK(0x34, 0x01) + P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST) = P4_OPCODE_PACK(0x34, 0x01), /* * MSR_P4_FIRM_ESCR0: 8, 9 * MSR_P4_FIRM_ESCR1: 10, 11 */ -#define P4_PACKED_SP_UOP P4_EVENT_PACK(0x08, 0x01) + P4_OPCODE(P4_EVENT_PACKED_SP_UOP) = P4_OPCODE_PACK(0x08, 0x01), /* * MSR_P4_FIRM_ESCR0: 8, 9 * MSR_P4_FIRM_ESCR1: 10, 11 */ -#define P4_PACKED_DP_UOP P4_EVENT_PACK(0x0c, 0x01) + P4_OPCODE(P4_EVENT_PACKED_DP_UOP) = P4_OPCODE_PACK(0x0c, 0x01), /* * MSR_P4_FIRM_ESCR0: 8, 9 * MSR_P4_FIRM_ESCR1: 10, 11 */ -#define P4_SCALAR_SP_UOP P4_EVENT_PACK(0x0a, 0x01) + P4_OPCODE(P4_EVENT_SCALAR_SP_UOP) = P4_OPCODE_PACK(0x0a, 0x01), /* * MSR_P4_FIRM_ESCR0: 8, 9 * MSR_P4_FIRM_ESCR1: 10, 11 */ -#define P4_SCALAR_DP_UOP P4_EVENT_PACK(0x0e, 0x01) + P4_OPCODE(P4_EVENT_SCALAR_DP_UOP) = P4_OPCODE_PACK(0x0e, 0x01), /* * MSR_P4_FIRM_ESCR0: 8, 9 * MSR_P4_FIRM_ESCR1: 10, 11 */ -#define P4_64BIT_MMX_UOP P4_EVENT_PACK(0x02, 0x01) + P4_OPCODE(P4_EVENT_64BIT_MMX_UOP) = P4_OPCODE_PACK(0x02, 0x01), /* * MSR_P4_FIRM_ESCR0: 8, 9 * MSR_P4_FIRM_ESCR1: 10, 11 */ -#define P4_128BIT_MMX_UOP P4_EVENT_PACK(0x1a, 0x01) + P4_OPCODE(P4_EVENT_128BIT_MMX_UOP) = P4_OPCODE_PACK(0x1a, 0x01), /* * MSR_P4_FIRM_ESCR0: 8, 9 * MSR_P4_FIRM_ESCR1: 10, 11 */ -#define P4_X87_FP_UOP P4_EVENT_PACK(0x04, 0x01) + P4_OPCODE(P4_EVENT_X87_FP_UOP) = P4_OPCODE_PACK(0x04, 0x01), /* * MSR_P4_FIRM_ESCR0: 8, 9 * MSR_P4_FIRM_ESCR1: 10, 11 */ -#define P4_TC_MISC P4_EVENT_PACK(0x06, 0x01) + P4_OPCODE(P4_EVENT_TC_MISC) = P4_OPCODE_PACK(0x06, 0x01), /* * MSR_P4_TC_ESCR0: 4, 5 * MSR_P4_TC_ESCR1: 6, 7 */ -#define P4_GLOBAL_POWER_EVENTS P4_EVENT_PACK(0x13, 0x06) + P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS) = P4_OPCODE_PACK(0x13, 0x06), /* * MSR_P4_FSB_ESCR0: 0, 1 * MSR_P4_FSB_ESCR1: 2, 3 */ -#define P4_TC_MS_XFER P4_EVENT_PACK(0x05, 0x00) + P4_OPCODE(P4_EVENT_TC_MS_XFER) = P4_OPCODE_PACK(0x05, 0x00), /* * MSR_P4_MS_ESCR0: 4, 5 * MSR_P4_MS_ESCR1: 6, 7 */ -#define P4_UOP_QUEUE_WRITES P4_EVENT_PACK(0x09, 0x00) + P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES) = P4_OPCODE_PACK(0x09, 0x00), /* * MSR_P4_MS_ESCR0: 4, 5 * MSR_P4_MS_ESCR1: 6, 7 */ -#define P4_RETIRED_MISPRED_BRANCH_TYPE P4_EVENT_PACK(0x05, 0x02) + P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE) = P4_OPCODE_PACK(0x05, 0x02), /* * MSR_P4_TBPU_ESCR0: 4, 5 * MSR_P4_TBPU_ESCR1: 6, 7 */ -#define P4_RETIRED_BRANCH_TYPE P4_EVENT_PACK(0x04, 0x02) + P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE) = P4_OPCODE_PACK(0x04, 0x02), /* * MSR_P4_TBPU_ESCR0: 4, 5 * MSR_P4_TBPU_ESCR1: 6, 7 */ -#define P4_RESOURCE_STALL P4_EVENT_PACK(0x01, 0x01) + P4_OPCODE(P4_EVENT_RESOURCE_STALL) = P4_OPCODE_PACK(0x01, 0x01), /* * MSR_P4_ALF_ESCR0: 12, 13, 16 * MSR_P4_ALF_ESCR1: 14, 15, 17 */ -#define P4_WC_BUFFER P4_EVENT_PACK(0x05, 0x05) + P4_OPCODE(P4_EVENT_WC_BUFFER) = P4_OPCODE_PACK(0x05, 0x05), /* * MSR_P4_DAC_ESCR0: 8, 9 * MSR_P4_DAC_ESCR1: 10, 11 */ -#define P4_B2B_CYCLES P4_EVENT_PACK(0x16, 0x03) + P4_OPCODE(P4_EVENT_B2B_CYCLES) = P4_OPCODE_PACK(0x16, 0x03), /* * MSR_P4_FSB_ESCR0: 0, 1 * MSR_P4_FSB_ESCR1: 2, 3 */ -#define P4_BNR P4_EVENT_PACK(0x08, 0x03) + P4_OPCODE(P4_EVENT_BNR) = P4_OPCODE_PACK(0x08, 0x03), /* * MSR_P4_FSB_ESCR0: 0, 1 * MSR_P4_FSB_ESCR1: 2, 3 */ -#define P4_SNOOP P4_EVENT_PACK(0x06, 0x03) + P4_OPCODE(P4_EVENT_SNOOP) = P4_OPCODE_PACK(0x06, 0x03), /* * MSR_P4_FSB_ESCR0: 0, 1 * MSR_P4_FSB_ESCR1: 2, 3 */ -#define P4_RESPONSE P4_EVENT_PACK(0x04, 0x03) + P4_OPCODE(P4_EVENT_RESPONSE) = P4_OPCODE_PACK(0x04, 0x03), /* * MSR_P4_FSB_ESCR0: 0, 1 * MSR_P4_FSB_ESCR1: 2, 3 */ -#define P4_FRONT_END_EVENT P4_EVENT_PACK(0x08, 0x05) + P4_OPCODE(P4_EVENT_FRONT_END_EVENT) = P4_OPCODE_PACK(0x08, 0x05), /* * MSR_P4_CRU_ESCR2: 12, 13, 16 * MSR_P4_CRU_ESCR3: 14, 15, 17 */ -#define P4_EXECUTION_EVENT P4_EVENT_PACK(0x0c, 0x05) + P4_OPCODE(P4_EVENT_EXECUTION_EVENT) = P4_OPCODE_PACK(0x0c, 0x05), /* * MSR_P4_CRU_ESCR2: 12, 13, 16 * MSR_P4_CRU_ESCR3: 14, 15, 17 */ -#define P4_REPLAY_EVENT P4_EVENT_PACK(0x09, 0x05) + P4_OPCODE(P4_EVENT_REPLAY_EVENT) = P4_OPCODE_PACK(0x09, 0x05), /* * MSR_P4_CRU_ESCR2: 12, 13, 16 * MSR_P4_CRU_ESCR3: 14, 15, 17 */ -#define P4_INSTR_RETIRED P4_EVENT_PACK(0x02, 0x04) + P4_OPCODE(P4_EVENT_INSTR_RETIRED) = P4_OPCODE_PACK(0x02, 0x04), /* * MSR_P4_CRU_ESCR0: 12, 13, 16 * MSR_P4_CRU_ESCR1: 14, 15, 17 */ -#define P4_UOPS_RETIRED P4_EVENT_PACK(0x01, 0x04) + P4_OPCODE(P4_EVENT_UOPS_RETIRED) = P4_OPCODE_PACK(0x01, 0x04), /* * MSR_P4_CRU_ESCR0: 12, 13, 16 * MSR_P4_CRU_ESCR1: 14, 15, 17 */ -#define P4_UOP_TYPE P4_EVENT_PACK(0x02, 0x02) + P4_OPCODE(P4_EVENT_UOP_TYPE) = P4_OPCODE_PACK(0x02, 0x02), /* * MSR_P4_RAT_ESCR0: 12, 13, 16 * MSR_P4_RAT_ESCR1: 14, 15, 17 */ -#define P4_BRANCH_RETIRED P4_EVENT_PACK(0x06, 0x05) + P4_OPCODE(P4_EVENT_BRANCH_RETIRED) = P4_OPCODE_PACK(0x06, 0x05), /* * MSR_P4_CRU_ESCR2: 12, 13, 16 * MSR_P4_CRU_ESCR3: 14, 15, 17 */ -#define P4_MISPRED_BRANCH_RETIRED P4_EVENT_PACK(0x03, 0x04) + P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED) = P4_OPCODE_PACK(0x03, 0x04), /* * MSR_P4_CRU_ESCR0: 12, 13, 16 * MSR_P4_CRU_ESCR1: 14, 15, 17 */ -#define P4_X87_ASSIST P4_EVENT_PACK(0x03, 0x05) + P4_OPCODE(P4_EVENT_X87_ASSIST) = P4_OPCODE_PACK(0x03, 0x05), /* * MSR_P4_CRU_ESCR2: 12, 13, 16 * MSR_P4_CRU_ESCR3: 14, 15, 17 */ -#define P4_MACHINE_CLEAR P4_EVENT_PACK(0x02, 0x05) + P4_OPCODE(P4_EVENT_MACHINE_CLEAR) = P4_OPCODE_PACK(0x02, 0x05), /* * MSR_P4_CRU_ESCR2: 12, 13, 16 * MSR_P4_CRU_ESCR3: 14, 15, 17 */ -#define P4_INSTR_COMPLETED P4_EVENT_PACK(0x07, 0x04) + P4_OPCODE(P4_EVENT_INSTR_COMPLETED) = P4_OPCODE_PACK(0x07, 0x04), /* * MSR_P4_CRU_ESCR0: 12, 13, 16 * MSR_P4_CRU_ESCR1: 14, 15, 17 */ +}; /* - * a caller should use P4_EVENT_ATTR helper to - * pick the attribute needed, for example + * a caller should use P4_ESCR_EMASK_NAME helper to + * pick the EventMask needed, for example * - * P4_EVENT_ATTR(P4_TC_DELIVER_MODE, DD) + * P4_ESCR_EMASK_NAME(P4_EVENT_TC_DELIVER_MODE, DD) */ -enum P4_EVENTS_ATTR { - P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, DD, 0), - P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, DB, 1), - P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, DI, 2), - P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, BD, 3), - P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, BB, 4), - P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, BI, 5), - P4_MAKE_EVENT_ATTR(P4_TC_DELIVER_MODE, ID, 6), - - P4_MAKE_EVENT_ATTR(P4_BPU_FETCH_REQUEST, TCMISS, 0), - - P4_MAKE_EVENT_ATTR(P4_ITLB_REFERENCE, HIT, 0), - P4_MAKE_EVENT_ATTR(P4_ITLB_REFERENCE, MISS, 1), - P4_MAKE_EVENT_ATTR(P4_ITLB_REFERENCE, HIT_UK, 2), - - P4_MAKE_EVENT_ATTR(P4_MEMORY_CANCEL, ST_RB_FULL, 2), - P4_MAKE_EVENT_ATTR(P4_MEMORY_CANCEL, 64K_CONF, 3), - - P4_MAKE_EVENT_ATTR(P4_MEMORY_COMPLETE, LSC, 0), - P4_MAKE_EVENT_ATTR(P4_MEMORY_COMPLETE, SSC, 1), - - P4_MAKE_EVENT_ATTR(P4_LOAD_PORT_REPLAY, SPLIT_LD, 1), - - P4_MAKE_EVENT_ATTR(P4_STORE_PORT_REPLAY, SPLIT_ST, 1), - - P4_MAKE_EVENT_ATTR(P4_MOB_LOAD_REPLAY, NO_STA, 1), - P4_MAKE_EVENT_ATTR(P4_MOB_LOAD_REPLAY, NO_STD, 3), - P4_MAKE_EVENT_ATTR(P4_MOB_LOAD_REPLAY, PARTIAL_DATA, 4), - P4_MAKE_EVENT_ATTR(P4_MOB_LOAD_REPLAY, UNALGN_ADDR, 5), - - P4_MAKE_EVENT_ATTR(P4_PAGE_WALK_TYPE, DTMISS, 0), - P4_MAKE_EVENT_ATTR(P4_PAGE_WALK_TYPE, ITMISS, 1), - - P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITS, 0), - P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITE, 1), - P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITM, 2), - P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITS, 3), - P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITE, 4), - P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITM, 5), - P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_MISS, 8), - P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_MISS, 9), - P4_MAKE_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, WR_2ndL_MISS, 10), - - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, DEFAULT, 0), - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, ALL_READ, 5), - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, ALL_WRITE, 6), - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, MEM_UC, 7), - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, MEM_WC, 8), - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, MEM_WT, 9), - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, MEM_WP, 10), - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, MEM_WB, 11), - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, OWN, 13), - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, OTHER, 14), - P4_MAKE_EVENT_ATTR(P4_IOQ_ALLOCATION, PREFETCH, 15), - - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, DEFAULT, 0), - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, ALL_READ, 5), - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, ALL_WRITE, 6), - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, MEM_UC, 7), - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, MEM_WC, 8), - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, MEM_WT, 9), - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, MEM_WP, 10), - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, MEM_WB, 11), - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, OWN, 13), - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, OTHER, 14), - P4_MAKE_EVENT_ATTR(P4_IOQ_ACTIVE_ENTRIES, PREFETCH, 15), - - P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_DRV, 0), - P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_OWN, 1), - P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_OTHER, 2), - P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DBSY_DRV, 3), - P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DBSY_OWN, 4), - P4_MAKE_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DBSY_OTHER, 5), - - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_TYPE0, 0), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_TYPE1, 1), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_LEN0, 2), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_LEN1, 3), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_IO_TYPE, 5), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_LOCK_TYPE, 6), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_CACHE_TYPE, 7), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_SPLIT_TYPE, 8), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_DEM_TYPE, 9), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, REQ_ORD_TYPE, 10), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, MEM_TYPE0, 11), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, MEM_TYPE1, 12), - P4_MAKE_EVENT_ATTR(P4_BSQ_ALLOCATION, MEM_TYPE2, 13), - - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_TYPE0, 0), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_TYPE1, 1), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_LEN0, 2), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_LEN1, 3), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE, 5), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE, 6), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE, 7), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE, 8), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE, 9), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE, 10), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, MEM_TYPE0, 11), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, MEM_TYPE1, 12), - P4_MAKE_EVENT_ATTR(P4_BSQ_ACTIVE_ENTRIES, MEM_TYPE2, 13), - - P4_MAKE_EVENT_ATTR(P4_SSE_INPUT_ASSIST, ALL, 15), - - P4_MAKE_EVENT_ATTR(P4_PACKED_SP_UOP, ALL, 15), - - P4_MAKE_EVENT_ATTR(P4_PACKED_DP_UOP, ALL, 15), - - P4_MAKE_EVENT_ATTR(P4_SCALAR_SP_UOP, ALL, 15), - - P4_MAKE_EVENT_ATTR(P4_SCALAR_DP_UOP, ALL, 15), - - P4_MAKE_EVENT_ATTR(P4_64BIT_MMX_UOP, ALL, 15), - - P4_MAKE_EVENT_ATTR(P4_128BIT_MMX_UOP, ALL, 15), - - P4_MAKE_EVENT_ATTR(P4_X87_FP_UOP, ALL, 15), - - P4_MAKE_EVENT_ATTR(P4_TC_MISC, FLUSH, 4), - - P4_MAKE_EVENT_ATTR(P4_GLOBAL_POWER_EVENTS, RUNNING, 0), - - P4_MAKE_EVENT_ATTR(P4_TC_MS_XFER, CISC, 0), - - P4_MAKE_EVENT_ATTR(P4_UOP_QUEUE_WRITES, FROM_TC_BUILD, 0), - P4_MAKE_EVENT_ATTR(P4_UOP_QUEUE_WRITES, FROM_TC_DELIVER, 1), - P4_MAKE_EVENT_ATTR(P4_UOP_QUEUE_WRITES, FROM_ROM, 2), - - P4_MAKE_EVENT_ATTR(P4_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL, 1), - P4_MAKE_EVENT_ATTR(P4_RETIRED_MISPRED_BRANCH_TYPE, CALL, 2), - P4_MAKE_EVENT_ATTR(P4_RETIRED_MISPRED_BRANCH_TYPE, RETURN, 3), - P4_MAKE_EVENT_ATTR(P4_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT, 4), - - P4_MAKE_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CONDITIONAL, 1), - P4_MAKE_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CALL, 2), - P4_MAKE_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, RETURN, 3), - P4_MAKE_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, INDIRECT, 4), - - P4_MAKE_EVENT_ATTR(P4_RESOURCE_STALL, SBFULL, 5), - - P4_MAKE_EVENT_ATTR(P4_WC_BUFFER, WCB_EVICTS, 0), - P4_MAKE_EVENT_ATTR(P4_WC_BUFFER, WCB_FULL_EVICTS, 1), - - P4_MAKE_EVENT_ATTR(P4_FRONT_END_EVENT, NBOGUS, 0), - P4_MAKE_EVENT_ATTR(P4_FRONT_END_EVENT, BOGUS, 1), - - P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, NBOGUS0, 0), - P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, NBOGUS1, 1), - P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, NBOGUS2, 2), - P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, NBOGUS3, 3), - P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, BOGUS0, 4), - P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, BOGUS1, 5), - P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, BOGUS2, 6), - P4_MAKE_EVENT_ATTR(P4_EXECUTION_EVENT, BOGUS3, 7), - - P4_MAKE_EVENT_ATTR(P4_REPLAY_EVENT, NBOGUS, 0), - P4_MAKE_EVENT_ATTR(P4_REPLAY_EVENT, BOGUS, 1), - - P4_MAKE_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSNTAG, 0), - P4_MAKE_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSTAG, 1), - P4_MAKE_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSNTAG, 2), - P4_MAKE_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSTAG, 3), - - P4_MAKE_EVENT_ATTR(P4_UOPS_RETIRED, NBOGUS, 0), - P4_MAKE_EVENT_ATTR(P4_UOPS_RETIRED, BOGUS, 1), +enum P4_ESCR_EMASKS { + P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DD, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DB, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DI, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BD, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BB, 4), + P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BI, 5), + P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, ID, 6), + + P4_GEN_ESCR_EMASK(P4_EVENT_BPU_FETCH_REQUEST, TCMISS, 0), + + P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, HIT, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, MISS, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, HIT_UK, 2), + + P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_CANCEL, ST_RB_FULL, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_CANCEL, 64K_CONF, 3), + + P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_COMPLETE, LSC, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_COMPLETE, SSC, 1), + + P4_GEN_ESCR_EMASK(P4_EVENT_LOAD_PORT_REPLAY, SPLIT_LD, 1), + + P4_GEN_ESCR_EMASK(P4_EVENT_STORE_PORT_REPLAY, SPLIT_ST, 1), + + P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, NO_STA, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, NO_STD, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, PARTIAL_DATA, 4), + P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, UNALGN_ADDR, 5), + + P4_GEN_ESCR_EMASK(P4_EVENT_PAGE_WALK_TYPE, DTMISS, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_PAGE_WALK_TYPE, ITMISS, 1), + + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE, 4), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM, 5), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS, 8), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS, 9), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS, 10), + + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, DEFAULT, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, ALL_READ, 5), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, ALL_WRITE, 6), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_UC, 7), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WC, 8), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WT, 9), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WP, 10), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WB, 11), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, OWN, 13), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, OTHER, 14), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, PREFETCH, 15), + + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, DEFAULT, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_READ, 5), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_WRITE, 6), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_UC, 7), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WC, 8), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WT, 9), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WP, 10), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WB, 11), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, OWN, 13), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, OTHER, 14), + P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, PREFETCH, 15), + + P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OTHER, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_DRV, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OWN, 4), + P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OTHER, 5), + + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE0, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE1, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LEN0, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LEN1, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_IO_TYPE, 5), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LOCK_TYPE, 6), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_CACHE_TYPE, 7), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_SPLIT_TYPE, 8), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_DEM_TYPE, 9), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_ORD_TYPE, 10), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE0, 11), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE1, 12), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE2, 13), + + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE0, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE1, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN0, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN1, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE, 5), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE, 6), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE, 7), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE, 8), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE, 9), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE, 10), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE0, 11), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE1, 12), + P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE2, 13), + + P4_GEN_ESCR_EMASK(P4_EVENT_SSE_INPUT_ASSIST, ALL, 15), + + P4_GEN_ESCR_EMASK(P4_EVENT_PACKED_SP_UOP, ALL, 15), + + P4_GEN_ESCR_EMASK(P4_EVENT_PACKED_DP_UOP, ALL, 15), + + P4_GEN_ESCR_EMASK(P4_EVENT_SCALAR_SP_UOP, ALL, 15), + + P4_GEN_ESCR_EMASK(P4_EVENT_SCALAR_DP_UOP, ALL, 15), + + P4_GEN_ESCR_EMASK(P4_EVENT_64BIT_MMX_UOP, ALL, 15), + + P4_GEN_ESCR_EMASK(P4_EVENT_128BIT_MMX_UOP, ALL, 15), + + P4_GEN_ESCR_EMASK(P4_EVENT_X87_FP_UOP, ALL, 15), + + P4_GEN_ESCR_EMASK(P4_EVENT_TC_MISC, FLUSH, 4), + + P4_GEN_ESCR_EMASK(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING, 0), + + P4_GEN_ESCR_EMASK(P4_EVENT_TC_MS_XFER, CISC, 0), + + P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_BUILD, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_DELIVER, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_ROM, 2), + + P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CALL, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, RETURN, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT, 4), + + P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, CALL, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT, 4), + + P4_GEN_ESCR_EMASK(P4_EVENT_RESOURCE_STALL, SBFULL, 5), + + P4_GEN_ESCR_EMASK(P4_EVENT_WC_BUFFER, WCB_EVICTS, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_WC_BUFFER, WCB_FULL_EVICTS, 1), + + P4_GEN_ESCR_EMASK(P4_EVENT_FRONT_END_EVENT, NBOGUS, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_FRONT_END_EVENT, BOGUS, 1), + + P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS0, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS1, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS2, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS3, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS0, 4), + P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS1, 5), + P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS2, 6), + P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS3, 7), + + P4_GEN_ESCR_EMASK(P4_EVENT_REPLAY_EVENT, NBOGUS, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_REPLAY_EVENT, BOGUS, 1), + + P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, NBOGUSTAG, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, BOGUSNTAG, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, BOGUSTAG, 3), + + P4_GEN_ESCR_EMASK(P4_EVENT_UOPS_RETIRED, NBOGUS, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_UOPS_RETIRED, BOGUS, 1), - P4_MAKE_EVENT_ATTR(P4_UOP_TYPE, TAGLOADS, 1), - P4_MAKE_EVENT_ATTR(P4_UOP_TYPE, TAGSTORES, 2), - - P4_MAKE_EVENT_ATTR(P4_BRANCH_RETIRED, MMNP, 0), - P4_MAKE_EVENT_ATTR(P4_BRANCH_RETIRED, MMNM, 1), - P4_MAKE_EVENT_ATTR(P4_BRANCH_RETIRED, MMTP, 2), - P4_MAKE_EVENT_ATTR(P4_BRANCH_RETIRED, MMTM, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_UOP_TYPE, TAGLOADS, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_UOP_TYPE, TAGSTORES, 2), + + P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMNP, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMNM, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMTP, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMTM, 3), - P4_MAKE_EVENT_ATTR(P4_MISPRED_BRANCH_RETIRED, NBOGUS, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS, 0), - P4_MAKE_EVENT_ATTR(P4_X87_ASSIST, FPSU, 0), - P4_MAKE_EVENT_ATTR(P4_X87_ASSIST, FPSO, 1), - P4_MAKE_EVENT_ATTR(P4_X87_ASSIST, POAO, 2), - P4_MAKE_EVENT_ATTR(P4_X87_ASSIST, POAU, 3), - P4_MAKE_EVENT_ATTR(P4_X87_ASSIST, PREA, 4), + P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, FPSU, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, FPSO, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, POAO, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, POAU, 3), + P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, PREA, 4), - P4_MAKE_EVENT_ATTR(P4_MACHINE_CLEAR, CLEAR, 0), - P4_MAKE_EVENT_ATTR(P4_MACHINE_CLEAR, MOCLEAR, 1), - P4_MAKE_EVENT_ATTR(P4_MACHINE_CLEAR, SMCLEAR, 2), + P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, CLEAR, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, MOCLEAR, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, SMCLEAR, 2), - P4_MAKE_EVENT_ATTR(P4_INSTR_COMPLETED, NBOGUS, 0), - P4_MAKE_EVENT_ATTR(P4_INSTR_COMPLETED, BOGUS, 1), + P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_COMPLETED, NBOGUS, 0), + P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_COMPLETED, BOGUS, 1), }; -enum { - KEY_P4_L1D_OP_READ_RESULT_MISS = PERF_COUNT_HW_MAX, - KEY_P4_LL_OP_READ_RESULT_MISS, - KEY_P4_DTLB_OP_READ_RESULT_MISS, - KEY_P4_DTLB_OP_WRITE_RESULT_MISS, - KEY_P4_ITLB_OP_READ_RESULT_ACCESS, - KEY_P4_ITLB_OP_READ_RESULT_MISS, - KEY_P4_UOP_TYPE, +/* P4 PEBS: stale for a while */ +#define P4_PEBS_METRIC_MASK 0x00001fffU +#define P4_PEBS_UOB_TAG 0x01000000U +#define P4_PEBS_ENABLE 0x02000000U + +/* Replay metrics for MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT */ +#define P4_PEBS__1stl_cache_load_miss_retired 0x3000001 +#define P4_PEBS__2ndl_cache_load_miss_retired 0x3000002 +#define P4_PEBS__dtlb_load_miss_retired 0x3000004 +#define P4_PEBS__dtlb_store_miss_retired 0x3000004 +#define P4_PEBS__dtlb_all_miss_retired 0x3000004 +#define P4_PEBS__tagged_mispred_branch 0x3018000 +#define P4_PEBS__mob_load_replay_retired 0x3000200 +#define P4_PEBS__split_load_retired 0x3000400 +#define P4_PEBS__split_store_retired 0x3000400 + +#define P4_VERT__1stl_cache_load_miss_retired 0x0000001 +#define P4_VERT__2ndl_cache_load_miss_retired 0x0000001 +#define P4_VERT__dtlb_load_miss_retired 0x0000001 +#define P4_VERT__dtlb_store_miss_retired 0x0000002 +#define P4_VERT__dtlb_all_miss_retired 0x0000003 +#define P4_VERT__tagged_mispred_branch 0x0000010 +#define P4_VERT__mob_load_replay_retired 0x0000001 +#define P4_VERT__split_load_retired 0x0000001 +#define P4_VERT__split_store_retired 0x0000002 + +enum P4_CACHE_EVENTS { + P4_CACHE__NONE, + + P4_CACHE__1stl_cache_load_miss_retired, + P4_CACHE__2ndl_cache_load_miss_retired, + P4_CACHE__dtlb_load_miss_retired, + P4_CACHE__dtlb_store_miss_retired, + P4_CACHE__itlb_reference_hit, + P4_CACHE__itlb_reference_miss, + + P4_CACHE__MAX }; #endif /* PERF_EVENT_P4_H */ diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index b8a811ab7609..f8fe069f14e2 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -11,35 +11,281 @@ #include +#define P4_CNTR_LIMIT 3 /* * array indices: 0,1 - HT threads, used with HT enabled cpu */ -struct p4_event_template { - u32 opcode; /* ESCR event + CCCR selector */ - u64 config; /* packed predefined bits */ - int dep; /* upstream dependency event index */ - int key; /* index into p4_templates */ - u64 msr; /* - * the high 32 bits set into MSR_IA32_PEBS_ENABLE and - * the low 32 bits set into MSR_P4_PEBS_MATRIX_VERT - * for cache events - */ - unsigned int emask; /* ESCR EventMask */ - unsigned int escr_msr[2]; /* ESCR MSR for this event */ - unsigned int cntr[2]; /* counter index (offset) */ +struct p4_event_bind { + unsigned int opcode; /* Event code and ESCR selector */ + unsigned int escr_msr[2]; /* ESCR MSR for this event */ + unsigned char cntr[2][P4_CNTR_LIMIT]; /* counter index (offset), -1 on abscence */ }; -struct p4_pmu_res { - /* maps hw_conf::idx into template for ESCR sake */ - struct p4_event_template *tpl[ARCH_P4_MAX_CCCR]; +struct p4_cache_event_bind { + unsigned int metric_pebs; + unsigned int metric_vert; }; -static DEFINE_PER_CPU(struct p4_pmu_res, p4_pmu_config); +#define P4_GEN_CACHE_EVENT_BIND(name) \ + [P4_CACHE__##name] = { \ + .metric_pebs = P4_PEBS__##name, \ + .metric_vert = P4_VERT__##name, \ + } + +static struct p4_cache_event_bind p4_cache_event_bind_map[] = { + P4_GEN_CACHE_EVENT_BIND(1stl_cache_load_miss_retired), + P4_GEN_CACHE_EVENT_BIND(2ndl_cache_load_miss_retired), + P4_GEN_CACHE_EVENT_BIND(dtlb_load_miss_retired), + P4_GEN_CACHE_EVENT_BIND(dtlb_store_miss_retired), +}; + +/* + * Note that we don't use CCCR1 here, there is an + * exception for P4_BSQ_ALLOCATION but we just have + * no workaround + * + * consider this binding as resources which particular + * event may borrow, it doesn't contain EventMask, + * Tags and friends -- they are left to a caller + */ +static struct p4_event_bind p4_event_bind_map[] = { + [P4_EVENT_TC_DELIVER_MODE] = { + .opcode = P4_OPCODE(P4_EVENT_TC_DELIVER_MODE), + .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 }, + .cntr = { {4, 5, -1}, {6, 7, -1} }, + }, + [P4_EVENT_BPU_FETCH_REQUEST] = { + .opcode = P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST), + .escr_msr = { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_ITLB_REFERENCE] = { + .opcode = P4_OPCODE(P4_EVENT_ITLB_REFERENCE), + .escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_MEMORY_CANCEL] = { + .opcode = P4_OPCODE(P4_EVENT_MEMORY_CANCEL), + .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_MEMORY_COMPLETE] = { + .opcode = P4_OPCODE(P4_EVENT_MEMORY_COMPLETE), + .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_LOAD_PORT_REPLAY] = { + .opcode = P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY), + .escr_msr = { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_STORE_PORT_REPLAY] = { + .opcode = P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY), + .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_MOB_LOAD_REPLAY] = { + .opcode = P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY), + .escr_msr = { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_PAGE_WALK_TYPE] = { + .opcode = P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE), + .escr_msr = { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_BSQ_CACHE_REFERENCE] = { + .opcode = P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE), + .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_IOQ_ALLOCATION] = { + .opcode = P4_OPCODE(P4_EVENT_IOQ_ALLOCATION), + .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_IOQ_ACTIVE_ENTRIES] = { /* shared ESCR */ + .opcode = P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES), + .escr_msr = { MSR_P4_FSB_ESCR1, MSR_P4_FSB_ESCR1 }, + .cntr = { {2, -1, -1}, {3, -1, -1} }, + }, + [P4_EVENT_FSB_DATA_ACTIVITY] = { + .opcode = P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY), + .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_BSQ_ALLOCATION] = { /* shared ESCR, broken CCCR1 */ + .opcode = P4_OPCODE(P4_EVENT_BSQ_ALLOCATION), + .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 }, + .cntr = { {0, -1, -1}, {1, -1, -1} }, + }, + [P4_EVENT_BSQ_ACTIVE_ENTRIES] = { /* shared ESCR */ + .opcode = P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES), + .escr_msr = { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 }, + .cntr = { {2, -1, -1}, {3, -1, -1} }, + }, + [P4_EVENT_SSE_INPUT_ASSIST] = { + .opcode = P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST), + .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_PACKED_SP_UOP] = { + .opcode = P4_OPCODE(P4_EVENT_PACKED_SP_UOP), + .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_PACKED_DP_UOP] = { + .opcode = P4_OPCODE(P4_EVENT_PACKED_DP_UOP), + .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_SCALAR_SP_UOP] = { + .opcode = P4_OPCODE(P4_EVENT_SCALAR_SP_UOP), + .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_SCALAR_DP_UOP] = { + .opcode = P4_OPCODE(P4_EVENT_SCALAR_DP_UOP), + .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_64BIT_MMX_UOP] = { + .opcode = P4_OPCODE(P4_EVENT_64BIT_MMX_UOP), + .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_128BIT_MMX_UOP] = { + .opcode = P4_OPCODE(P4_EVENT_128BIT_MMX_UOP), + .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_X87_FP_UOP] = { + .opcode = P4_OPCODE(P4_EVENT_X87_FP_UOP), + .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_TC_MISC] = { + .opcode = P4_OPCODE(P4_EVENT_TC_MISC), + .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 }, + .cntr = { {4, 5, -1}, {6, 7, -1} }, + }, + [P4_EVENT_GLOBAL_POWER_EVENTS] = { + .opcode = P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS), + .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_TC_MS_XFER] = { + .opcode = P4_OPCODE(P4_EVENT_TC_MS_XFER), + .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 }, + .cntr = { {4, 5, -1}, {6, 7, -1} }, + }, + [P4_EVENT_UOP_QUEUE_WRITES] = { + .opcode = P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES), + .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 }, + .cntr = { {4, 5, -1}, {6, 7, -1} }, + }, + [P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = { + .opcode = P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE), + .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 }, + .cntr = { {4, 5, -1}, {6, 7, -1} }, + }, + [P4_EVENT_RETIRED_BRANCH_TYPE] = { + .opcode = P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE), + .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 }, + .cntr = { {4, 5, -1}, {6, 7, -1} }, + }, + [P4_EVENT_RESOURCE_STALL] = { + .opcode = P4_OPCODE(P4_EVENT_RESOURCE_STALL), + .escr_msr = { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_WC_BUFFER] = { + .opcode = P4_OPCODE(P4_EVENT_WC_BUFFER), + .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 }, + .cntr = { {8, 9, -1}, {10, 11, -1} }, + }, + [P4_EVENT_B2B_CYCLES] = { + .opcode = P4_OPCODE(P4_EVENT_B2B_CYCLES), + .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_BNR] = { + .opcode = P4_OPCODE(P4_EVENT_BNR), + .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_SNOOP] = { + .opcode = P4_OPCODE(P4_EVENT_SNOOP), + .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_RESPONSE] = { + .opcode = P4_OPCODE(P4_EVENT_RESPONSE), + .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, + .cntr = { {0, -1, -1}, {2, -1, -1} }, + }, + [P4_EVENT_FRONT_END_EVENT] = { + .opcode = P4_OPCODE(P4_EVENT_FRONT_END_EVENT), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_EXECUTION_EVENT] = { + .opcode = P4_OPCODE(P4_EVENT_EXECUTION_EVENT), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_REPLAY_EVENT] = { + .opcode = P4_OPCODE(P4_EVENT_REPLAY_EVENT), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_INSTR_RETIRED] = { + .opcode = P4_OPCODE(P4_EVENT_INSTR_RETIRED), + .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_UOPS_RETIRED] = { + .opcode = P4_OPCODE(P4_EVENT_UOPS_RETIRED), + .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_UOP_TYPE] = { + .opcode = P4_OPCODE(P4_EVENT_UOP_TYPE), + .escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_BRANCH_RETIRED] = { + .opcode = P4_OPCODE(P4_EVENT_BRANCH_RETIRED), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_MISPRED_BRANCH_RETIRED] = { + .opcode = P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED), + .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_X87_ASSIST] = { + .opcode = P4_OPCODE(P4_EVENT_X87_ASSIST), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_MACHINE_CLEAR] = { + .opcode = P4_OPCODE(P4_EVENT_MACHINE_CLEAR), + .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, + [P4_EVENT_INSTR_COMPLETED] = { + .opcode = P4_OPCODE(P4_EVENT_INSTR_COMPLETED), + .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, + .cntr = { {12, 13, 16}, {14, 15, 17} }, + }, +}; -#define P4_CACHE_EVENT_CONFIG(event, bit) \ - p4_config_pack_escr(P4_EVENT_UNPACK_EVENT(event) << P4_EVNTSEL_EVENT_SHIFT) | \ - p4_config_pack_escr((event##_##bit) << P4_EVNTSEL_EVENTMASK_SHIFT) | \ - p4_config_pack_cccr(P4_EVENT_UNPACK_SELECTOR(event) << P4_CCCR_ESCR_SELECT_SHIFT) +#define P4_GEN_CACHE_EVENT(event, bit, cache_event) \ + p4_config_pack_escr(P4_ESCR_EVENT(event) | \ + P4_ESCR_EMASK_BIT(event, bit)) | \ + p4_config_pack_cccr(cache_event | \ + P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event)))) static __initconst u64 p4_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] @@ -49,42 +295,35 @@ static __initconst u64 p4_hw_cache_event_ids [ C(L1D ) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = 0x0, - /* 1stL_cache_load_miss_retired */ - [ C(RESULT_MISS) ] = P4_CACHE_EVENT_CONFIG(P4_REPLAY_EVENT, NBOGUS) - | KEY_P4_L1D_OP_READ_RESULT_MISS, + [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS, + P4_CACHE__1stl_cache_load_miss_retired), }, }, [ C(LL ) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = 0x0, - /* 2ndL_cache_load_miss_retired */ - [ C(RESULT_MISS) ] = P4_CACHE_EVENT_CONFIG(P4_REPLAY_EVENT, NBOGUS) - | KEY_P4_LL_OP_READ_RESULT_MISS, + [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS, + P4_CACHE__2ndl_cache_load_miss_retired), }, - }, +}, [ C(DTLB) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = 0x0, - /* DTLB_load_miss_retired */ - [ C(RESULT_MISS) ] = P4_CACHE_EVENT_CONFIG(P4_REPLAY_EVENT, NBOGUS) - | KEY_P4_DTLB_OP_READ_RESULT_MISS, + [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS, + P4_CACHE__dtlb_load_miss_retired), }, [ C(OP_WRITE) ] = { [ C(RESULT_ACCESS) ] = 0x0, - /* DTLB_store_miss_retired */ - [ C(RESULT_MISS) ] = P4_CACHE_EVENT_CONFIG(P4_REPLAY_EVENT, NBOGUS) - | KEY_P4_DTLB_OP_WRITE_RESULT_MISS, + [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS, + P4_CACHE__dtlb_store_miss_retired), }, }, [ C(ITLB) ] = { [ C(OP_READ) ] = { - /* ITLB_reference.HIT */ - [ C(RESULT_ACCESS) ] = P4_CACHE_EVENT_CONFIG(P4_ITLB_REFERENCE, HIT) - | KEY_P4_ITLB_OP_READ_RESULT_ACCESS, - - /* ITLB_reference.MISS */ - [ C(RESULT_MISS) ] = P4_CACHE_EVENT_CONFIG(P4_ITLB_REFERENCE, MISS) - | KEY_P4_ITLB_OP_READ_RESULT_MISS, + [ C(RESULT_ACCESS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, HIT, + P4_CACHE__itlb_reference_hit), + [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, MISS, + P4_CACHE__itlb_reference_miss), }, [ C(OP_WRITE) ] = { [ C(RESULT_ACCESS) ] = -1, @@ -97,219 +336,89 @@ static __initconst u64 p4_hw_cache_event_ids }, }; -/* - * WARN: CCCR1 doesn't have a working enable bit so try to not - * use it if possible - * - * Also as only we start to support raw events we will need to - * append _all_ P4_EVENT_PACK'ed events here - */ -struct p4_event_template p4_templates[] = { - [0] = { - .opcode = P4_GLOBAL_POWER_EVENTS, - .config = 0, - .dep = -1, - .key = 0, - .emask = - P4_EVENT_ATTR(P4_GLOBAL_POWER_EVENTS, RUNNING), - .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, - .cntr = { 0, 2 }, - }, - [1] = { - .opcode = P4_INSTR_RETIRED, - .config = 0, - .dep = -1, /* needs front-end tagging */ - .key = 1, - .emask = - P4_EVENT_ATTR(P4_INSTR_RETIRED, NBOGUSNTAG) | - P4_EVENT_ATTR(P4_INSTR_RETIRED, BOGUSNTAG), - .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, - .cntr = { 12, 14 }, - }, - [2] = { - .opcode = P4_BSQ_CACHE_REFERENCE, - .config = 0, - .dep = -1, - .key = 2, - .emask = - P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) | - P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) | - P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_HITM) | - P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITS) | - P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITE) | - P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_HITM), - .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 }, - .cntr = { 0, 2 }, - }, - [3] = { - .opcode = P4_BSQ_CACHE_REFERENCE, - .config = 0, - .dep = -1, - .key = 3, - .emask = - P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) | - P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) | - P4_EVENT_ATTR(P4_BSQ_CACHE_REFERENCE, WR_2ndL_MISS), - .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 }, - .cntr = { 0, 3 }, - }, - [4] = { - .opcode = P4_RETIRED_BRANCH_TYPE, - .config = 0, - .dep = -1, - .key = 4, - .emask = - P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CONDITIONAL) | - P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, CALL) | - P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, RETURN) | - P4_EVENT_ATTR(P4_RETIRED_BRANCH_TYPE, INDIRECT), - .escr_msr = { MSR_P4_TBPU_ESCR0, MSR_P4_TBPU_ESCR1 }, - .cntr = { 4, 6 }, - }, - [5] = { - .opcode = P4_MISPRED_BRANCH_RETIRED, - .config = 0, - .dep = -1, - .key = 5, - .emask = - P4_EVENT_ATTR(P4_MISPRED_BRANCH_RETIRED, NBOGUS), - .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, - .cntr = { 12, 14 }, - }, - [6] = { - .opcode = P4_FSB_DATA_ACTIVITY, - .config = p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE), - .dep = -1, - .key = 6, - .emask = - P4_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_DRV) | - P4_EVENT_ATTR(P4_FSB_DATA_ACTIVITY, DRDY_OWN), - .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, - .cntr = { 0, 2 }, - }, - [KEY_P4_L1D_OP_READ_RESULT_MISS] = { - .opcode = P4_REPLAY_EVENT, - .config = 0, - .dep = -1, - .msr = (u64)(1 << 0 | 1 << 24) << 32 | (1 << 0), - .key = KEY_P4_L1D_OP_READ_RESULT_MISS, - .emask = - P4_EVENT_ATTR(P4_REPLAY_EVENT, NBOGUS), - .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR2 }, - .cntr = { 16, 17 }, - }, - [KEY_P4_LL_OP_READ_RESULT_MISS] = { - .opcode = P4_REPLAY_EVENT, - .config = 0, - .dep = -1, - .msr = (u64)(1 << 1 | 1 << 24) << 32 | (1 << 0), - .key = KEY_P4_LL_OP_READ_RESULT_MISS, - .emask = - P4_EVENT_ATTR(P4_REPLAY_EVENT, NBOGUS), - .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR2 }, - .cntr = { 16, 17 }, - }, - [KEY_P4_DTLB_OP_READ_RESULT_MISS] = { - .opcode = P4_REPLAY_EVENT, - .config = 0, - .dep = -1, - .msr = (u64)(1 << 2 | 1 << 24) << 32 | (1 << 0), - .key = KEY_P4_DTLB_OP_READ_RESULT_MISS, - .emask = - P4_EVENT_ATTR(P4_REPLAY_EVENT, NBOGUS), - .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR2 }, - .cntr = { 16, 17 }, - }, - [KEY_P4_DTLB_OP_WRITE_RESULT_MISS] = { - .opcode = P4_REPLAY_EVENT, - .config = 0, - .dep = -1, - .msr = (u64)(1 << 2 | 1 << 24) << 32 | (1 << 1), - .key = KEY_P4_DTLB_OP_WRITE_RESULT_MISS, - .emask = - P4_EVENT_ATTR(P4_REPLAY_EVENT, NBOGUS), - .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR2 }, - .cntr = { 16, 17 }, - }, - [KEY_P4_ITLB_OP_READ_RESULT_ACCESS] = { - .opcode = P4_ITLB_REFERENCE, - .config = 0, - .dep = -1, - .msr = 0, - .key = KEY_P4_ITLB_OP_READ_RESULT_ACCESS, - .emask = - P4_EVENT_ATTR(P4_ITLB_REFERENCE, HIT), - .escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 }, - .cntr = { 0, 2 }, - }, - [KEY_P4_ITLB_OP_READ_RESULT_MISS] = { - .opcode = P4_ITLB_REFERENCE, - .config = 0, - .dep = -1, - .msr = 0, - .key = KEY_P4_ITLB_OP_READ_RESULT_MISS, - .emask = - P4_EVENT_ATTR(P4_ITLB_REFERENCE, MISS), - .escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 }, - .cntr = { 0, 2 }, - }, - [KEY_P4_UOP_TYPE] = { - .opcode = P4_UOP_TYPE, - .config = 0, - .dep = -1, - .key = KEY_P4_UOP_TYPE, - .emask = - P4_EVENT_ATTR(P4_UOP_TYPE, TAGLOADS) | - P4_EVENT_ATTR(P4_UOP_TYPE, TAGSTORES), - .escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 }, - .cntr = { 16, 17 }, - }, +static u64 p4_general_events[PERF_COUNT_HW_MAX] = { + /* non-halted CPU clocks */ + [PERF_COUNT_HW_CPU_CYCLES] = + p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS) | + P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING)), + + /* + * retired instructions + * in a sake of simplicity we don't use the FSB tagging + */ + [PERF_COUNT_HW_INSTRUCTIONS] = + p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_INSTR_RETIRED) | + P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG) | + P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG)), + + /* cache hits */ + [PERF_COUNT_HW_CACHE_REFERENCES] = + p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE) | + P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) | + P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) | + P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM) | + P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS) | + P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE) | + P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM)), + + /* cache misses */ + [PERF_COUNT_HW_CACHE_MISSES] = + p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE) | + P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) | + P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) | + P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS)), + + /* branch instructions retired */ + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = + p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_RETIRED_BRANCH_TYPE) | + P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL) | + P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL) | + P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN) | + P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT)), + + /* mispredicted branches retired */ + [PERF_COUNT_HW_BRANCH_MISSES] = + p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_MISPRED_BRANCH_RETIRED) | + P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS)), + + /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN): */ + [PERF_COUNT_HW_BUS_CYCLES] = + p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_FSB_DATA_ACTIVITY) | + P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV) | + P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN)) | + p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE), }; +static struct p4_event_bind *p4_config_get_bind(u64 config) +{ + unsigned int evnt = p4_config_unpack_event(config); + struct p4_event_bind *bind = NULL; + + if (evnt < ARRAY_SIZE(p4_event_bind_map)) + bind = &p4_event_bind_map[evnt]; + + return bind; +} + static u64 p4_pmu_event_map(int hw_event) { - struct p4_event_template *tpl; + struct p4_event_bind *bind; + unsigned int esel; u64 config; - if (hw_event > ARRAY_SIZE(p4_templates)) { - printk_once(KERN_ERR "PMU: Incorrect event index\n"); + if (hw_event > ARRAY_SIZE(p4_general_events)) { + printk_once(KERN_ERR "P4 PMU: Bad index: %i\n", hw_event); return 0; } - tpl = &p4_templates[hw_event]; - /* - * fill config up according to - * a predefined event template - */ - config = tpl->config; - config |= p4_config_pack_escr(P4_EVENT_UNPACK_EVENT(tpl->opcode) << P4_EVNTSEL_EVENT_SHIFT); - config |= p4_config_pack_escr(tpl->emask << P4_EVNTSEL_EVENTMASK_SHIFT); - config |= p4_config_pack_cccr(P4_EVENT_UNPACK_SELECTOR(tpl->opcode) << P4_CCCR_ESCR_SELECT_SHIFT); - config |= p4_config_pack_cccr(hw_event & P4_CCCR_RESERVED); + config = p4_general_events[hw_event]; + bind = p4_config_get_bind(config); + esel = P4_OPCODE_ESEL(bind->opcode); + config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel)); return config; } -/* - * Note that we still have 5 events (from global events SDM list) - * intersected in opcode+emask bits so we will need another - * scheme there do distinguish templates. - */ -static inline int p4_pmu_emask_match(unsigned int dst, unsigned int src) -{ - return dst & src; -} - -static struct p4_event_template *p4_pmu_template_lookup(u64 config) -{ - int key = p4_config_unpack_key(config); - - if (key < ARRAY_SIZE(p4_templates)) - return &p4_templates[key]; - else - return NULL; -} - /* * We don't control raw events so it's up to the caller * to pass sane values (and we don't count the thread number @@ -319,13 +428,14 @@ static struct p4_event_template *p4_pmu_template_lookup(u64 config) static u64 p4_pmu_raw_event(u64 hw_event) { return hw_event & - (p4_config_pack_escr(P4_EVNTSEL_MASK_HT) | + (p4_config_pack_escr(P4_ESCR_MASK_HT) | p4_config_pack_cccr(P4_CCCR_MASK_HT)); } static int p4_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc) { int cpu = raw_smp_processor_id(); + u32 escr, cccr; /* * the reason we use cpu that early is that: if we get scheduled @@ -333,13 +443,10 @@ static int p4_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc) * specific flags in config (and will save some cpu cycles) */ - /* CCCR by default */ - hwc->config = p4_config_pack_cccr(p4_default_cccr_conf(cpu)); + cccr = p4_default_cccr_conf(cpu); + escr = p4_default_escr_conf(cpu, attr->exclude_kernel, attr->exclude_user); + hwc->config = p4_config_pack_escr(escr) | p4_config_pack_cccr(cccr); - /* Count user and OS events unless not requested to */ - hwc->config |= p4_config_pack_escr(p4_default_escr_conf(cpu, attr->exclude_kernel, - attr->exclude_user)); - /* on HT machine we need a special bit */ if (p4_ht_active() && p4_ht_thread(cpu)) hwc->config = p4_set_ht_bit(hwc->config); @@ -368,7 +475,7 @@ static inline void p4_pmu_disable_event(struct perf_event *event) */ (void)checking_wrmsrl(hwc->config_base + hwc->idx, (u64)(p4_config_unpack_cccr(hwc->config)) & - ~P4_CCCR_ENABLE & ~P4_CCCR_OVF); + ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); } static void p4_pmu_disable_all(void) @@ -389,27 +496,14 @@ static void p4_pmu_enable_event(struct perf_event *event) struct hw_perf_event *hwc = &event->hw; int thread = p4_ht_config_thread(hwc->config); u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config)); - u64 escr_base; - struct p4_event_template *tpl; - struct p4_pmu_res *c; + unsigned int idx = p4_config_unpack_event(hwc->config); + unsigned int idx_cache = p4_config_unpack_cache_event(hwc->config); + struct p4_event_bind *bind; + struct p4_cache_event_bind *bind_cache; + u64 escr_addr, cccr; - /* - * some preparation work from per-cpu private fields - * since we need to find out which ESCR to use - */ - c = &__get_cpu_var(p4_pmu_config); - tpl = c->tpl[hwc->idx]; - if (!tpl) { - pr_crit("%s: Wrong index: %d\n", __func__, hwc->idx); - return; - } - - if (tpl->msr) { - (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, tpl->msr >> 32); - (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, tpl->msr & 0xffffffff); - } - - escr_base = (u64)tpl->escr_msr[thread]; + bind = &p4_event_bind_map[idx]; + escr_addr = (u64)bind->escr_msr[thread]; /* * - we dont support cascaded counters yet @@ -418,9 +512,27 @@ static void p4_pmu_enable_event(struct perf_event *event) WARN_ON_ONCE(p4_is_event_cascaded(hwc->config)); WARN_ON_ONCE(hwc->idx == 1); - (void)checking_wrmsrl(escr_base, escr_conf); + /* we need a real Event value */ + escr_conf &= ~P4_ESCR_EVENT_MASK; + escr_conf |= P4_ESCR_EVENT(P4_OPCODE_EVNT(bind->opcode)); + + cccr = p4_config_unpack_cccr(hwc->config); + + /* + * it could be Cache event so that we need to + * set metrics into additional MSRs + */ + BUILD_BUG_ON(P4_CACHE__MAX > P4_CCCR_CACHE_OPS_MASK); + if (idx_cache > P4_CACHE__NONE && + idx_cache < ARRAY_SIZE(p4_cache_event_bind_map)) { + bind_cache = &p4_cache_event_bind_map[idx_cache]; + (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind_cache->metric_pebs); + (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind_cache->metric_vert); + } + + (void)checking_wrmsrl(escr_addr, escr_conf); (void)checking_wrmsrl(hwc->config_base + hwc->idx, - (u64)(p4_config_unpack_cccr(hwc->config)) | P4_CCCR_ENABLE); + (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE); } static void p4_pmu_enable_all(void) @@ -516,13 +628,13 @@ static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu) if (p4_ht_thread(cpu)) { cccr &= ~P4_CCCR_OVF_PMI_T0; cccr |= P4_CCCR_OVF_PMI_T1; - if (escr & P4_EVNTSEL_T0_OS) { - escr &= ~P4_EVNTSEL_T0_OS; - escr |= P4_EVNTSEL_T1_OS; + if (escr & P4_ESCR_T0_OS) { + escr &= ~P4_ESCR_T0_OS; + escr |= P4_ESCR_T1_OS; } - if (escr & P4_EVNTSEL_T0_USR) { - escr &= ~P4_EVNTSEL_T0_USR; - escr |= P4_EVNTSEL_T1_USR; + if (escr & P4_ESCR_T0_USR) { + escr &= ~P4_ESCR_T0_USR; + escr |= P4_ESCR_T1_USR; } hwc->config = p4_config_pack_escr(escr); hwc->config |= p4_config_pack_cccr(cccr); @@ -530,13 +642,13 @@ static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu) } else { cccr &= ~P4_CCCR_OVF_PMI_T1; cccr |= P4_CCCR_OVF_PMI_T0; - if (escr & P4_EVNTSEL_T1_OS) { - escr &= ~P4_EVNTSEL_T1_OS; - escr |= P4_EVNTSEL_T0_OS; + if (escr & P4_ESCR_T1_OS) { + escr &= ~P4_ESCR_T1_OS; + escr |= P4_ESCR_T0_OS; } - if (escr & P4_EVNTSEL_T1_USR) { - escr &= ~P4_EVNTSEL_T1_USR; - escr |= P4_EVNTSEL_T0_USR; + if (escr & P4_ESCR_T1_USR) { + escr &= ~P4_ESCR_T1_USR; + escr |= P4_ESCR_T0_USR; } hwc->config = p4_config_pack_escr(escr); hwc->config |= p4_config_pack_cccr(cccr); @@ -606,66 +718,56 @@ static int p4_get_escr_idx(unsigned int addr) return -1; } +static int p4_next_cntr(int thread, unsigned long *used_mask, + struct p4_event_bind *bind) +{ + int i = 0, j; + + for (i = 0; i < P4_CNTR_LIMIT; i++) { + j = bind->cntr[thread][i++]; + if (j == -1 || !test_bit(j, used_mask)) + return j; + } + + return -1; +} + static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) { unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; unsigned long escr_mask[BITS_TO_LONGS(ARCH_P4_TOTAL_ESCR)]; - - struct hw_perf_event *hwc; - struct p4_event_template *tpl; - struct p4_pmu_res *c; int cpu = raw_smp_processor_id(); - int escr_idx, thread, i, num; + struct hw_perf_event *hwc; + struct p4_event_bind *bind; + unsigned int i, thread, num; + int cntr_idx, escr_idx; bitmap_zero(used_mask, X86_PMC_IDX_MAX); bitmap_zero(escr_mask, ARCH_P4_TOTAL_ESCR); - c = &__get_cpu_var(p4_pmu_config); - /* - * Firstly find out which resource events are going - * to use, if ESCR+CCCR tuple is already borrowed - * then get out of here - */ for (i = 0, num = n; i < n; i++, num--) { + hwc = &cpuc->event_list[i]->hw; - tpl = p4_pmu_template_lookup(hwc->config); - if (!tpl) - goto done; thread = p4_ht_thread(cpu); - escr_idx = p4_get_escr_idx(tpl->escr_msr[thread]); - if (escr_idx == -1) - goto done; + bind = p4_config_get_bind(hwc->config); + escr_idx = p4_get_escr_idx(bind->escr_msr[thread]); - /* already allocated and remains on the same cpu */ if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) { + cntr_idx = hwc->idx; if (assign) assign[i] = hwc->idx; - /* upstream dependent event */ - if (unlikely(tpl->dep != -1)) - printk_once(KERN_WARNING "PMU: Dep events are " - "not implemented yet\n"); goto reserve; } - /* it may be already borrowed */ - if (test_bit(tpl->cntr[thread], used_mask) || - test_bit(escr_idx, escr_mask)) + cntr_idx = p4_next_cntr(thread, used_mask, bind); + if (cntr_idx == -1 || test_bit(escr_idx, escr_mask)) goto done; - /* - * ESCR+CCCR+COUNTERs are available to use lets swap - * thread specific bits, push assigned bits - * back and save template into per-cpu - * area (which will allow us to find out the ESCR - * to be used at moment of "enable event via real MSR") - */ p4_pmu_swap_config_ts(hwc, cpu); - if (assign) { - assign[i] = tpl->cntr[thread]; - c->tpl[assign[i]] = tpl; - } + if (assign) + assign[i] = cntr_idx; reserve: - set_bit(tpl->cntr[thread], used_mask); + set_bit(cntr_idx, used_mask); set_bit(escr_idx, escr_mask); } @@ -684,7 +786,7 @@ static __initconst struct x86_pmu p4_pmu = { .perfctr = MSR_P4_BPU_PERFCTR0, .event_map = p4_pmu_event_map, .raw_event = p4_pmu_raw_event, - .max_events = ARRAY_SIZE(p4_templates), + .max_events = ARRAY_SIZE(p4_general_events), .get_event_constraints = x86_get_event_constraints, /* * IF HT disabled we may need to use all @@ -716,7 +818,7 @@ static __init int p4_pmu_init(void) } memcpy(hw_cache_event_ids, p4_hw_cache_event_ids, - sizeof(hw_cache_event_ids)); + sizeof(hw_cache_event_ids)); pr_cont("Netburst events, "); -- cgit v1.2.3-59-g8ed1b From 7c5ecaf7666617889f337296c610815b519abfa9 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 25 Mar 2010 14:51:49 +0100 Subject: perf, x86: Clean up debugctlmsr bit definitions Move all debugctlmsr thingies into msr-index.h Signed-off-by: Peter Zijlstra LKML-Reference: <20100325135413.861425293@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/msr-index.h | 13 ++++++++----- arch/x86/kernel/cpu/perf_event_intel_ds.c | 23 +++++++---------------- arch/x86/kernel/cpu/perf_event_intel_lbr.c | 7 ++----- 3 files changed, 17 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index aef562c0a647..06e4cf0d3846 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -71,11 +71,14 @@ #define MSR_IA32_LASTINTTOIP 0x000001de /* DEBUGCTLMSR bits (others vary by model): */ -#define _DEBUGCTLMSR_LBR 0 /* last branch recording */ -#define _DEBUGCTLMSR_BTF 1 /* single-step on branches */ - -#define DEBUGCTLMSR_LBR (1UL << _DEBUGCTLMSR_LBR) -#define DEBUGCTLMSR_BTF (1UL << _DEBUGCTLMSR_BTF) +#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ +#define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */ +#define DEBUGCTLMSR_TR (1UL << 6) +#define DEBUGCTLMSR_BTS (1UL << 7) +#define DEBUGCTLMSR_BTINT (1UL << 8) +#define DEBUGCTLMSR_BTS_OFF_OS (1UL << 9) +#define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10) +#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11) #define MSR_IA32_MC0_CTL 0x00000400 #define MSR_IA32_MC0_STATUS 0x00000401 diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index c59678a14a2e..2fea3622af7f 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -37,15 +37,6 @@ struct pebs_record_nhm { u64 status, dla, dse, lat; }; -/* - * Bits in the debugctlmsr controlling branch tracing. - */ -#define X86_DEBUGCTL_TR (1 << 6) -#define X86_DEBUGCTL_BTS (1 << 7) -#define X86_DEBUGCTL_BTINT (1 << 8) -#define X86_DEBUGCTL_BTS_OFF_OS (1 << 9) -#define X86_DEBUGCTL_BTS_OFF_USR (1 << 10) - /* * A debug store configuration. * @@ -193,15 +184,15 @@ static void intel_pmu_enable_bts(u64 config) debugctlmsr = get_debugctlmsr(); - debugctlmsr |= X86_DEBUGCTL_TR; - debugctlmsr |= X86_DEBUGCTL_BTS; - debugctlmsr |= X86_DEBUGCTL_BTINT; + debugctlmsr |= DEBUGCTLMSR_TR; + debugctlmsr |= DEBUGCTLMSR_BTS; + debugctlmsr |= DEBUGCTLMSR_BTINT; if (!(config & ARCH_PERFMON_EVENTSEL_OS)) - debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS; + debugctlmsr |= DEBUGCTLMSR_BTS_OFF_OS; if (!(config & ARCH_PERFMON_EVENTSEL_USR)) - debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR; + debugctlmsr |= DEBUGCTLMSR_BTS_OFF_USR; update_debugctlmsr(debugctlmsr); } @@ -217,8 +208,8 @@ static void intel_pmu_disable_bts(void) debugctlmsr = get_debugctlmsr(); debugctlmsr &= - ~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT | - X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR); + ~(DEBUGCTLMSR_TR | DEBUGCTLMSR_BTS | DEBUGCTLMSR_BTINT | + DEBUGCTLMSR_BTS_OFF_OS | DEBUGCTLMSR_BTS_OFF_USR); update_debugctlmsr(debugctlmsr); } diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index df4c98e26c5b..d202c1bece1a 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -12,15 +12,12 @@ enum { * otherwise it becomes near impossible to get a reliable stack. */ -#define X86_DEBUGCTL_LBR (1 << 0) -#define X86_DEBUGCTL_FREEZE_LBRS_ON_PMI (1 << 11) - static void __intel_pmu_lbr_enable(void) { u64 debugctl; rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); - debugctl |= (X86_DEBUGCTL_LBR | X86_DEBUGCTL_FREEZE_LBRS_ON_PMI); + debugctl |= (DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI); wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); } @@ -29,7 +26,7 @@ static void __intel_pmu_lbr_disable(void) u64 debugctl; rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); - debugctl &= ~(X86_DEBUGCTL_LBR | X86_DEBUGCTL_FREEZE_LBRS_ON_PMI); + debugctl &= ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI); wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); } -- cgit v1.2.3-59-g8ed1b From faa4602e47690fb11221e00f9b9697c8dc0d4b19 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 25 Mar 2010 14:51:50 +0100 Subject: x86, perf, bts, mm: Delete the never used BTS-ptrace code Support for the PMU's BTS features has been upstreamed in v2.6.32, but we still have the old and disabled ptrace-BTS, as Linus noticed it not so long ago. It's buggy: TIF_DEBUGCTLMSR is trampling all over that MSR without regard for other uses (perf) and doesn't provide the flexibility needed for perf either. Its users are ptrace-block-step and ptrace-bts, since ptrace-bts was never used and ptrace-block-step can be implemented using a much simpler approach. So axe all 3000 lines of it. That includes the *locked_memory*() APIs in mm/mlock.c as well. Reported-by: Linus Torvalds Signed-off-by: Peter Zijlstra Cc: Roland McGrath Cc: Oleg Nesterov Cc: Markus Metzger Cc: Steven Rostedt Cc: Andrew Morton LKML-Reference: <20100325135413.938004390@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/Kconfig.cpu | 20 - arch/x86/Kconfig.debug | 9 - arch/x86/include/asm/ds.h | 302 -------- arch/x86/include/asm/processor.h | 33 +- arch/x86/include/asm/ptrace-abi.h | 57 +- arch/x86/include/asm/ptrace.h | 6 - arch/x86/include/asm/thread_info.h | 6 +- arch/x86/kernel/Makefile | 2 - arch/x86/kernel/cpu/intel.c | 2 - arch/x86/kernel/ds.c | 1437 ------------------------------------ arch/x86/kernel/ds_selftest.c | 408 ---------- arch/x86/kernel/ds_selftest.h | 15 - arch/x86/kernel/dumpstack.c | 5 - arch/x86/kernel/kprobes.c | 6 +- arch/x86/kernel/process.c | 9 - arch/x86/kernel/process_32.c | 8 - arch/x86/kernel/process_64.c | 8 - arch/x86/kernel/ptrace.c | 382 ---------- arch/x86/kernel/step.c | 36 +- arch/x86/kernel/traps.c | 5 - include/linux/ftrace.h | 12 - include/linux/mm.h | 4 - include/linux/ptrace.h | 12 - include/linux/sched.h | 9 - kernel/fork.c | 3 - kernel/ptrace.c | 1 - kernel/sched.c | 43 -- kernel/trace/Kconfig | 11 - kernel/trace/Makefile | 1 - kernel/trace/trace.h | 4 - kernel/trace/trace_entries.h | 12 - kernel/trace/trace_hw_branches.c | 312 -------- kernel/trace/trace_selftest.c | 57 -- mm/mlock.c | 41 - 34 files changed, 9 insertions(+), 3269 deletions(-) delete mode 100644 arch/x86/include/asm/ds.h delete mode 100644 arch/x86/kernel/ds.c delete mode 100644 arch/x86/kernel/ds_selftest.c delete mode 100644 arch/x86/kernel/ds_selftest.h delete mode 100644 kernel/trace/trace_hw_branches.c (limited to 'arch') diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index a19829374e6a..918fbb1855cc 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -502,23 +502,3 @@ config CPU_SUP_UMC_32 CPU might render the kernel unbootable. If unsure, say N. - -config X86_DS - def_bool X86_PTRACE_BTS - depends on X86_DEBUGCTLMSR - select HAVE_HW_BRANCH_TRACER - -config X86_PTRACE_BTS - bool "Branch Trace Store" - default y - depends on X86_DEBUGCTLMSR - depends on BROKEN - ---help--- - This adds a ptrace interface to the hardware's branch trace store. - - Debuggers may use it to collect an execution trace of the debugged - application in order to answer the question 'how did I get here?'. - Debuggers may trace user mode as well as kernel mode. - - Say Y unless there is no application development on this machine - and you want to save a small amount of code size. diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index bc01e3ebfeb2..bd58c8abbfbd 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -174,15 +174,6 @@ config IOMMU_LEAK Add a simple leak tracer to the IOMMU code. This is useful when you are debugging a buggy device driver that leaks IOMMU mappings. -config X86_DS_SELFTEST - bool "DS selftest" - default y - depends on DEBUG_KERNEL - depends on X86_DS - ---help--- - Perform Debug Store selftests at boot time. - If in doubt, say "N". - config HAVE_MMIOTRACE_SUPPORT def_bool y diff --git a/arch/x86/include/asm/ds.h b/arch/x86/include/asm/ds.h deleted file mode 100644 index 70dac199b093..000000000000 --- a/arch/x86/include/asm/ds.h +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Debug Store (DS) support - * - * This provides a low-level interface to the hardware's Debug Store - * feature that is used for branch trace store (BTS) and - * precise-event based sampling (PEBS). - * - * It manages: - * - DS and BTS hardware configuration - * - buffer overflow handling (to be done) - * - buffer access - * - * It does not do: - * - security checking (is the caller allowed to trace the task) - * - buffer allocation (memory accounting) - * - * - * Copyright (C) 2007-2009 Intel Corporation. - * Markus Metzger , 2007-2009 - */ - -#ifndef _ASM_X86_DS_H -#define _ASM_X86_DS_H - - -#include -#include -#include - - -#ifdef CONFIG_X86_DS - -struct task_struct; -struct ds_context; -struct ds_tracer; -struct bts_tracer; -struct pebs_tracer; - -typedef void (*bts_ovfl_callback_t)(struct bts_tracer *); -typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *); - - -/* - * A list of features plus corresponding macros to talk about them in - * the ds_request function's flags parameter. - * - * We use the enum to index an array of corresponding control bits; - * we use the macro to index a flags bit-vector. - */ -enum ds_feature { - dsf_bts = 0, - dsf_bts_kernel, -#define BTS_KERNEL (1 << dsf_bts_kernel) - /* trace kernel-mode branches */ - - dsf_bts_user, -#define BTS_USER (1 << dsf_bts_user) - /* trace user-mode branches */ - - dsf_bts_overflow, - dsf_bts_max, - dsf_pebs = dsf_bts_max, - - dsf_pebs_max, - dsf_ctl_max = dsf_pebs_max, - dsf_bts_timestamps = dsf_ctl_max, -#define BTS_TIMESTAMPS (1 << dsf_bts_timestamps) - /* add timestamps into BTS trace */ - -#define BTS_USER_FLAGS (BTS_KERNEL | BTS_USER | BTS_TIMESTAMPS) -}; - - -/* - * Request BTS or PEBS - * - * Due to alignement constraints, the actual buffer may be slightly - * smaller than the requested or provided buffer. - * - * Returns a pointer to a tracer structure on success, or - * ERR_PTR(errcode) on failure. - * - * The interrupt threshold is independent from the overflow callback - * to allow users to use their own overflow interrupt handling mechanism. - * - * The function might sleep. - * - * task: the task to request recording for - * cpu: the cpu to request recording for - * base: the base pointer for the (non-pageable) buffer; - * size: the size of the provided buffer in bytes - * ovfl: pointer to a function to be called on buffer overflow; - * NULL if cyclic buffer requested - * th: the interrupt threshold in records from the end of the buffer; - * -1 if no interrupt threshold is requested. - * flags: a bit-mask of the above flags - */ -extern struct bts_tracer *ds_request_bts_task(struct task_struct *task, - void *base, size_t size, - bts_ovfl_callback_t ovfl, - size_t th, unsigned int flags); -extern struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size, - bts_ovfl_callback_t ovfl, - size_t th, unsigned int flags); -extern struct pebs_tracer *ds_request_pebs_task(struct task_struct *task, - void *base, size_t size, - pebs_ovfl_callback_t ovfl, - size_t th, unsigned int flags); -extern struct pebs_tracer *ds_request_pebs_cpu(int cpu, - void *base, size_t size, - pebs_ovfl_callback_t ovfl, - size_t th, unsigned int flags); - -/* - * Release BTS or PEBS resources - * Suspend and resume BTS or PEBS tracing - * - * Must be called with irq's enabled. - * - * tracer: the tracer handle returned from ds_request_~() - */ -extern void ds_release_bts(struct bts_tracer *tracer); -extern void ds_suspend_bts(struct bts_tracer *tracer); -extern void ds_resume_bts(struct bts_tracer *tracer); -extern void ds_release_pebs(struct pebs_tracer *tracer); -extern void ds_suspend_pebs(struct pebs_tracer *tracer); -extern void ds_resume_pebs(struct pebs_tracer *tracer); - -/* - * Release BTS or PEBS resources - * Suspend and resume BTS or PEBS tracing - * - * Cpu tracers must call this on the traced cpu. - * Task tracers must call ds_release_~_noirq() for themselves. - * - * May be called with irq's disabled. - * - * Returns 0 if successful; - * -EPERM if the cpu tracer does not trace the current cpu. - * -EPERM if the task tracer does not trace itself. - * - * tracer: the tracer handle returned from ds_request_~() - */ -extern int ds_release_bts_noirq(struct bts_tracer *tracer); -extern int ds_suspend_bts_noirq(struct bts_tracer *tracer); -extern int ds_resume_bts_noirq(struct bts_tracer *tracer); -extern int ds_release_pebs_noirq(struct pebs_tracer *tracer); -extern int ds_suspend_pebs_noirq(struct pebs_tracer *tracer); -extern int ds_resume_pebs_noirq(struct pebs_tracer *tracer); - - -/* - * The raw DS buffer state as it is used for BTS and PEBS recording. - * - * This is the low-level, arch-dependent interface for working - * directly on the raw trace data. - */ -struct ds_trace { - /* the number of bts/pebs records */ - size_t n; - /* the size of a bts/pebs record in bytes */ - size_t size; - /* pointers into the raw buffer: - - to the first entry */ - void *begin; - /* - one beyond the last entry */ - void *end; - /* - one beyond the newest entry */ - void *top; - /* - the interrupt threshold */ - void *ith; - /* flags given on ds_request() */ - unsigned int flags; -}; - -/* - * An arch-independent view on branch trace data. - */ -enum bts_qualifier { - bts_invalid, -#define BTS_INVALID bts_invalid - - bts_branch, -#define BTS_BRANCH bts_branch - - bts_task_arrives, -#define BTS_TASK_ARRIVES bts_task_arrives - - bts_task_departs, -#define BTS_TASK_DEPARTS bts_task_departs - - bts_qual_bit_size = 4, - bts_qual_max = (1 << bts_qual_bit_size), -}; - -struct bts_struct { - __u64 qualifier; - union { - /* BTS_BRANCH */ - struct { - __u64 from; - __u64 to; - } lbr; - /* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */ - struct { - __u64 clock; - pid_t pid; - } event; - } variant; -}; - - -/* - * The BTS state. - * - * This gives access to the raw DS state and adds functions to provide - * an arch-independent view of the BTS data. - */ -struct bts_trace { - struct ds_trace ds; - - int (*read)(struct bts_tracer *tracer, const void *at, - struct bts_struct *out); - int (*write)(struct bts_tracer *tracer, const struct bts_struct *in); -}; - - -/* - * The PEBS state. - * - * This gives access to the raw DS state and the PEBS-specific counter - * reset value. - */ -struct pebs_trace { - struct ds_trace ds; - - /* the number of valid counters in the below array */ - unsigned int counters; - -#define MAX_PEBS_COUNTERS 4 - /* the counter reset value */ - unsigned long long counter_reset[MAX_PEBS_COUNTERS]; -}; - - -/* - * Read the BTS or PEBS trace. - * - * Returns a view on the trace collected for the parameter tracer. - * - * The view remains valid as long as the traced task is not running or - * the tracer is suspended. - * Writes into the trace buffer are not reflected. - * - * tracer: the tracer handle returned from ds_request_~() - */ -extern const struct bts_trace *ds_read_bts(struct bts_tracer *tracer); -extern const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer); - - -/* - * Reset the write pointer of the BTS/PEBS buffer. - * - * Returns 0 on success; -Eerrno on error - * - * tracer: the tracer handle returned from ds_request_~() - */ -extern int ds_reset_bts(struct bts_tracer *tracer); -extern int ds_reset_pebs(struct pebs_tracer *tracer); - -/* - * Set the PEBS counter reset value. - * - * Returns 0 on success; -Eerrno on error - * - * tracer: the tracer handle returned from ds_request_pebs() - * counter: the index of the counter - * value: the new counter reset value - */ -extern int ds_set_pebs_reset(struct pebs_tracer *tracer, - unsigned int counter, u64 value); - -/* - * Initialization - */ -struct cpuinfo_x86; -extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *); - -/* - * Context switch work - */ -extern void ds_switch_to(struct task_struct *prev, struct task_struct *next); - -#else /* CONFIG_X86_DS */ - -struct cpuinfo_x86; -static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {} -static inline void ds_switch_to(struct task_struct *prev, - struct task_struct *next) {} - -#endif /* CONFIG_X86_DS */ -#endif /* _ASM_X86_DS_H */ diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index b753ea59703a..5bec21a66dc5 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -21,7 +21,6 @@ struct mm_struct; #include #include #include -#include #include #include @@ -29,6 +28,7 @@ struct mm_struct; #include #include #include +#include #define HBP_NUM 4 /* @@ -473,10 +473,6 @@ struct thread_struct { unsigned long iopl; /* Max allowed port in the bitmap, in bytes: */ unsigned io_bitmap_max; -/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ - unsigned long debugctlmsr; - /* Debug Store context; see asm/ds.h */ - struct ds_context *ds_ctx; }; static inline unsigned long native_get_debugreg(int regno) @@ -814,21 +810,6 @@ static inline unsigned long get_debugctlmsr(void) return debugctlmsr; } -static inline unsigned long get_debugctlmsr_on_cpu(int cpu) -{ - u64 debugctlmsr = 0; - u32 val1, val2; - -#ifndef CONFIG_X86_DEBUGCTLMSR - if (boot_cpu_data.x86 < 6) - return 0; -#endif - rdmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR, &val1, &val2); - debugctlmsr = val1 | ((u64)val2 << 32); - - return debugctlmsr; -} - static inline void update_debugctlmsr(unsigned long debugctlmsr) { #ifndef CONFIG_X86_DEBUGCTLMSR @@ -838,18 +819,6 @@ static inline void update_debugctlmsr(unsigned long debugctlmsr) wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr); } -static inline void update_debugctlmsr_on_cpu(int cpu, - unsigned long debugctlmsr) -{ -#ifndef CONFIG_X86_DEBUGCTLMSR - if (boot_cpu_data.x86 < 6) - return; -#endif - wrmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR, - (u32)((u64)debugctlmsr), - (u32)((u64)debugctlmsr >> 32)); -} - /* * from system description table in BIOS. Mostly for MCA use, but * others may find it useful: diff --git a/arch/x86/include/asm/ptrace-abi.h b/arch/x86/include/asm/ptrace-abi.h index 86723035a515..52b098a6eebb 100644 --- a/arch/x86/include/asm/ptrace-abi.h +++ b/arch/x86/include/asm/ptrace-abi.h @@ -82,61 +82,6 @@ #ifndef __ASSEMBLY__ #include - -/* configuration/status structure used in PTRACE_BTS_CONFIG and - PTRACE_BTS_STATUS commands. -*/ -struct ptrace_bts_config { - /* requested or actual size of BTS buffer in bytes */ - __u32 size; - /* bitmask of below flags */ - __u32 flags; - /* buffer overflow signal */ - __u32 signal; - /* actual size of bts_struct in bytes */ - __u32 bts_size; -}; -#endif /* __ASSEMBLY__ */ - -#define PTRACE_BTS_O_TRACE 0x1 /* branch trace */ -#define PTRACE_BTS_O_SCHED 0x2 /* scheduling events w/ jiffies */ -#define PTRACE_BTS_O_SIGNAL 0x4 /* send SIG on buffer overflow - instead of wrapping around */ -#define PTRACE_BTS_O_ALLOC 0x8 /* (re)allocate buffer */ - -#define PTRACE_BTS_CONFIG 40 -/* Configure branch trace recording. - ADDR points to a struct ptrace_bts_config. - DATA gives the size of that buffer. - A new buffer is allocated, if requested in the flags. - An overflow signal may only be requested for new buffers. - Returns the number of bytes read. -*/ -#define PTRACE_BTS_STATUS 41 -/* Return the current configuration in a struct ptrace_bts_config - pointed to by ADDR; DATA gives the size of that buffer. - Returns the number of bytes written. -*/ -#define PTRACE_BTS_SIZE 42 -/* Return the number of available BTS records for draining. - DATA and ADDR are ignored. -*/ -#define PTRACE_BTS_GET 43 -/* Get a single BTS record. - DATA defines the index into the BTS array, where 0 is the newest - entry, and higher indices refer to older entries. - ADDR is pointing to struct bts_struct (see asm/ds.h). -*/ -#define PTRACE_BTS_CLEAR 44 -/* Clear the BTS buffer. - DATA and ADDR are ignored. -*/ -#define PTRACE_BTS_DRAIN 45 -/* Read all available BTS records and clear the buffer. - ADDR points to an array of struct bts_struct. - DATA gives the size of that buffer. - BTS records are read from oldest to newest. - Returns number of BTS records drained. -*/ +#endif #endif /* _ASM_X86_PTRACE_ABI_H */ diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 69a686a7dff0..78cd1ea94500 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -289,12 +289,6 @@ extern int do_get_thread_area(struct task_struct *p, int idx, extern int do_set_thread_area(struct task_struct *p, int idx, struct user_desc __user *info, int can_allocate); -#ifdef CONFIG_X86_PTRACE_BTS -extern void ptrace_bts_untrace(struct task_struct *tsk); - -#define arch_ptrace_untrace(tsk) ptrace_bts_untrace(tsk) -#endif /* CONFIG_X86_PTRACE_BTS */ - #endif /* __KERNEL__ */ #endif /* !__ASSEMBLY__ */ diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index e0d28901e969..dc85e12d1405 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -92,8 +92,6 @@ struct thread_info { #define TIF_IO_BITMAP 22 /* uses I/O bitmap */ #define TIF_FREEZE 23 /* is freezing for suspend */ #define TIF_FORCED_TF 24 /* true if TF in eflags artificially */ -#define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */ -#define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */ #define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */ #define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */ @@ -115,8 +113,6 @@ struct thread_info { #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) #define _TIF_FREEZE (1 << TIF_FREEZE) #define _TIF_FORCED_TF (1 << TIF_FORCED_TF) -#define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR) -#define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR) #define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) @@ -147,7 +143,7 @@ struct thread_info { /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW \ - (_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_NOTSC) + (_TIF_IO_BITMAP|_TIF_NOTSC) #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG) diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 4c58352209e0..e77b22083721 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -47,8 +47,6 @@ obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o obj-y += process.o obj-y += i387.o xsave.o obj-y += ptrace.o -obj-$(CONFIG_X86_DS) += ds.o -obj-$(CONFIG_X86_DS_SELFTEST) += ds_selftest.o obj-$(CONFIG_X86_32) += tls.o obj-$(CONFIG_IA32_EMULATION) += tls.o obj-y += step.o diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 7e1cca13af35..d72377c41c76 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -367,7 +366,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) set_cpu_cap(c, X86_FEATURE_BTS); if (!(l1 & (1<<12))) set_cpu_cap(c, X86_FEATURE_PEBS); - ds_init_intel(c); } if (c->x86 == 6 && c->x86_model == 29 && cpu_has_clflush) diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c deleted file mode 100644 index 1c47390dd0e5..000000000000 --- a/arch/x86/kernel/ds.c +++ /dev/null @@ -1,1437 +0,0 @@ -/* - * Debug Store support - * - * This provides a low-level interface to the hardware's Debug Store - * feature that is used for branch trace store (BTS) and - * precise-event based sampling (PEBS). - * - * It manages: - * - DS and BTS hardware configuration - * - buffer overflow handling (to be done) - * - buffer access - * - * It does not do: - * - security checking (is the caller allowed to trace the task) - * - buffer allocation (memory accounting) - * - * - * Copyright (C) 2007-2009 Intel Corporation. - * Markus Metzger , 2007-2009 - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "ds_selftest.h" - -/* - * The configuration for a particular DS hardware implementation: - */ -struct ds_configuration { - /* The name of the configuration: */ - const char *name; - - /* The size of pointer-typed fields in DS, BTS, and PEBS: */ - unsigned char sizeof_ptr_field; - - /* The size of a BTS/PEBS record in bytes: */ - unsigned char sizeof_rec[2]; - - /* The number of pebs counter reset values in the DS structure. */ - unsigned char nr_counter_reset; - - /* Control bit-masks indexed by enum ds_feature: */ - unsigned long ctl[dsf_ctl_max]; -}; -static struct ds_configuration ds_cfg __read_mostly; - - -/* Maximal size of a DS configuration: */ -#define MAX_SIZEOF_DS 0x80 - -/* Maximal size of a BTS record: */ -#define MAX_SIZEOF_BTS (3 * 8) - -/* BTS and PEBS buffer alignment: */ -#define DS_ALIGNMENT (1 << 3) - -/* Number of buffer pointers in DS: */ -#define NUM_DS_PTR_FIELDS 8 - -/* Size of a pebs reset value in DS: */ -#define PEBS_RESET_FIELD_SIZE 8 - -/* Mask of control bits in the DS MSR register: */ -#define BTS_CONTROL \ - ( ds_cfg.ctl[dsf_bts] | \ - ds_cfg.ctl[dsf_bts_kernel] | \ - ds_cfg.ctl[dsf_bts_user] | \ - ds_cfg.ctl[dsf_bts_overflow] ) - -/* - * A BTS or PEBS tracer. - * - * This holds the configuration of the tracer and serves as a handle - * to identify tracers. - */ -struct ds_tracer { - /* The DS context (partially) owned by this tracer. */ - struct ds_context *context; - /* The buffer provided on ds_request() and its size in bytes. */ - void *buffer; - size_t size; -}; - -struct bts_tracer { - /* The common DS part: */ - struct ds_tracer ds; - - /* The trace including the DS configuration: */ - struct bts_trace trace; - - /* Buffer overflow notification function: */ - bts_ovfl_callback_t ovfl; - - /* Active flags affecting trace collection. */ - unsigned int flags; -}; - -struct pebs_tracer { - /* The common DS part: */ - struct ds_tracer ds; - - /* The trace including the DS configuration: */ - struct pebs_trace trace; - - /* Buffer overflow notification function: */ - pebs_ovfl_callback_t ovfl; -}; - -/* - * Debug Store (DS) save area configuration (see Intel64 and IA32 - * Architectures Software Developer's Manual, section 18.5) - * - * The DS configuration consists of the following fields; different - * architetures vary in the size of those fields. - * - * - double-word aligned base linear address of the BTS buffer - * - write pointer into the BTS buffer - * - end linear address of the BTS buffer (one byte beyond the end of - * the buffer) - * - interrupt pointer into BTS buffer - * (interrupt occurs when write pointer passes interrupt pointer) - * - double-word aligned base linear address of the PEBS buffer - * - write pointer into the PEBS buffer - * - end linear address of the PEBS buffer (one byte beyond the end of - * the buffer) - * - interrupt pointer into PEBS buffer - * (interrupt occurs when write pointer passes interrupt pointer) - * - value to which counter is reset following counter overflow - * - * Later architectures use 64bit pointers throughout, whereas earlier - * architectures use 32bit pointers in 32bit mode. - * - * - * We compute the base address for the first 8 fields based on: - * - the field size stored in the DS configuration - * - the relative field position - * - an offset giving the start of the respective region - * - * This offset is further used to index various arrays holding - * information for BTS and PEBS at the respective index. - * - * On later 32bit processors, we only access the lower 32bit of the - * 64bit pointer fields. The upper halves will be zeroed out. - */ - -enum ds_field { - ds_buffer_base = 0, - ds_index, - ds_absolute_maximum, - ds_interrupt_threshold, -}; - -enum ds_qualifier { - ds_bts = 0, - ds_pebs -}; - -static inline unsigned long -ds_get(const unsigned char *base, enum ds_qualifier qual, enum ds_field field) -{ - base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual))); - return *(unsigned long *)base; -} - -static inline void -ds_set(unsigned char *base, enum ds_qualifier qual, enum ds_field field, - unsigned long value) -{ - base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual))); - (*(unsigned long *)base) = value; -} - - -/* - * Locking is done only for allocating BTS or PEBS resources. - */ -static DEFINE_SPINLOCK(ds_lock); - -/* - * We either support (system-wide) per-cpu or per-thread allocation. - * We distinguish the two based on the task_struct pointer, where a - * NULL pointer indicates per-cpu allocation for the current cpu. - * - * Allocations are use-counted. As soon as resources are allocated, - * further allocations must be of the same type (per-cpu or - * per-thread). We model this by counting allocations (i.e. the number - * of tracers of a certain type) for one type negatively: - * =0 no tracers - * >0 number of per-thread tracers - * <0 number of per-cpu tracers - * - * Tracers essentially gives the number of ds contexts for a certain - * type of allocation. - */ -static atomic_t tracers = ATOMIC_INIT(0); - -static inline int get_tracer(struct task_struct *task) -{ - int error; - - spin_lock_irq(&ds_lock); - - if (task) { - error = -EPERM; - if (atomic_read(&tracers) < 0) - goto out; - atomic_inc(&tracers); - } else { - error = -EPERM; - if (atomic_read(&tracers) > 0) - goto out; - atomic_dec(&tracers); - } - - error = 0; -out: - spin_unlock_irq(&ds_lock); - return error; -} - -static inline void put_tracer(struct task_struct *task) -{ - if (task) - atomic_dec(&tracers); - else - atomic_inc(&tracers); -} - -/* - * The DS context is either attached to a thread or to a cpu: - * - in the former case, the thread_struct contains a pointer to the - * attached context. - * - in the latter case, we use a static array of per-cpu context - * pointers. - * - * Contexts are use-counted. They are allocated on first access and - * deallocated when the last user puts the context. - */ -struct ds_context { - /* The DS configuration; goes into MSR_IA32_DS_AREA: */ - unsigned char ds[MAX_SIZEOF_DS]; - - /* The owner of the BTS and PEBS configuration, respectively: */ - struct bts_tracer *bts_master; - struct pebs_tracer *pebs_master; - - /* Use count: */ - unsigned long count; - - /* Pointer to the context pointer field: */ - struct ds_context **this; - - /* The traced task; NULL for cpu tracing: */ - struct task_struct *task; - - /* The traced cpu; only valid if task is NULL: */ - int cpu; -}; - -static DEFINE_PER_CPU(struct ds_context *, cpu_ds_context); - - -static struct ds_context *ds_get_context(struct task_struct *task, int cpu) -{ - struct ds_context **p_context = - (task ? &task->thread.ds_ctx : &per_cpu(cpu_ds_context, cpu)); - struct ds_context *context = NULL; - struct ds_context *new_context = NULL; - - /* Chances are small that we already have a context. */ - new_context = kzalloc(sizeof(*new_context), GFP_KERNEL); - if (!new_context) - return NULL; - - spin_lock_irq(&ds_lock); - - context = *p_context; - if (likely(!context)) { - context = new_context; - - context->this = p_context; - context->task = task; - context->cpu = cpu; - context->count = 0; - - *p_context = context; - } - - context->count++; - - spin_unlock_irq(&ds_lock); - - if (context != new_context) - kfree(new_context); - - return context; -} - -static void ds_put_context(struct ds_context *context) -{ - struct task_struct *task; - unsigned long irq; - - if (!context) - return; - - spin_lock_irqsave(&ds_lock, irq); - - if (--context->count) { - spin_unlock_irqrestore(&ds_lock, irq); - return; - } - - *(context->this) = NULL; - - task = context->task; - - if (task) - clear_tsk_thread_flag(task, TIF_DS_AREA_MSR); - - /* - * We leave the (now dangling) pointer to the DS configuration in - * the DS_AREA msr. This is as good or as bad as replacing it with - * NULL - the hardware would crash if we enabled tracing. - * - * This saves us some problems with having to write an msr on a - * different cpu while preventing others from doing the same for the - * next context for that same cpu. - */ - - spin_unlock_irqrestore(&ds_lock, irq); - - /* The context might still be in use for context switching. */ - if (task && (task != current)) - wait_task_context_switch(task); - - kfree(context); -} - -static void ds_install_ds_area(struct ds_context *context) -{ - unsigned long ds; - - ds = (unsigned long)context->ds; - - /* - * There is a race between the bts master and the pebs master. - * - * The thread/cpu access is synchronized via get/put_cpu() for - * task tracing and via wrmsr_on_cpu for cpu tracing. - * - * If bts and pebs are collected for the same task or same cpu, - * the same confiuration is written twice. - */ - if (context->task) { - get_cpu(); - if (context->task == current) - wrmsrl(MSR_IA32_DS_AREA, ds); - set_tsk_thread_flag(context->task, TIF_DS_AREA_MSR); - put_cpu(); - } else - wrmsr_on_cpu(context->cpu, MSR_IA32_DS_AREA, - (u32)((u64)ds), (u32)((u64)ds >> 32)); -} - -/* - * Call the tracer's callback on a buffer overflow. - * - * context: the ds context - * qual: the buffer type - */ -static void ds_overflow(struct ds_context *context, enum ds_qualifier qual) -{ - switch (qual) { - case ds_bts: - if (context->bts_master && - context->bts_master->ovfl) - context->bts_master->ovfl(context->bts_master); - break; - case ds_pebs: - if (context->pebs_master && - context->pebs_master->ovfl) - context->pebs_master->ovfl(context->pebs_master); - break; - } -} - - -/* - * Write raw data into the BTS or PEBS buffer. - * - * The remainder of any partially written record is zeroed out. - * - * context: the DS context - * qual: the buffer type - * record: the data to write - * size: the size of the data - */ -static int ds_write(struct ds_context *context, enum ds_qualifier qual, - const void *record, size_t size) -{ - int bytes_written = 0; - - if (!record) - return -EINVAL; - - while (size) { - unsigned long base, index, end, write_end, int_th; - unsigned long write_size, adj_write_size; - - /* - * Write as much as possible without producing an - * overflow interrupt. - * - * Interrupt_threshold must either be - * - bigger than absolute_maximum or - * - point to a record between buffer_base and absolute_maximum - * - * Index points to a valid record. - */ - base = ds_get(context->ds, qual, ds_buffer_base); - index = ds_get(context->ds, qual, ds_index); - end = ds_get(context->ds, qual, ds_absolute_maximum); - int_th = ds_get(context->ds, qual, ds_interrupt_threshold); - - write_end = min(end, int_th); - - /* - * If we are already beyond the interrupt threshold, - * we fill the entire buffer. - */ - if (write_end <= index) - write_end = end; - - if (write_end <= index) - break; - - write_size = min((unsigned long) size, write_end - index); - memcpy((void *)index, record, write_size); - - record = (const char *)record + write_size; - size -= write_size; - bytes_written += write_size; - - adj_write_size = write_size / ds_cfg.sizeof_rec[qual]; - adj_write_size *= ds_cfg.sizeof_rec[qual]; - - /* Zero out trailing bytes. */ - memset((char *)index + write_size, 0, - adj_write_size - write_size); - index += adj_write_size; - - if (index >= end) - index = base; - ds_set(context->ds, qual, ds_index, index); - - if (index >= int_th) - ds_overflow(context, qual); - } - - return bytes_written; -} - - -/* - * Branch Trace Store (BTS) uses the following format. Different - * architectures vary in the size of those fields. - * - source linear address - * - destination linear address - * - flags - * - * Later architectures use 64bit pointers throughout, whereas earlier - * architectures use 32bit pointers in 32bit mode. - * - * We compute the base address for the fields based on: - * - the field size stored in the DS configuration - * - the relative field position - * - * In order to store additional information in the BTS buffer, we use - * a special source address to indicate that the record requires - * special interpretation. - * - * Netburst indicated via a bit in the flags field whether the branch - * was predicted; this is ignored. - * - * We use two levels of abstraction: - * - the raw data level defined here - * - an arch-independent level defined in ds.h - */ - -enum bts_field { - bts_from, - bts_to, - bts_flags, - - bts_qual = bts_from, - bts_clock = bts_to, - bts_pid = bts_flags, - - bts_qual_mask = (bts_qual_max - 1), - bts_escape = ((unsigned long)-1 & ~bts_qual_mask) -}; - -static inline unsigned long bts_get(const char *base, unsigned long field) -{ - base += (ds_cfg.sizeof_ptr_field * field); - return *(unsigned long *)base; -} - -static inline void bts_set(char *base, unsigned long field, unsigned long val) -{ - base += (ds_cfg.sizeof_ptr_field * field); - (*(unsigned long *)base) = val; -} - - -/* - * The raw BTS data is architecture dependent. - * - * For higher-level users, we give an arch-independent view. - * - ds.h defines struct bts_struct - * - bts_read translates one raw bts record into a bts_struct - * - bts_write translates one bts_struct into the raw format and - * writes it into the top of the parameter tracer's buffer. - * - * return: bytes read/written on success; -Eerrno, otherwise - */ -static int -bts_read(struct bts_tracer *tracer, const void *at, struct bts_struct *out) -{ - if (!tracer) - return -EINVAL; - - if (at < tracer->trace.ds.begin) - return -EINVAL; - - if (tracer->trace.ds.end < (at + tracer->trace.ds.size)) - return -EINVAL; - - memset(out, 0, sizeof(*out)); - if ((bts_get(at, bts_qual) & ~bts_qual_mask) == bts_escape) { - out->qualifier = (bts_get(at, bts_qual) & bts_qual_mask); - out->variant.event.clock = bts_get(at, bts_clock); - out->variant.event.pid = bts_get(at, bts_pid); - } else { - out->qualifier = bts_branch; - out->variant.lbr.from = bts_get(at, bts_from); - out->variant.lbr.to = bts_get(at, bts_to); - - if (!out->variant.lbr.from && !out->variant.lbr.to) - out->qualifier = bts_invalid; - } - - return ds_cfg.sizeof_rec[ds_bts]; -} - -static int bts_write(struct bts_tracer *tracer, const struct bts_struct *in) -{ - unsigned char raw[MAX_SIZEOF_BTS]; - - if (!tracer) - return -EINVAL; - - if (MAX_SIZEOF_BTS < ds_cfg.sizeof_rec[ds_bts]) - return -EOVERFLOW; - - switch (in->qualifier) { - case bts_invalid: - bts_set(raw, bts_from, 0); - bts_set(raw, bts_to, 0); - bts_set(raw, bts_flags, 0); - break; - case bts_branch: - bts_set(raw, bts_from, in->variant.lbr.from); - bts_set(raw, bts_to, in->variant.lbr.to); - bts_set(raw, bts_flags, 0); - break; - case bts_task_arrives: - case bts_task_departs: - bts_set(raw, bts_qual, (bts_escape | in->qualifier)); - bts_set(raw, bts_clock, in->variant.event.clock); - bts_set(raw, bts_pid, in->variant.event.pid); - break; - default: - return -EINVAL; - } - - return ds_write(tracer->ds.context, ds_bts, raw, - ds_cfg.sizeof_rec[ds_bts]); -} - - -static void ds_write_config(struct ds_context *context, - struct ds_trace *cfg, enum ds_qualifier qual) -{ - unsigned char *ds = context->ds; - - ds_set(ds, qual, ds_buffer_base, (unsigned long)cfg->begin); - ds_set(ds, qual, ds_index, (unsigned long)cfg->top); - ds_set(ds, qual, ds_absolute_maximum, (unsigned long)cfg->end); - ds_set(ds, qual, ds_interrupt_threshold, (unsigned long)cfg->ith); -} - -static void ds_read_config(struct ds_context *context, - struct ds_trace *cfg, enum ds_qualifier qual) -{ - unsigned char *ds = context->ds; - - cfg->begin = (void *)ds_get(ds, qual, ds_buffer_base); - cfg->top = (void *)ds_get(ds, qual, ds_index); - cfg->end = (void *)ds_get(ds, qual, ds_absolute_maximum); - cfg->ith = (void *)ds_get(ds, qual, ds_interrupt_threshold); -} - -static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual, - void *base, size_t size, size_t ith, - unsigned int flags) { - unsigned long buffer, adj; - - /* - * Adjust the buffer address and size to meet alignment - * constraints: - * - buffer is double-word aligned - * - size is multiple of record size - * - * We checked the size at the very beginning; we have enough - * space to do the adjustment. - */ - buffer = (unsigned long)base; - - adj = ALIGN(buffer, DS_ALIGNMENT) - buffer; - buffer += adj; - size -= adj; - - trace->n = size / ds_cfg.sizeof_rec[qual]; - trace->size = ds_cfg.sizeof_rec[qual]; - - size = (trace->n * trace->size); - - trace->begin = (void *)buffer; - trace->top = trace->begin; - trace->end = (void *)(buffer + size); - /* - * The value for 'no threshold' is -1, which will set the - * threshold outside of the buffer, just like we want it. - */ - ith *= ds_cfg.sizeof_rec[qual]; - trace->ith = (void *)(buffer + size - ith); - - trace->flags = flags; -} - - -static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace, - enum ds_qualifier qual, struct task_struct *task, - int cpu, void *base, size_t size, size_t th) -{ - struct ds_context *context; - int error; - size_t req_size; - - error = -EOPNOTSUPP; - if (!ds_cfg.sizeof_rec[qual]) - goto out; - - error = -EINVAL; - if (!base) - goto out; - - req_size = ds_cfg.sizeof_rec[qual]; - /* We might need space for alignment adjustments. */ - if (!IS_ALIGNED((unsigned long)base, DS_ALIGNMENT)) - req_size += DS_ALIGNMENT; - - error = -EINVAL; - if (size < req_size) - goto out; - - if (th != (size_t)-1) { - th *= ds_cfg.sizeof_rec[qual]; - - error = -EINVAL; - if (size <= th) - goto out; - } - - tracer->buffer = base; - tracer->size = size; - - error = -ENOMEM; - context = ds_get_context(task, cpu); - if (!context) - goto out; - tracer->context = context; - - /* - * Defer any tracer-specific initialization work for the context until - * context ownership has been clarified. - */ - - error = 0; - out: - return error; -} - -static struct bts_tracer *ds_request_bts(struct task_struct *task, int cpu, - void *base, size_t size, - bts_ovfl_callback_t ovfl, size_t th, - unsigned int flags) -{ - struct bts_tracer *tracer; - int error; - - /* Buffer overflow notification is not yet implemented. */ - error = -EOPNOTSUPP; - if (ovfl) - goto out; - - error = get_tracer(task); - if (error < 0) - goto out; - - error = -ENOMEM; - tracer = kzalloc(sizeof(*tracer), GFP_KERNEL); - if (!tracer) - goto out_put_tracer; - tracer->ovfl = ovfl; - - /* Do some more error checking and acquire a tracing context. */ - error = ds_request(&tracer->ds, &tracer->trace.ds, - ds_bts, task, cpu, base, size, th); - if (error < 0) - goto out_tracer; - - /* Claim the bts part of the tracing context we acquired above. */ - spin_lock_irq(&ds_lock); - - error = -EPERM; - if (tracer->ds.context->bts_master) - goto out_unlock; - tracer->ds.context->bts_master = tracer; - - spin_unlock_irq(&ds_lock); - - /* - * Now that we own the bts part of the context, let's complete the - * initialization for that part. - */ - ds_init_ds_trace(&tracer->trace.ds, ds_bts, base, size, th, flags); - ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_bts); - ds_install_ds_area(tracer->ds.context); - - tracer->trace.read = bts_read; - tracer->trace.write = bts_write; - - /* Start tracing. */ - ds_resume_bts(tracer); - - return tracer; - - out_unlock: - spin_unlock_irq(&ds_lock); - ds_put_context(tracer->ds.context); - out_tracer: - kfree(tracer); - out_put_tracer: - put_tracer(task); - out: - return ERR_PTR(error); -} - -struct bts_tracer *ds_request_bts_task(struct task_struct *task, - void *base, size_t size, - bts_ovfl_callback_t ovfl, - size_t th, unsigned int flags) -{ - return ds_request_bts(task, 0, base, size, ovfl, th, flags); -} - -struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size, - bts_ovfl_callback_t ovfl, - size_t th, unsigned int flags) -{ - return ds_request_bts(NULL, cpu, base, size, ovfl, th, flags); -} - -static struct pebs_tracer *ds_request_pebs(struct task_struct *task, int cpu, - void *base, size_t size, - pebs_ovfl_callback_t ovfl, size_t th, - unsigned int flags) -{ - struct pebs_tracer *tracer; - int error; - - /* Buffer overflow notification is not yet implemented. */ - error = -EOPNOTSUPP; - if (ovfl) - goto out; - - error = get_tracer(task); - if (error < 0) - goto out; - - error = -ENOMEM; - tracer = kzalloc(sizeof(*tracer), GFP_KERNEL); - if (!tracer) - goto out_put_tracer; - tracer->ovfl = ovfl; - - /* Do some more error checking and acquire a tracing context. */ - error = ds_request(&tracer->ds, &tracer->trace.ds, - ds_pebs, task, cpu, base, size, th); - if (error < 0) - goto out_tracer; - - /* Claim the pebs part of the tracing context we acquired above. */ - spin_lock_irq(&ds_lock); - - error = -EPERM; - if (tracer->ds.context->pebs_master) - goto out_unlock; - tracer->ds.context->pebs_master = tracer; - - spin_unlock_irq(&ds_lock); - - /* - * Now that we own the pebs part of the context, let's complete the - * initialization for that part. - */ - ds_init_ds_trace(&tracer->trace.ds, ds_pebs, base, size, th, flags); - ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_pebs); - ds_install_ds_area(tracer->ds.context); - - /* Start tracing. */ - ds_resume_pebs(tracer); - - return tracer; - - out_unlock: - spin_unlock_irq(&ds_lock); - ds_put_context(tracer->ds.context); - out_tracer: - kfree(tracer); - out_put_tracer: - put_tracer(task); - out: - return ERR_PTR(error); -} - -struct pebs_tracer *ds_request_pebs_task(struct task_struct *task, - void *base, size_t size, - pebs_ovfl_callback_t ovfl, - size_t th, unsigned int flags) -{ - return ds_request_pebs(task, 0, base, size, ovfl, th, flags); -} - -struct pebs_tracer *ds_request_pebs_cpu(int cpu, void *base, size_t size, - pebs_ovfl_callback_t ovfl, - size_t th, unsigned int flags) -{ - return ds_request_pebs(NULL, cpu, base, size, ovfl, th, flags); -} - -static void ds_free_bts(struct bts_tracer *tracer) -{ - struct task_struct *task; - - task = tracer->ds.context->task; - - WARN_ON_ONCE(tracer->ds.context->bts_master != tracer); - tracer->ds.context->bts_master = NULL; - - /* Make sure tracing stopped and the tracer is not in use. */ - if (task && (task != current)) - wait_task_context_switch(task); - - ds_put_context(tracer->ds.context); - put_tracer(task); - - kfree(tracer); -} - -void ds_release_bts(struct bts_tracer *tracer) -{ - might_sleep(); - - if (!tracer) - return; - - ds_suspend_bts(tracer); - ds_free_bts(tracer); -} - -int ds_release_bts_noirq(struct bts_tracer *tracer) -{ - struct task_struct *task; - unsigned long irq; - int error; - - if (!tracer) - return 0; - - task = tracer->ds.context->task; - - local_irq_save(irq); - - error = -EPERM; - if (!task && - (tracer->ds.context->cpu != smp_processor_id())) - goto out; - - error = -EPERM; - if (task && (task != current)) - goto out; - - ds_suspend_bts_noirq(tracer); - ds_free_bts(tracer); - - error = 0; - out: - local_irq_restore(irq); - return error; -} - -static void update_task_debugctlmsr(struct task_struct *task, - unsigned long debugctlmsr) -{ - task->thread.debugctlmsr = debugctlmsr; - - get_cpu(); - if (task == current) - update_debugctlmsr(debugctlmsr); - put_cpu(); -} - -void ds_suspend_bts(struct bts_tracer *tracer) -{ - struct task_struct *task; - unsigned long debugctlmsr; - int cpu; - - if (!tracer) - return; - - tracer->flags = 0; - - task = tracer->ds.context->task; - cpu = tracer->ds.context->cpu; - - WARN_ON(!task && irqs_disabled()); - - debugctlmsr = (task ? - task->thread.debugctlmsr : - get_debugctlmsr_on_cpu(cpu)); - debugctlmsr &= ~BTS_CONTROL; - - if (task) - update_task_debugctlmsr(task, debugctlmsr); - else - update_debugctlmsr_on_cpu(cpu, debugctlmsr); -} - -int ds_suspend_bts_noirq(struct bts_tracer *tracer) -{ - struct task_struct *task; - unsigned long debugctlmsr, irq; - int cpu, error = 0; - - if (!tracer) - return 0; - - tracer->flags = 0; - - task = tracer->ds.context->task; - cpu = tracer->ds.context->cpu; - - local_irq_save(irq); - - error = -EPERM; - if (!task && (cpu != smp_processor_id())) - goto out; - - debugctlmsr = (task ? - task->thread.debugctlmsr : - get_debugctlmsr()); - debugctlmsr &= ~BTS_CONTROL; - - if (task) - update_task_debugctlmsr(task, debugctlmsr); - else - update_debugctlmsr(debugctlmsr); - - error = 0; - out: - local_irq_restore(irq); - return error; -} - -static unsigned long ds_bts_control(struct bts_tracer *tracer) -{ - unsigned long control; - - control = ds_cfg.ctl[dsf_bts]; - if (!(tracer->trace.ds.flags & BTS_KERNEL)) - control |= ds_cfg.ctl[dsf_bts_kernel]; - if (!(tracer->trace.ds.flags & BTS_USER)) - control |= ds_cfg.ctl[dsf_bts_user]; - - return control; -} - -void ds_resume_bts(struct bts_tracer *tracer) -{ - struct task_struct *task; - unsigned long debugctlmsr; - int cpu; - - if (!tracer) - return; - - tracer->flags = tracer->trace.ds.flags; - - task = tracer->ds.context->task; - cpu = tracer->ds.context->cpu; - - WARN_ON(!task && irqs_disabled()); - - debugctlmsr = (task ? - task->thread.debugctlmsr : - get_debugctlmsr_on_cpu(cpu)); - debugctlmsr |= ds_bts_control(tracer); - - if (task) - update_task_debugctlmsr(task, debugctlmsr); - else - update_debugctlmsr_on_cpu(cpu, debugctlmsr); -} - -int ds_resume_bts_noirq(struct bts_tracer *tracer) -{ - struct task_struct *task; - unsigned long debugctlmsr, irq; - int cpu, error = 0; - - if (!tracer) - return 0; - - tracer->flags = tracer->trace.ds.flags; - - task = tracer->ds.context->task; - cpu = tracer->ds.context->cpu; - - local_irq_save(irq); - - error = -EPERM; - if (!task && (cpu != smp_processor_id())) - goto out; - - debugctlmsr = (task ? - task->thread.debugctlmsr : - get_debugctlmsr()); - debugctlmsr |= ds_bts_control(tracer); - - if (task) - update_task_debugctlmsr(task, debugctlmsr); - else - update_debugctlmsr(debugctlmsr); - - error = 0; - out: - local_irq_restore(irq); - return error; -} - -static void ds_free_pebs(struct pebs_tracer *tracer) -{ - struct task_struct *task; - - task = tracer->ds.context->task; - - WARN_ON_ONCE(tracer->ds.context->pebs_master != tracer); - tracer->ds.context->pebs_master = NULL; - - ds_put_context(tracer->ds.context); - put_tracer(task); - - kfree(tracer); -} - -void ds_release_pebs(struct pebs_tracer *tracer) -{ - might_sleep(); - - if (!tracer) - return; - - ds_suspend_pebs(tracer); - ds_free_pebs(tracer); -} - -int ds_release_pebs_noirq(struct pebs_tracer *tracer) -{ - struct task_struct *task; - unsigned long irq; - int error; - - if (!tracer) - return 0; - - task = tracer->ds.context->task; - - local_irq_save(irq); - - error = -EPERM; - if (!task && - (tracer->ds.context->cpu != smp_processor_id())) - goto out; - - error = -EPERM; - if (task && (task != current)) - goto out; - - ds_suspend_pebs_noirq(tracer); - ds_free_pebs(tracer); - - error = 0; - out: - local_irq_restore(irq); - return error; -} - -void ds_suspend_pebs(struct pebs_tracer *tracer) -{ - -} - -int ds_suspend_pebs_noirq(struct pebs_tracer *tracer) -{ - return 0; -} - -void ds_resume_pebs(struct pebs_tracer *tracer) -{ - -} - -int ds_resume_pebs_noirq(struct pebs_tracer *tracer) -{ - return 0; -} - -const struct bts_trace *ds_read_bts(struct bts_tracer *tracer) -{ - if (!tracer) - return NULL; - - ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_bts); - return &tracer->trace; -} - -const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer) -{ - if (!tracer) - return NULL; - - ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_pebs); - - tracer->trace.counters = ds_cfg.nr_counter_reset; - memcpy(tracer->trace.counter_reset, - tracer->ds.context->ds + - (NUM_DS_PTR_FIELDS * ds_cfg.sizeof_ptr_field), - ds_cfg.nr_counter_reset * PEBS_RESET_FIELD_SIZE); - - return &tracer->trace; -} - -int ds_reset_bts(struct bts_tracer *tracer) -{ - if (!tracer) - return -EINVAL; - - tracer->trace.ds.top = tracer->trace.ds.begin; - - ds_set(tracer->ds.context->ds, ds_bts, ds_index, - (unsigned long)tracer->trace.ds.top); - - return 0; -} - -int ds_reset_pebs(struct pebs_tracer *tracer) -{ - if (!tracer) - return -EINVAL; - - tracer->trace.ds.top = tracer->trace.ds.begin; - - ds_set(tracer->ds.context->ds, ds_pebs, ds_index, - (unsigned long)tracer->trace.ds.top); - - return 0; -} - -int ds_set_pebs_reset(struct pebs_tracer *tracer, - unsigned int counter, u64 value) -{ - if (!tracer) - return -EINVAL; - - if (ds_cfg.nr_counter_reset < counter) - return -EINVAL; - - *(u64 *)(tracer->ds.context->ds + - (NUM_DS_PTR_FIELDS * ds_cfg.sizeof_ptr_field) + - (counter * PEBS_RESET_FIELD_SIZE)) = value; - - return 0; -} - -static const struct ds_configuration ds_cfg_netburst = { - .name = "Netburst", - .ctl[dsf_bts] = (1 << 2) | (1 << 3), - .ctl[dsf_bts_kernel] = (1 << 5), - .ctl[dsf_bts_user] = (1 << 6), - .nr_counter_reset = 1, -}; -static const struct ds_configuration ds_cfg_pentium_m = { - .name = "Pentium M", - .ctl[dsf_bts] = (1 << 6) | (1 << 7), - .nr_counter_reset = 1, -}; -static const struct ds_configuration ds_cfg_core2_atom = { - .name = "Core 2/Atom", - .ctl[dsf_bts] = (1 << 6) | (1 << 7), - .ctl[dsf_bts_kernel] = (1 << 9), - .ctl[dsf_bts_user] = (1 << 10), - .nr_counter_reset = 1, -}; -static const struct ds_configuration ds_cfg_core_i7 = { - .name = "Core i7", - .ctl[dsf_bts] = (1 << 6) | (1 << 7), - .ctl[dsf_bts_kernel] = (1 << 9), - .ctl[dsf_bts_user] = (1 << 10), - .nr_counter_reset = 4, -}; - -static void -ds_configure(const struct ds_configuration *cfg, - struct cpuinfo_x86 *cpu) -{ - unsigned long nr_pebs_fields = 0; - - printk(KERN_INFO "[ds] using %s configuration\n", cfg->name); - -#ifdef __i386__ - nr_pebs_fields = 10; -#else - nr_pebs_fields = 18; -#endif - - /* - * Starting with version 2, architectural performance - * monitoring supports a format specifier. - */ - if ((cpuid_eax(0xa) & 0xff) > 1) { - unsigned long perf_capabilities, format; - - rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_capabilities); - - format = (perf_capabilities >> 8) & 0xf; - - switch (format) { - case 0: - nr_pebs_fields = 18; - break; - case 1: - nr_pebs_fields = 22; - break; - default: - printk(KERN_INFO - "[ds] unknown PEBS format: %lu\n", format); - nr_pebs_fields = 0; - break; - } - } - - memset(&ds_cfg, 0, sizeof(ds_cfg)); - ds_cfg = *cfg; - - ds_cfg.sizeof_ptr_field = - (cpu_has(cpu, X86_FEATURE_DTES64) ? 8 : 4); - - ds_cfg.sizeof_rec[ds_bts] = ds_cfg.sizeof_ptr_field * 3; - ds_cfg.sizeof_rec[ds_pebs] = ds_cfg.sizeof_ptr_field * nr_pebs_fields; - - if (!cpu_has(cpu, X86_FEATURE_BTS)) { - ds_cfg.sizeof_rec[ds_bts] = 0; - printk(KERN_INFO "[ds] bts not available\n"); - } - if (!cpu_has(cpu, X86_FEATURE_PEBS)) { - ds_cfg.sizeof_rec[ds_pebs] = 0; - printk(KERN_INFO "[ds] pebs not available\n"); - } - - printk(KERN_INFO "[ds] sizes: address: %u bit, ", - 8 * ds_cfg.sizeof_ptr_field); - printk("bts/pebs record: %u/%u bytes\n", - ds_cfg.sizeof_rec[ds_bts], ds_cfg.sizeof_rec[ds_pebs]); - - WARN_ON_ONCE(MAX_PEBS_COUNTERS < ds_cfg.nr_counter_reset); -} - -void __cpuinit ds_init_intel(struct cpuinfo_x86 *c) -{ - /* Only configure the first cpu. Others are identical. */ - if (ds_cfg.name) - return; - - switch (c->x86) { - case 0x6: - switch (c->x86_model) { - case 0x9: - case 0xd: /* Pentium M */ - ds_configure(&ds_cfg_pentium_m, c); - break; - case 0xf: - case 0x17: /* Core2 */ - case 0x1c: /* Atom */ - ds_configure(&ds_cfg_core2_atom, c); - break; - case 0x1a: /* Core i7 */ - ds_configure(&ds_cfg_core_i7, c); - break; - default: - /* Sorry, don't know about them. */ - break; - } - break; - case 0xf: - switch (c->x86_model) { - case 0x0: - case 0x1: - case 0x2: /* Netburst */ - ds_configure(&ds_cfg_netburst, c); - break; - default: - /* Sorry, don't know about them. */ - break; - } - break; - default: - /* Sorry, don't know about them. */ - break; - } -} - -static inline void ds_take_timestamp(struct ds_context *context, - enum bts_qualifier qualifier, - struct task_struct *task) -{ - struct bts_tracer *tracer = context->bts_master; - struct bts_struct ts; - - /* Prevent compilers from reading the tracer pointer twice. */ - barrier(); - - if (!tracer || !(tracer->flags & BTS_TIMESTAMPS)) - return; - - memset(&ts, 0, sizeof(ts)); - ts.qualifier = qualifier; - ts.variant.event.clock = trace_clock_global(); - ts.variant.event.pid = task->pid; - - bts_write(tracer, &ts); -} - -/* - * Change the DS configuration from tracing prev to tracing next. - */ -void ds_switch_to(struct task_struct *prev, struct task_struct *next) -{ - struct ds_context *prev_ctx = prev->thread.ds_ctx; - struct ds_context *next_ctx = next->thread.ds_ctx; - unsigned long debugctlmsr = next->thread.debugctlmsr; - - /* Make sure all data is read before we start. */ - barrier(); - - if (prev_ctx) { - update_debugctlmsr(0); - - ds_take_timestamp(prev_ctx, bts_task_departs, prev); - } - - if (next_ctx) { - ds_take_timestamp(next_ctx, bts_task_arrives, next); - - wrmsrl(MSR_IA32_DS_AREA, (unsigned long)next_ctx->ds); - } - - update_debugctlmsr(debugctlmsr); -} - -static __init int ds_selftest(void) -{ - if (ds_cfg.sizeof_rec[ds_bts]) { - int error; - - error = ds_selftest_bts(); - if (error) { - WARN(1, "[ds] selftest failed. disabling bts.\n"); - ds_cfg.sizeof_rec[ds_bts] = 0; - } - } - - if (ds_cfg.sizeof_rec[ds_pebs]) { - int error; - - error = ds_selftest_pebs(); - if (error) { - WARN(1, "[ds] selftest failed. disabling pebs.\n"); - ds_cfg.sizeof_rec[ds_pebs] = 0; - } - } - - return 0; -} -device_initcall(ds_selftest); diff --git a/arch/x86/kernel/ds_selftest.c b/arch/x86/kernel/ds_selftest.c deleted file mode 100644 index 6bc7c199ab99..000000000000 --- a/arch/x86/kernel/ds_selftest.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Debug Store support - selftest - * - * - * Copyright (C) 2009 Intel Corporation. - * Markus Metzger , 2009 - */ - -#include "ds_selftest.h" - -#include -#include -#include -#include - -#include - - -#define BUFFER_SIZE 521 /* Intentionally chose an odd size. */ -#define SMALL_BUFFER_SIZE 24 /* A single bts entry. */ - -struct ds_selftest_bts_conf { - struct bts_tracer *tracer; - int error; - int (*suspend)(struct bts_tracer *); - int (*resume)(struct bts_tracer *); -}; - -static int ds_selftest_bts_consistency(const struct bts_trace *trace) -{ - int error = 0; - - if (!trace) { - printk(KERN_CONT "failed to access trace..."); - /* Bail out. Other tests are pointless. */ - return -1; - } - - if (!trace->read) { - printk(KERN_CONT "bts read not available..."); - error = -1; - } - - /* Do some sanity checks on the trace configuration. */ - if (!trace->ds.n) { - printk(KERN_CONT "empty bts buffer..."); - error = -1; - } - if (!trace->ds.size) { - printk(KERN_CONT "bad bts trace setup..."); - error = -1; - } - if (trace->ds.end != - (char *)trace->ds.begin + (trace->ds.n * trace->ds.size)) { - printk(KERN_CONT "bad bts buffer setup..."); - error = -1; - } - /* - * We allow top in [begin; end], since its not clear when the - * overflow adjustment happens: after the increment or before the - * write. - */ - if ((trace->ds.top < trace->ds.begin) || - (trace->ds.end < trace->ds.top)) { - printk(KERN_CONT "bts top out of bounds..."); - error = -1; - } - - return error; -} - -static int ds_selftest_bts_read(struct bts_tracer *tracer, - const struct bts_trace *trace, - const void *from, const void *to) -{ - const unsigned char *at; - - /* - * Check a few things which do not belong to this test. - * They should be covered by other tests. - */ - if (!trace) - return -1; - - if (!trace->read) - return -1; - - if (to < from) - return -1; - - if (from < trace->ds.begin) - return -1; - - if (trace->ds.end < to) - return -1; - - if (!trace->ds.size) - return -1; - - /* Now to the test itself. */ - for (at = from; (void *)at < to; at += trace->ds.size) { - struct bts_struct bts; - unsigned long index; - int error; - - if (((void *)at - trace->ds.begin) % trace->ds.size) { - printk(KERN_CONT - "read from non-integer index..."); - return -1; - } - index = ((void *)at - trace->ds.begin) / trace->ds.size; - - memset(&bts, 0, sizeof(bts)); - error = trace->read(tracer, at, &bts); - if (error < 0) { - printk(KERN_CONT - "error reading bts trace at [%lu] (0x%p)...", - index, at); - return error; - } - - switch (bts.qualifier) { - case BTS_BRANCH: - break; - default: - printk(KERN_CONT - "unexpected bts entry %llu at [%lu] (0x%p)...", - bts.qualifier, index, at); - return -1; - } - } - - return 0; -} - -static void ds_selftest_bts_cpu(void *arg) -{ - struct ds_selftest_bts_conf *conf = arg; - const struct bts_trace *trace; - void *top; - - if (IS_ERR(conf->tracer)) { - conf->error = PTR_ERR(conf->tracer); - conf->tracer = NULL; - - printk(KERN_CONT - "initialization failed (err: %d)...", conf->error); - return; - } - - /* We should meanwhile have enough trace. */ - conf->error = conf->suspend(conf->tracer); - if (conf->error < 0) - return; - - /* Let's see if we can access the trace. */ - trace = ds_read_bts(conf->tracer); - - conf->error = ds_selftest_bts_consistency(trace); - if (conf->error < 0) - return; - - /* If everything went well, we should have a few trace entries. */ - if (trace->ds.top == trace->ds.begin) { - /* - * It is possible but highly unlikely that we got a - * buffer overflow and end up at exactly the same - * position we started from. - * Let's issue a warning, but continue. - */ - printk(KERN_CONT "no trace/overflow..."); - } - - /* Let's try to read the trace we collected. */ - conf->error = - ds_selftest_bts_read(conf->tracer, trace, - trace->ds.begin, trace->ds.top); - if (conf->error < 0) - return; - - /* - * Let's read the trace again. - * Since we suspended tracing, we should get the same result. - */ - top = trace->ds.top; - - trace = ds_read_bts(conf->tracer); - conf->error = ds_selftest_bts_consistency(trace); - if (conf->error < 0) - return; - - if (top != trace->ds.top) { - printk(KERN_CONT "suspend not working..."); - conf->error = -1; - return; - } - - /* Let's collect some more trace - see if resume is working. */ - conf->error = conf->resume(conf->tracer); - if (conf->error < 0) - return; - - conf->error = conf->suspend(conf->tracer); - if (conf->error < 0) - return; - - trace = ds_read_bts(conf->tracer); - - conf->error = ds_selftest_bts_consistency(trace); - if (conf->error < 0) - return; - - if (trace->ds.top == top) { - /* - * It is possible but highly unlikely that we got a - * buffer overflow and end up at exactly the same - * position we started from. - * Let's issue a warning and check the full trace. - */ - printk(KERN_CONT - "no resume progress/overflow..."); - - conf->error = - ds_selftest_bts_read(conf->tracer, trace, - trace->ds.begin, trace->ds.end); - } else if (trace->ds.top < top) { - /* - * We had a buffer overflow - the entire buffer should - * contain trace records. - */ - conf->error = - ds_selftest_bts_read(conf->tracer, trace, - trace->ds.begin, trace->ds.end); - } else { - /* - * It is quite likely that the buffer did not overflow. - * Let's just check the delta trace. - */ - conf->error = - ds_selftest_bts_read(conf->tracer, trace, top, - trace->ds.top); - } - if (conf->error < 0) - return; - - conf->error = 0; -} - -static int ds_suspend_bts_wrap(struct bts_tracer *tracer) -{ - ds_suspend_bts(tracer); - return 0; -} - -static int ds_resume_bts_wrap(struct bts_tracer *tracer) -{ - ds_resume_bts(tracer); - return 0; -} - -static void ds_release_bts_noirq_wrap(void *tracer) -{ - (void)ds_release_bts_noirq(tracer); -} - -static int ds_selftest_bts_bad_release_noirq(int cpu, - struct bts_tracer *tracer) -{ - int error = -EPERM; - - /* Try to release the tracer on the wrong cpu. */ - get_cpu(); - if (cpu != smp_processor_id()) { - error = ds_release_bts_noirq(tracer); - if (error != -EPERM) - printk(KERN_CONT "release on wrong cpu..."); - } - put_cpu(); - - return error ? 0 : -1; -} - -static int ds_selftest_bts_bad_request_cpu(int cpu, void *buffer) -{ - struct bts_tracer *tracer; - int error; - - /* Try to request cpu tracing while task tracing is active. */ - tracer = ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, NULL, - (size_t)-1, BTS_KERNEL); - error = PTR_ERR(tracer); - if (!IS_ERR(tracer)) { - ds_release_bts(tracer); - error = 0; - } - - if (error != -EPERM) - printk(KERN_CONT "cpu/task tracing overlap..."); - - return error ? 0 : -1; -} - -static int ds_selftest_bts_bad_request_task(void *buffer) -{ - struct bts_tracer *tracer; - int error; - - /* Try to request cpu tracing while task tracing is active. */ - tracer = ds_request_bts_task(current, buffer, BUFFER_SIZE, NULL, - (size_t)-1, BTS_KERNEL); - error = PTR_ERR(tracer); - if (!IS_ERR(tracer)) { - error = 0; - ds_release_bts(tracer); - } - - if (error != -EPERM) - printk(KERN_CONT "task/cpu tracing overlap..."); - - return error ? 0 : -1; -} - -int ds_selftest_bts(void) -{ - struct ds_selftest_bts_conf conf; - unsigned char buffer[BUFFER_SIZE], *small_buffer; - unsigned long irq; - int cpu; - - printk(KERN_INFO "[ds] bts selftest..."); - conf.error = 0; - - small_buffer = (unsigned char *)ALIGN((unsigned long)buffer, 8) + 8; - - get_online_cpus(); - for_each_online_cpu(cpu) { - conf.suspend = ds_suspend_bts_wrap; - conf.resume = ds_resume_bts_wrap; - conf.tracer = - ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, - NULL, (size_t)-1, BTS_KERNEL); - ds_selftest_bts_cpu(&conf); - if (conf.error >= 0) - conf.error = ds_selftest_bts_bad_request_task(buffer); - ds_release_bts(conf.tracer); - if (conf.error < 0) - goto out; - - conf.suspend = ds_suspend_bts_noirq; - conf.resume = ds_resume_bts_noirq; - conf.tracer = - ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, - NULL, (size_t)-1, BTS_KERNEL); - smp_call_function_single(cpu, ds_selftest_bts_cpu, &conf, 1); - if (conf.error >= 0) { - conf.error = - ds_selftest_bts_bad_release_noirq(cpu, - conf.tracer); - /* We must not release the tracer twice. */ - if (conf.error < 0) - conf.tracer = NULL; - } - if (conf.error >= 0) - conf.error = ds_selftest_bts_bad_request_task(buffer); - smp_call_function_single(cpu, ds_release_bts_noirq_wrap, - conf.tracer, 1); - if (conf.error < 0) - goto out; - } - - conf.suspend = ds_suspend_bts_wrap; - conf.resume = ds_resume_bts_wrap; - conf.tracer = - ds_request_bts_task(current, buffer, BUFFER_SIZE, - NULL, (size_t)-1, BTS_KERNEL); - ds_selftest_bts_cpu(&conf); - if (conf.error >= 0) - conf.error = ds_selftest_bts_bad_request_cpu(0, buffer); - ds_release_bts(conf.tracer); - if (conf.error < 0) - goto out; - - conf.suspend = ds_suspend_bts_noirq; - conf.resume = ds_resume_bts_noirq; - conf.tracer = - ds_request_bts_task(current, small_buffer, SMALL_BUFFER_SIZE, - NULL, (size_t)-1, BTS_KERNEL); - local_irq_save(irq); - ds_selftest_bts_cpu(&conf); - if (conf.error >= 0) - conf.error = ds_selftest_bts_bad_request_cpu(0, buffer); - ds_release_bts_noirq(conf.tracer); - local_irq_restore(irq); - if (conf.error < 0) - goto out; - - conf.error = 0; - out: - put_online_cpus(); - printk(KERN_CONT "%s.\n", (conf.error ? "failed" : "passed")); - - return conf.error; -} - -int ds_selftest_pebs(void) -{ - return 0; -} diff --git a/arch/x86/kernel/ds_selftest.h b/arch/x86/kernel/ds_selftest.h deleted file mode 100644 index 2ba8745c6663..000000000000 --- a/arch/x86/kernel/ds_selftest.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Debug Store support - selftest - * - * - * Copyright (C) 2009 Intel Corporation. - * Markus Metzger , 2009 - */ - -#ifdef CONFIG_X86_DS_SELFTEST -extern int ds_selftest_bts(void); -extern int ds_selftest_pebs(void); -#else -static inline int ds_selftest_bts(void) { return 0; } -static inline int ds_selftest_pebs(void) { return 0; } -#endif diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 6d817554780a..c89a386930b7 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -224,11 +224,6 @@ unsigned __kprobes long oops_begin(void) int cpu; unsigned long flags; - /* notify the hw-branch tracer so it may disable tracing and - add the last trace to the trace buffer - - the earlier this happens, the more useful the trace. */ - trace_hw_branch_oops(); - oops_enter(); /* racy, but better than risking deadlock. */ diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index b43bbaebe2c0..7a880ad3a208 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c @@ -422,14 +422,12 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, static void __kprobes clear_btf(void) { - if (test_thread_flag(TIF_DEBUGCTLMSR)) - update_debugctlmsr(0); + /* XXX */ } static void __kprobes restore_btf(void) { - if (test_thread_flag(TIF_DEBUGCTLMSR)) - update_debugctlmsr(current->thread.debugctlmsr); + /* XXX */ } void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index ad9540676fcc..1a60beb32ede 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -20,7 +20,6 @@ #include #include #include -#include #include unsigned long idle_halt; @@ -50,8 +49,6 @@ void free_thread_xstate(struct task_struct *tsk) kmem_cache_free(task_xstate_cachep, tsk->thread.xstate); tsk->thread.xstate = NULL; } - - WARN(tsk->thread.ds_ctx, "leaking DS context\n"); } void free_thread_info(struct thread_info *ti) @@ -198,12 +195,6 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, prev = &prev_p->thread; next = &next_p->thread; - if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) || - test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR)) - ds_switch_to(prev_p, next_p); - else if (next->debugctlmsr != prev->debugctlmsr) - update_debugctlmsr(next->debugctlmsr); - if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ test_tsk_thread_flag(next_p, TIF_NOTSC)) { /* prev and next are different */ diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index f6c62667e30c..75090c589b7a 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -55,7 +55,6 @@ #include #include #include -#include #include asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); @@ -238,13 +237,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, kfree(p->thread.io_bitmap_ptr); p->thread.io_bitmap_max = 0; } - - clear_tsk_thread_flag(p, TIF_DS_AREA_MSR); - p->thread.ds_ctx = NULL; - - clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR); - p->thread.debugctlmsr = 0; - return err; } diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index dc9690b4c4cc..cc4258f2beb5 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -49,7 +49,6 @@ #include #include #include -#include #include asmlinkage extern void ret_from_fork(void); @@ -313,13 +312,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, if (err) goto out; } - - clear_tsk_thread_flag(p, TIF_DS_AREA_MSR); - p->thread.ds_ctx = NULL; - - clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR); - p->thread.debugctlmsr = 0; - err = 0; out: if (err && p->thread.io_bitmap_ptr) { diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index a503b1fd04e5..f2fd3b80e565 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -2,9 +2,6 @@ /* * Pentium III FXSR, SSE support * Gareth Hughes , May 2000 - * - * BTS tracing - * Markus Metzger , Dec 2007 */ #include @@ -21,7 +18,6 @@ #include #include #include -#include #include #include @@ -35,7 +31,6 @@ #include #include #include -#include #include #include "tls.h" @@ -788,342 +783,6 @@ static int ioperm_get(struct task_struct *target, 0, IO_BITMAP_BYTES); } -#ifdef CONFIG_X86_PTRACE_BTS -/* - * A branch trace store context. - * - * Contexts may only be installed by ptrace_bts_config() and only for - * ptraced tasks. - * - * Contexts are destroyed when the tracee is detached from the tracer. - * The actual destruction work requires interrupts enabled, so the - * work is deferred and will be scheduled during __ptrace_unlink(). - * - * Contexts hold an additional task_struct reference on the traced - * task, as well as a reference on the tracer's mm. - * - * Ptrace already holds a task_struct for the duration of ptrace operations, - * but since destruction is deferred, it may be executed after both - * tracer and tracee exited. - */ -struct bts_context { - /* The branch trace handle. */ - struct bts_tracer *tracer; - - /* The buffer used to store the branch trace and its size. */ - void *buffer; - unsigned int size; - - /* The mm that paid for the above buffer. */ - struct mm_struct *mm; - - /* The task this context belongs to. */ - struct task_struct *task; - - /* The signal to send on a bts buffer overflow. */ - unsigned int bts_ovfl_signal; - - /* The work struct to destroy a context. */ - struct work_struct work; -}; - -static int alloc_bts_buffer(struct bts_context *context, unsigned int size) -{ - void *buffer = NULL; - int err = -ENOMEM; - - err = account_locked_memory(current->mm, current->signal->rlim, size); - if (err < 0) - return err; - - buffer = kzalloc(size, GFP_KERNEL); - if (!buffer) - goto out_refund; - - context->buffer = buffer; - context->size = size; - context->mm = get_task_mm(current); - - return 0; - - out_refund: - refund_locked_memory(current->mm, size); - return err; -} - -static inline void free_bts_buffer(struct bts_context *context) -{ - if (!context->buffer) - return; - - kfree(context->buffer); - context->buffer = NULL; - - refund_locked_memory(context->mm, context->size); - context->size = 0; - - mmput(context->mm); - context->mm = NULL; -} - -static void free_bts_context_work(struct work_struct *w) -{ - struct bts_context *context; - - context = container_of(w, struct bts_context, work); - - ds_release_bts(context->tracer); - put_task_struct(context->task); - free_bts_buffer(context); - kfree(context); -} - -static inline void free_bts_context(struct bts_context *context) -{ - INIT_WORK(&context->work, free_bts_context_work); - schedule_work(&context->work); -} - -static inline struct bts_context *alloc_bts_context(struct task_struct *task) -{ - struct bts_context *context = kzalloc(sizeof(*context), GFP_KERNEL); - if (context) { - context->task = task; - task->bts = context; - - get_task_struct(task); - } - - return context; -} - -static int ptrace_bts_read_record(struct task_struct *child, size_t index, - struct bts_struct __user *out) -{ - struct bts_context *context; - const struct bts_trace *trace; - struct bts_struct bts; - const unsigned char *at; - int error; - - context = child->bts; - if (!context) - return -ESRCH; - - trace = ds_read_bts(context->tracer); - if (!trace) - return -ESRCH; - - at = trace->ds.top - ((index + 1) * trace->ds.size); - if ((void *)at < trace->ds.begin) - at += (trace->ds.n * trace->ds.size); - - if (!trace->read) - return -EOPNOTSUPP; - - error = trace->read(context->tracer, at, &bts); - if (error < 0) - return error; - - if (copy_to_user(out, &bts, sizeof(bts))) - return -EFAULT; - - return sizeof(bts); -} - -static int ptrace_bts_drain(struct task_struct *child, - long size, - struct bts_struct __user *out) -{ - struct bts_context *context; - const struct bts_trace *trace; - const unsigned char *at; - int error, drained = 0; - - context = child->bts; - if (!context) - return -ESRCH; - - trace = ds_read_bts(context->tracer); - if (!trace) - return -ESRCH; - - if (!trace->read) - return -EOPNOTSUPP; - - if (size < (trace->ds.top - trace->ds.begin)) - return -EIO; - - for (at = trace->ds.begin; (void *)at < trace->ds.top; - out++, drained++, at += trace->ds.size) { - struct bts_struct bts; - - error = trace->read(context->tracer, at, &bts); - if (error < 0) - return error; - - if (copy_to_user(out, &bts, sizeof(bts))) - return -EFAULT; - } - - memset(trace->ds.begin, 0, trace->ds.n * trace->ds.size); - - error = ds_reset_bts(context->tracer); - if (error < 0) - return error; - - return drained; -} - -static int ptrace_bts_config(struct task_struct *child, - long cfg_size, - const struct ptrace_bts_config __user *ucfg) -{ - struct bts_context *context; - struct ptrace_bts_config cfg; - unsigned int flags = 0; - - if (cfg_size < sizeof(cfg)) - return -EIO; - - if (copy_from_user(&cfg, ucfg, sizeof(cfg))) - return -EFAULT; - - context = child->bts; - if (!context) - context = alloc_bts_context(child); - if (!context) - return -ENOMEM; - - if (cfg.flags & PTRACE_BTS_O_SIGNAL) { - if (!cfg.signal) - return -EINVAL; - - return -EOPNOTSUPP; - context->bts_ovfl_signal = cfg.signal; - } - - ds_release_bts(context->tracer); - context->tracer = NULL; - - if ((cfg.flags & PTRACE_BTS_O_ALLOC) && (cfg.size != context->size)) { - int err; - - free_bts_buffer(context); - if (!cfg.size) - return 0; - - err = alloc_bts_buffer(context, cfg.size); - if (err < 0) - return err; - } - - if (cfg.flags & PTRACE_BTS_O_TRACE) - flags |= BTS_USER; - - if (cfg.flags & PTRACE_BTS_O_SCHED) - flags |= BTS_TIMESTAMPS; - - context->tracer = - ds_request_bts_task(child, context->buffer, context->size, - NULL, (size_t)-1, flags); - if (unlikely(IS_ERR(context->tracer))) { - int error = PTR_ERR(context->tracer); - - free_bts_buffer(context); - context->tracer = NULL; - return error; - } - - return sizeof(cfg); -} - -static int ptrace_bts_status(struct task_struct *child, - long cfg_size, - struct ptrace_bts_config __user *ucfg) -{ - struct bts_context *context; - const struct bts_trace *trace; - struct ptrace_bts_config cfg; - - context = child->bts; - if (!context) - return -ESRCH; - - if (cfg_size < sizeof(cfg)) - return -EIO; - - trace = ds_read_bts(context->tracer); - if (!trace) - return -ESRCH; - - memset(&cfg, 0, sizeof(cfg)); - cfg.size = trace->ds.end - trace->ds.begin; - cfg.signal = context->bts_ovfl_signal; - cfg.bts_size = sizeof(struct bts_struct); - - if (cfg.signal) - cfg.flags |= PTRACE_BTS_O_SIGNAL; - - if (trace->ds.flags & BTS_USER) - cfg.flags |= PTRACE_BTS_O_TRACE; - - if (trace->ds.flags & BTS_TIMESTAMPS) - cfg.flags |= PTRACE_BTS_O_SCHED; - - if (copy_to_user(ucfg, &cfg, sizeof(cfg))) - return -EFAULT; - - return sizeof(cfg); -} - -static int ptrace_bts_clear(struct task_struct *child) -{ - struct bts_context *context; - const struct bts_trace *trace; - - context = child->bts; - if (!context) - return -ESRCH; - - trace = ds_read_bts(context->tracer); - if (!trace) - return -ESRCH; - - memset(trace->ds.begin, 0, trace->ds.n * trace->ds.size); - - return ds_reset_bts(context->tracer); -} - -static int ptrace_bts_size(struct task_struct *child) -{ - struct bts_context *context; - const struct bts_trace *trace; - - context = child->bts; - if (!context) - return -ESRCH; - - trace = ds_read_bts(context->tracer); - if (!trace) - return -ESRCH; - - return (trace->ds.top - trace->ds.begin) / trace->ds.size; -} - -/* - * Called from __ptrace_unlink() after the child has been moved back - * to its original parent. - */ -void ptrace_bts_untrace(struct task_struct *child) -{ - if (unlikely(child->bts)) { - free_bts_context(child->bts); - child->bts = NULL; - } -} -#endif /* CONFIG_X86_PTRACE_BTS */ - /* * Called by kernel/ptrace.c when detaching.. * @@ -1251,39 +910,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; #endif - /* - * These bits need more cooking - not enabled yet: - */ -#ifdef CONFIG_X86_PTRACE_BTS - case PTRACE_BTS_CONFIG: - ret = ptrace_bts_config - (child, data, (struct ptrace_bts_config __user *)addr); - break; - - case PTRACE_BTS_STATUS: - ret = ptrace_bts_status - (child, data, (struct ptrace_bts_config __user *)addr); - break; - - case PTRACE_BTS_SIZE: - ret = ptrace_bts_size(child); - break; - - case PTRACE_BTS_GET: - ret = ptrace_bts_read_record - (child, data, (struct bts_struct __user *) addr); - break; - - case PTRACE_BTS_CLEAR: - ret = ptrace_bts_clear(child); - break; - - case PTRACE_BTS_DRAIN: - ret = ptrace_bts_drain - (child, data, (struct bts_struct __user *) addr); - break; -#endif /* CONFIG_X86_PTRACE_BTS */ - default: ret = ptrace_request(child, request, addr, data); break; @@ -1543,14 +1169,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, case PTRACE_GET_THREAD_AREA: case PTRACE_SET_THREAD_AREA: -#ifdef CONFIG_X86_PTRACE_BTS - case PTRACE_BTS_CONFIG: - case PTRACE_BTS_STATUS: - case PTRACE_BTS_SIZE: - case PTRACE_BTS_GET: - case PTRACE_BTS_CLEAR: - case PTRACE_BTS_DRAIN: -#endif /* CONFIG_X86_PTRACE_BTS */ return arch_ptrace(child, request, addr, data); default: diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c index 3149032ff107..7beba0769a8c 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c @@ -157,22 +157,6 @@ static int enable_single_step(struct task_struct *child) return 1; } -/* - * Install this value in MSR_IA32_DEBUGCTLMSR whenever child is running. - */ -static void write_debugctlmsr(struct task_struct *child, unsigned long val) -{ - if (child->thread.debugctlmsr == val) - return; - - child->thread.debugctlmsr = val; - - if (child != current) - return; - - update_debugctlmsr(val); -} - /* * Enable single or block step. */ @@ -185,17 +169,9 @@ static void enable_step(struct task_struct *child, bool block) * So noone should try to use debugger block stepping in a program * that uses user-mode single stepping itself. */ - if (enable_single_step(child) && block) { - set_tsk_thread_flag(child, TIF_DEBUGCTLMSR); - write_debugctlmsr(child, - child->thread.debugctlmsr | DEBUGCTLMSR_BTF); - } else { - write_debugctlmsr(child, - child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF); - - if (!child->thread.debugctlmsr) - clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); - } + if (!enable_single_step(child)) + return; + /* XXX */ } void user_enable_single_step(struct task_struct *child) @@ -213,11 +189,7 @@ void user_disable_single_step(struct task_struct *child) /* * Make sure block stepping (BTF) is disabled. */ - write_debugctlmsr(child, - child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF); - - if (!child->thread.debugctlmsr) - clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); + /* XXX */ /* Always clear TIF_SINGLESTEP... */ clear_tsk_thread_flag(child, TIF_SINGLESTEP); diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 1168e4454188..e3da5d726a37 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -543,11 +543,6 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) /* DR6 may or may not be cleared by the CPU */ set_debugreg(0, 6); - /* - * The processor cleared BTF, so don't mark that we need it set. - */ - clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR); - tsk->thread.debugctlmsr = 0; /* Store the virtualized DR6 value */ tsk->thread.debugreg6 = dr6; diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 01e6adea07ec..cc12b3c556b3 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -504,18 +504,6 @@ extern int ftrace_dump_on_oops; #define INIT_TRACE_RECURSION #endif -#ifdef CONFIG_HW_BRANCH_TRACER - -void trace_hw_branch(u64 from, u64 to); -void trace_hw_branch_oops(void); - -#else /* CONFIG_HW_BRANCH_TRACER */ - -static inline void trace_hw_branch(u64 from, u64 to) {} -static inline void trace_hw_branch_oops(void) {} - -#endif /* CONFIG_HW_BRANCH_TRACER */ - #ifdef CONFIG_FTRACE_SYSCALLS unsigned long arch_syscall_addr(int nr); diff --git a/include/linux/mm.h b/include/linux/mm.h index e70f21beb4b4..c8442b655111 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -19,7 +19,6 @@ struct anon_vma; struct file_ra_state; struct user_struct; struct writeback_control; -struct rlimit; #ifndef CONFIG_DISCONTIGMEM /* Don't use mapnrs, do it properly */ extern unsigned long max_mapnr; @@ -1449,9 +1448,6 @@ int vmemmap_populate_basepages(struct page *start_page, int vmemmap_populate(struct page *start_page, unsigned long pages, int node); void vmemmap_populate_print_last(void); -extern int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim, - size_t size); -extern void refund_locked_memory(struct mm_struct *mm, size_t size); enum mf_flags { MF_COUNT_INCREASED = 1 << 0, diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index e1fb60729979..4272521e29e9 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -345,18 +345,6 @@ static inline void user_single_step_siginfo(struct task_struct *tsk, #define arch_ptrace_stop(code, info) do { } while (0) #endif -#ifndef arch_ptrace_untrace -/* - * Do machine-specific work before untracing child. - * - * This is called for a normal detach as well as from ptrace_exit() - * when the tracing task dies. - * - * Called with write_lock(&tasklist_lock) held. - */ -#define arch_ptrace_untrace(task) do { } while (0) -#endif - extern int task_current_syscall(struct task_struct *target, long *callno, unsigned long args[6], unsigned int maxargs, unsigned long *sp, unsigned long *pc); diff --git a/include/linux/sched.h b/include/linux/sched.h index dad7f668ebf7..e0447c64af6a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -99,7 +99,6 @@ struct futex_pi_state; struct robust_list_head; struct bio_list; struct fs_struct; -struct bts_context; struct perf_event_context; /* @@ -1272,12 +1271,6 @@ struct task_struct { struct list_head ptraced; struct list_head ptrace_entry; - /* - * This is the tracer handle for the ptrace BTS extension. - * This field actually belongs to the ptracer task. - */ - struct bts_context *bts; - /* PID/PID hash table linkage. */ struct pid_link pids[PIDTYPE_MAX]; struct list_head thread_group; @@ -2123,10 +2116,8 @@ extern void set_task_comm(struct task_struct *tsk, char *from); extern char *get_task_comm(char *to, struct task_struct *tsk); #ifdef CONFIG_SMP -extern void wait_task_context_switch(struct task_struct *p); extern unsigned long wait_task_inactive(struct task_struct *, long match_state); #else -static inline void wait_task_context_switch(struct task_struct *p) {} static inline unsigned long wait_task_inactive(struct task_struct *p, long match_state) { diff --git a/kernel/fork.c b/kernel/fork.c index 4799c5f0e6d0..d67f1dbfbe03 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1108,9 +1108,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->memcg_batch.do_batch = 0; p->memcg_batch.memcg = NULL; #endif - - p->bts = NULL; - p->stack_start = stack_start; /* Perform scheduler related setup. Assign this task to a CPU. */ diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 42ad8ae729a0..9fb51237b18c 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -76,7 +76,6 @@ void __ptrace_unlink(struct task_struct *child) child->parent = child->real_parent; list_del_init(&child->ptrace_entry); - arch_ptrace_untrace(child); if (task_is_traced(child)) ptrace_untrace(child); } diff --git a/kernel/sched.c b/kernel/sched.c index 9ab3cd7858d3..117b7cad31b3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2076,49 +2076,6 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req) return 1; } -/* - * wait_task_context_switch - wait for a thread to complete at least one - * context switch. - * - * @p must not be current. - */ -void wait_task_context_switch(struct task_struct *p) -{ - unsigned long nvcsw, nivcsw, flags; - int running; - struct rq *rq; - - nvcsw = p->nvcsw; - nivcsw = p->nivcsw; - for (;;) { - /* - * The runqueue is assigned before the actual context - * switch. We need to take the runqueue lock. - * - * We could check initially without the lock but it is - * very likely that we need to take the lock in every - * iteration. - */ - rq = task_rq_lock(p, &flags); - running = task_running(rq, p); - task_rq_unlock(rq, &flags); - - if (likely(!running)) - break; - /* - * The switch count is incremented before the actual - * context switch. We thus wait for two switches to be - * sure at least one completed. - */ - if ((p->nvcsw - nvcsw) > 1) - break; - if ((p->nivcsw - nivcsw) > 1) - break; - - cpu_relax(); - } -} - /* * wait_task_inactive - wait for a thread to unschedule. * diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 13e13d428cd3..8b1797c4545b 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -44,9 +44,6 @@ config HAVE_FTRACE_MCOUNT_RECORD help See Documentation/trace/ftrace-design.txt -config HAVE_HW_BRANCH_TRACER - bool - config HAVE_SYSCALL_TRACEPOINTS bool help @@ -374,14 +371,6 @@ config STACK_TRACER Say N if unsure. -config HW_BRANCH_TRACER - depends on HAVE_HW_BRANCH_TRACER - bool "Trace hw branches" - select GENERIC_TRACER - help - This tracer records all branches on the system in a circular - buffer, giving access to the last N branches for each cpu. - config KMEMTRACE bool "Trace SLAB allocations" select GENERIC_TRACER diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 78edc6490038..ffb1a5b0550e 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -41,7 +41,6 @@ obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o obj-$(CONFIG_BOOT_TRACER) += trace_boot.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += trace_functions_graph.o obj-$(CONFIG_TRACE_BRANCH_PROFILING) += trace_branch.o -obj-$(CONFIG_HW_BRANCH_TRACER) += trace_hw_branches.o obj-$(CONFIG_KMEMTRACE) += kmemtrace.o obj-$(CONFIG_WORKQUEUE_TRACER) += trace_workqueue.o obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 2825ef2c0b15..bec2c973ff0c 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -34,7 +34,6 @@ enum trace_type { TRACE_GRAPH_RET, TRACE_GRAPH_ENT, TRACE_USER_STACK, - TRACE_HW_BRANCHES, TRACE_KMEM_ALLOC, TRACE_KMEM_FREE, TRACE_BLK, @@ -229,7 +228,6 @@ extern void __ftrace_bad_type(void); TRACE_GRAPH_ENT); \ IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry, \ TRACE_GRAPH_RET); \ - IF_ASSIGN(var, ent, struct hw_branch_entry, TRACE_HW_BRANCHES);\ IF_ASSIGN(var, ent, struct kmemtrace_alloc_entry, \ TRACE_KMEM_ALLOC); \ IF_ASSIGN(var, ent, struct kmemtrace_free_entry, \ @@ -467,8 +465,6 @@ extern int trace_selftest_startup_sysprof(struct tracer *trace, struct trace_array *tr); extern int trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr); -extern int trace_selftest_startup_hw_branches(struct tracer *trace, - struct trace_array *tr); extern int trace_selftest_startup_ksym(struct tracer *trace, struct trace_array *tr); #endif /* CONFIG_FTRACE_STARTUP_TEST */ diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index c16a08f399df..dc008c1240da 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -318,18 +318,6 @@ FTRACE_ENTRY(branch, trace_branch, __entry->func, __entry->file, __entry->correct) ); -FTRACE_ENTRY(hw_branch, hw_branch_entry, - - TRACE_HW_BRANCHES, - - F_STRUCT( - __field( u64, from ) - __field( u64, to ) - ), - - F_printk("from: %llx to: %llx", __entry->from, __entry->to) -); - FTRACE_ENTRY(kmem_alloc, kmemtrace_alloc_entry, TRACE_KMEM_ALLOC, diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c deleted file mode 100644 index 7b97000745f5..000000000000 --- a/kernel/trace/trace_hw_branches.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * h/w branch tracer for x86 based on BTS - * - * Copyright (C) 2008-2009 Intel Corporation. - * Markus Metzger , 2008-2009 - */ -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "trace_output.h" -#include "trace.h" - - -#define BTS_BUFFER_SIZE (1 << 13) - -static DEFINE_PER_CPU(struct bts_tracer *, hwb_tracer); -static DEFINE_PER_CPU(unsigned char[BTS_BUFFER_SIZE], hwb_buffer); - -#define this_tracer per_cpu(hwb_tracer, smp_processor_id()) - -static int trace_hw_branches_enabled __read_mostly; -static int trace_hw_branches_suspended __read_mostly; -static struct trace_array *hw_branch_trace __read_mostly; - - -static void bts_trace_init_cpu(int cpu) -{ - per_cpu(hwb_tracer, cpu) = - ds_request_bts_cpu(cpu, per_cpu(hwb_buffer, cpu), - BTS_BUFFER_SIZE, NULL, (size_t)-1, - BTS_KERNEL); - - if (IS_ERR(per_cpu(hwb_tracer, cpu))) - per_cpu(hwb_tracer, cpu) = NULL; -} - -static int bts_trace_init(struct trace_array *tr) -{ - int cpu; - - hw_branch_trace = tr; - trace_hw_branches_enabled = 0; - - get_online_cpus(); - for_each_online_cpu(cpu) { - bts_trace_init_cpu(cpu); - - if (likely(per_cpu(hwb_tracer, cpu))) - trace_hw_branches_enabled = 1; - } - trace_hw_branches_suspended = 0; - put_online_cpus(); - - /* If we could not enable tracing on a single cpu, we fail. */ - return trace_hw_branches_enabled ? 0 : -EOPNOTSUPP; -} - -static void bts_trace_reset(struct trace_array *tr) -{ - int cpu; - - get_online_cpus(); - for_each_online_cpu(cpu) { - if (likely(per_cpu(hwb_tracer, cpu))) { - ds_release_bts(per_cpu(hwb_tracer, cpu)); - per_cpu(hwb_tracer, cpu) = NULL; - } - } - trace_hw_branches_enabled = 0; - trace_hw_branches_suspended = 0; - put_online_cpus(); -} - -static void bts_trace_start(struct trace_array *tr) -{ - int cpu; - - get_online_cpus(); - for_each_online_cpu(cpu) - if (likely(per_cpu(hwb_tracer, cpu))) - ds_resume_bts(per_cpu(hwb_tracer, cpu)); - trace_hw_branches_suspended = 0; - put_online_cpus(); -} - -static void bts_trace_stop(struct trace_array *tr) -{ - int cpu; - - get_online_cpus(); - for_each_online_cpu(cpu) - if (likely(per_cpu(hwb_tracer, cpu))) - ds_suspend_bts(per_cpu(hwb_tracer, cpu)); - trace_hw_branches_suspended = 1; - put_online_cpus(); -} - -static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - int cpu = (long)hcpu; - - switch (action) { - case CPU_ONLINE: - case CPU_DOWN_FAILED: - /* The notification is sent with interrupts enabled. */ - if (trace_hw_branches_enabled) { - bts_trace_init_cpu(cpu); - - if (trace_hw_branches_suspended && - likely(per_cpu(hwb_tracer, cpu))) - ds_suspend_bts(per_cpu(hwb_tracer, cpu)); - } - break; - - case CPU_DOWN_PREPARE: - /* The notification is sent with interrupts enabled. */ - if (likely(per_cpu(hwb_tracer, cpu))) { - ds_release_bts(per_cpu(hwb_tracer, cpu)); - per_cpu(hwb_tracer, cpu) = NULL; - } - } - - return NOTIFY_DONE; -} - -static struct notifier_block bts_hotcpu_notifier __cpuinitdata = { - .notifier_call = bts_hotcpu_handler -}; - -static void bts_trace_print_header(struct seq_file *m) -{ - seq_puts(m, "# CPU# TO <- FROM\n"); -} - -static enum print_line_t bts_trace_print_line(struct trace_iterator *iter) -{ - unsigned long symflags = TRACE_ITER_SYM_OFFSET; - struct trace_entry *entry = iter->ent; - struct trace_seq *seq = &iter->seq; - struct hw_branch_entry *it; - - trace_assign_type(it, entry); - - if (entry->type == TRACE_HW_BRANCHES) { - if (trace_seq_printf(seq, "%4d ", iter->cpu) && - seq_print_ip_sym(seq, it->to, symflags) && - trace_seq_printf(seq, "\t <- ") && - seq_print_ip_sym(seq, it->from, symflags) && - trace_seq_printf(seq, "\n")) - return TRACE_TYPE_HANDLED; - return TRACE_TYPE_PARTIAL_LINE; - } - return TRACE_TYPE_UNHANDLED; -} - -void trace_hw_branch(u64 from, u64 to) -{ - struct ftrace_event_call *call = &event_hw_branch; - struct trace_array *tr = hw_branch_trace; - struct ring_buffer_event *event; - struct ring_buffer *buf; - struct hw_branch_entry *entry; - unsigned long irq1; - int cpu; - - if (unlikely(!tr)) - return; - - if (unlikely(!trace_hw_branches_enabled)) - return; - - local_irq_save(irq1); - cpu = raw_smp_processor_id(); - if (atomic_inc_return(&tr->data[cpu]->disabled) != 1) - goto out; - - buf = tr->buffer; - event = trace_buffer_lock_reserve(buf, TRACE_HW_BRANCHES, - sizeof(*entry), 0, 0); - if (!event) - goto out; - entry = ring_buffer_event_data(event); - tracing_generic_entry_update(&entry->ent, 0, from); - entry->ent.type = TRACE_HW_BRANCHES; - entry->from = from; - entry->to = to; - if (!filter_check_discard(call, entry, buf, event)) - trace_buffer_unlock_commit(buf, event, 0, 0); - - out: - atomic_dec(&tr->data[cpu]->disabled); - local_irq_restore(irq1); -} - -static void trace_bts_at(const struct bts_trace *trace, void *at) -{ - struct bts_struct bts; - int err = 0; - - WARN_ON_ONCE(!trace->read); - if (!trace->read) - return; - - err = trace->read(this_tracer, at, &bts); - if (err < 0) - return; - - switch (bts.qualifier) { - case BTS_BRANCH: - trace_hw_branch(bts.variant.lbr.from, bts.variant.lbr.to); - break; - } -} - -/* - * Collect the trace on the current cpu and write it into the ftrace buffer. - * - * pre: tracing must be suspended on the current cpu - */ -static void trace_bts_cpu(void *arg) -{ - struct trace_array *tr = (struct trace_array *)arg; - const struct bts_trace *trace; - unsigned char *at; - - if (unlikely(!tr)) - return; - - if (unlikely(atomic_read(&tr->data[raw_smp_processor_id()]->disabled))) - return; - - if (unlikely(!this_tracer)) - return; - - trace = ds_read_bts(this_tracer); - if (!trace) - return; - - for (at = trace->ds.top; (void *)at < trace->ds.end; - at += trace->ds.size) - trace_bts_at(trace, at); - - for (at = trace->ds.begin; (void *)at < trace->ds.top; - at += trace->ds.size) - trace_bts_at(trace, at); -} - -static void trace_bts_prepare(struct trace_iterator *iter) -{ - int cpu; - - get_online_cpus(); - for_each_online_cpu(cpu) - if (likely(per_cpu(hwb_tracer, cpu))) - ds_suspend_bts(per_cpu(hwb_tracer, cpu)); - /* - * We need to collect the trace on the respective cpu since ftrace - * implicitly adds the record for the current cpu. - * Once that is more flexible, we could collect the data from any cpu. - */ - on_each_cpu(trace_bts_cpu, iter->tr, 1); - - for_each_online_cpu(cpu) - if (likely(per_cpu(hwb_tracer, cpu))) - ds_resume_bts(per_cpu(hwb_tracer, cpu)); - put_online_cpus(); -} - -static void trace_bts_close(struct trace_iterator *iter) -{ - tracing_reset_online_cpus(iter->tr); -} - -void trace_hw_branch_oops(void) -{ - if (this_tracer) { - ds_suspend_bts_noirq(this_tracer); - trace_bts_cpu(hw_branch_trace); - ds_resume_bts_noirq(this_tracer); - } -} - -struct tracer bts_tracer __read_mostly = -{ - .name = "hw-branch-tracer", - .init = bts_trace_init, - .reset = bts_trace_reset, - .print_header = bts_trace_print_header, - .print_line = bts_trace_print_line, - .start = bts_trace_start, - .stop = bts_trace_stop, - .open = trace_bts_prepare, - .close = trace_bts_close, -#ifdef CONFIG_FTRACE_SELFTEST - .selftest = trace_selftest_startup_hw_branches, -#endif /* CONFIG_FTRACE_SELFTEST */ -}; - -__init static int init_bts_trace(void) -{ - register_hotcpu_notifier(&bts_hotcpu_notifier); - return register_tracer(&bts_tracer); -} -device_initcall(init_bts_trace); diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 280fea470d67..a7084e7c0427 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -16,7 +16,6 @@ static inline int trace_valid_entry(struct trace_entry *entry) case TRACE_BRANCH: case TRACE_GRAPH_ENT: case TRACE_GRAPH_RET: - case TRACE_HW_BRANCHES: case TRACE_KSYM: return 1; } @@ -754,62 +753,6 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr) } #endif /* CONFIG_BRANCH_TRACER */ -#ifdef CONFIG_HW_BRANCH_TRACER -int -trace_selftest_startup_hw_branches(struct tracer *trace, - struct trace_array *tr) -{ - struct trace_iterator *iter; - struct tracer tracer; - unsigned long count; - int ret; - - if (!trace->open) { - printk(KERN_CONT "missing open function..."); - return -1; - } - - ret = tracer_init(trace, tr); - if (ret) { - warn_failed_init_tracer(trace, ret); - return ret; - } - - /* - * The hw-branch tracer needs to collect the trace from the various - * cpu trace buffers - before tracing is stopped. - */ - iter = kzalloc(sizeof(*iter), GFP_KERNEL); - if (!iter) - return -ENOMEM; - - memcpy(&tracer, trace, sizeof(tracer)); - - iter->trace = &tracer; - iter->tr = tr; - iter->pos = -1; - mutex_init(&iter->mutex); - - trace->open(iter); - - mutex_destroy(&iter->mutex); - kfree(iter); - - tracing_stop(); - - ret = trace_test_buffer(tr, &count); - trace->reset(tr); - tracing_start(); - - if (!ret && !count) { - printk(KERN_CONT "no entries found.."); - ret = -1; - } - - return ret; -} -#endif /* CONFIG_HW_BRANCH_TRACER */ - #ifdef CONFIG_KSYM_TRACER static int ksym_selftest_dummy; diff --git a/mm/mlock.c b/mm/mlock.c index 8f4e2dfceec1..3f82720e0515 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -607,44 +607,3 @@ void user_shm_unlock(size_t size, struct user_struct *user) spin_unlock(&shmlock_user_lock); free_uid(user); } - -int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim, - size_t size) -{ - unsigned long lim, vm, pgsz; - int error = -ENOMEM; - - pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT; - - down_write(&mm->mmap_sem); - - lim = ACCESS_ONCE(rlim[RLIMIT_AS].rlim_cur) >> PAGE_SHIFT; - vm = mm->total_vm + pgsz; - if (lim < vm) - goto out; - - lim = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur) >> PAGE_SHIFT; - vm = mm->locked_vm + pgsz; - if (lim < vm) - goto out; - - mm->total_vm += pgsz; - mm->locked_vm += pgsz; - - error = 0; - out: - up_write(&mm->mmap_sem); - return error; -} - -void refund_locked_memory(struct mm_struct *mm, size_t size) -{ - unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT; - - down_write(&mm->mmap_sem); - - mm->total_vm -= pgsz; - mm->locked_vm -= pgsz; - - up_write(&mm->mmap_sem); -} -- cgit v1.2.3-59-g8ed1b From ea8e61b7bbc4a2faef77db34eb2db2a2c2372ff6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 25 Mar 2010 14:51:51 +0100 Subject: x86, ptrace: Fix block-step Implement ptrace-block-step using TIF_BLOCKSTEP which will set DEBUGCTLMSR_BTF when set for a task while preserving any other DEBUGCTLMSR bits. Signed-off-by: Peter Zijlstra LKML-Reference: <20100325135414.017536066@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/processor.h | 4 ++-- arch/x86/include/asm/thread_info.h | 4 +++- arch/x86/kernel/kprobes.c | 14 ++++++++++++-- arch/x86/kernel/process.c | 11 +++++++++++ arch/x86/kernel/step.c | 24 ++++++++++++++++++++---- arch/x86/kernel/traps.c | 5 +++++ 6 files changed, 53 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 5bec21a66dc5..32428b410b55 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -799,7 +799,7 @@ extern void cpu_init(void); static inline unsigned long get_debugctlmsr(void) { - unsigned long debugctlmsr = 0; + unsigned long debugctlmsr = 0; #ifndef CONFIG_X86_DEBUGCTLMSR if (boot_cpu_data.x86 < 6) @@ -807,7 +807,7 @@ static inline unsigned long get_debugctlmsr(void) #endif rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr); - return debugctlmsr; + return debugctlmsr; } static inline void update_debugctlmsr(unsigned long debugctlmsr) diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index dc85e12d1405..d017ed5502e2 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -92,6 +92,7 @@ struct thread_info { #define TIF_IO_BITMAP 22 /* uses I/O bitmap */ #define TIF_FREEZE 23 /* is freezing for suspend */ #define TIF_FORCED_TF 24 /* true if TF in eflags artificially */ +#define TIF_BLOCKSTEP 25 /* set when we want DEBUGCTLMSR_BTF */ #define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */ #define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */ @@ -113,6 +114,7 @@ struct thread_info { #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) #define _TIF_FREEZE (1 << TIF_FREEZE) #define _TIF_FORCED_TF (1 << TIF_FORCED_TF) +#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP) #define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) @@ -143,7 +145,7 @@ struct thread_info { /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW \ - (_TIF_IO_BITMAP|_TIF_NOTSC) + (_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP) #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG) diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 7a880ad3a208..f2f56c0967b6 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c @@ -422,12 +422,22 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, static void __kprobes clear_btf(void) { - /* XXX */ + if (test_thread_flag(TIF_BLOCKSTEP)) { + unsigned long debugctl = get_debugctlmsr(); + + debugctl &= ~DEBUGCTLMSR_BTF; + update_debugctlmsr(debugctl); + } } static void __kprobes restore_btf(void) { - /* XXX */ + if (test_thread_flag(TIF_BLOCKSTEP)) { + unsigned long debugctl = get_debugctlmsr(); + + debugctl |= DEBUGCTLMSR_BTF; + update_debugctlmsr(debugctl); + } } void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 1a60beb32ede..8328009416d7 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -195,6 +195,17 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, prev = &prev_p->thread; next = &next_p->thread; + if (test_tsk_thread_flag(prev_p, TIF_BLOCKSTEP) ^ + test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) { + unsigned long debugctl = get_debugctlmsr(); + + debugctl &= ~DEBUGCTLMSR_BTF; + if (test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) + debugctl |= DEBUGCTLMSR_BTF; + + update_debugctlmsr(debugctl); + } + if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ test_tsk_thread_flag(next_p, TIF_NOTSC)) { /* prev and next are different */ diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c index 7beba0769a8c..58de45ee08b6 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c @@ -169,9 +169,19 @@ static void enable_step(struct task_struct *child, bool block) * So noone should try to use debugger block stepping in a program * that uses user-mode single stepping itself. */ - if (!enable_single_step(child)) - return; - /* XXX */ + if (enable_single_step(child) && block) { + unsigned long debugctl = get_debugctlmsr(); + + debugctl |= DEBUGCTLMSR_BTF; + update_debugctlmsr(debugctl); + set_tsk_thread_flag(child, TIF_BLOCKSTEP); + } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) { + unsigned long debugctl = get_debugctlmsr(); + + debugctl &= ~DEBUGCTLMSR_BTF; + update_debugctlmsr(debugctl); + clear_tsk_thread_flag(child, TIF_BLOCKSTEP); + } } void user_enable_single_step(struct task_struct *child) @@ -189,7 +199,13 @@ void user_disable_single_step(struct task_struct *child) /* * Make sure block stepping (BTF) is disabled. */ - /* XXX */ + if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) { + unsigned long debugctl = get_debugctlmsr(); + + debugctl &= ~DEBUGCTLMSR_BTF; + update_debugctlmsr(debugctl); + clear_tsk_thread_flag(child, TIF_BLOCKSTEP); + } /* Always clear TIF_SINGLESTEP... */ clear_tsk_thread_flag(child, TIF_SINGLESTEP); diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index e3da5d726a37..36f1bd9f8e76 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -544,6 +544,11 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) /* DR6 may or may not be cleared by the CPU */ set_debugreg(0, 6); + /* + * The processor cleared BTF, so don't mark that we need it set. + */ + clear_tsk_thread_flag(tsk, TIF_BLOCKSTEP); + /* Store the virtualized DR6 value */ tsk->thread.debugreg6 = dr6; -- cgit v1.2.3-59-g8ed1b From 11164cd4f6dab326a88bdf27f2f8f7c11977e91a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 26 Mar 2010 14:08:44 +0100 Subject: perf, x86: Add Nehelem PMU programming errata workaround Implement the workaround for Intel Errata AAK100 and AAP53. Also, remove the Core-i7 name for Nehalem events since there are also Westmere based i7 chips. Signed-off-by: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: <1269608924.12097.147.camel@laptop> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 8 +++---- arch/x86/kernel/cpu/perf_event_intel.c | 43 ++++++++++++++++++++++++++++++---- arch/x86/kernel/cpu/perf_event_p4.c | 2 +- arch/x86/kernel/cpu/perf_event_p6.c | 2 +- 4 files changed, 45 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index f571f514de2a..6f66d4a845ff 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -184,7 +184,7 @@ struct x86_pmu { int version; int (*handle_irq)(struct pt_regs *); void (*disable_all)(void); - void (*enable_all)(void); + void (*enable_all)(int added); void (*enable)(struct perf_event *); void (*disable)(struct perf_event *); int (*hw_config)(struct perf_event_attr *attr, struct hw_perf_event *hwc); @@ -576,7 +576,7 @@ void hw_perf_disable(void) x86_pmu.disable_all(); } -static void x86_pmu_enable_all(void) +static void x86_pmu_enable_all(int added) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); int idx; @@ -784,7 +784,7 @@ void hw_perf_enable(void) struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct perf_event *event; struct hw_perf_event *hwc; - int i; + int i, added = cpuc->n_added; if (!x86_pmu_initialized()) return; @@ -836,7 +836,7 @@ void hw_perf_enable(void) cpuc->enabled = 1; barrier(); - x86_pmu.enable_all(); + x86_pmu.enable_all(added); } static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc) diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 044b8436b19d..676aac27aca4 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -483,7 +483,7 @@ static void intel_pmu_disable_all(void) intel_pmu_lbr_disable_all(); } -static void intel_pmu_enable_all(void) +static void intel_pmu_enable_all(int added) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); @@ -502,6 +502,40 @@ static void intel_pmu_enable_all(void) } } +/* + * Workaround for: + * Intel Errata AAK100 (model 26) + * Intel Errata AAP53 (model 30) + * + * These chips need to be 'reset' when adding counters by programming + * the magic three (non counting) events 0x4300D2, 0x4300B1 and 0x4300B5 + * either in sequence on the same PMC or on different PMCs. + */ +static void intel_pmu_nhm_enable_all(int added) +{ + if (added) { + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + int i; + + wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 0, 0x4300D2); + wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 1, 0x4300B1); + wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 2, 0x4300B5); + + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x3); + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0); + + for (i = 0; i < 3; i++) { + struct perf_event *event = cpuc->events[i]; + + if (!event) + continue; + + __x86_pmu_enable_event(&event->hw); + } + } + intel_pmu_enable_all(added); +} + static inline u64 intel_pmu_get_status(void) { u64 status; @@ -658,7 +692,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) intel_pmu_drain_bts_buffer(); status = intel_pmu_get_status(); if (!status) { - intel_pmu_enable_all(); + intel_pmu_enable_all(0); return 0; } @@ -707,7 +741,7 @@ again: goto again; done: - intel_pmu_enable_all(); + intel_pmu_enable_all(0); return 1; } @@ -920,7 +954,8 @@ static __init int intel_pmu_init(void) intel_pmu_lbr_init_nhm(); x86_pmu.event_constraints = intel_nehalem_event_constraints; - pr_cont("Nehalem/Corei7 events, "); + x86_pmu.enable_all = intel_pmu_nhm_enable_all; + pr_cont("Nehalem events, "); break; case 28: /* Atom */ diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index f8fe069f14e2..0d1be36cbe9e 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -535,7 +535,7 @@ static void p4_pmu_enable_event(struct perf_event *event) (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE); } -static void p4_pmu_enable_all(void) +static void p4_pmu_enable_all(int added) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); int idx; diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index 6ff4d01d880f..877182c850df 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -66,7 +66,7 @@ static void p6_pmu_disable_all(void) wrmsrl(MSR_P6_EVNTSEL0, val); } -static void p6_pmu_enable_all(void) +static void p6_pmu_enable_all(int added) { unsigned long val; -- cgit v1.2.3-59-g8ed1b From c3635c78e500a52c9fcd55de381a72928d9e054d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 26 Mar 2010 16:44:01 -0700 Subject: DMAENGINE: generic slave control v2 Convert the device_terminate_all() operation on the DMA engine to a generic device_control() operation which can now optionally support also pausing and resuming DMA on a certain channel. Implemented for the COH 901 318 DMAC as an example. [dan.j.williams@intel.com: update for timberdale] Signed-off-by: Linus Walleij Acked-by: Mark Brown Cc: Maciej Sosnowski Cc: Nicolas Ferre Cc: Pavel Machek Cc: Li Yang Cc: Guennadi Liakhovetski Cc: Paul Mundt Cc: Ralf Baechle Cc: Haavard Skinnemoen Cc: Magnus Damm Cc: Liam Girdwood Cc: Joe Perches Cc: Roland Dreier Signed-off-by: Dan Williams --- arch/arm/mach-u300/include/mach/coh901318.h | 14 ---------- drivers/dma/at_hdmac.c | 10 +++++-- drivers/dma/coh901318.c | 42 +++++++++++++++++++---------- drivers/dma/dmaengine.c | 2 +- drivers/dma/dw_dmac.c | 10 +++++-- drivers/dma/fsldma.c | 13 ++++++--- drivers/dma/ipu/ipu_idmac.c | 21 ++++++++++----- drivers/dma/shdma.c | 12 ++++++--- drivers/dma/timb_dma.c | 9 +++++-- drivers/dma/txx9dmac.c | 10 +++++-- drivers/mmc/host/atmel-mci.c | 2 +- drivers/serial/sh-sci.c | 2 +- drivers/video/mx3fb.c | 3 ++- include/linux/dmaengine.h | 18 +++++++++++-- sound/soc/txx9/txx9aclc.c | 6 ++--- 15 files changed, 117 insertions(+), 57 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index b8155b4e5ffa..43ec040e765b 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h @@ -109,20 +109,6 @@ struct coh901318_platform { */ u32 coh901318_get_bytes_left(struct dma_chan *chan); -/** - * coh901318_stop() - Stops dma transfer - * @chan: dma channel handle - * return 0 on success otherwise negative value - */ -void coh901318_stop(struct dma_chan *chan); - -/** - * coh901318_continue() - Resumes a stopped dma transfer - * @chan: dma channel handle - * return 0 on success otherwise negative value - */ -void coh901318_continue(struct dma_chan *chan); - /** * coh901318_filter_id() - DMA channel filter function * @chan: dma channel handle diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index efc1a61ca231..f9143cf9e50a 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -759,13 +759,17 @@ err_desc_get: return NULL; } -static void atc_terminate_all(struct dma_chan *chan) +static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct at_dma_chan *atchan = to_at_dma_chan(chan); struct at_dma *atdma = to_at_dma(chan->device); struct at_desc *desc, *_desc; LIST_HEAD(list); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* * This is only called when something went wrong elsewhere, so * we don't really care about the data. Just disable the @@ -789,6 +793,8 @@ static void atc_terminate_all(struct dma_chan *chan) /* Flush all pending and queued descriptors */ list_for_each_entry_safe(desc, _desc, &list, desc_node) atc_chain_complete(atchan, desc); + + return 0; } /** @@ -1091,7 +1097,7 @@ static int __init at_dma_probe(struct platform_device *pdev) if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) { atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg; - atdma->dma_common.device_terminate_all = atc_terminate_all; + atdma->dma_common.device_control = atc_control; } dma_writel(atdma, EN, AT_DMA_ENABLE); diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index f636c4a87c7f..53c54e034aa3 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -506,10 +506,11 @@ u32 coh901318_get_bytes_left(struct dma_chan *chan) EXPORT_SYMBOL(coh901318_get_bytes_left); -/* Stops a transfer without losing data. Enables power save. - Use this function in conjunction with coh901318_continue(..) -*/ -void coh901318_stop(struct dma_chan *chan) +/* + * Pauses a transfer without losing data. Enables power save. + * Use this function in conjunction with coh901318_resume. + */ +static void coh901318_pause(struct dma_chan *chan) { u32 val; unsigned long flags; @@ -550,12 +551,11 @@ void coh901318_stop(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); } -EXPORT_SYMBOL(coh901318_stop); -/* Continues a transfer that has been stopped via 300_dma_stop(..). +/* Resumes a transfer that has been stopped via 300_dma_stop(..). Power save is handled. */ -void coh901318_continue(struct dma_chan *chan) +static void coh901318_resume(struct dma_chan *chan) { u32 val; unsigned long flags; @@ -581,7 +581,6 @@ void coh901318_continue(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); } -EXPORT_SYMBOL(coh901318_continue); bool coh901318_filter_id(struct dma_chan *chan, void *chan_id) { @@ -945,7 +944,7 @@ coh901318_free_chan_resources(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); } @@ -1179,16 +1178,29 @@ coh901318_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); } -static void -coh901318_terminate_all(struct dma_chan *chan) +static int +coh901318_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { unsigned long flags; struct coh901318_chan *cohc = to_coh901318_chan(chan); struct coh901318_desc *cohd; void __iomem *virtbase = cohc->base->virtbase; - coh901318_stop(chan); + if (cmd == DMA_PAUSE) { + coh901318_pause(chan); + return 0; + } + + if (cmd == DMA_RESUME) { + coh901318_resume(chan); + return 0; + } + + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* The remainder of this function terminates the transfer */ + coh901318_pause(chan); spin_lock_irqsave(&cohc->lock, flags); /* Clear any pending BE or TC interrupt */ @@ -1227,6 +1239,8 @@ coh901318_terminate_all(struct dma_chan *chan) cohc->busy = 0; spin_unlock_irqrestore(&cohc->lock, flags); + + return 0; } void coh901318_base_init(struct dma_device *dma, const int *pick_chans, struct coh901318_base *base) @@ -1344,7 +1358,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete; base->dma_slave.device_issue_pending = coh901318_issue_pending; - base->dma_slave.device_terminate_all = coh901318_terminate_all; + base->dma_slave.device_control = coh901318_control; base->dma_slave.dev = &pdev->dev; err = dma_async_device_register(&base->dma_slave); @@ -1364,7 +1378,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete; base->dma_memcpy.device_issue_pending = coh901318_issue_pending; - base->dma_memcpy.device_terminate_all = coh901318_terminate_all; + base->dma_memcpy.device_control = coh901318_control; base->dma_memcpy.dev = &pdev->dev; /* * This controller can only access address at even 32bit boundaries, diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 87399cafce37..ffc4ee9c5e21 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -694,7 +694,7 @@ int dma_async_device_register(struct dma_device *device) BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) && !device->device_prep_slave_sg); BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) && - !device->device_terminate_all); + !device->device_control); BUG_ON(!device->device_alloc_chan_resources); BUG_ON(!device->device_free_chan_resources); diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index d28369f7afd2..8a6b85f61176 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -781,13 +781,17 @@ err_desc_get: return NULL; } -static void dwc_terminate_all(struct dma_chan *chan) +static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); struct dw_dma *dw = to_dw_dma(chan->device); struct dw_desc *desc, *_desc; LIST_HEAD(list); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* * This is only called when something went wrong elsewhere, so * we don't really care about the data. Just disable the @@ -810,6 +814,8 @@ static void dwc_terminate_all(struct dma_chan *chan) /* Flush all pending and queued descriptors */ list_for_each_entry_safe(desc, _desc, &list, desc_node) dwc_descriptor_complete(dwc, desc); + + return 0; } static enum dma_status @@ -1338,7 +1344,7 @@ static int __init dw_probe(struct platform_device *pdev) dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy; dw->dma.device_prep_slave_sg = dwc_prep_slave_sg; - dw->dma.device_terminate_all = dwc_terminate_all; + dw->dma.device_control = dwc_control; dw->dma.device_is_tx_complete = dwc_is_tx_complete; dw->dma.device_issue_pending = dwc_issue_pending; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index bbb4be5a3ff4..714fc46e7695 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -774,13 +774,18 @@ fail: return NULL; } -static void fsl_dma_device_terminate_all(struct dma_chan *dchan) +static int fsl_dma_device_control(struct dma_chan *dchan, + enum dma_ctrl_cmd cmd) { struct fsldma_chan *chan; unsigned long flags; + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + if (!dchan) - return; + return -EINVAL; chan = to_fsl_chan(dchan); @@ -794,6 +799,8 @@ static void fsl_dma_device_terminate_all(struct dma_chan *dchan) fsldma_free_desc_list(chan, &chan->ld_running); spin_unlock_irqrestore(&chan->desc_lock, flags); + + return 0; } /** @@ -1332,7 +1339,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, fdev->common.device_is_tx_complete = fsl_dma_is_complete; fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; - fdev->common.device_terminate_all = fsl_dma_device_terminate_all; + fdev->common.device_control = fsl_dma_device_control; fdev->common.dev = &op->dev; dev_set_drvdata(&op->dev, fdev); diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 2a446397c884..39e7fb2a90e3 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1472,13 +1472,17 @@ static void idmac_issue_pending(struct dma_chan *chan) */ } -static void __idmac_terminate_all(struct dma_chan *chan) +static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct idmac_channel *ichan = to_idmac_chan(chan); struct idmac *idmac = to_idmac(chan->device); unsigned long flags; int i; + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + ipu_disable_channel(idmac, ichan, ichan->status >= IPU_CHANNEL_ENABLED); @@ -1505,17 +1509,22 @@ static void __idmac_terminate_all(struct dma_chan *chan) tasklet_enable(&to_ipu(idmac)->tasklet); ichan->status = IPU_CHANNEL_INITIALIZED; + + return 0; } -static void idmac_terminate_all(struct dma_chan *chan) +static int idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct idmac_channel *ichan = to_idmac_chan(chan); + int ret; mutex_lock(&ichan->chan_mutex); - __idmac_terminate_all(chan); + ret = __idmac_control(chan, cmd); mutex_unlock(&ichan->chan_mutex); + + return ret; } #ifdef DEBUG @@ -1607,7 +1616,7 @@ static void idmac_free_chan_resources(struct dma_chan *chan) mutex_lock(&ichan->chan_mutex); - __idmac_terminate_all(chan); + __idmac_control(chan, DMA_TERMINATE_ALL); if (ichan->status > IPU_CHANNEL_FREE) { #ifdef DEBUG @@ -1669,7 +1678,7 @@ static int __init ipu_idmac_init(struct ipu *ipu) /* Compulsory for DMA_SLAVE fields */ dma->device_prep_slave_sg = idmac_prep_slave_sg; - dma->device_terminate_all = idmac_terminate_all; + dma->device_control = idmac_control; INIT_LIST_HEAD(&dma->channels); for (i = 0; i < IPU_CHANNELS_NUM; i++) { @@ -1703,7 +1712,7 @@ static void __exit ipu_idmac_exit(struct ipu *ipu) for (i = 0; i < IPU_CHANNELS_NUM; i++) { struct idmac_channel *ichan = ipu->channel + i; - idmac_terminate_all(&ichan->dma_chan); + idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL); idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0); } diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 5d17e09cb625..ce28c1e22825 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -580,12 +580,16 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( direction, flags); } -static void sh_dmae_terminate_all(struct dma_chan *chan) +static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct sh_dmae_chan *sh_chan = to_sh_chan(chan); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + if (!chan) - return; + return -EINVAL; dmae_halt(sh_chan); @@ -601,6 +605,8 @@ static void sh_dmae_terminate_all(struct dma_chan *chan) spin_unlock_bh(&sh_chan->desc_lock); sh_dmae_chan_ld_cleanup(sh_chan, true); + + return 0; } static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) @@ -1029,7 +1035,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) /* Compulsory for DMA_SLAVE fields */ shdev->common.device_prep_slave_sg = sh_dmae_prep_slave_sg; - shdev->common.device_terminate_all = sh_dmae_terminate_all; + shdev->common.device_control = sh_dmae_control; shdev->common.dev = &pdev->dev; /* Default transfer size of 32 bytes requires 32-byte alignment */ diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 145f1c23408f..7c06471ef863 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -613,7 +613,7 @@ static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan, return &td_desc->txd; } -static void td_terminate_all(struct dma_chan *chan) +static int td_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct timb_dma_chan *td_chan = container_of(chan, struct timb_dma_chan, chan); @@ -621,6 +621,9 @@ static void td_terminate_all(struct dma_chan *chan) dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* first the easy part, put the queue into the free list */ spin_lock_bh(&td_chan->lock); list_for_each_entry_safe(td_desc, _td_desc, &td_chan->queue, @@ -630,6 +633,8 @@ static void td_terminate_all(struct dma_chan *chan) /* now tear down the runnning */ __td_finish(td_chan); spin_unlock_bh(&td_chan->lock); + + return 0; } static void td_tasklet(unsigned long data) @@ -743,7 +748,7 @@ static int __devinit td_probe(struct platform_device *pdev) dma_cap_set(DMA_SLAVE, td->dma.cap_mask); dma_cap_set(DMA_PRIVATE, td->dma.cap_mask); td->dma.device_prep_slave_sg = td_prep_slave_sg; - td->dma.device_terminate_all = td_terminate_all; + td->dma.device_control = td_control; td->dma.dev = &pdev->dev; diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index 3ebc61067e54..e528e15f44ab 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -938,12 +938,16 @@ txx9dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return &first->txd; } -static void txx9dmac_terminate_all(struct dma_chan *chan) +static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct txx9dmac_chan *dc = to_txx9dmac_chan(chan); struct txx9dmac_desc *desc, *_desc; LIST_HEAD(list); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -EINVAL; + dev_vdbg(chan2dev(chan), "terminate_all\n"); spin_lock_bh(&dc->lock); @@ -958,6 +962,8 @@ static void txx9dmac_terminate_all(struct dma_chan *chan) /* Flush all pending and queued descriptors */ list_for_each_entry_safe(desc, _desc, &list, desc_node) txx9dmac_descriptor_complete(dc, desc); + + return 0; } static enum dma_status @@ -1153,7 +1159,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev) dc->dma.dev = &pdev->dev; dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources; dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources; - dc->dma.device_terminate_all = txx9dmac_terminate_all; + dc->dma.device_control = txx9dmac_control; dc->dma.device_is_tx_complete = txx9dmac_is_tx_complete; dc->dma.device_issue_pending = txx9dmac_issue_pending; if (pdata && pdata->memcpy_chan == ch) { diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 8072128e933b..ae6d24ba4f08 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -578,7 +578,7 @@ static void atmci_stop_dma(struct atmel_mci *host) struct dma_chan *chan = host->data_chan; if (chan) { - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); atmci_dma_cleanup(host); } else { /* Data transfer was stopped by the interrupt handler */ diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index f7b9aff88f4a..690988237971 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -1087,7 +1087,7 @@ static void work_fn_rx(struct work_struct *work) unsigned long flags; int count; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); dev_dbg(port->dev, "Read %u bytes with cookie %d\n", sh_desc->partial, sh_desc->cookie); diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 772ba3f45e6f..3aa50bc276eb 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -387,7 +387,8 @@ static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) spin_unlock_irqrestore(&mx3fb->lock, flags); - mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan); + mx3_fbi->txd->chan->device->device_control(mx3_fbi->txd->chan, + DMA_TERMINATE_ALL); mx3_fbi->txd = NULL; mx3_fbi->cookie = -EINVAL; } diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 20ea12c86fd0..0731802f876f 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -106,6 +106,19 @@ enum dma_ctrl_flags { DMA_PREP_FENCE = (1 << 9), }; +/** + * enum dma_ctrl_cmd - DMA operations that can optionally be exercised + * on a running channel. + * @DMA_TERMINATE_ALL: terminate all ongoing transfers + * @DMA_PAUSE: pause ongoing transfers + * @DMA_RESUME: resume paused transfer + */ +enum dma_ctrl_cmd { + DMA_TERMINATE_ALL, + DMA_PAUSE, + DMA_RESUME, +}; + /** * enum sum_check_bits - bit position of pq_check_flags */ @@ -261,7 +274,8 @@ struct dma_async_tx_descriptor { * @device_prep_dma_memset: prepares a memset operation * @device_prep_dma_interrupt: prepares an end of chain interrupt operation * @device_prep_slave_sg: prepares a slave dma operation - * @device_terminate_all: terminate all pending operations + * @device_control: manipulate all pending operations on a channel, returns + * zero or error code * @device_is_tx_complete: poll for transaction completion * @device_issue_pending: push pending transactions to hardware */ @@ -313,7 +327,7 @@ struct dma_device { struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_data_direction direction, unsigned long flags); - void (*device_terminate_all)(struct dma_chan *chan); + int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd); enum dma_status (*device_is_tx_complete)(struct dma_chan *chan, dma_cookie_t cookie, dma_cookie_t *last, diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index efed64b8b026..b35d00706c0e 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -159,7 +159,7 @@ static void txx9aclc_dma_tasklet(unsigned long data) void __iomem *base = drvdata->base; spin_unlock_irqrestore(&dmadata->dma_lock, flags); - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); /* first time */ for (i = 0; i < NR_DMA_CHAIN; i++) { desc = txx9aclc_dma_submit(dmadata, @@ -267,7 +267,7 @@ static int txx9aclc_pcm_close(struct snd_pcm_substream *substream) struct dma_chan *chan = dmadata->dma_chan; dmadata->frag_count = -1; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); return 0; } @@ -396,7 +396,7 @@ static int txx9aclc_pcm_remove(struct platform_device *pdev) struct dma_chan *chan = dmadata->dma_chan; if (chan) { dmadata->frag_count = -1; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); dma_release_channel(chan); } dev->dmadata[i].dma_chan = NULL; -- cgit v1.2.3-59-g8ed1b From 0793448187643b50af89d36b08470baf45a3cab4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 26 Mar 2010 16:50:49 -0700 Subject: DMAENGINE: generic channel status v2 Convert the device_is_tx_complete() operation on the DMA engine to a generic device_tx_status()operation which can return three states, DMA_TX_RUNNING, DMA_TX_COMPLETE, DMA_TX_PAUSED. [dan.j.williams@intel.com: update for timberdale] Signed-off-by: Linus Walleij Acked-by: Mark Brown Cc: Maciej Sosnowski Cc: Nicolas Ferre Cc: Pavel Machek Cc: Li Yang Cc: Guennadi Liakhovetski Cc: Paul Mundt Cc: Ralf Baechle Cc: Haavard Skinnemoen Cc: Magnus Damm Cc: Liam Girdwood Cc: Joe Perches Cc: Roland Dreier Signed-off-by: Dan Williams --- arch/arm/mach-u300/include/mach/coh901318.h | 7 ----- drivers/dma/at_hdmac.c | 29 ++++++++++--------- drivers/dma/coh901318.c | 25 ++++++++-------- drivers/dma/dmaengine.c | 2 +- drivers/dma/dw_dmac.c | 17 +++++------ drivers/dma/fsldma.c | 19 ++++++------- drivers/dma/ioat/dma.c | 12 ++++---- drivers/dma/ioat/dma.h | 22 +++++++-------- drivers/dma/ioat/dma_v2.c | 2 +- drivers/dma/ioat/dma_v3.c | 20 ++++++------- drivers/dma/iop-adma.c | 44 +++++++++++++++-------------- drivers/dma/ipu/ipu_idmac.c | 15 +++++----- drivers/dma/mpc512x_dma.c | 16 +++++------ drivers/dma/mv_xor.c | 32 +++++++++++---------- drivers/dma/ppc4xx/adma.c | 27 ++++++++++-------- drivers/dma/shdma.c | 17 ++++++----- drivers/dma/timb_dma.c | 15 +++++----- drivers/dma/txx9dmac.c | 16 +++++------ include/linux/dmaengine.h | 38 +++++++++++++++++++++---- 19 files changed, 203 insertions(+), 172 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index 43ec040e765b..193da2df732c 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h @@ -102,13 +102,6 @@ struct coh901318_platform { const int max_channels; }; -/** - * coh901318_get_bytes_left() - Get number of bytes left on a current transfer - * @chan: dma channel handle - * return number of bytes left, or negative on error - */ -u32 coh901318_get_bytes_left(struct dma_chan *chan); - /** * coh901318_filter_id() - DMA channel filter function * @chan: dma channel handle diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index f9143cf9e50a..ff75cf18d32e 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -798,29 +798,25 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) } /** - * atc_is_tx_complete - poll for transaction completion + * atc_tx_status - poll for transaction completion * @chan: DMA channel * @cookie: transaction identifier to check status of - * @done: if not %NULL, updated with last completed transaction - * @used: if not %NULL, updated with last used transaction + * @txstate: if not %NULL updated with transaction state * - * If @done and @used are passed in, upon return they reflect the driver + * If @txstate is passed in, upon return it reflect the driver * internal state and can be used with dma_async_is_complete() to check * the status of multiple cookies without re-checking hardware state. */ static enum dma_status -atc_is_tx_complete(struct dma_chan *chan, +atc_tx_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) + struct dma_tx_state *txstate) { struct at_dma_chan *atchan = to_at_dma_chan(chan); dma_cookie_t last_used; dma_cookie_t last_complete; enum dma_status ret; - dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n", - cookie, done ? *done : 0, used ? *used : 0); - spin_lock_bh(&atchan->lock); last_complete = atchan->completed_cookie; @@ -838,10 +834,15 @@ atc_is_tx_complete(struct dma_chan *chan, spin_unlock_bh(&atchan->lock); - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } + + dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n", + cookie, last_complete ? last_complete : 0, + last_used ? last_used : 0); return ret; } @@ -1087,7 +1088,7 @@ static int __init at_dma_probe(struct platform_device *pdev) /* set base routines */ atdma->dma_common.device_alloc_chan_resources = atc_alloc_chan_resources; atdma->dma_common.device_free_chan_resources = atc_free_chan_resources; - atdma->dma_common.device_is_tx_complete = atc_is_tx_complete; + atdma->dma_common.device_tx_status = atc_tx_status; atdma->dma_common.device_issue_pending = atc_issue_pending; atdma->dma_common.dev = &pdev->dev; diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 53c54e034aa3..309db3beef16 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -426,7 +426,7 @@ static inline u32 coh901318_get_bytes_in_lli(struct coh901318_lli *in_lli) * absolute measures, but for a rough guess you can still call * it. */ -u32 coh901318_get_bytes_left(struct dma_chan *chan) +static u32 coh901318_get_bytes_left(struct dma_chan *chan) { struct coh901318_chan *cohc = to_coh901318_chan(chan); struct coh901318_desc *cohd; @@ -503,8 +503,6 @@ u32 coh901318_get_bytes_left(struct dma_chan *chan) return left; } -EXPORT_SYMBOL(coh901318_get_bytes_left); - /* * Pauses a transfer without losing data. Enables power save. @@ -1136,9 +1134,8 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, } static enum dma_status -coh901318_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, - dma_cookie_t *used) +coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct coh901318_chan *cohc = to_coh901318_chan(chan); dma_cookie_t last_used; @@ -1150,10 +1147,14 @@ coh901318_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = coh901318_get_bytes_left(chan); + } + + if (ret == DMA_IN_PROGRESS && cohc->stopped) + ret = DMA_PAUSED; return ret; } @@ -1356,7 +1357,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_slave.device_alloc_chan_resources = coh901318_alloc_chan_resources; base->dma_slave.device_free_chan_resources = coh901318_free_chan_resources; base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; - base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete; + base->dma_slave.device_tx_status = coh901318_tx_status; base->dma_slave.device_issue_pending = coh901318_issue_pending; base->dma_slave.device_control = coh901318_control; base->dma_slave.dev = &pdev->dev; @@ -1376,7 +1377,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_memcpy.device_alloc_chan_resources = coh901318_alloc_chan_resources; base->dma_memcpy.device_free_chan_resources = coh901318_free_chan_resources; base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; - base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete; + base->dma_memcpy.device_tx_status = coh901318_tx_status; base->dma_memcpy.device_issue_pending = coh901318_issue_pending; base->dma_memcpy.device_control = coh901318_control; base->dma_memcpy.dev = &pdev->dev; diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index ffc4ee9c5e21..790caeeb4ccd 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -698,7 +698,7 @@ int dma_async_device_register(struct dma_device *device) BUG_ON(!device->device_alloc_chan_resources); BUG_ON(!device->device_free_chan_resources); - BUG_ON(!device->device_is_tx_complete); + BUG_ON(!device->device_tx_status); BUG_ON(!device->device_issue_pending); BUG_ON(!device->dev); diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 8a6b85f61176..263b70ee8562 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -819,9 +819,9 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) } static enum dma_status -dwc_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +dwc_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); dma_cookie_t last_used; @@ -841,10 +841,11 @@ dwc_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); } - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return ret; } @@ -1346,7 +1347,7 @@ static int __init dw_probe(struct platform_device *pdev) dw->dma.device_prep_slave_sg = dwc_prep_slave_sg; dw->dma.device_control = dwc_control; - dw->dma.device_is_tx_complete = dwc_is_tx_complete; + dw->dma.device_tx_status = dwc_tx_status; dw->dma.device_issue_pending = dwc_issue_pending; dma_writel(dw, CFG, DW_CFG_DMA_EN); diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 714fc46e7695..ca5e8a3dce72 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -971,13 +971,12 @@ static void fsl_dma_memcpy_issue_pending(struct dma_chan *dchan) } /** - * fsl_dma_is_complete - Determine the DMA status + * fsl_tx_status - Determine the DMA status * @chan : Freescale DMA channel */ -static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan, +static enum dma_status fsl_tx_status(struct dma_chan *dchan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct fsldma_chan *chan = to_fsl_chan(dchan); dma_cookie_t last_used; @@ -988,11 +987,11 @@ static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan, last_used = dchan->cookie; last_complete = chan->completed_cookie; - if (done) - *done = last_complete; - - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -1336,7 +1335,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources; fdev->common.device_prep_dma_interrupt = fsl_dma_prep_interrupt; fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy; - fdev->common.device_is_tx_complete = fsl_dma_is_complete; + fdev->common.device_tx_status = fsl_tx_status; fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; fdev->common.device_control = fsl_dma_device_control; diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 0099340b9616..59cebbfc89ec 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -726,18 +726,18 @@ static void ioat1_timer_event(unsigned long data) } enum dma_status -ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct ioat_chan_common *chan = to_chan_common(c); struct ioatdma_device *device = chan->device; - if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS) + if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS) return DMA_SUCCESS; device->cleanup_fn((unsigned long) c); - return ioat_is_complete(c, cookie, done, used); + return ioat_tx_status(c, cookie, txstate); } static void ioat1_dma_start_null_desc(struct ioat_dma_chan *ioat) @@ -857,7 +857,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); if (tmo == 0 || - dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) + dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test copy timed out, disabling\n"); err = -ENODEV; @@ -1198,7 +1198,7 @@ int __devinit ioat1_dma_probe(struct ioatdma_device *device, int dca) dma->device_issue_pending = ioat1_dma_memcpy_issue_pending; dma->device_alloc_chan_resources = ioat1_dma_alloc_chan_resources; dma->device_free_chan_resources = ioat1_dma_free_chan_resources; - dma->device_is_tx_complete = ioat_is_dma_complete; + dma->device_tx_status = ioat_dma_tx_status; err = ioat_probe(device); if (err) diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 86b97ac8774e..23399672239e 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -142,15 +142,14 @@ static inline struct ioat_dma_chan *to_ioat_chan(struct dma_chan *c) } /** - * ioat_is_complete - poll the status of an ioat transaction + * ioat_tx_status - poll the status of an ioat transaction * @c: channel handle * @cookie: transaction identifier - * @done: if set, updated with last completed transaction - * @used: if set, updated with last used transaction + * @txstate: if set, updated with the transaction state */ static inline enum dma_status -ioat_is_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct ioat_chan_common *chan = to_chan_common(c); dma_cookie_t last_used; @@ -159,10 +158,11 @@ ioat_is_complete(struct dma_chan *c, dma_cookie_t cookie, last_used = c->cookie; last_complete = chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -338,8 +338,8 @@ struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev, unsigned long ioat_get_current_completion(struct ioat_chan_common *chan); void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *chan, int idx); -enum dma_status ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used); +enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate); void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, size_t len, struct ioat_dma_descriptor *hw); bool ioat_cleanup_preamble(struct ioat_chan_common *chan, diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 1ed5d66d7dca..f540e0be7f31 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -854,7 +854,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca) dma->device_issue_pending = ioat2_issue_pending; dma->device_alloc_chan_resources = ioat2_alloc_chan_resources; dma->device_free_chan_resources = ioat2_free_chan_resources; - dma->device_is_tx_complete = ioat_is_dma_complete; + dma->device_tx_status = ioat_tx_status; err = ioat_probe(device); if (err) diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 26febc56dab1..d1adbf35268c 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -438,17 +438,17 @@ static void ioat3_timer_event(unsigned long data) } static enum dma_status -ioat3_is_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +ioat3_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct ioat2_dma_chan *ioat = to_ioat2_chan(c); - if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS) + if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS) return DMA_SUCCESS; ioat3_cleanup_poll(ioat); - return ioat_is_complete(c, cookie, done, used); + return ioat_tx_status(c, cookie, txstate); } static struct dma_async_tx_descriptor * @@ -976,7 +976,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test xor timed out\n"); err = -ENODEV; goto free_resources; @@ -1030,7 +1030,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test validate timed out\n"); err = -ENODEV; goto free_resources; @@ -1071,7 +1071,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test memset timed out\n"); err = -ENODEV; goto free_resources; @@ -1114,7 +1114,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test 2nd validate timed out\n"); err = -ENODEV; goto free_resources; @@ -1258,11 +1258,11 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) if (is_raid_device) { - dma->device_is_tx_complete = ioat3_is_complete; + dma->device_tx_status = ioat3_tx_status; device->cleanup_fn = ioat3_cleanup_event; device->timer_fn = ioat3_timer_event; } else { - dma->device_is_tx_complete = ioat_is_dma_complete; + dma->device_tx_status = ioat_dma_tx_status; device->cleanup_fn = ioat2_cleanup_event; device->timer_fn = ioat2_timer_event; } diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index ca6e6a0cb793..ee40dbba1879 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -893,14 +893,14 @@ static void iop_adma_free_chan_resources(struct dma_chan *chan) } /** - * iop_adma_is_complete - poll the status of an ADMA transaction + * iop_adma_status - poll the status of an ADMA transaction * @chan: ADMA channel handle * @cookie: ADMA transaction identifier + * @txstate: a holder for the current state of the channel or NULL */ -static enum dma_status iop_adma_is_complete(struct dma_chan *chan, +static enum dma_status iop_adma_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan); dma_cookie_t last_used; @@ -910,10 +910,11 @@ static enum dma_status iop_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = iop_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) @@ -924,10 +925,11 @@ static enum dma_status iop_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = iop_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -1042,7 +1044,7 @@ static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(1); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test copy timed out, disabling\n"); @@ -1142,7 +1144,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test xor timed out, disabling\n"); @@ -1189,7 +1191,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test zero sum timed out, disabling\n"); err = -ENODEV; @@ -1213,7 +1215,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test memset timed out, disabling\n"); err = -ENODEV; @@ -1245,7 +1247,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test non-zero sum timed out, disabling\n"); err = -ENODEV; @@ -1340,7 +1342,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test pq timed out, disabling\n"); err = -ENODEV; @@ -1377,7 +1379,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test pq-zero-sum timed out, disabling\n"); err = -ENODEV; @@ -1409,7 +1411,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test !pq-zero-sum timed out, disabling\n"); err = -ENODEV; @@ -1507,7 +1509,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev) /* set base routines */ dma_dev->device_alloc_chan_resources = iop_adma_alloc_chan_resources; dma_dev->device_free_chan_resources = iop_adma_free_chan_resources; - dma_dev->device_is_tx_complete = iop_adma_is_complete; + dma_dev->device_tx_status = iop_adma_status; dma_dev->device_issue_pending = iop_adma_issue_pending; dma_dev->dev = &pdev->dev; diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 39e7fb2a90e3..b9cef8b1701c 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1646,15 +1646,16 @@ static void idmac_free_chan_resources(struct dma_chan *chan) tasklet_schedule(&to_ipu(idmac)->tasklet); } -static enum dma_status idmac_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +static enum dma_status idmac_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *txstate) { struct idmac_channel *ichan = to_idmac_chan(chan); - if (done) - *done = ichan->completed; - if (used) - *used = chan->cookie; + if (txstate) { + txstate->last = ichan->completed; + txstate->used = chan->cookie; + txstate->residue = 0; + } if (cookie != chan->cookie) return DMA_ERROR; return DMA_SUCCESS; @@ -1673,7 +1674,7 @@ static int __init ipu_idmac_init(struct ipu *ipu) dma->dev = ipu->dev; dma->device_alloc_chan_resources = idmac_alloc_chan_resources; dma->device_free_chan_resources = idmac_free_chan_resources; - dma->device_is_tx_complete = idmac_is_tx_complete; + dma->device_tx_status = idmac_tx_status; dma->device_issue_pending = idmac_issue_pending; /* Compulsory for DMA_SLAVE fields */ diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 3fdf1f46bd63..cb3a8e94ea48 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -540,8 +540,8 @@ static void mpc_dma_issue_pending(struct dma_chan *chan) /* Check request completion status */ static enum dma_status -mpc_dma_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +mpc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan); unsigned long flags; @@ -553,11 +553,11 @@ mpc_dma_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, last_complete = mchan->completed_cookie; spin_unlock_irqrestore(&mchan->lock, flags); - if (done) - *done = last_complete; - - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -693,7 +693,7 @@ static int __devinit mpc_dma_probe(struct of_device *op, dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources; dma->device_free_chan_resources = mpc_dma_free_chan_resources; dma->device_issue_pending = mpc_dma_issue_pending; - dma->device_is_tx_complete = mpc_dma_is_tx_complete; + dma->device_tx_status = mpc_dma_tx_status; dma->device_prep_dma_memcpy = mpc_dma_prep_memcpy; INIT_LIST_HEAD(&dma->channels); diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 466ab10c1ff1..79fb1dea691b 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -809,14 +809,14 @@ static void mv_xor_free_chan_resources(struct dma_chan *chan) } /** - * mv_xor_is_complete - poll the status of an XOR transaction + * mv_xor_status - poll the status of an XOR transaction * @chan: XOR channel handle * @cookie: XOR transaction identifier + * @txstate: XOR transactions state holder (or NULL) */ -static enum dma_status mv_xor_is_complete(struct dma_chan *chan, +static enum dma_status mv_xor_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); dma_cookie_t last_used; @@ -826,10 +826,11 @@ static enum dma_status mv_xor_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = mv_chan->completed_cookie; mv_chan->is_complete_cookie = cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) { @@ -841,10 +842,11 @@ static enum dma_status mv_xor_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = mv_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -974,7 +976,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) async_tx_ack(tx); msleep(1); - if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) != + if (mv_xor_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test copy timed out, disabling\n"); @@ -1072,7 +1074,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device) async_tx_ack(tx); msleep(8); - if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) != + if (mv_xor_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test xor timed out, disabling\n"); @@ -1167,7 +1169,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) /* set base routines */ dma_dev->device_alloc_chan_resources = mv_xor_alloc_chan_resources; dma_dev->device_free_chan_resources = mv_xor_free_chan_resources; - dma_dev->device_is_tx_complete = mv_xor_is_complete; + dma_dev->device_tx_status = mv_xor_status; dma_dev->device_issue_pending = mv_xor_issue_pending; dma_dev->dev = &pdev->dev; diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index e69d87f24a25..d9a54c018652 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -3934,12 +3934,13 @@ static void ppc440spe_adma_free_chan_resources(struct dma_chan *chan) } /** - * ppc440spe_adma_is_complete - poll the status of an ADMA transaction + * ppc440spe_adma_tx_status - poll the status of an ADMA transaction * @chan: ADMA channel handle * @cookie: ADMA transaction identifier + * @txstate: a holder for the current state of the channel */ -static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *txstate) { struct ppc440spe_adma_chan *ppc440spe_chan; dma_cookie_t last_used; @@ -3950,10 +3951,11 @@ static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = ppc440spe_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) @@ -3964,10 +3966,11 @@ static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = ppc440spe_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -4179,7 +4182,7 @@ static void ppc440spe_adma_init_capabilities(struct ppc440spe_adma_device *adev) ppc440spe_adma_alloc_chan_resources; adev->common.device_free_chan_resources = ppc440spe_adma_free_chan_resources; - adev->common.device_is_tx_complete = ppc440spe_adma_is_complete; + adev->common.device_tx_status = ppc440spe_adma_tx_status; adev->common.device_issue_pending = ppc440spe_adma_issue_pending; /* Set prep routines based on capability */ diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index ce28c1e22825..8aeda9ceb225 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -738,10 +738,9 @@ static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan) sh_chan_xfer_ld_queue(sh_chan); } -static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, +static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct sh_dmae_chan *sh_chan = to_sh_chan(chan); dma_cookie_t last_used; @@ -754,11 +753,11 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, last_complete = sh_chan->completed_cookie; BUG_ON(last_complete < 0); - if (done) - *done = last_complete; - - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } spin_lock_bh(&sh_chan->desc_lock); @@ -1030,7 +1029,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) = sh_dmae_alloc_chan_resources; shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources; shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy; - shdev->common.device_is_tx_complete = sh_dmae_is_complete; + shdev->common.device_tx_status = sh_dmae_tx_status; shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending; /* Compulsory for DMA_SLAVE fields */ diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 7c06471ef863..8fc28814561a 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -511,8 +511,8 @@ static void td_free_chan_resources(struct dma_chan *chan) } } -static enum dma_status td_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct timb_dma_chan *td_chan = container_of(chan, struct timb_dma_chan, chan); @@ -527,10 +527,11 @@ static enum dma_status td_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } dev_dbg(chan2dev(chan), "%s: exit, ret: %d, last_complete: %d, last_used: %d\n", @@ -742,7 +743,7 @@ static int __devinit td_probe(struct platform_device *pdev) td->dma.device_alloc_chan_resources = td_alloc_chan_resources; td->dma.device_free_chan_resources = td_free_chan_resources; - td->dma.device_is_tx_complete = td_is_tx_complete; + td->dma.device_tx_status = td_tx_status; td->dma.device_issue_pending = td_issue_pending; dma_cap_set(DMA_SLAVE, td->dma.cap_mask); diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index e528e15f44ab..a44e422cbc27 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -967,9 +967,8 @@ static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) } static enum dma_status -txx9dmac_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct txx9dmac_chan *dc = to_txx9dmac_chan(chan); dma_cookie_t last_used; @@ -991,10 +990,11 @@ txx9dmac_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); } - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return ret; } @@ -1160,7 +1160,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev) dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources; dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources; dc->dma.device_control = txx9dmac_control; - dc->dma.device_is_tx_complete = txx9dmac_is_tx_complete; + dc->dma.device_tx_status = txx9dmac_tx_status; dc->dma.device_issue_pending = txx9dmac_issue_pending; if (pdata && pdata->memcpy_chan == ch) { dc->dma.device_prep_dma_memcpy = txx9dmac_prep_dma_memcpy; diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 0731802f876f..55b08e84ac8d 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -40,11 +40,13 @@ typedef s32 dma_cookie_t; * enum dma_status - DMA transaction status * @DMA_SUCCESS: transaction completed successfully * @DMA_IN_PROGRESS: transaction not yet processed + * @DMA_PAUSED: transaction is paused * @DMA_ERROR: transaction failed */ enum dma_status { DMA_SUCCESS, DMA_IN_PROGRESS, + DMA_PAUSED, DMA_ERROR, }; @@ -248,6 +250,21 @@ struct dma_async_tx_descriptor { spinlock_t lock; }; +/** + * struct dma_tx_state - filled in to report the status of + * a transfer. + * @last: last completed DMA cookie + * @used: last issued DMA cookie (i.e. the one in progress) + * @residue: the remaining number of bytes left to transmit + * on the selected transfer for states DMA_IN_PROGRESS and + * DMA_PAUSED if this is implemented in the driver, else 0 + */ +struct dma_tx_state { + dma_cookie_t last; + dma_cookie_t used; + u32 residue; +}; + /** * struct dma_device - info on the entity supplying DMA services * @chancnt: how many DMA channels are supported @@ -276,7 +293,10 @@ struct dma_async_tx_descriptor { * @device_prep_slave_sg: prepares a slave dma operation * @device_control: manipulate all pending operations on a channel, returns * zero or error code - * @device_is_tx_complete: poll for transaction completion + * @device_tx_status: poll for transaction completion, the optional + * txstate parameter can be supplied with a pointer to get a + * struct with auxilary transfer status information, otherwise the call + * will just return a simple status code * @device_issue_pending: push pending transactions to hardware */ struct dma_device { @@ -329,9 +349,9 @@ struct dma_device { unsigned long flags); int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd); - enum dma_status (*device_is_tx_complete)(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *last, - dma_cookie_t *used); + enum dma_status (*device_tx_status)(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate); void (*device_issue_pending)(struct dma_chan *chan); }; @@ -572,7 +592,15 @@ static inline void dma_async_issue_pending(struct dma_chan *chan) static inline enum dma_status dma_async_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used) { - return chan->device->device_is_tx_complete(chan, cookie, last, used); + struct dma_tx_state state; + enum dma_status status; + + status = chan->device->device_tx_status(chan, cookie, &state); + if (last) + *last = state.last; + if (used) + *used = state.used; + return status; } #define dma_async_memcpy_complete(chan, cookie, last, used)\ -- cgit v1.2.3-59-g8ed1b From 6ae6650232ddcf2f50e8817acd63cde37cf1d093 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 29 Mar 2010 15:24:54 +0900 Subject: sh: tlb debugfs support. Export the status of the utlb and itlb entries through debugfs. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/cpu-sh4/cpu/mmu_context.h | 7 ++ arch/sh/mm/Makefile | 8 +- arch/sh/mm/tlb-debugfs.c | 179 ++++++++++++++++++++++++++++++ 3 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 arch/sh/mm/tlb-debugfs.c (limited to 'arch') diff --git a/arch/sh/include/cpu-sh4/cpu/mmu_context.h b/arch/sh/include/cpu-sh4/cpu/mmu_context.h index 5963124c1d4a..2941be617a5f 100644 --- a/arch/sh/include/cpu-sh4/cpu/mmu_context.h +++ b/arch/sh/include/cpu-sh4/cpu/mmu_context.h @@ -19,10 +19,17 @@ #define MMUCR 0xFF000010 /* MMU Control Register */ +#define MMU_TLB_ENTRY_SHIFT 8 + #define MMU_ITLB_ADDRESS_ARRAY 0xF2000000 #define MMU_ITLB_ADDRESS_ARRAY2 0xF2800000 +#define MMU_ITLB_DATA_ARRAY 0xF3000000 +#define MMU_ITLB_DATA_ARRAY2 0xF3800000 + #define MMU_UTLB_ADDRESS_ARRAY 0xF6000000 #define MMU_UTLB_ADDRESS_ARRAY2 0xF6800000 +#define MMU_UTLB_DATA_ARRAY 0xF7000000 +#define MMU_UTLB_DATA_ARRAY2 0xF7800000 #define MMU_PAGE_ASSOC_BIT 0x80 #define MMUCR_TI (1<<2) diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 3dc8a8a63822..c73018a9972c 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -18,13 +18,14 @@ mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \ ioremap.o kmap.o pgtable.o tlbflush_$(BITS).o obj-y += $(mmu-y) -obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o -ifdef CONFIG_DEBUG_FS -obj-$(CONFIG_CPU_SH4) += cache-debugfs.o +debugfs-y := asids-debugfs.o +ifndef CONFIG_CACHE_OFF +debugfs-$(CONFIG_CPU_SH4) += cache-debugfs.o endif ifdef CONFIG_MMU +debugfs-$(CONFIG_CPU_SH4) += tlb-debugfs.o tlb-$(CONFIG_CPU_SH3) := tlb-sh3.o tlb-$(CONFIG_CPU_SH4) := tlb-sh4.o tlb-urb.o tlb-$(CONFIG_CPU_SH5) := tlb-sh5.o @@ -32,6 +33,7 @@ tlb-$(CONFIG_CPU_HAS_PTEAEX) := tlb-pteaex.o tlb-urb.o obj-y += $(tlb-y) endif +obj-$(CONFIG_DEBUG_FS) += $(debugfs-y) obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_PMB) += pmb.o obj-$(CONFIG_NUMA) += numa.o diff --git a/arch/sh/mm/tlb-debugfs.c b/arch/sh/mm/tlb-debugfs.c new file mode 100644 index 000000000000..229bf75f28df --- /dev/null +++ b/arch/sh/mm/tlb-debugfs.c @@ -0,0 +1,179 @@ +/* + * arch/sh/mm/tlb-debugfs.c + * + * debugfs ops for SH-4 ITLB/UTLBs. + * + * Copyright (C) 2010 Matt Fleming + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +enum tlb_type { + TLB_TYPE_ITLB, + TLB_TYPE_UTLB, +}; + +static struct { + int bits; + const char *size; +} tlb_sizes[] = { + { 0x0, " 1KB" }, + { 0x1, " 4KB" }, + { 0x2, " 8KB" }, + { 0x4, " 64KB" }, + { 0x5, "256KB" }, + { 0x7, " 1MB" }, + { 0x8, " 4MB" }, + { 0xc, " 64MB" }, +}; + +static int tlb_seq_show(struct seq_file *file, void *iter) +{ + unsigned int tlb_type = (unsigned int)file->private; + unsigned long addr1, addr2, data1, data2; + unsigned long flags; + unsigned long mmucr; + unsigned int nentries, entry; + unsigned int urb; + + mmucr = __raw_readl(MMUCR); + if ((mmucr & 0x1) == 0) { + seq_printf(file, "address translation disabled\n"); + return 0; + } + + if (tlb_type == TLB_TYPE_ITLB) { + addr1 = MMU_ITLB_ADDRESS_ARRAY; + addr2 = MMU_ITLB_ADDRESS_ARRAY2; + data1 = MMU_ITLB_DATA_ARRAY; + data2 = MMU_ITLB_DATA_ARRAY2; + nentries = 4; + } else { + addr1 = MMU_UTLB_ADDRESS_ARRAY; + addr2 = MMU_UTLB_ADDRESS_ARRAY2; + data1 = MMU_UTLB_DATA_ARRAY; + data2 = MMU_UTLB_DATA_ARRAY2; + nentries = 64; + } + + local_irq_save(flags); + jump_to_uncached(); + + urb = (mmucr & MMUCR_URB) >> MMUCR_URB_SHIFT; + + /* Make the "entry >= urb" test fail. */ + if (urb == 0) + urb = MMUCR_URB_NENTRIES + 1; + + if (tlb_type == TLB_TYPE_ITLB) { + addr1 = MMU_ITLB_ADDRESS_ARRAY; + addr2 = MMU_ITLB_ADDRESS_ARRAY2; + data1 = MMU_ITLB_DATA_ARRAY; + data2 = MMU_ITLB_DATA_ARRAY2; + nentries = 4; + } else { + addr1 = MMU_UTLB_ADDRESS_ARRAY; + addr2 = MMU_UTLB_ADDRESS_ARRAY2; + data1 = MMU_UTLB_DATA_ARRAY; + data2 = MMU_UTLB_DATA_ARRAY2; + nentries = 64; + } + + seq_printf(file, "entry: vpn ppn asid size valid wired\n"); + + for (entry = 0; entry < nentries; entry++) { + unsigned long vpn, ppn, asid, size; + unsigned long valid; + unsigned long val; + const char *sz = " ?"; + int i; + + val = __raw_readl(addr1 | (entry << MMU_TLB_ENTRY_SHIFT)); + ctrl_barrier(); + vpn = val & 0xfffffc00; + valid = val & 0x100; + + val = __raw_readl(addr2 | (entry << MMU_TLB_ENTRY_SHIFT)); + ctrl_barrier(); + asid = val & MMU_CONTEXT_ASID_MASK; + + val = __raw_readl(data1 | (entry << MMU_TLB_ENTRY_SHIFT)); + ctrl_barrier(); + ppn = (val & 0x0ffffc00) << 4; + + val = __raw_readl(data2 | (entry << MMU_TLB_ENTRY_SHIFT)); + ctrl_barrier(); + size = (val & 0xf0) >> 4; + + for (i = 0; i < ARRAY_SIZE(tlb_sizes); i++) { + if (tlb_sizes[i].bits == size) + break; + } + + if (i != ARRAY_SIZE(tlb_sizes)) + sz = tlb_sizes[i].size; + + seq_printf(file, "%2d: 0x%08lx 0x%08lx %5lu %s %s %s\n", + entry, vpn, ppn, asid, + sz, valid ? "V" : "-", + (urb <= entry) ? "W" : "-"); + } + + back_to_cached(); + local_irq_restore(flags); + + return 0; +} + +static int tlb_debugfs_open(struct inode *inode, struct file *file) +{ + return single_open(file, tlb_seq_show, inode->i_private); +} + +static const struct file_operations tlb_debugfs_fops = { + .owner = THIS_MODULE, + .open = tlb_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init tlb_debugfs_init(void) +{ + struct dentry *itlb, *utlb; + + itlb = debugfs_create_file("itlb", S_IRUSR, sh_debugfs_root, + (unsigned int *)TLB_TYPE_ITLB, + &tlb_debugfs_fops); + if (unlikely(!itlb)) + return -ENOMEM; + if (IS_ERR(itlb)) + return PTR_ERR(itlb); + + utlb = debugfs_create_file("utlb", S_IRUSR, sh_debugfs_root, + (unsigned int *)TLB_TYPE_UTLB, + &tlb_debugfs_fops); + if (unlikely(!utlb)) { + debugfs_remove(itlb); + return -ENOMEM; + } + + if (IS_ERR(utlb)) { + debugfs_remove(itlb); + return PTR_ERR(utlb); + } + + return 0; +} +module_init(tlb_debugfs_init); + +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-59-g8ed1b From e21d2aa76e1fc91cbf18c4b593d32112d954fab5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 29 Mar 2010 17:03:15 +0900 Subject: sh: sh7786 clkdev lookups. This plugs in clkdev lookups for the SH7786 clocks and migrates off of clock string usage for the TMU clocks. Previously the TMU clocks were aliased to the peripheral clock, so this gets the driver actually toggling the proper clocks now as well. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 68 ++++++++++++++++++++++++++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 12 ------ 2 files changed, 68 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 85e8d57f4971..c4a84bb2f3d9 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -120,12 +122,78 @@ static struct clk mstp_clks[] = { SH_CLK_MSTP32("ether_fck", -1, NULL, MSTPCR1, 2, 0), }; +static struct clk_lookup lookups[] = { + { + /* TMU0 */ + .dev_id = "sh_tmu.0", + .con_id = "tmu_fck", + .clk = &mstp_clks[17], /* tmu012_fck */ + }, { + /* TMU1 */ + .dev_id = "sh_tmu.1", + .con_id = "tmu_fck", + .clk = &mstp_clks[17], + }, { + /* TMU2 */ + .dev_id = "sh_tmu.2", + .con_id = "tmu_fck", + .clk = &mstp_clks[17], + }, { + /* TMU3 */ + .dev_id = "sh_tmu.3", + .con_id = "tmu_fck", + .clk = &mstp_clks[16], /* tmu345_fck */ + }, { + /* TMU4 */ + .dev_id = "sh_tmu.4", + .con_id = "tmu_fck", + .clk = &mstp_clks[16], + }, { + /* TMU5 */ + .dev_id = "sh_tmu.5", + .con_id = "tmu_fck", + .clk = &mstp_clks[16], + }, { + /* TMU6 */ + .dev_id = "sh_tmu.6", + .con_id = "tmu_fck", + .clk = &mstp_clks[15], /* tmu678_fck */ + }, { + /* TMU7 */ + .dev_id = "sh_tmu.7", + .con_id = "tmu_fck", + .clk = &mstp_clks[15], + }, { + /* TMU8 */ + .dev_id = "sh_tmu.8", + .con_id = "tmu_fck", + .clk = &mstp_clks[15], + }, { + /* TMU9 */ + .dev_id = "sh_tmu.9", + .con_id = "tmu_fck", + .clk = &mstp_clks[14], /* tmu9_11_fck */ + }, { + /* TMU10 */ + .dev_id = "sh_tmu.10", + .con_id = "tmu_fck", + .clk = &mstp_clks[14], + }, { + /* TMU11 */ + .dev_id = "sh_tmu.11", + .con_id = "tmu_fck", + .clk = &mstp_clks[14], + } +}; + int __init arch_clk_init(void) { int i, ret = 0; for (i = 0; i < ARRAY_SIZE(clks); i++) ret |= clk_register(clks[i]); + for (i = 0; i < ARRAY_SIZE(lookups); i++) + clkdev_add(&lookups[i]); if (!ret) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 542ced88e50f..f5599907ac3d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -119,7 +119,6 @@ static struct platform_device scif5_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -148,7 +147,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -177,7 +175,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -205,7 +202,6 @@ static struct platform_device tmu2_device = { static struct sh_timer_config tmu3_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -233,7 +229,6 @@ static struct platform_device tmu3_device = { static struct sh_timer_config tmu4_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -261,7 +256,6 @@ static struct platform_device tmu4_device = { static struct sh_timer_config tmu5_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { @@ -289,7 +283,6 @@ static struct platform_device tmu5_device = { static struct sh_timer_config tmu6_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", }; static struct resource tmu6_resources[] = { @@ -317,7 +310,6 @@ static struct platform_device tmu6_device = { static struct sh_timer_config tmu7_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", }; static struct resource tmu7_resources[] = { @@ -345,7 +337,6 @@ static struct platform_device tmu7_device = { static struct sh_timer_config tmu8_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu8_resources[] = { @@ -373,7 +364,6 @@ static struct platform_device tmu8_device = { static struct sh_timer_config tmu9_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", }; static struct resource tmu9_resources[] = { @@ -401,7 +391,6 @@ static struct platform_device tmu9_device = { static struct sh_timer_config tmu10_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", }; static struct resource tmu10_resources[] = { @@ -429,7 +418,6 @@ static struct platform_device tmu10_device = { static struct sh_timer_config tmu11_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu11_resources[] = { -- cgit v1.2.3-59-g8ed1b From c55fbdd3f97a468d51cbdb03bb7c9c7287fbda2f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 29 Mar 2010 17:10:06 +0900 Subject: sh: sh7785 clkdev lookups. Convert to TMU clock lookups for SH7785. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 39 +++++++++++++++++++++++++++++++++- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 6 ------ 2 files changed, 38 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 6061c736c281..28de049a59b1 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -3,7 +3,7 @@ * * SH7785 support for the clock framework * - * Copyright (C) 2007 - 2009 Paul Mundt + * Copyright (C) 2007 - 2010 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -113,12 +114,48 @@ static struct clk mstp_clks[] = { SH_CLK_MSTP32("gdta_fck", -1, NULL, MSTPCR1, 0, 0), }; +static struct clk_lookup lookups[] = { + { + /* TMU0 */ + .dev_id = "sh_tmu.0", + .con_id = "tmu_fck", + .clk = &mstp_clks[13], /* tmu012_fck */ + }, { + /* TMU1 */ + .dev_id = "sh_tmu.1", + .con_id = "tmu_fck", + .clk = &mstp_clks[13], + }, { + /* TMU2 */ + .dev_id = "sh_tmu.2", + .con_id = "tmu_fck", + .clk = &mstp_clks[13], + }, { + /* TMU3 */ + .dev_id = "sh_tmu.3", + .con_id = "tmu_fck", + .clk = &mstp_clks[12], /* tmu345_fck */ + }, { + /* TMU4 */ + .dev_id = "sh_tmu.4", + .con_id = "tmu_fck", + .clk = &mstp_clks[12], + }, { + /* TMU5 */ + .dev_id = "sh_tmu.5", + .con_id = "tmu_fck", + .clk = &mstp_clks[12], + }, +}; + int __init arch_clk_init(void) { int i, ret = 0; for (i = 0; i < ARRAY_SIZE(clks); i++) ret |= clk_register(clks[i]); + for (i = 0; i < ARRAY_SIZE(lookups); i++) + clkdev_add(&lookups[i]); if (!ret) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 76afe571f3a2..07bb2d4619f8 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -113,7 +113,6 @@ static struct platform_device scif5_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "tmu012_fck", .clockevent_rating = 200, }; @@ -142,7 +141,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "tmu012_fck", .clocksource_rating = 200, }; @@ -171,7 +169,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "tmu012_fck", }; static struct resource tmu2_resources[] = { @@ -199,7 +196,6 @@ static struct platform_device tmu2_device = { static struct sh_timer_config tmu3_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "tmu345_fck", }; static struct resource tmu3_resources[] = { @@ -227,7 +223,6 @@ static struct platform_device tmu3_device = { static struct sh_timer_config tmu4_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "tmu345_fck", }; static struct resource tmu4_resources[] = { @@ -255,7 +250,6 @@ static struct platform_device tmu4_device = { static struct sh_timer_config tmu5_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "tmu345_fck", }; static struct resource tmu5_resources[] = { -- cgit v1.2.3-59-g8ed1b From 0776d602abe61871d27accd8e3bcb225a96f4a9f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 29 Mar 2010 17:22:50 +0900 Subject: sh: provide some clock lookup aliases for legacy CPG parts. For the CPUs that have not yet been converted off of legacy CPG we provide some pclk aliases in order to make driver migration easier. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock-cpg.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index eed5eaff96ba..17a73ad7a20d 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -338,6 +338,11 @@ int __init __deprecated cpg_clk_init(void) ret |= clk_register(clk); } + clk_add_alias("tmu_fck", NULL, "peripheral_clk", NULL); + clk_add_alias("mtu2_fck", NULL, "peripheral_clk", NULL); + clk_add_alias("cmt_fck", NULL, "peripheral_clk", NULL); + clk_add_alias("sci_ick", NULL, "peripheral_clk", NULL); + return ret; } -- cgit v1.2.3-59-g8ed1b From 4dc50a068ad8fbbd2dd6dd5ac8ac2652589ba046 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 29 Mar 2010 17:25:03 +0900 Subject: sh: Kill off timer clock strings for legacy CPG parts. Now with the lookup aliases in place there is no longer any need to provide the clock string, kill it off for all legacy CPG CPUs. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 2 -- arch/sh/kernel/cpu/sh2a/setup-mxg.c | 3 --- arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 3 --- arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 4 ---- arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 5 ----- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 3 --- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 3 --- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 3 --- arch/sh/kernel/cpu/sh3/setup-sh7720.c | 8 -------- arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 3 --- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 5 ----- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 3 --- arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 2 -- arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 6 ------ arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 9 --------- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 6 ------ arch/sh/kernel/cpu/sh4a/setup-shx3.c | 6 ------ arch/sh/kernel/cpu/sh5/setup-sh5.c | 3 --- 18 files changed, 77 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 9b96457ccc7b..c3638516bffc 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -130,7 +130,6 @@ static struct platform_device eth_device = { static struct sh_timer_config cmt0_platform_data = { .channel_offset = 0x02, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; @@ -160,7 +159,6 @@ static struct platform_device cmt0_device = { static struct sh_timer_config cmt1_platform_data = { .channel_offset = 0x08, .timer_bit = 1, - .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index 5301450656cc..6c96ea02bf8d 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -117,7 +117,6 @@ static DECLARE_INTC_DESC(intc_desc, "mxg", vectors, groups, static struct sh_timer_config mtu2_0_platform_data = { .channel_offset = -0x80, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -146,7 +145,6 @@ static struct platform_device mtu2_0_device = { static struct sh_timer_config mtu2_1_platform_data = { .channel_offset = -0x100, .timer_bit = 1, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -175,7 +173,6 @@ static struct platform_device mtu2_1_device = { static struct sh_timer_config mtu2_2_platform_data = { .channel_offset = 0x80, .timer_bit = 2, - .clk = "peripheral_clk", .clockevent_rating = 200, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index 5b07ab57acfd..d08bf4c07d60 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -320,7 +320,6 @@ static struct platform_device rtc_device = { static struct sh_timer_config mtu2_0_platform_data = { .channel_offset = -0x80, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -349,7 +348,6 @@ static struct platform_device mtu2_0_device = { static struct sh_timer_config mtu2_1_platform_data = { .channel_offset = -0x100, .timer_bit = 1, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -378,7 +376,6 @@ static struct platform_device mtu2_1_device = { static struct sh_timer_config mtu2_2_platform_data = { .channel_offset = 0x80, .timer_bit = 2, - .clk = "peripheral_clk", .clockevent_rating = 200, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 433ac5301314..832f401b5860 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -236,7 +236,6 @@ static struct platform_device scif3_device = { static struct sh_timer_config cmt0_platform_data = { .channel_offset = 0x02, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; @@ -266,7 +265,6 @@ static struct platform_device cmt0_device = { static struct sh_timer_config cmt1_platform_data = { .channel_offset = 0x08, .timer_bit = 1, - .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; @@ -296,7 +294,6 @@ static struct platform_device cmt1_device = { static struct sh_timer_config mtu2_0_platform_data = { .channel_offset = -0x80, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -325,7 +322,6 @@ static struct platform_device mtu2_0_device = { static struct sh_timer_config mtu2_1_platform_data = { .channel_offset = -0x100, .timer_bit = 1, - .clk = "peripheral_clk", .clockevent_rating = 200, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 8caecb41e4e6..dc47b04e1049 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -196,7 +196,6 @@ static struct platform_device scif3_device = { static struct sh_timer_config cmt0_platform_data = { .channel_offset = 0x02, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; @@ -226,7 +225,6 @@ static struct platform_device cmt0_device = { static struct sh_timer_config cmt1_platform_data = { .channel_offset = 0x08, .timer_bit = 1, - .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 0, /* disabled due to code generation issues */ }; @@ -256,7 +254,6 @@ static struct platform_device cmt1_device = { static struct sh_timer_config mtu2_0_platform_data = { .channel_offset = -0x80, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -285,7 +282,6 @@ static struct platform_device mtu2_0_device = { static struct sh_timer_config mtu2_1_platform_data = { .channel_offset = -0x100, .timer_bit = 1, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -314,7 +310,6 @@ static struct platform_device mtu2_1_device = { static struct sh_timer_config mtu2_2_platform_data = { .channel_offset = 0x80, .timer_bit = 2, - .clk = "peripheral_clk", .clockevent_rating = 200, }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 5e45fb7338fd..baadd7f54d94 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -126,7 +126,6 @@ static struct platform_device rtc_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x02, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -155,7 +154,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0xe, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -184,7 +182,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1a, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 9adb853a9184..3cf8c8ef7b32 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -159,7 +159,6 @@ static struct platform_device scif2_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x02, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -188,7 +187,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0xe, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -217,7 +215,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1a, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 2e581e30d13d..b0c2fb4ab479 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -129,7 +129,6 @@ static struct platform_device scif1_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x02, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -158,7 +157,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0xe, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -187,7 +185,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1a, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 9a006e13b41d..24b17135d5d2 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -132,7 +132,6 @@ static struct platform_device usbf_device = { static struct sh_timer_config cmt0_platform_data = { .channel_offset = 0x10, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 125, .clocksource_rating = 125, }; @@ -162,7 +161,6 @@ static struct platform_device cmt0_device = { static struct sh_timer_config cmt1_platform_data = { .channel_offset = 0x20, .timer_bit = 1, - .clk = "peripheral_clk", }; static struct resource cmt1_resources[] = { @@ -190,7 +188,6 @@ static struct platform_device cmt1_device = { static struct sh_timer_config cmt2_platform_data = { .channel_offset = 0x30, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource cmt2_resources[] = { @@ -218,7 +215,6 @@ static struct platform_device cmt2_device = { static struct sh_timer_config cmt3_platform_data = { .channel_offset = 0x40, .timer_bit = 3, - .clk = "peripheral_clk", }; static struct resource cmt3_resources[] = { @@ -246,7 +242,6 @@ static struct platform_device cmt3_device = { static struct sh_timer_config cmt4_platform_data = { .channel_offset = 0x50, .timer_bit = 4, - .clk = "peripheral_clk", }; static struct resource cmt4_resources[] = { @@ -274,7 +269,6 @@ static struct platform_device cmt4_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x02, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -303,7 +297,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0xe, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -332,7 +325,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1a, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index 223d06657775..e916b18e1f7c 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -33,7 +33,6 @@ static struct platform_device scif0_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -62,7 +61,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -91,7 +89,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 2f337b143c8f..911d196e86b5 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -68,7 +68,6 @@ static struct platform_device scif1_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -97,7 +96,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -126,7 +124,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -159,7 +156,6 @@ static struct platform_device tmu2_device = { static struct sh_timer_config tmu3_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -187,7 +183,6 @@ static struct platform_device tmu3_device = { static struct sh_timer_config tmu4_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index fa43da0502bd..48ea8fe85dc5 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -189,7 +189,6 @@ static struct platform_device scif3_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -218,7 +217,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -247,7 +245,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index 25eddf24f634..444aca95b20d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -65,7 +65,6 @@ static struct platform_device scif4_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -94,7 +93,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index a91263e0358b..5b5f6b005fc5 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -133,7 +133,6 @@ static struct platform_device usbf_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -162,7 +161,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -191,7 +189,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -219,7 +216,6 @@ static struct platform_device tmu2_device = { static struct sh_timer_config tmu3_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -247,7 +243,6 @@ static struct platform_device tmu3_device = { static struct sh_timer_config tmu4_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -275,7 +270,6 @@ static struct platform_device tmu4_device = { static struct sh_timer_config tmu5_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 83a27b0e4ed2..7270d7fd6761 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -167,7 +167,6 @@ static struct platform_device scif9_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -196,7 +195,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -225,7 +223,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -253,7 +250,6 @@ static struct platform_device tmu2_device = { static struct sh_timer_config tmu3_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -281,7 +277,6 @@ static struct platform_device tmu3_device = { static struct sh_timer_config tmu4_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -309,7 +304,6 @@ static struct platform_device tmu4_device = { static struct sh_timer_config tmu5_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { @@ -337,7 +331,6 @@ static struct platform_device tmu5_device = { static struct sh_timer_config tmu6_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", }; static struct resource tmu6_resources[] = { @@ -365,7 +358,6 @@ static struct platform_device tmu6_device = { static struct sh_timer_config tmu7_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", }; static struct resource tmu7_resources[] = { @@ -393,7 +385,6 @@ static struct platform_device tmu7_device = { static struct sh_timer_config tmu8_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu8_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index f7c48e92b95b..05fc38df1582 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -51,7 +51,6 @@ static struct platform_device scif1_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -80,7 +79,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -109,7 +107,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -137,7 +134,6 @@ static struct platform_device tmu2_device = { static struct sh_timer_config tmu3_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -165,7 +161,6 @@ static struct platform_device tmu3_device = { static struct sh_timer_config tmu4_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -193,7 +188,6 @@ static struct platform_device tmu4_device = { static struct sh_timer_config tmu5_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index ba545b5ccc15..9158bc5ea38b 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -72,7 +72,6 @@ static struct platform_device scif2_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -101,7 +100,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -130,7 +128,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { @@ -158,7 +155,6 @@ static struct platform_device tmu2_device = { static struct sh_timer_config tmu3_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", }; static struct resource tmu3_resources[] = { @@ -186,7 +182,6 @@ static struct platform_device tmu3_device = { static struct sh_timer_config tmu4_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", }; static struct resource tmu4_resources[] = { @@ -214,7 +209,6 @@ static struct platform_device tmu4_device = { static struct sh_timer_config tmu5_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu5_resources[] = { diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index c84ca204240b..d910666142b1 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -70,7 +70,6 @@ static struct platform_device rtc_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "peripheral_clk", .clockevent_rating = 200, }; @@ -99,7 +98,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "peripheral_clk", .clocksource_rating = 200, }; @@ -128,7 +126,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "peripheral_clk", }; static struct resource tmu2_resources[] = { -- cgit v1.2.3-59-g8ed1b From 5afdd0d93a32938752384f195fdbde06163b3c2e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 29 Mar 2010 17:35:04 +0900 Subject: sh: sh7343 clock string death. Kills off clock string usage, using the new function clock definition instead. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 4 ++-- arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index c541301c7f2b..a63cdcaee0b2 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -154,8 +154,8 @@ static struct clk mstp_clks[] = { MSTP("sh0", &div4_clks[DIV4_P], MSTPCR0, 20, 0), MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0), MSTP("ubc0", &div4_clks[DIV4_P], MSTPCR0, 17, 0), - MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0), - MSTP("cmt0", &r_clk, MSTPCR0, 14, 0), + MSTP("tmu_fck", &div4_clks[DIV4_P], MSTPCR0, 15, 0), + MSTP("cmt_fck", &r_clk, MSTPCR0, 14, 0), MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0), MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0), MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0), diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index 6f8394942fc5..3681cafdb4af 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -205,7 +205,6 @@ static struct platform_device jpu_device = { static struct sh_timer_config cmt_platform_data = { .channel_offset = 0x60, .timer_bit = 5, - .clk = "cmt0", .clockevent_rating = 125, .clocksource_rating = 200, }; @@ -235,7 +234,6 @@ static struct platform_device cmt_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "tmu0", .clockevent_rating = 200, }; @@ -264,7 +262,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "tmu0", .clocksource_rating = 200, }; @@ -293,7 +290,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "tmu0", }; static struct resource tmu2_resources[] = { -- cgit v1.2.3-59-g8ed1b From 2169bc1bae5d6d996276ddbd017f9d9b582abcae Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 29 Mar 2010 17:36:41 +0900 Subject: sh: sh7366 clock string death. Kills off clock string usage, using the new function clock definition instead. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 4 ++-- arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index e10c64fd8095..f99db94cf8fb 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -158,8 +158,8 @@ static struct clk mstp_clks[] = { MSTP("sh0", &div4_clks[DIV4_P], MSTPCR0, 20, 0), MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0), MSTP("ubc0", &div4_clks[DIV4_P], MSTPCR0, 17, 0), - MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0), - MSTP("cmt0", &r_clk, MSTPCR0, 14, 0), + MSTP("tmu_fck", &div4_clks[DIV4_P], MSTPCR0, 15, 0), + MSTP("cmt_fck", &r_clk, MSTPCR0, 14, 0), MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0), MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0), MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0), diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 1d897ed256b0..8dab9e1bbd89 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -170,7 +170,6 @@ static struct platform_device veu1_device = { static struct sh_timer_config cmt_platform_data = { .channel_offset = 0x60, .timer_bit = 5, - .clk = "cmt0", .clockevent_rating = 125, .clocksource_rating = 200, }; @@ -200,7 +199,6 @@ static struct platform_device cmt_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "tmu0", .clockevent_rating = 200, }; @@ -229,7 +227,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "tmu0", .clocksource_rating = 200, }; @@ -258,7 +255,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "tmu0", }; static struct resource tmu2_resources[] = { -- cgit v1.2.3-59-g8ed1b From 04b1731766b22cd41a0acd480e3206e93f2d5931 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 29 Mar 2010 17:37:39 +0900 Subject: sh: sh7722 clock string death. Kills off clock string usage, using the new function clock definition instead. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 4 ++-- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 0732c8bab1e2..107b200e78bd 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -160,8 +160,8 @@ struct clk div6_clks[] = { static struct clk mstp_clks[] = { SH_HWBLK_CLK("uram0", -1, U_CLK, HWBLK_URAM, CLK_ENABLE_ON_INIT), SH_HWBLK_CLK("xymem0", -1, B_CLK, HWBLK_XYMEM, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU, 0), - SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0), + SH_HWBLK_CLK("tmu_fck", -1, P_CLK, HWBLK_TMU, 0), + SH_HWBLK_CLK("cmt_fck", -1, R_CLK, HWBLK_CMT, 0), SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0), SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0), SH_HWBLK_CLK("sci_fck", 0, P_CLK, HWBLK_SCIF0, 0), diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 847a27619af5..dc9b30d086a4 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -400,7 +400,6 @@ static struct platform_device jpu_device = { static struct sh_timer_config cmt_platform_data = { .channel_offset = 0x60, .timer_bit = 5, - .clk = "cmt0", .clockevent_rating = 125, .clocksource_rating = 125, }; @@ -433,7 +432,6 @@ static struct platform_device cmt_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "tmu0", .clockevent_rating = 200, }; @@ -465,7 +463,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "tmu0", .clocksource_rating = 200, }; @@ -497,7 +494,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "tmu0", }; static struct resource tmu2_resources[] = { -- cgit v1.2.3-59-g8ed1b From f4221802ea3a28f7c16d157ac6f697d58267cb58 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 29 Mar 2010 17:45:12 +0900 Subject: sh: sh7723 clkdev lookups. Convert to TMU clock lookups for SH7723. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 46 +++++++++++++++++++++++++++++++--- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 7 ------ 2 files changed, 42 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 4d4c123d02c4..fc86c88223f4 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -171,11 +173,11 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT), SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0), SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0), - SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0), - SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0), + SH_HWBLK_CLK("tmu012_fck", -1, P_CLK, HWBLK_TMU0, 0), + SH_HWBLK_CLK("cmt_fck", -1, R_CLK, HWBLK_CMT, 0), SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0), SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0), - SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0), + SH_HWBLK_CLK("tmu345_fck", -1, P_CLK, HWBLK_TMU1, 0), SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0), SH_HWBLK_CLK("sci_fck", 0, P_CLK, HWBLK_SCIF0, 0), SH_HWBLK_CLK("sci_fck", 1, P_CLK, HWBLK_SCIF1, 0), @@ -211,6 +213,40 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0), }; +static struct clk_lookup lookups[] = { + { + /* TMU0 */ + .dev_id = "sh_tmu.0", + .con_id = "tmu_fck", + .clk = &mstp_clks[11], /* tmu012_fck */ + }, { + /* TMU1 */ + .dev_id = "sh_tmu.1", + .con_id = "tmu_fck", + .clk = &mstp_clks[11], + }, { + /* TMU2 */ + .dev_id = "sh_tmu.2", + .con_id = "tmu_fck", + .clk = &mstp_clks[11], + }, { + /* TMU3 */ + .dev_id = "sh_tmu.3", + .con_id = "tmu_fck", + .clk = &mstp_clks[15], /* tmu345_fck */ + }, { + /* TMU4 */ + .dev_id = "sh_tmu.4", + .con_id = "tmu_fck", + .clk = &mstp_clks[15], + }, { + /* TMU5 */ + .dev_id = "sh_tmu.5", + .con_id = "tmu_fck", + .clk = &mstp_clks[15], + }, +}; + int __init arch_clk_init(void) { int k, ret = 0; @@ -222,7 +258,9 @@ int __init arch_clk_init(void) pll_clk.parent = &extal_clk; for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) - ret = clk_register(main_clks[k]); + ret |= clk_register(main_clks[k]); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 187462b51be0..0eadefdbbba1 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -207,7 +207,6 @@ static struct platform_device veu1_device = { static struct sh_timer_config cmt_platform_data = { .channel_offset = 0x60, .timer_bit = 5, - .clk = "cmt0", .clockevent_rating = 125, .clocksource_rating = 125, }; @@ -240,7 +239,6 @@ static struct platform_device cmt_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "tmu0", .clockevent_rating = 200, }; @@ -272,7 +270,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "tmu0", .clocksource_rating = 200, }; @@ -304,7 +301,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "tmu0", }; static struct resource tmu2_resources[] = { @@ -335,7 +331,6 @@ static struct platform_device tmu2_device = { static struct sh_timer_config tmu3_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "tmu1", }; static struct resource tmu3_resources[] = { @@ -366,7 +361,6 @@ static struct platform_device tmu3_device = { static struct sh_timer_config tmu4_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "tmu1", }; static struct resource tmu4_resources[] = { @@ -397,7 +391,6 @@ static struct platform_device tmu4_device = { static struct sh_timer_config tmu5_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "tmu1", }; static struct resource tmu5_resources[] = { -- cgit v1.2.3-59-g8ed1b From f77f13e22df4a40d237697df496152c8c37f3f2b Mon Sep 17 00:00:00 2001 From: Gilles Espinasse Date: Mon, 29 Mar 2010 15:41:47 +0200 Subject: Fix comment and Kconfig typos for 'require' and 'fragment' Signed-off-by: Gilles Espinasse Signed-off-by: Jiri Kosina --- Documentation/powerpc/dts-bindings/xilinx.txt | 2 +- arch/mips/sibyte/bcm1480/irq.c | 2 +- arch/mips/sibyte/sb1250/irq.c | 2 +- crypto/Kconfig | 2 +- drivers/gpu/drm/i915/intel_display.c | 4 ++-- drivers/gpu/drm/radeon/atombios.h | 4 ++-- drivers/isdn/hardware/mISDN/hfcmulti.c | 2 +- drivers/net/bnx2x_hsi.h | 2 +- drivers/net/ps3_gelic_wireless.c | 2 +- drivers/staging/vt6655/rxtx.c | 14 +++++++------- drivers/staging/vt6656/rxtx.c | 6 +++--- drivers/usb/wusbcore/wa-xfer.c | 2 +- net/ipv4/ipmr.c | 2 +- scripts/package/mkspec | 2 +- 14 files changed, 24 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/Documentation/powerpc/dts-bindings/xilinx.txt b/Documentation/powerpc/dts-bindings/xilinx.txt index ea68046bb9cb..299d0923537b 100644 --- a/Documentation/powerpc/dts-bindings/xilinx.txt +++ b/Documentation/powerpc/dts-bindings/xilinx.txt @@ -11,7 +11,7 @@ control how the core is synthesized. Historically, the EDK tool would extract the device parameters relevant to device drivers and copy them into an 'xparameters.h' in the form of #define symbols. This tells the - device drivers how the IP cores are configured, but it requres the kernel + device drivers how the IP cores are configured, but it requires the kernel to be recompiled every time the FPGA bitstream is resynthesized. The new approach is to export the parameters into the device tree and diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 06e25d949768..3fbb033e23d8 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -254,7 +254,7 @@ void __init init_bcm1480_irqs(void) * On the second cpu, everything is set to IP5, which is * ignored, EXCEPT the mailbox interrupt. That one is * set to IP[2] so it is handled. This is needed so we - * can do cross-cpu function calls, as requred by SMP + * can do cross-cpu function calls, as required by SMP */ #define IMR_IP2_VAL K_BCM1480_INT_MAP_I0 diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index ab44a2f59ee4..b452e3c82792 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -237,7 +237,7 @@ void __init init_sb1250_irqs(void) * On the second cpu, everything is set to IP5, which is * ignored, EXCEPT the mailbox interrupt. That one is * set to IP[2] so it is handled. This is needed so we - * can do cross-cpu function calls, as requred by SMP + * can do cross-cpu function calls, as required by SMP */ #define IMR_IP2_VAL K_INT_MAP_I0 diff --git a/crypto/Kconfig b/crypto/Kconfig index 403857ad06d4..9d9434f08c92 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -28,7 +28,7 @@ config CRYPTO_FIPS This options enables the fips boot option which is required if you want to system to operate in a FIPS 200 certification. You should say no unless you know what - this is. Note that CRYPTO_ANSI_CPRNG is requred if this + this is. Note that CRYPTO_ANSI_CPRNG is required if this option is selected config CRYPTO_ALGAPI diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9cd6de5f9906..c297fc22867e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -904,9 +904,9 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, memset(best_clock, 0, sizeof(*best_clock)); max_n = limit->n.max; - /* based on hardware requriment prefer smaller n to precision */ + /* based on hardware requirement, prefer smaller n to precision */ for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { - /* based on hardware requirment prefere larger m1,m2 */ + /* based on hardware requirement, prefere larger m1,m2 */ for (clock.m1 = limit->m1.max; clock.m1 >= limit->m1.min; clock.m1--) { for (clock.m2 = limit->m2.max; diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 6732b5dd8ff4..e91a815861f4 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -3780,7 +3780,7 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT UCHAR ucReserved[2]; }ATOM_ASIC_SS_ASSIGNMENT; -//Define ucClockIndication, SW uses the IDs below to search if the SS is requried/enabled on a clock branch/signal type. +//Define ucClockIndication, SW uses the IDs below to search if the SS is required/enabled on a clock branch/signal type. //SS is not required or enabled if a match is not found. #define ASIC_INTERNAL_MEMORY_SS 1 #define ASIC_INTERNAL_ENGINE_SS 2 @@ -5895,7 +5895,7 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO UCHAR ucPadding; // For proper alignment and size. USHORT usVDDC; // For the 780, use: None, Low, High, Variable UCHAR ucMaxHTLinkWidth; // From SBIOS - {2, 4, 8, 16} - UCHAR ucMinHTLinkWidth; // From SBIOS - {2, 4, 8, 16}. Effective only if CDLW enabled. Minimum down stream width could be bigger as display BW requriement. + UCHAR ucMinHTLinkWidth; // From SBIOS - {2, 4, 8, 16}. Effective only if CDLW enabled. Minimum down stream width could be bigger as display BW requirement. USHORT usHTLinkFreq; // See definition ATOM_PPLIB_RS780_HTLINKFREQ_xxx or in MHz(>=200). ULONG ulFlags; } ATOM_PPLIB_RS780_CLOCK_INFO; diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index ad36df9b759c..fa82ce32aa4e 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -117,7 +117,7 @@ * NOTE: only one mode value must be given for every card. * -> See hfc_multi.h for HFC_IO_MODE_* values * By default, the IO mode is pci memory IO (MEMIO). - * Some cards requre specific IO mode, so it cannot be changed. + * Some cards require specific IO mode, so it cannot be changed. * It may be usefull to set IO mode to register io (REGIO) to solve * PCI bridge problems. * If unsure, don't give this parameter. diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h index 760069345b11..fd1f29e0317d 100644 --- a/drivers/net/bnx2x_hsi.h +++ b/drivers/net/bnx2x_hsi.h @@ -683,7 +683,7 @@ struct drv_func_mb { #define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000 #define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000 /* - * The optic module verification commands requris bootcode + * The optic module verification commands require bootcode * v5.0.6 or later */ #define DRV_MSG_CODE_VRFY_OPT_MDL 0xa0000000 diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 2663b2fdc0bb..7fe54c261c44 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -95,7 +95,7 @@ static inline int precise_ie(void) * post_eurus_cmd helpers */ struct eurus_cmd_arg_info { - int pre_arg; /* command requres arg1, arg2 at POST COMMAND */ + int pre_arg; /* command requires arg1, arg2 at POST COMMAND */ int post_arg; /* command requires arg1, arg2 at GET_RESULT */ }; diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index ed3070edcac1..4fcc4351e73f 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -25,19 +25,19 @@ * Date: May 20, 2003 * * Functions: - * s_vGenerateTxParameter - Generate tx dma requried parameter. + * s_vGenerateTxParameter - Generate tx dma required parameter. * vGenerateMACHeader - Translate 802.3 to 802.11 header - * cbGetFragCount - Caculate fragement number count + * cbGetFragCount - Caculate fragment number count * csBeacon_xmit - beacon tx function * csMgmt_xmit - management tx function * s_cbFillTxBufHead - fulfill tx dma buffer header * s_uGetDataDuration - get tx data required duration * s_uFillDataHead- fulfill tx data duration header - * s_uGetRTSCTSDuration- get rtx/cts requried duration + * s_uGetRTSCTSDuration- get rtx/cts required duration * s_uGetRTSCTSRsvTime- get rts/cts reserved time * s_uGetTxRsvTime- get frame reserved time * s_vFillCTSHead- fulfill CTS ctl header - * s_vFillFragParameter- Set fragement ctl parameter. + * s_vFillFragParameter- Set fragment ctl parameter. * s_vFillRTSHead- fulfill RTS ctl header * s_vFillTxKey- fulfill tx encrypt key * s_vSWencryption- Software encrypt header @@ -877,7 +877,7 @@ s_vFillRTSHead ( } // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account. - // Otherwise, we need to modified codes for them. + // Otherwise, we need to modify codes for them. if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { if (byFBOption == AUTO_FB_NONE) { PSRTS_g pBuf = (PSRTS_g)pvRTS; @@ -1133,7 +1133,7 @@ s_vFillCTSHead ( * * Parameters: * In: - * pDevice - Pointer to adpater + * pDevice - Pointer to adapter * pTxDataHead - Transmit Data Buffer * pTxBufHead - pTxBufHead * pvRrvTime - pvRrvTime @@ -2252,7 +2252,7 @@ vGenerateFIFOHeader ( * * Parameters: * In: - * pDevice - Pointer to adpater + * pDevice - Pointer to adapter * dwTxBufferAddr - Transmit Buffer * pPacket - Packet from upper layer * cbPacketSize - Transmit Data Length diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index d9fa36c95230..a2ce6fad8ee5 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -25,17 +25,17 @@ * Date: May 20, 2003 * * Functions: - * s_vGenerateTxParameter - Generate tx dma requried parameter. + * s_vGenerateTxParameter - Generate tx dma required parameter. * s_vGenerateMACHeader - Translate 802.3 to 802.11 header * csBeacon_xmit - beacon tx function * csMgmt_xmit - management tx function * s_uGetDataDuration - get tx data required duration * s_uFillDataHead- fulfill tx data duration header - * s_uGetRTSCTSDuration- get rtx/cts requried duration + * s_uGetRTSCTSDuration- get rtx/cts required duration * s_uGetRTSCTSRsvTime- get rts/cts reserved time * s_uGetTxRsvTime- get frame reserved time * s_vFillCTSHead- fulfill CTS ctl header - * s_vFillFragParameter- Set fragement ctl parameter. + * s_vFillFragParameter- Set fragment ctl parameter. * s_vFillRTSHead- fulfill RTS ctl header * s_vFillTxKey- fulfill tx encrypt key * s_vSWencryption- Software encrypt header diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 489b47833e2c..3aad333ae9ce 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c @@ -76,7 +76,7 @@ * xfers-per-ripe, blocks-per-rpipe, rpipes-per-host), at the end * we are going to have to rebuild all this based on an scheduler, * to where we have a list of transactions to do and based on the - * availability of the different requried components (blocks, + * availability of the different required components (blocks, * rpipes, segment slots, etc), we go scheduling them. Painful. */ #include diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8582e12e4a62..b1373abe2489 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -22,7 +22,7 @@ * overflow. * Carlos Picoto : PIMv1 Support * Pavlin Ivanov Radoslavov: PIMv2 Registers must checksum only PIM header - * Relax this requrement to work with older peers. + * Relax this requirement to work with older peers. * */ diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 47bdd2f99b78..fa27f3dac769 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -1,6 +1,6 @@ #!/bin/sh # -# Output a simple RPM spec file that uses no fancy features requring +# Output a simple RPM spec file that uses no fancy features requiring # RPM v4. This is intended to work with any RPM distro. # # The only gothic bit here is redefining install_post to avoid -- cgit v1.2.3-59-g8ed1b From f4cff0d0ffc0162636357d0475409ecf1304f854 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 30 Mar 2010 11:20:35 +0900 Subject: sh: sh7724 clkdev lookups. Conver to TMU clock lookups for SH7724. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 44 +++++++++++++++++++++++++++++++--- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 7 ------ 2 files changed, 41 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index bcf2b97db300..f1583a23b3a5 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -189,11 +191,11 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT), SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0), SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0), - SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0), - SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0), + SH_HWBLK_CLK("tmu012_fck", -1, P_CLK, HWBLK_TMU0, 0), + SH_HWBLK_CLK("cmt_fck", -1, R_CLK, HWBLK_CMT, 0), SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0), SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0), - SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0), + SH_HWBLK_CLK("tmu345_fck", -1, P_CLK, HWBLK_TMU1, 0), SH_HWBLK_CLK("sci_fck", 0, P_CLK, HWBLK_SCIF0, 0), SH_HWBLK_CLK("sci_fck", 1, P_CLK, HWBLK_SCIF1, 0), SH_HWBLK_CLK("sci_fck", 2, P_CLK, HWBLK_SCIF2, 0), @@ -233,6 +235,40 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0), }; +static struct clk_lookup lookups[] = { + { + /* TMU0 */ + .dev_id = "sh_tmu.0", + .con_id = "tmu_fck", + .clk = &mstp_clks[12], /* tmu012_fck */ + }, { + /* TMU1 */ + .dev_id = "sh_tmu.1", + .con_id = "tmu_fck", + .clk = &mstp_clks[12], + }, { + /* TMU2 */ + .dev_id = "sh_tmu.2", + .con_id = "tmu_fck", + .clk = &mstp_clks[12], + }, { + /* TMU3 */ + .dev_id = "sh_tmu.3", + .con_id = "tmu_fck", + .clk = &mstp_clks[16], /* tmu345_fck */ + }, { + /* TMU4 */ + .dev_id = "sh_tmu.4", + .con_id = "tmu_fck", + .clk = &mstp_clks[16], + }, { + /* TMU5 */ + .dev_id = "sh_tmu.5", + .con_id = "tmu_fck", + .clk = &mstp_clks[16], + }, +}; + int __init arch_clk_init(void) { int k, ret = 0; @@ -246,6 +282,8 @@ int __init arch_clk_init(void) for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) ret = clk_register(main_clks[k]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + if (!ret) ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index ee9789003193..8a0a4a99f86b 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -481,7 +481,6 @@ static struct platform_device veu1_device = { static struct sh_timer_config cmt_platform_data = { .channel_offset = 0x60, .timer_bit = 5, - .clk = "cmt0", .clockevent_rating = 125, .clocksource_rating = 200, }; @@ -514,7 +513,6 @@ static struct platform_device cmt_device = { static struct sh_timer_config tmu0_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "tmu0", .clockevent_rating = 200, }; @@ -546,7 +544,6 @@ static struct platform_device tmu0_device = { static struct sh_timer_config tmu1_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "tmu0", .clocksource_rating = 200, }; @@ -578,7 +575,6 @@ static struct platform_device tmu1_device = { static struct sh_timer_config tmu2_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "tmu0", }; static struct resource tmu2_resources[] = { @@ -610,7 +606,6 @@ static struct platform_device tmu2_device = { static struct sh_timer_config tmu3_platform_data = { .channel_offset = 0x04, .timer_bit = 0, - .clk = "tmu1", }; static struct resource tmu3_resources[] = { @@ -641,7 +636,6 @@ static struct platform_device tmu3_device = { static struct sh_timer_config tmu4_platform_data = { .channel_offset = 0x10, .timer_bit = 1, - .clk = "tmu1", }; static struct resource tmu4_resources[] = { @@ -672,7 +666,6 @@ static struct platform_device tmu4_device = { static struct sh_timer_config tmu5_platform_data = { .channel_offset = 0x1c, .timer_bit = 2, - .clk = "tmu1", }; static struct resource tmu5_resources[] = { -- cgit v1.2.3-59-g8ed1b From e446630c960946b5c1762e4eadb618becef599e7 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 29 Mar 2010 08:57:56 +0000 Subject: Add hotplug support to mcp251x driver Chip model can now be selected directly by matching the modalias name (instead of filling the .model field in platform_data), and allows the module to be auto-loaded. Previous behaviour is of course still supported. Convert the two in-tree users to this feature (icontrol & zeus). Tested on an Zeus platform (mcp2515). Signed-off-by: Marc Zyngier Acked-by: Christian Pellegrin Cc: Edwin Peer Acked-by: Wolfgang Grandegger Signed-off-by: David S. Miller --- arch/arm/mach-pxa/icontrol.c | 9 ++++----- arch/arm/mach-pxa/zeus.c | 4 +--- drivers/net/can/mcp251x.c | 14 ++++++++++++++ include/linux/can/platform/mcp251x.h | 4 ++-- 4 files changed, 21 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c index 771137fc1a82..5ccb0ceff6c4 100644 --- a/arch/arm/mach-pxa/icontrol.c +++ b/arch/arm/mach-pxa/icontrol.c @@ -73,7 +73,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info4 = { static struct mcp251x_platform_data mcp251x_info = { .oscillator_frequency = 16E6, - .model = CAN_MCP251X_MCP2515, .board_specific_setup = NULL, .power_enable = NULL, .transceiver_enable = NULL @@ -81,7 +80,7 @@ static struct mcp251x_platform_data mcp251x_info = { static struct spi_board_info mcp251x_board_info[] = { { - .modalias = "mcp251x", + .modalias = "mcp2515", .max_speed_hz = 6500000, .bus_num = 3, .chip_select = 0, @@ -90,7 +89,7 @@ static struct spi_board_info mcp251x_board_info[] = { .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ1) }, { - .modalias = "mcp251x", + .modalias = "mcp2515", .max_speed_hz = 6500000, .bus_num = 3, .chip_select = 1, @@ -99,7 +98,7 @@ static struct spi_board_info mcp251x_board_info[] = { .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ2) }, { - .modalias = "mcp251x", + .modalias = "mcp2515", .max_speed_hz = 6500000, .bus_num = 4, .chip_select = 0, @@ -108,7 +107,7 @@ static struct spi_board_info mcp251x_board_info[] = { .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ3) }, { - .modalias = "mcp251x", + .modalias = "mcp2515", .max_speed_hz = 6500000, .bus_num = 4, .chip_select = 1, diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 39896d883584..dbd256966379 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -414,15 +414,13 @@ static int zeus_mcp2515_transceiver_enable(int enable) static struct mcp251x_platform_data zeus_mcp2515_pdata = { .oscillator_frequency = 16*1000*1000, - .model = CAN_MCP251X_MCP2515, .board_specific_setup = zeus_mcp2515_setup, - .transceiver_enable = zeus_mcp2515_transceiver_enable, .power_enable = zeus_mcp2515_transceiver_enable, }; static struct spi_board_info zeus_spi_board_info[] = { [0] = { - .modalias = "mcp251x", + .modalias = "mcp2515", .platform_data = &zeus_mcp2515_pdata, .irq = gpio_to_irq(ZEUS_CAN_GPIO), .max_speed_hz = 1*1000*1000, diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index f8cc168ec76c..f521579f5adb 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -922,12 +922,16 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) struct net_device *net; struct mcp251x_priv *priv; struct mcp251x_platform_data *pdata = spi->dev.platform_data; + int model = spi_get_device_id(spi)->driver_data; int ret = -ENODEV; if (!pdata) /* Platform data is required for osc freq */ goto error_out; + if (model) + pdata->model = model; + /* Allocate can/net device */ net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX); if (!net) { @@ -1117,6 +1121,15 @@ static int mcp251x_can_resume(struct spi_device *spi) #define mcp251x_can_resume NULL #endif +static struct spi_device_id mcp251x_id_table[] = { + { "mcp251x", 0 /* Use pdata.model */ }, + { "mcp2510", CAN_MCP251X_MCP2510 }, + { "mcp2515", CAN_MCP251X_MCP2515 }, + { }, +}; + +MODULE_DEVICE_TABLE(spi, mcp251x_id_table); + static struct spi_driver mcp251x_can_driver = { .driver = { .name = DEVICE_NAME, @@ -1124,6 +1137,7 @@ static struct spi_driver mcp251x_can_driver = { .owner = THIS_MODULE, }, + .id_table = mcp251x_id_table, .probe = mcp251x_can_probe, .remove = __devexit_p(mcp251x_can_remove), .suspend = mcp251x_can_suspend, diff --git a/include/linux/can/platform/mcp251x.h b/include/linux/can/platform/mcp251x.h index 1448177d86d5..dba28268e651 100644 --- a/include/linux/can/platform/mcp251x.h +++ b/include/linux/can/platform/mcp251x.h @@ -26,8 +26,8 @@ struct mcp251x_platform_data { unsigned long oscillator_frequency; int model; -#define CAN_MCP251X_MCP2510 0 -#define CAN_MCP251X_MCP2515 1 +#define CAN_MCP251X_MCP2510 0x2510 +#define CAN_MCP251X_MCP2515 0x2515 int (*board_specific_setup)(struct spi_device *spi); int (*transceiver_enable)(int enable); int (*power_enable) (int enable); -- cgit v1.2.3-59-g8ed1b From 948b1bb89a44561560531394c18da4a99215f772 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 29 Mar 2010 18:36:50 +0200 Subject: perf, x86: Undo some some *_counter* -> *_event* renames The big rename: cdd6c48 perf: Do the big rename: Performance Counters -> Performance Events accidentally renamed some members of stucts that were named after registers in the spec. To avoid confusion this patch reverts some changes. The related specs are MSR descriptions in AMD's BKDGs and the ARCHITECTURAL PERFORMANCE MONITORING section in the Intel 64 and IA-32 Architectures Software Developer's Manuals. This patch does: $ sed -i -e 's:num_events:num_counters:g' \ arch/x86/include/asm/perf_event.h \ arch/x86/kernel/cpu/perf_event_amd.c \ arch/x86/kernel/cpu/perf_event.c \ arch/x86/kernel/cpu/perf_event_intel.c \ arch/x86/kernel/cpu/perf_event_p6.c \ arch/x86/kernel/cpu/perf_event_p4.c \ arch/x86/oprofile/op_model_ppro.c $ sed -i -e 's:event_bits:cntval_bits:g' -e 's:event_mask:cntval_mask:g' \ arch/x86/kernel/cpu/perf_event_amd.c \ arch/x86/kernel/cpu/perf_event.c \ arch/x86/kernel/cpu/perf_event_intel.c \ arch/x86/kernel/cpu/perf_event_p6.c \ arch/x86/kernel/cpu/perf_event_p4.c Signed-off-by: Robert Richter Signed-off-by: Peter Zijlstra LKML-Reference: <1269880612-25800-2-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event.h | 4 +- arch/x86/kernel/cpu/perf_event.c | 74 +++++++++++++++++----------------- arch/x86/kernel/cpu/perf_event_amd.c | 12 +++--- arch/x86/kernel/cpu/perf_event_intel.c | 16 ++++---- arch/x86/kernel/cpu/perf_event_p4.c | 14 +++---- arch/x86/kernel/cpu/perf_event_p6.c | 6 +-- arch/x86/oprofile/op_model_ppro.c | 4 +- 7 files changed, 65 insertions(+), 65 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 124dddd598f3..987bf673141e 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -67,7 +67,7 @@ union cpuid10_eax { struct { unsigned int version_id:8; - unsigned int num_events:8; + unsigned int num_counters:8; unsigned int bit_width:8; unsigned int mask_length:8; } split; @@ -76,7 +76,7 @@ union cpuid10_eax { union cpuid10_edx { struct { - unsigned int num_events_fixed:4; + unsigned int num_counters_fixed:4; unsigned int reserved:28; } split; unsigned int full; diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index b53435661813..9daaa1ef504c 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -195,10 +195,10 @@ struct x86_pmu { u64 (*event_map)(int); u64 (*raw_event)(u64); int max_events; - int num_events; - int num_events_fixed; - int event_bits; - u64 event_mask; + int num_counters; + int num_counters_fixed; + int cntval_bits; + u64 cntval_mask; int apic; u64 max_period; struct event_constraint * @@ -268,7 +268,7 @@ static u64 x86_perf_event_update(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; - int shift = 64 - x86_pmu.event_bits; + int shift = 64 - x86_pmu.cntval_bits; u64 prev_raw_count, new_raw_count; int idx = hwc->idx; s64 delta; @@ -320,12 +320,12 @@ static bool reserve_pmc_hardware(void) if (nmi_watchdog == NMI_LOCAL_APIC) disable_lapic_nmi_watchdog(); - for (i = 0; i < x86_pmu.num_events; i++) { + for (i = 0; i < x86_pmu.num_counters; i++) { if (!reserve_perfctr_nmi(x86_pmu.perfctr + i)) goto perfctr_fail; } - for (i = 0; i < x86_pmu.num_events; i++) { + for (i = 0; i < x86_pmu.num_counters; i++) { if (!reserve_evntsel_nmi(x86_pmu.eventsel + i)) goto eventsel_fail; } @@ -336,7 +336,7 @@ eventsel_fail: for (i--; i >= 0; i--) release_evntsel_nmi(x86_pmu.eventsel + i); - i = x86_pmu.num_events; + i = x86_pmu.num_counters; perfctr_fail: for (i--; i >= 0; i--) @@ -352,7 +352,7 @@ static void release_pmc_hardware(void) { int i; - for (i = 0; i < x86_pmu.num_events; i++) { + for (i = 0; i < x86_pmu.num_counters; i++) { release_perfctr_nmi(x86_pmu.perfctr + i); release_evntsel_nmi(x86_pmu.eventsel + i); } @@ -547,7 +547,7 @@ static void x86_pmu_disable_all(void) struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); int idx; - for (idx = 0; idx < x86_pmu.num_events; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { u64 val; if (!test_bit(idx, cpuc->active_mask)) @@ -582,7 +582,7 @@ static void x86_pmu_enable_all(int added) struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); int idx; - for (idx = 0; idx < x86_pmu.num_events; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { struct perf_event *event = cpuc->events[idx]; u64 val; @@ -657,14 +657,14 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) * assign events to counters starting with most * constrained events. */ - wmax = x86_pmu.num_events; + wmax = x86_pmu.num_counters; /* * when fixed event counters are present, * wmax is incremented by 1 to account * for one more choice */ - if (x86_pmu.num_events_fixed) + if (x86_pmu.num_counters_fixed) wmax++; for (w = 1, num = n; num && w <= wmax; w++) { @@ -714,7 +714,7 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, struct perf_event *event; int n, max_count; - max_count = x86_pmu.num_events + x86_pmu.num_events_fixed; + max_count = x86_pmu.num_counters + x86_pmu.num_counters_fixed; /* current number of events already accepted */ n = cpuc->n_events; @@ -904,7 +904,7 @@ x86_perf_event_set_period(struct perf_event *event) atomic64_set(&hwc->prev_count, (u64)-left); wrmsrl(hwc->event_base + idx, - (u64)(-left) & x86_pmu.event_mask); + (u64)(-left) & x86_pmu.cntval_mask); perf_event_update_userpage(event); @@ -987,7 +987,7 @@ void perf_event_print_debug(void) unsigned long flags; int cpu, idx; - if (!x86_pmu.num_events) + if (!x86_pmu.num_counters) return; local_irq_save(flags); @@ -1011,7 +1011,7 @@ void perf_event_print_debug(void) } pr_info("CPU#%d: active: %016llx\n", cpu, *(u64 *)cpuc->active_mask); - for (idx = 0; idx < x86_pmu.num_events; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl); rdmsrl(x86_pmu.perfctr + idx, pmc_count); @@ -1024,7 +1024,7 @@ void perf_event_print_debug(void) pr_info("CPU#%d: gen-PMC%d left: %016llx\n", cpu, idx, prev_left); } - for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) { + for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) { rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count); pr_info("CPU#%d: fixed-PMC%d count: %016llx\n", @@ -1089,7 +1089,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) cpuc = &__get_cpu_var(cpu_hw_events); - for (idx = 0; idx < x86_pmu.num_events; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { if (!test_bit(idx, cpuc->active_mask)) continue; @@ -1097,7 +1097,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) hwc = &event->hw; val = x86_perf_event_update(event); - if (val & (1ULL << (x86_pmu.event_bits - 1))) + if (val & (1ULL << (x86_pmu.cntval_bits - 1))) continue; /* @@ -1401,46 +1401,46 @@ void __init init_hw_perf_events(void) if (x86_pmu.quirks) x86_pmu.quirks(); - if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) { + if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) { WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", - x86_pmu.num_events, X86_PMC_MAX_GENERIC); - x86_pmu.num_events = X86_PMC_MAX_GENERIC; + x86_pmu.num_counters, X86_PMC_MAX_GENERIC); + x86_pmu.num_counters = X86_PMC_MAX_GENERIC; } - x86_pmu.intel_ctrl = (1 << x86_pmu.num_events) - 1; - perf_max_events = x86_pmu.num_events; + x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1; + perf_max_events = x86_pmu.num_counters; - if (x86_pmu.num_events_fixed > X86_PMC_MAX_FIXED) { + if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!", - x86_pmu.num_events_fixed, X86_PMC_MAX_FIXED); - x86_pmu.num_events_fixed = X86_PMC_MAX_FIXED; + x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED); + x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; } x86_pmu.intel_ctrl |= - ((1LL << x86_pmu.num_events_fixed)-1) << X86_PMC_IDX_FIXED; + ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED; perf_events_lapic_init(); register_die_notifier(&perf_event_nmi_notifier); unconstrained = (struct event_constraint) - __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_events) - 1, - 0, x86_pmu.num_events); + __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, + 0, x86_pmu.num_counters); if (x86_pmu.event_constraints) { for_each_event_constraint(c, x86_pmu.event_constraints) { if (c->cmask != INTEL_ARCH_FIXED_MASK) continue; - c->idxmsk64 |= (1ULL << x86_pmu.num_events) - 1; - c->weight += x86_pmu.num_events; + c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1; + c->weight += x86_pmu.num_counters; } } pr_info("... version: %d\n", x86_pmu.version); - pr_info("... bit width: %d\n", x86_pmu.event_bits); - pr_info("... generic registers: %d\n", x86_pmu.num_events); - pr_info("... value mask: %016Lx\n", x86_pmu.event_mask); + pr_info("... bit width: %d\n", x86_pmu.cntval_bits); + pr_info("... generic registers: %d\n", x86_pmu.num_counters); + pr_info("... value mask: %016Lx\n", x86_pmu.cntval_mask); pr_info("... max period: %016Lx\n", x86_pmu.max_period); - pr_info("... fixed-purpose events: %d\n", x86_pmu.num_events_fixed); + pr_info("... fixed-purpose events: %d\n", x86_pmu.num_counters_fixed); pr_info("... event mask: %016Lx\n", x86_pmu.intel_ctrl); perf_cpu_notifier(x86_pmu_notifier); diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 285623bc3cc8..7753a5c76535 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -165,7 +165,7 @@ static void amd_put_event_constraints(struct cpu_hw_events *cpuc, * be removed on one CPU at a time AND PMU is disabled * when we come here */ - for (i = 0; i < x86_pmu.num_events; i++) { + for (i = 0; i < x86_pmu.num_counters; i++) { if (nb->owners[i] == event) { cmpxchg(nb->owners+i, event, NULL); break; @@ -215,7 +215,7 @@ amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) struct hw_perf_event *hwc = &event->hw; struct amd_nb *nb = cpuc->amd_nb; struct perf_event *old = NULL; - int max = x86_pmu.num_events; + int max = x86_pmu.num_counters; int i, j, k = -1; /* @@ -293,7 +293,7 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id) /* * initialize all possible NB constraints */ - for (i = 0; i < x86_pmu.num_events; i++) { + for (i = 0; i < x86_pmu.num_counters; i++) { __set_bit(i, nb->event_constraints[i].idxmsk); nb->event_constraints[i].weight = 1; } @@ -385,9 +385,9 @@ static __initconst struct x86_pmu amd_pmu = { .event_map = amd_pmu_event_map, .raw_event = amd_pmu_raw_event, .max_events = ARRAY_SIZE(amd_perfmon_event_map), - .num_events = 4, - .event_bits = 48, - .event_mask = (1ULL << 48) - 1, + .num_counters = 4, + .cntval_bits = 48, + .cntval_mask = (1ULL << 48) - 1, .apic = 1, /* use highest bit to detect overflow */ .max_period = (1ULL << 47) - 1, diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 676aac27aca4..cc4d90a13d53 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -653,20 +653,20 @@ static void intel_pmu_reset(void) unsigned long flags; int idx; - if (!x86_pmu.num_events) + if (!x86_pmu.num_counters) return; local_irq_save(flags); printk("clearing PMU state on CPU#%d\n", smp_processor_id()); - for (idx = 0; idx < x86_pmu.num_events; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { checking_wrmsrl(x86_pmu.eventsel + idx, 0ull); checking_wrmsrl(x86_pmu.perfctr + idx, 0ull); } - for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) { + for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); - } + if (ds) ds->bts_index = ds->bts_buffer_base; @@ -901,16 +901,16 @@ static __init int intel_pmu_init(void) x86_pmu = intel_pmu; x86_pmu.version = version; - x86_pmu.num_events = eax.split.num_events; - x86_pmu.event_bits = eax.split.bit_width; - x86_pmu.event_mask = (1ULL << eax.split.bit_width) - 1; + x86_pmu.num_counters = eax.split.num_counters; + x86_pmu.cntval_bits = eax.split.bit_width; + x86_pmu.cntval_mask = (1ULL << eax.split.bit_width) - 1; /* * Quirk: v2 perfmon does not report fixed-purpose events, so * assume at least 3 events: */ if (version > 1) - x86_pmu.num_events_fixed = max((int)edx.split.num_events_fixed, 3); + x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); /* * v2 and above have a perf capabilities MSR diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 0d1be36cbe9e..4139100404e8 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -483,7 +483,7 @@ static void p4_pmu_disable_all(void) struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); int idx; - for (idx = 0; idx < x86_pmu.num_events; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { struct perf_event *event = cpuc->events[idx]; if (!test_bit(idx, cpuc->active_mask)) continue; @@ -540,7 +540,7 @@ static void p4_pmu_enable_all(int added) struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); int idx; - for (idx = 0; idx < x86_pmu.num_events; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { struct perf_event *event = cpuc->events[idx]; if (!test_bit(idx, cpuc->active_mask)) continue; @@ -562,7 +562,7 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) cpuc = &__get_cpu_var(cpu_hw_events); - for (idx = 0; idx < x86_pmu.num_events; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { if (!test_bit(idx, cpuc->active_mask)) continue; @@ -579,7 +579,7 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) p4_pmu_clear_cccr_ovf(hwc); val = x86_perf_event_update(event); - if (val & (1ULL << (x86_pmu.event_bits - 1))) + if (val & (1ULL << (x86_pmu.cntval_bits - 1))) continue; /* @@ -794,10 +794,10 @@ static __initconst struct x86_pmu p4_pmu = { * though leave it restricted at moment assuming * HT is on */ - .num_events = ARCH_P4_MAX_CCCR, + .num_counters = ARCH_P4_MAX_CCCR, .apic = 1, - .event_bits = 40, - .event_mask = (1ULL << 40) - 1, + .cntval_bits = 40, + .cntval_mask = (1ULL << 40) - 1, .max_period = (1ULL << 39) - 1, .hw_config = p4_hw_config, .schedule_events = p4_pmu_schedule_events, diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index 877182c850df..b26fbc7eb93c 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -119,7 +119,7 @@ static __initconst struct x86_pmu p6_pmu = { .apic = 1, .max_period = (1ULL << 31) - 1, .version = 0, - .num_events = 2, + .num_counters = 2, /* * Events have 40 bits implemented. However they are designed such * that bits [32-39] are sign extensions of bit 31. As such the @@ -127,8 +127,8 @@ static __initconst struct x86_pmu p6_pmu = { * * See IA-32 Intel Architecture Software developer manual Vol 3B */ - .event_bits = 32, - .event_mask = (1ULL << 32) - 1, + .cntval_bits = 32, + .cntval_mask = (1ULL << 32) - 1, .get_event_constraints = x86_get_event_constraints, .event_constraints = p6_event_constraints, }; diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index 2bf90fafa7b5..c8abc4d1bf35 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c @@ -239,11 +239,11 @@ static void arch_perfmon_setup_counters(void) if (eax.split.version_id == 0 && current_cpu_data.x86 == 6 && current_cpu_data.x86_model == 15) { eax.split.version_id = 2; - eax.split.num_events = 2; + eax.split.num_counters = 2; eax.split.bit_width = 40; } - num_counters = eax.split.num_events; + num_counters = eax.split.num_counters; op_arch_perfmon_spec.num_counters = num_counters; op_arch_perfmon_spec.num_controls = num_counters; -- cgit v1.2.3-59-g8ed1b From a098f4484bc7dae23f5b62360954007b99b64600 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 30 Mar 2010 11:28:21 +0200 Subject: perf, x86: implement ARCH_PERFMON_EVENTSEL bit masks ARCH_PERFMON_EVENTSEL bit masks are often used in the kernel. This patch adds macros for the bit masks and removes local defines. The function intel_pmu_raw_event() becomes x86_pmu_raw_event() which is generic for x86 models and same also for p6. Duplicate code is removed. Signed-off-by: Robert Richter Signed-off-by: Peter Zijlstra LKML-Reference: <20100330092821.GH11907@erda.amd.com> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event.h | 58 +++++++++++++++------------------- arch/x86/kernel/cpu/perf_event.c | 19 +++++++++-- arch/x86/kernel/cpu/perf_event_amd.c | 15 +-------- arch/x86/kernel/cpu/perf_event_intel.c | 22 ++----------- arch/x86/kernel/cpu/perf_event_p6.c | 20 +----------- 5 files changed, 45 insertions(+), 89 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 987bf673141e..f6d43dbfd8e7 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -18,39 +18,31 @@ #define MSR_ARCH_PERFMON_EVENTSEL0 0x186 #define MSR_ARCH_PERFMON_EVENTSEL1 0x187 -#define ARCH_PERFMON_EVENTSEL_ENABLE (1 << 22) -#define ARCH_PERFMON_EVENTSEL_ANY (1 << 21) -#define ARCH_PERFMON_EVENTSEL_INT (1 << 20) -#define ARCH_PERFMON_EVENTSEL_OS (1 << 17) -#define ARCH_PERFMON_EVENTSEL_USR (1 << 16) - -/* - * Includes eventsel and unit mask as well: - */ - - -#define INTEL_ARCH_EVTSEL_MASK 0x000000FFULL -#define INTEL_ARCH_UNIT_MASK 0x0000FF00ULL -#define INTEL_ARCH_EDGE_MASK 0x00040000ULL -#define INTEL_ARCH_INV_MASK 0x00800000ULL -#define INTEL_ARCH_CNT_MASK 0xFF000000ULL -#define INTEL_ARCH_EVENT_MASK (INTEL_ARCH_UNIT_MASK|INTEL_ARCH_EVTSEL_MASK) - -/* - * filter mask to validate fixed counter events. - * the following filters disqualify for fixed counters: - * - inv - * - edge - * - cnt-mask - * The other filters are supported by fixed counters. - * The any-thread option is supported starting with v3. - */ -#define INTEL_ARCH_FIXED_MASK \ - (INTEL_ARCH_CNT_MASK| \ - INTEL_ARCH_INV_MASK| \ - INTEL_ARCH_EDGE_MASK|\ - INTEL_ARCH_UNIT_MASK|\ - INTEL_ARCH_EVENT_MASK) +#define ARCH_PERFMON_EVENTSEL_EVENT 0x000000FFULL +#define ARCH_PERFMON_EVENTSEL_UMASK 0x0000FF00ULL +#define ARCH_PERFMON_EVENTSEL_USR (1ULL << 16) +#define ARCH_PERFMON_EVENTSEL_OS (1ULL << 17) +#define ARCH_PERFMON_EVENTSEL_EDGE (1ULL << 18) +#define ARCH_PERFMON_EVENTSEL_INT (1ULL << 20) +#define ARCH_PERFMON_EVENTSEL_ANY (1ULL << 21) +#define ARCH_PERFMON_EVENTSEL_ENABLE (1ULL << 22) +#define ARCH_PERFMON_EVENTSEL_INV (1ULL << 23) +#define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL + +#define AMD64_EVENTSEL_EVENT \ + (ARCH_PERFMON_EVENTSEL_EVENT | (0x0FULL << 32)) +#define INTEL_ARCH_EVENT_MASK \ + (ARCH_PERFMON_EVENTSEL_UMASK | ARCH_PERFMON_EVENTSEL_EVENT) + +#define X86_RAW_EVENT_MASK \ + (ARCH_PERFMON_EVENTSEL_EVENT | \ + ARCH_PERFMON_EVENTSEL_UMASK | \ + ARCH_PERFMON_EVENTSEL_EDGE | \ + ARCH_PERFMON_EVENTSEL_INV | \ + ARCH_PERFMON_EVENTSEL_CMASK) +#define AMD64_RAW_EVENT_MASK \ + (X86_RAW_EVENT_MASK | \ + AMD64_EVENTSEL_EVENT) #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 9daaa1ef504c..1dd42c18f1cb 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -143,13 +143,21 @@ struct cpu_hw_events { * Constraint on the Event code. */ #define INTEL_EVENT_CONSTRAINT(c, n) \ - EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVTSEL_MASK) + EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT) /* * Constraint on the Event code + UMask + fixed-mask + * + * filter mask to validate fixed counter events. + * the following filters disqualify for fixed counters: + * - inv + * - edge + * - cnt-mask + * The other filters are supported by fixed counters. + * The any-thread option is supported starting with v3. */ #define FIXED_EVENT_CONSTRAINT(c, n) \ - EVENT_CONSTRAINT(c, (1ULL << (32+n)), INTEL_ARCH_FIXED_MASK) + EVENT_CONSTRAINT(c, (1ULL << (32+n)), X86_RAW_EVENT_MASK) /* * Constraint on the Event code + UMask @@ -437,6 +445,11 @@ static int x86_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc return 0; } +static u64 x86_pmu_raw_event(u64 hw_event) +{ + return hw_event & X86_RAW_EVENT_MASK; +} + /* * Setup the hardware configuration for a given attr_type */ @@ -1427,7 +1440,7 @@ void __init init_hw_perf_events(void) if (x86_pmu.event_constraints) { for_each_event_constraint(c, x86_pmu.event_constraints) { - if (c->cmask != INTEL_ARCH_FIXED_MASK) + if (c->cmask != X86_RAW_EVENT_MASK) continue; c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1; diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 7753a5c76535..37e9517729df 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -113,20 +113,7 @@ static u64 amd_pmu_event_map(int hw_event) static u64 amd_pmu_raw_event(u64 hw_event) { -#define K7_EVNTSEL_EVENT_MASK 0xF000000FFULL -#define K7_EVNTSEL_UNIT_MASK 0x00000FF00ULL -#define K7_EVNTSEL_EDGE_MASK 0x000040000ULL -#define K7_EVNTSEL_INV_MASK 0x000800000ULL -#define K7_EVNTSEL_REG_MASK 0x0FF000000ULL - -#define K7_EVNTSEL_MASK \ - (K7_EVNTSEL_EVENT_MASK | \ - K7_EVNTSEL_UNIT_MASK | \ - K7_EVNTSEL_EDGE_MASK | \ - K7_EVNTSEL_INV_MASK | \ - K7_EVNTSEL_REG_MASK) - - return hw_event & K7_EVNTSEL_MASK; + return hw_event & AMD64_RAW_EVENT_MASK; } /* diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index cc4d90a13d53..dfdd6f90fc8e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -452,24 +452,6 @@ static __initconst u64 atom_hw_cache_event_ids }, }; -static u64 intel_pmu_raw_event(u64 hw_event) -{ -#define CORE_EVNTSEL_EVENT_MASK 0x000000FFULL -#define CORE_EVNTSEL_UNIT_MASK 0x0000FF00ULL -#define CORE_EVNTSEL_EDGE_MASK 0x00040000ULL -#define CORE_EVNTSEL_INV_MASK 0x00800000ULL -#define CORE_EVNTSEL_REG_MASK 0xFF000000ULL - -#define CORE_EVNTSEL_MASK \ - (INTEL_ARCH_EVTSEL_MASK | \ - INTEL_ARCH_UNIT_MASK | \ - INTEL_ARCH_EDGE_MASK | \ - INTEL_ARCH_INV_MASK | \ - INTEL_ARCH_CNT_MASK) - - return hw_event & CORE_EVNTSEL_MASK; -} - static void intel_pmu_disable_all(void) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); @@ -788,7 +770,7 @@ static __initconst struct x86_pmu core_pmu = { .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, .perfctr = MSR_ARCH_PERFMON_PERFCTR0, .event_map = intel_pmu_event_map, - .raw_event = intel_pmu_raw_event, + .raw_event = x86_pmu_raw_event, .max_events = ARRAY_SIZE(intel_perfmon_event_map), .apic = 1, /* @@ -827,7 +809,7 @@ static __initconst struct x86_pmu intel_pmu = { .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, .perfctr = MSR_ARCH_PERFMON_PERFCTR0, .event_map = intel_pmu_event_map, - .raw_event = intel_pmu_raw_event, + .raw_event = x86_pmu_raw_event, .max_events = ARRAY_SIZE(intel_perfmon_event_map), .apic = 1, /* diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index b26fbc7eb93c..03c139a67baa 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -27,24 +27,6 @@ static u64 p6_pmu_event_map(int hw_event) */ #define P6_NOP_EVENT 0x0000002EULL -static u64 p6_pmu_raw_event(u64 hw_event) -{ -#define P6_EVNTSEL_EVENT_MASK 0x000000FFULL -#define P6_EVNTSEL_UNIT_MASK 0x0000FF00ULL -#define P6_EVNTSEL_EDGE_MASK 0x00040000ULL -#define P6_EVNTSEL_INV_MASK 0x00800000ULL -#define P6_EVNTSEL_REG_MASK 0xFF000000ULL - -#define P6_EVNTSEL_MASK \ - (P6_EVNTSEL_EVENT_MASK | \ - P6_EVNTSEL_UNIT_MASK | \ - P6_EVNTSEL_EDGE_MASK | \ - P6_EVNTSEL_INV_MASK | \ - P6_EVNTSEL_REG_MASK) - - return hw_event & P6_EVNTSEL_MASK; -} - static struct event_constraint p6_event_constraints[] = { INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */ @@ -114,7 +96,7 @@ static __initconst struct x86_pmu p6_pmu = { .eventsel = MSR_P6_EVNTSEL0, .perfctr = MSR_P6_PERFCTR0, .event_map = p6_pmu_event_map, - .raw_event = p6_pmu_raw_event, + .raw_event = x86_pmu_raw_event, .max_events = ARRAY_SIZE(p6_perfmon_event_map), .apic = 1, .max_period = (1ULL << 31) - 1, -- cgit v1.2.3-59-g8ed1b From b4cdc5c264b35c67007800dec3928e9547a9d70b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 30 Mar 2010 17:00:06 +0200 Subject: perf, x86: Fix up the ANY flag stuff Stephane noticed that the ANY flag was in generic arch code, and Cyrill reported that it broke the P4 code. Solve this by merging x86_pmu::raw_event into x86_pmu::hw_config and provide intel_pmu and amd_pmu specific versions of this callback. The intel_pmu one deals with the ANY flag, the amd_pmu adds the few extra event bits AMD64 has. Reported-by: Stephane Eranian Reported-by: Cyrill Gorcunov Acked-by: Robert Richter Acked-by: Cyrill Gorcunov Acked-by: Stephane Eranian Signed-off-by: Peter Zijlstra LKML-Reference: <1269968113.5258.442.camel@laptop> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 35 ++++++++++------------------- arch/x86/kernel/cpu/perf_event_amd.c | 17 +++++++++++---- arch/x86/kernel/cpu/perf_event_intel.c | 30 +++++++++++++++++++++---- arch/x86/kernel/cpu/perf_event_p4.c | 40 +++++++++++++++++++--------------- arch/x86/kernel/cpu/perf_event_p6.c | 3 +-- 5 files changed, 74 insertions(+), 51 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 1dd42c18f1cb..65e9c5efb618 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -196,12 +196,11 @@ struct x86_pmu { void (*enable_all)(int added); void (*enable)(struct perf_event *); void (*disable)(struct perf_event *); - int (*hw_config)(struct perf_event_attr *attr, struct hw_perf_event *hwc); + int (*hw_config)(struct perf_event *event); int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign); unsigned eventsel; unsigned perfctr; u64 (*event_map)(int); - u64 (*raw_event)(u64); int max_events; int num_counters; int num_counters_fixed; @@ -426,28 +425,26 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event_attr *attr) return 0; } -static int x86_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc) +static int x86_pmu_hw_config(struct perf_event *event) { /* * Generate PMC IRQs: * (keep 'enabled' bit clear for now) */ - hwc->config = ARCH_PERFMON_EVENTSEL_INT; + event->hw.config = ARCH_PERFMON_EVENTSEL_INT; /* * Count user and OS events unless requested not to */ - if (!attr->exclude_user) - hwc->config |= ARCH_PERFMON_EVENTSEL_USR; - if (!attr->exclude_kernel) - hwc->config |= ARCH_PERFMON_EVENTSEL_OS; + if (!event->attr.exclude_user) + event->hw.config |= ARCH_PERFMON_EVENTSEL_USR; + if (!event->attr.exclude_kernel) + event->hw.config |= ARCH_PERFMON_EVENTSEL_OS; - return 0; -} + if (event->attr.type == PERF_TYPE_RAW) + event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK; -static u64 x86_pmu_raw_event(u64 hw_event) -{ - return hw_event & X86_RAW_EVENT_MASK; + return 0; } /* @@ -489,7 +486,7 @@ static int __hw_perf_event_init(struct perf_event *event) hwc->last_tag = ~0ULL; /* Processor specifics */ - err = x86_pmu.hw_config(attr, hwc); + err = x86_pmu.hw_config(event); if (err) return err; @@ -508,16 +505,8 @@ static int __hw_perf_event_init(struct perf_event *event) return -EOPNOTSUPP; } - /* - * Raw hw_event type provide the config in the hw_event structure - */ - if (attr->type == PERF_TYPE_RAW) { - hwc->config |= x86_pmu.raw_event(attr->config); - if ((hwc->config & ARCH_PERFMON_EVENTSEL_ANY) && - perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) - return -EACCES; + if (attr->type == PERF_TYPE_RAW) return 0; - } if (attr->type == PERF_TYPE_HW_CACHE) return set_ext_hw_attr(hwc, attr); diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 37e9517729df..bbd7339f08a9 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -111,9 +111,19 @@ static u64 amd_pmu_event_map(int hw_event) return amd_perfmon_event_map[hw_event]; } -static u64 amd_pmu_raw_event(u64 hw_event) +static int amd_pmu_hw_config(struct perf_event *event) { - return hw_event & AMD64_RAW_EVENT_MASK; + int ret = x86_pmu_hw_config(event); + + if (ret) + return ret; + + if (event->attr.type != PERF_TYPE_RAW) + return 0; + + event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK; + + return 0; } /* @@ -365,12 +375,11 @@ static __initconst struct x86_pmu amd_pmu = { .enable_all = x86_pmu_enable_all, .enable = x86_pmu_enable_event, .disable = x86_pmu_disable_event, - .hw_config = x86_hw_config, + .hw_config = amd_pmu_hw_config, .schedule_events = x86_schedule_events, .eventsel = MSR_K7_EVNTSEL0, .perfctr = MSR_K7_PERFCTR0, .event_map = amd_pmu_event_map, - .raw_event = amd_pmu_raw_event, .max_events = ARRAY_SIZE(amd_perfmon_event_map), .num_counters = 4, .cntval_bits = 48, diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index dfdd6f90fc8e..30bf10c55f1e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -758,6 +758,30 @@ intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event return x86_get_event_constraints(cpuc, event); } +static int intel_pmu_hw_config(struct perf_event *event) +{ + int ret = x86_pmu_hw_config(event); + + if (ret) + return ret; + + if (event->attr.type != PERF_TYPE_RAW) + return 0; + + if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY)) + return 0; + + if (x86_pmu.version < 3) + return -EINVAL; + + if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) + return -EACCES; + + event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY; + + return 0; +} + static __initconst struct x86_pmu core_pmu = { .name = "core", .handle_irq = x86_pmu_handle_irq, @@ -765,12 +789,11 @@ static __initconst struct x86_pmu core_pmu = { .enable_all = x86_pmu_enable_all, .enable = x86_pmu_enable_event, .disable = x86_pmu_disable_event, - .hw_config = x86_hw_config, + .hw_config = x86_pmu_hw_config, .schedule_events = x86_schedule_events, .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, .perfctr = MSR_ARCH_PERFMON_PERFCTR0, .event_map = intel_pmu_event_map, - .raw_event = x86_pmu_raw_event, .max_events = ARRAY_SIZE(intel_perfmon_event_map), .apic = 1, /* @@ -804,12 +827,11 @@ static __initconst struct x86_pmu intel_pmu = { .enable_all = intel_pmu_enable_all, .enable = intel_pmu_enable_event, .disable = intel_pmu_disable_event, - .hw_config = x86_hw_config, + .hw_config = intel_pmu_hw_config, .schedule_events = x86_schedule_events, .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, .perfctr = MSR_ARCH_PERFMON_PERFCTR0, .event_map = intel_pmu_event_map, - .raw_event = x86_pmu_raw_event, .max_events = ARRAY_SIZE(intel_perfmon_event_map), .apic = 1, /* diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 4139100404e8..acd237d29f11 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -419,20 +419,7 @@ static u64 p4_pmu_event_map(int hw_event) return config; } -/* - * We don't control raw events so it's up to the caller - * to pass sane values (and we don't count the thread number - * on HT machine but allow HT-compatible specifics to be - * passed on) - */ -static u64 p4_pmu_raw_event(u64 hw_event) -{ - return hw_event & - (p4_config_pack_escr(P4_ESCR_MASK_HT) | - p4_config_pack_cccr(P4_CCCR_MASK_HT)); -} - -static int p4_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc) +static int p4_hw_config(struct perf_event *event) { int cpu = raw_smp_processor_id(); u32 escr, cccr; @@ -444,11 +431,29 @@ static int p4_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc) */ cccr = p4_default_cccr_conf(cpu); - escr = p4_default_escr_conf(cpu, attr->exclude_kernel, attr->exclude_user); - hwc->config = p4_config_pack_escr(escr) | p4_config_pack_cccr(cccr); + escr = p4_default_escr_conf(cpu, event->attr.exclude_kernel, + event->attr.exclude_user); + event->hw.config = p4_config_pack_escr(escr) | + p4_config_pack_cccr(cccr); if (p4_ht_active() && p4_ht_thread(cpu)) - hwc->config = p4_set_ht_bit(hwc->config); + event->hw.config = p4_set_ht_bit(event->hw.config); + + if (event->attr.type != PERF_TYPE_RAW) + return 0; + + /* + * We don't control raw events so it's up to the caller + * to pass sane values (and we don't count the thread number + * on HT machine but allow HT-compatible specifics to be + * passed on) + * + * XXX: HT wide things should check perf_paranoid_cpu() && + * CAP_SYS_ADMIN + */ + event->hw.config |= event->attr.config & + (p4_config_pack_escr(P4_ESCR_MASK_HT) | + p4_config_pack_cccr(P4_CCCR_MASK_HT)); return 0; } @@ -785,7 +790,6 @@ static __initconst struct x86_pmu p4_pmu = { .eventsel = MSR_P4_BPU_CCCR0, .perfctr = MSR_P4_BPU_PERFCTR0, .event_map = p4_pmu_event_map, - .raw_event = p4_pmu_raw_event, .max_events = ARRAY_SIZE(p4_general_events), .get_event_constraints = x86_get_event_constraints, /* diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index 03c139a67baa..9123e8ec9958 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -91,12 +91,11 @@ static __initconst struct x86_pmu p6_pmu = { .enable_all = p6_pmu_enable_all, .enable = p6_pmu_enable_event, .disable = p6_pmu_disable_event, - .hw_config = x86_hw_config, + .hw_config = x86_pmu_hw_config, .schedule_events = x86_schedule_events, .eventsel = MSR_P6_EVNTSEL0, .perfctr = MSR_P6_PERFCTR0, .event_map = p6_pmu_event_map, - .raw_event = x86_pmu_raw_event, .max_events = ARRAY_SIZE(p6_perfmon_event_map), .apic = 1, .max_period = (1ULL << 31) - 1, -- cgit v1.2.3-59-g8ed1b From caaa8be3b6707cb9664e573a28b00f845ce9f32e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 29 Mar 2010 13:09:53 +0200 Subject: perf, x86: Fix __initconst vs const All variables that have __initconst should also be const. Suggested-by: Stephen Rothwell Signed-off-by: Peter Zijlstra LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_amd.c | 4 ++-- arch/x86/kernel/cpu/perf_event_intel.c | 12 ++++++------ arch/x86/kernel/cpu/perf_event_p4.c | 4 ++-- arch/x86/kernel/cpu/perf_event_p6.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index bbd7339f08a9..611df11ba15e 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -2,7 +2,7 @@ static DEFINE_RAW_SPINLOCK(amd_nb_lock); -static __initconst u64 amd_hw_cache_event_ids +static __initconst const u64 amd_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = @@ -368,7 +368,7 @@ static void amd_pmu_cpu_dead(int cpu) raw_spin_unlock(&amd_nb_lock); } -static __initconst struct x86_pmu amd_pmu = { +static __initconst const struct x86_pmu amd_pmu = { .name = "AMD", .handle_irq = x86_pmu_handle_irq, .disable_all = x86_pmu_disable_all, diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 30bf10c55f1e..1957e3f14c04 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -88,7 +88,7 @@ static u64 intel_pmu_event_map(int hw_event) return intel_perfmon_event_map[hw_event]; } -static __initconst u64 westmere_hw_cache_event_ids +static __initconst const u64 westmere_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = @@ -179,7 +179,7 @@ static __initconst u64 westmere_hw_cache_event_ids }, }; -static __initconst u64 nehalem_hw_cache_event_ids +static __initconst const u64 nehalem_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = @@ -270,7 +270,7 @@ static __initconst u64 nehalem_hw_cache_event_ids }, }; -static __initconst u64 core2_hw_cache_event_ids +static __initconst const u64 core2_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = @@ -361,7 +361,7 @@ static __initconst u64 core2_hw_cache_event_ids }, }; -static __initconst u64 atom_hw_cache_event_ids +static __initconst const u64 atom_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = @@ -782,7 +782,7 @@ static int intel_pmu_hw_config(struct perf_event *event) return 0; } -static __initconst struct x86_pmu core_pmu = { +static __initconst const struct x86_pmu core_pmu = { .name = "core", .handle_irq = x86_pmu_handle_irq, .disable_all = x86_pmu_disable_all, @@ -820,7 +820,7 @@ static void intel_pmu_cpu_dying(int cpu) fini_debug_store_on_cpu(cpu); } -static __initconst struct x86_pmu intel_pmu = { +static __initconst const struct x86_pmu intel_pmu = { .name = "Intel", .handle_irq = intel_pmu_handle_irq, .disable_all = intel_pmu_disable_all, diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index acd237d29f11..15367cce66bd 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -287,7 +287,7 @@ static struct p4_event_bind p4_event_bind_map[] = { p4_config_pack_cccr(cache_event | \ P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event)))) -static __initconst u64 p4_hw_cache_event_ids +static __initconst const u64 p4_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = @@ -780,7 +780,7 @@ done: return num ? -ENOSPC : 0; } -static __initconst struct x86_pmu p4_pmu = { +static __initconst const struct x86_pmu p4_pmu = { .name = "Netburst P4/Xeon", .handle_irq = p4_pmu_handle_irq, .disable_all = p4_pmu_disable_all, diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index 9123e8ec9958..34ba07be2cda 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -84,7 +84,7 @@ static void p6_pmu_enable_event(struct perf_event *event) (void)checking_wrmsrl(hwc->config_base + hwc->idx, val); } -static __initconst struct x86_pmu p6_pmu = { +static __initconst const struct x86_pmu p6_pmu = { .name = "p6", .handle_irq = x86_pmu_handle_irq, .disable_all = p6_pmu_disable_all, -- cgit v1.2.3-59-g8ed1b From 40b91cd10f000b4c4934e48e2e5c0bec66def144 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 29 Mar 2010 16:37:17 +0200 Subject: perf, x86: Add Nehalem programming quirk to Westmere According to the Xeon-5600 errata the Westmere suffers the same PMU programming bug as the original Nehalem did. Signed-off-by: Peter Zijlstra LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 1957e3f14c04..f168b4030d40 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -488,6 +488,7 @@ static void intel_pmu_enable_all(int added) * Workaround for: * Intel Errata AAK100 (model 26) * Intel Errata AAP53 (model 30) + * Intel Errata BD53 (model 44) * * These chips need to be 'reset' when adding counters by programming * the magic three (non counting) events 0x4300D2, 0x4300B1 and 0x4300B5 @@ -980,6 +981,7 @@ static __init int intel_pmu_init(void) intel_pmu_lbr_init_nhm(); x86_pmu.event_constraints = intel_westmere_event_constraints; + x86_pmu.enable_all = intel_pmu_nhm_enable_all; pr_cont("Westmere events, "); break; -- cgit v1.2.3-59-g8ed1b From 6f4dee06fbf0133917f3d76fa3fb50e18b10c1f5 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 18 Mar 2010 23:47:01 +0100 Subject: perf: Drop the frame reliablity check It is useless now that we have a pure stack frame walker, as given addr are always reliable. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 65e9c5efb618..353a174adb44 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1602,8 +1602,7 @@ static void backtrace_address(void *data, unsigned long addr, int reliable) { struct perf_callchain_entry *entry = data; - if (reliable) - callchain_store(entry, addr); + callchain_store(entry, addr); } static const struct stacktrace_ops backtrace_ops = { -- cgit v1.2.3-59-g8ed1b From 4f64625412be120cef9e9b97e88c406ec2c78027 Mon Sep 17 00:00:00 2001 From: Pauli Nieminen Date: Thu, 1 Apr 2010 12:45:01 +0000 Subject: arch/x86: Add array variants for setting memory to wc caching. Setting single memory pages at a time to wc takes a lot time in cache flush. To reduce number of cache flush set_pages_array_wc and set_memory_array_wc can be used to set multiple pages to WC with single cache flush. This improves allocation performance for wc cached pages in drm/ttm. CC: Suresh Siddha CC: Venkatesh Pallipadi Signed-off-by: Pauli Nieminen Signed-off-by: Dave Airlie --- arch/x86/include/asm/cacheflush.h | 2 ++ arch/x86/mm/pageattr.c | 53 +++++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h index 634c40a739a6..d92d63a6286b 100644 --- a/arch/x86/include/asm/cacheflush.h +++ b/arch/x86/include/asm/cacheflush.h @@ -139,9 +139,11 @@ int set_memory_np(unsigned long addr, int numpages); int set_memory_4k(unsigned long addr, int numpages); int set_memory_array_uc(unsigned long *addr, int addrinarray); +int set_memory_array_wc(unsigned long *addr, int addrinarray); int set_memory_array_wb(unsigned long *addr, int addrinarray); int set_pages_array_uc(struct page **pages, int addrinarray); +int set_pages_array_wc(struct page **pages, int addrinarray); int set_pages_array_wb(struct page **pages, int addrinarray); /* diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index cf07c26d9a4a..0c98a7583bfa 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -997,7 +997,8 @@ out_err: } EXPORT_SYMBOL(set_memory_uc); -int set_memory_array_uc(unsigned long *addr, int addrinarray) +int _set_memory_array(unsigned long *addr, int addrinarray, + unsigned long new_type) { int i, j; int ret; @@ -1007,13 +1008,19 @@ int set_memory_array_uc(unsigned long *addr, int addrinarray) */ for (i = 0; i < addrinarray; i++) { ret = reserve_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE, - _PAGE_CACHE_UC_MINUS, NULL); + new_type, NULL); if (ret) goto out_free; } ret = change_page_attr_set(addr, addrinarray, __pgprot(_PAGE_CACHE_UC_MINUS), 1); + + if (!ret && new_type == _PAGE_CACHE_WC) + ret = change_page_attr_set_clr(addr, addrinarray, + __pgprot(_PAGE_CACHE_WC), + __pgprot(_PAGE_CACHE_MASK), + 0, CPA_ARRAY, NULL); if (ret) goto out_free; @@ -1025,8 +1032,19 @@ out_free: return ret; } + +int set_memory_array_uc(unsigned long *addr, int addrinarray) +{ + return _set_memory_array(addr, addrinarray, _PAGE_CACHE_UC_MINUS); +} EXPORT_SYMBOL(set_memory_array_uc); +int set_memory_array_wc(unsigned long *addr, int addrinarray) +{ + return _set_memory_array(addr, addrinarray, _PAGE_CACHE_WC); +} +EXPORT_SYMBOL(set_memory_array_wc); + int _set_memory_wc(unsigned long addr, int numpages) { int ret; @@ -1153,26 +1171,34 @@ int set_pages_uc(struct page *page, int numpages) } EXPORT_SYMBOL(set_pages_uc); -int set_pages_array_uc(struct page **pages, int addrinarray) +static int _set_pages_array(struct page **pages, int addrinarray, + unsigned long new_type) { unsigned long start; unsigned long end; int i; int free_idx; + int ret; for (i = 0; i < addrinarray; i++) { if (PageHighMem(pages[i])) continue; start = page_to_pfn(pages[i]) << PAGE_SHIFT; end = start + PAGE_SIZE; - if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL)) + if (reserve_memtype(start, end, new_type, NULL)) goto err_out; } - if (cpa_set_pages_array(pages, addrinarray, - __pgprot(_PAGE_CACHE_UC_MINUS)) == 0) { - return 0; /* Success */ - } + ret = cpa_set_pages_array(pages, addrinarray, + __pgprot(_PAGE_CACHE_UC_MINUS)); + if (!ret && new_type == _PAGE_CACHE_WC) + ret = change_page_attr_set_clr(NULL, addrinarray, + __pgprot(_PAGE_CACHE_WC), + __pgprot(_PAGE_CACHE_MASK), + 0, CPA_PAGES_ARRAY, pages); + if (ret) + goto err_out; + return 0; /* Success */ err_out: free_idx = i; for (i = 0; i < free_idx; i++) { @@ -1184,8 +1210,19 @@ err_out: } return -EINVAL; } + +int set_pages_array_uc(struct page **pages, int addrinarray) +{ + return _set_pages_array(pages, addrinarray, _PAGE_CACHE_UC_MINUS); +} EXPORT_SYMBOL(set_pages_array_uc); +int set_pages_array_wc(struct page **pages, int addrinarray) +{ + return _set_pages_array(pages, addrinarray, _PAGE_CACHE_WC); +} +EXPORT_SYMBOL(set_pages_array_wc); + int set_pages_wb(struct page *page, int numpages) { unsigned long addr = (unsigned long)page_address(page); -- cgit v1.2.3-59-g8ed1b From 1527bc8b928dd1399c3d3467dd47d9ede210978a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 1 Feb 2010 15:03:07 +0100 Subject: bitops: Optimize hweight() by making use of compile-time evaluation Rename the extisting runtime hweight() implementations to __arch_hweight(), rename the compile-time versions to __const_hweight() and then have hweight() pick between them. Suggested-by: H. Peter Anvin Signed-off-by: Peter Zijlstra LKML-Reference: <20100318111929.GB11152@aftab> Acked-by: H. Peter Anvin LKML-Reference: <1265028224.24455.154.camel@laptop> Signed-off-by: H. Peter Anvin --- arch/alpha/include/asm/bitops.h | 18 +++++++------ arch/ia64/include/asm/bitops.h | 11 ++++---- arch/sparc/include/asm/bitops_64.h | 11 ++++---- include/asm-generic/bitops/arch_hweight.h | 11 ++++++++ include/asm-generic/bitops/const_hweight.h | 42 ++++++++++++++++++++++++++++++ include/asm-generic/bitops/hweight.h | 8 ++---- include/linux/bitops.h | 25 ------------------ lib/hweight.c | 19 +++++++------- 8 files changed, 87 insertions(+), 58 deletions(-) create mode 100644 include/asm-generic/bitops/arch_hweight.h create mode 100644 include/asm-generic/bitops/const_hweight.h (limited to 'arch') diff --git a/arch/alpha/include/asm/bitops.h b/arch/alpha/include/asm/bitops.h index 15f3ae25c511..296da1d5ed57 100644 --- a/arch/alpha/include/asm/bitops.h +++ b/arch/alpha/include/asm/bitops.h @@ -405,29 +405,31 @@ static inline int fls(int x) #if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67) /* Whee. EV67 can calculate it directly. */ -static inline unsigned long hweight64(unsigned long w) +static inline unsigned long __arch_hweight64(unsigned long w) { return __kernel_ctpop(w); } -static inline unsigned int hweight32(unsigned int w) +static inline unsigned int __arch_weight32(unsigned int w) { - return hweight64(w); + return __arch_hweight64(w); } -static inline unsigned int hweight16(unsigned int w) +static inline unsigned int __arch_hweight16(unsigned int w) { - return hweight64(w & 0xffff); + return __arch_hweight64(w & 0xffff); } -static inline unsigned int hweight8(unsigned int w) +static inline unsigned int __arch_hweight8(unsigned int w) { - return hweight64(w & 0xff); + return __arch_hweight64(w & 0xff); } #else -#include +#include #endif +#include + #endif /* __KERNEL__ */ #include diff --git a/arch/ia64/include/asm/bitops.h b/arch/ia64/include/asm/bitops.h index 6ebc229a1c51..9da3df6f1a52 100644 --- a/arch/ia64/include/asm/bitops.h +++ b/arch/ia64/include/asm/bitops.h @@ -437,17 +437,18 @@ __fls (unsigned long x) * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word */ -static __inline__ unsigned long -hweight64 (unsigned long x) +static __inline__ unsigned long __arch_hweight64(unsigned long x) { unsigned long result; result = ia64_popcnt(x); return result; } -#define hweight32(x) (unsigned int) hweight64((x) & 0xfffffffful) -#define hweight16(x) (unsigned int) hweight64((x) & 0xfffful) -#define hweight8(x) (unsigned int) hweight64((x) & 0xfful) +#define __arch_hweight32(x) ((unsigned int) __arch_hweight64((x) & 0xfffffffful)) +#define __arch_hweight16(x) ((unsigned int) __arch_hweight64((x) & 0xfffful)) +#define __arch_hweight8(x) ((unsigned int) __arch_hweight64((x) & 0xfful)) + +#include #endif /* __KERNEL__ */ diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h index e72ac9cdfb98..766121a67a24 100644 --- a/arch/sparc/include/asm/bitops_64.h +++ b/arch/sparc/include/asm/bitops_64.h @@ -44,7 +44,7 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr); #ifdef ULTRA_HAS_POPULATION_COUNT -static inline unsigned int hweight64(unsigned long w) +static inline unsigned int __arch_hweight64(unsigned long w) { unsigned int res; @@ -52,7 +52,7 @@ static inline unsigned int hweight64(unsigned long w) return res; } -static inline unsigned int hweight32(unsigned int w) +static inline unsigned int __arch_hweight32(unsigned int w) { unsigned int res; @@ -60,7 +60,7 @@ static inline unsigned int hweight32(unsigned int w) return res; } -static inline unsigned int hweight16(unsigned int w) +static inline unsigned int __arch_hweight16(unsigned int w) { unsigned int res; @@ -68,7 +68,7 @@ static inline unsigned int hweight16(unsigned int w) return res; } -static inline unsigned int hweight8(unsigned int w) +static inline unsigned int __arch_hweight8(unsigned int w) { unsigned int res; @@ -78,9 +78,10 @@ static inline unsigned int hweight8(unsigned int w) #else -#include +#include #endif +#include #include #endif /* __KERNEL__ */ diff --git a/include/asm-generic/bitops/arch_hweight.h b/include/asm-generic/bitops/arch_hweight.h new file mode 100644 index 000000000000..3a7be842cdce --- /dev/null +++ b/include/asm-generic/bitops/arch_hweight.h @@ -0,0 +1,11 @@ +#ifndef _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_ +#define _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_ + +#include + +extern unsigned int __arch_hweight32(unsigned int w); +extern unsigned int __arch_hweight16(unsigned int w); +extern unsigned int __arch_hweight8(unsigned int w); +extern unsigned long __arch_hweight64(__u64 w); + +#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */ diff --git a/include/asm-generic/bitops/const_hweight.h b/include/asm-generic/bitops/const_hweight.h new file mode 100644 index 000000000000..fa2a50b7ee66 --- /dev/null +++ b/include/asm-generic/bitops/const_hweight.h @@ -0,0 +1,42 @@ +#ifndef _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_ +#define _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_ + +/* + * Compile time versions of __arch_hweightN() + */ +#define __const_hweight8(w) \ + ( (!!((w) & (1ULL << 0))) + \ + (!!((w) & (1ULL << 1))) + \ + (!!((w) & (1ULL << 2))) + \ + (!!((w) & (1ULL << 3))) + \ + (!!((w) & (1ULL << 4))) + \ + (!!((w) & (1ULL << 5))) + \ + (!!((w) & (1ULL << 6))) + \ + (!!((w) & (1ULL << 7))) ) + +#define __const_hweight16(w) (__const_hweight8(w) + __const_hweight8((w) >> 8 )) +#define __const_hweight32(w) (__const_hweight16(w) + __const_hweight16((w) >> 16)) +#define __const_hweight64(w) (__const_hweight32(w) + __const_hweight32((w) >> 32)) + +/* + * Generic interface. + */ +#define hweight8(w) (__builtin_constant_p(w) ? __const_hweight8(w) : __arch_hweight8(w)) +#define hweight16(w) (__builtin_constant_p(w) ? __const_hweight16(w) : __arch_hweight16(w)) +#define hweight32(w) (__builtin_constant_p(w) ? __const_hweight32(w) : __arch_hweight32(w)) +#define hweight64(w) (__builtin_constant_p(w) ? __const_hweight64(w) : __arch_hweight64(w)) + +/* + * Interface for known constant arguments + */ +#define HWEIGHT8(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight8(w)) +#define HWEIGHT16(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight16(w)) +#define HWEIGHT32(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight32(w)) +#define HWEIGHT64(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight64(w)) + +/* + * Type invariant interface to the compile time constant hweight functions. + */ +#define HWEIGHT(w) HWEIGHT64((u64)w) + +#endif /* _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_ */ diff --git a/include/asm-generic/bitops/hweight.h b/include/asm-generic/bitops/hweight.h index fbbc383771da..a94d6519c7ed 100644 --- a/include/asm-generic/bitops/hweight.h +++ b/include/asm-generic/bitops/hweight.h @@ -1,11 +1,7 @@ #ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_ #define _ASM_GENERIC_BITOPS_HWEIGHT_H_ -#include - -extern unsigned int hweight32(unsigned int w); -extern unsigned int hweight16(unsigned int w); -extern unsigned int hweight8(unsigned int w); -extern unsigned long hweight64(__u64 w); +#include +#include #endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */ diff --git a/include/linux/bitops.h b/include/linux/bitops.h index b79389879238..c55d5bc4ee58 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -47,31 +47,6 @@ static inline unsigned long hweight_long(unsigned long w) return sizeof(w) == 4 ? hweight32(w) : hweight64(w); } -/* - * Clearly slow versions of the hweightN() functions, their benefit is - * of course compile time evaluation of constant arguments. - */ -#define HWEIGHT8(w) \ - ( BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + \ - (!!((w) & (1ULL << 0))) + \ - (!!((w) & (1ULL << 1))) + \ - (!!((w) & (1ULL << 2))) + \ - (!!((w) & (1ULL << 3))) + \ - (!!((w) & (1ULL << 4))) + \ - (!!((w) & (1ULL << 5))) + \ - (!!((w) & (1ULL << 6))) + \ - (!!((w) & (1ULL << 7))) ) - -#define HWEIGHT16(w) (HWEIGHT8(w) + HWEIGHT8((w) >> 8)) -#define HWEIGHT32(w) (HWEIGHT16(w) + HWEIGHT16((w) >> 16)) -#define HWEIGHT64(w) (HWEIGHT32(w) + HWEIGHT32((w) >> 32)) - -/* - * Type invariant version that simply casts things to the - * largest type. - */ -#define HWEIGHT(w) HWEIGHT64((u64)(w)) - /** * rol32 - rotate a 32-bit value left * @word: value to rotate diff --git a/lib/hweight.c b/lib/hweight.c index 63ee4eb1228d..a6927e76840f 100644 --- a/lib/hweight.c +++ b/lib/hweight.c @@ -9,7 +9,7 @@ * The Hamming Weight of a number is the total number of bits set in it. */ -unsigned int hweight32(unsigned int w) +unsigned int __arch_hweight32(unsigned int w) { #ifdef ARCH_HAS_FAST_MULTIPLIER w -= (w >> 1) & 0x55555555; @@ -24,29 +24,30 @@ unsigned int hweight32(unsigned int w) return (res + (res >> 16)) & 0x000000FF; #endif } -EXPORT_SYMBOL(hweight32); +EXPORT_SYMBOL(__arch_hweight32); -unsigned int hweight16(unsigned int w) +unsigned int __arch_hweight16(unsigned int w) { unsigned int res = w - ((w >> 1) & 0x5555); res = (res & 0x3333) + ((res >> 2) & 0x3333); res = (res + (res >> 4)) & 0x0F0F; return (res + (res >> 8)) & 0x00FF; } -EXPORT_SYMBOL(hweight16); +EXPORT_SYMBOL(__arch_hweight16); -unsigned int hweight8(unsigned int w) +unsigned int __arch_hweight8(unsigned int w) { unsigned int res = w - ((w >> 1) & 0x55); res = (res & 0x33) + ((res >> 2) & 0x33); return (res + (res >> 4)) & 0x0F; } -EXPORT_SYMBOL(hweight8); +EXPORT_SYMBOL(__arch_hweight8); -unsigned long hweight64(__u64 w) +unsigned long __arch_hweight64(__u64 w) { #if BITS_PER_LONG == 32 - return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); + return __arch_hweight32((unsigned int)(w >> 32)) + + __arch_hweight32((unsigned int)w); #elif BITS_PER_LONG == 64 #ifdef ARCH_HAS_FAST_MULTIPLIER w -= (w >> 1) & 0x5555555555555555ul; @@ -63,4 +64,4 @@ unsigned long hweight64(__u64 w) #endif #endif } -EXPORT_SYMBOL(hweight64); +EXPORT_SYMBOL(__arch_hweight64); -- cgit v1.2.3-59-g8ed1b From d61931d89be506372d01a90d1755f6d0a9fafe2d Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 5 Mar 2010 17:34:46 +0100 Subject: x86: Add optimized popcnt variants Add support for the hardware version of the Hamming weight function, popcnt, present in CPUs which advertize it under CPUID, Function 0x0000_0001_ECX[23]. On CPUs which don't support it, we fallback to the default lib/hweight.c sw versions. A synthetic benchmark comparing popcnt with __sw_hweight64 showed almost a 3x speedup on a F10h machine. Signed-off-by: Borislav Petkov LKML-Reference: <20100318112015.GC11152@aftab> Signed-off-by: H. Peter Anvin --- arch/x86/Kconfig | 5 +++ arch/x86/include/asm/alternative.h | 9 +++-- arch/x86/include/asm/arch_hweight.h | 59 +++++++++++++++++++++++++++++++ arch/x86/include/asm/bitops.h | 4 ++- include/asm-generic/bitops/arch_hweight.h | 22 +++++++++--- lib/Makefile | 3 ++ lib/hweight.c | 20 +++++------ scripts/Makefile.lib | 4 +++ 8 files changed, 108 insertions(+), 18 deletions(-) create mode 100644 arch/x86/include/asm/arch_hweight.h (limited to 'arch') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 0eacb1ffb421..89d8c54cdd37 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -238,6 +238,11 @@ config X86_32_LAZY_GS def_bool y depends on X86_32 && !CC_STACKPROTECTOR +config ARCH_HWEIGHT_CFLAGS + string + default "-fcall-saved-ecx -fcall-saved-edx" if X86_32 + default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64 + config KTIME_SCALAR def_bool X86_32 source "init/Kconfig" diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index b09ec55650b3..67dae51e7fd0 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -39,9 +39,6 @@ #define LOCK_PREFIX "" #endif -/* This must be included *after* the definition of LOCK_PREFIX */ -#include - struct alt_instr { u8 *instr; /* original instruction */ u8 *replacement; @@ -95,6 +92,12 @@ static inline int alternatives_text_reserved(void *start, void *end) "663:\n\t" newinstr "\n664:\n" /* replacement */ \ ".previous" +/* + * This must be included *after* the definition of ALTERNATIVE due to + * + */ +#include + /* * Alternative instructions for different CPU types or capabilities. * diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h new file mode 100644 index 000000000000..d1fc3c219ae6 --- /dev/null +++ b/arch/x86/include/asm/arch_hweight.h @@ -0,0 +1,59 @@ +#ifndef _ASM_X86_HWEIGHT_H +#define _ASM_X86_HWEIGHT_H + +#ifdef CONFIG_64BIT +/* popcnt %rdi, %rax */ +#define POPCNT ".byte 0xf3,0x48,0x0f,0xb8,0xc7" +#define REG_IN "D" +#define REG_OUT "a" +#else +/* popcnt %eax, %eax */ +#define POPCNT ".byte 0xf3,0x0f,0xb8,0xc0" +#define REG_IN "a" +#define REG_OUT "a" +#endif + +/* + * __sw_hweightXX are called from within the alternatives below + * and callee-clobbered registers need to be taken care of. See + * ARCH_HWEIGHT_CFLAGS in for the respective + * compiler switches. + */ +static inline unsigned int __arch_hweight32(unsigned int w) +{ + unsigned int res = 0; + + asm (ALTERNATIVE("call __sw_hweight32", POPCNT, X86_FEATURE_POPCNT) + : "="REG_OUT (res) + : REG_IN (w)); + + return res; +} + +static inline unsigned int __arch_hweight16(unsigned int w) +{ + return __arch_hweight32(w & 0xffff); +} + +static inline unsigned int __arch_hweight8(unsigned int w) +{ + return __arch_hweight32(w & 0xff); +} + +static inline unsigned long __arch_hweight64(__u64 w) +{ + unsigned long res = 0; + +#ifdef CONFIG_X86_32 + return __arch_hweight32((u32)w) + + __arch_hweight32((u32)(w >> 32)); +#else + asm (ALTERNATIVE("call __sw_hweight64", POPCNT, X86_FEATURE_POPCNT) + : "="REG_OUT (res) + : REG_IN (w)); +#endif /* CONFIG_X86_32 */ + + return res; +} + +#endif diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 02b47a603fc8..545776efeb16 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -444,7 +444,9 @@ static inline int fls(int x) #define ARCH_HAS_FAST_MULTIPLIER 1 -#include +#include + +#include #endif /* __KERNEL__ */ diff --git a/include/asm-generic/bitops/arch_hweight.h b/include/asm-generic/bitops/arch_hweight.h index 3a7be842cdce..9a81c1e9436c 100644 --- a/include/asm-generic/bitops/arch_hweight.h +++ b/include/asm-generic/bitops/arch_hweight.h @@ -3,9 +3,23 @@ #include -extern unsigned int __arch_hweight32(unsigned int w); -extern unsigned int __arch_hweight16(unsigned int w); -extern unsigned int __arch_hweight8(unsigned int w); -extern unsigned long __arch_hweight64(__u64 w); +inline unsigned int __arch_hweight32(unsigned int w) +{ + return __sw_hweight32(w); +} +inline unsigned int __arch_hweight16(unsigned int w) +{ + return __sw_hweight16(w); +} + +inline unsigned int __arch_hweight8(unsigned int w) +{ + return __sw_hweight8(w); +} + +inline unsigned long __arch_hweight64(__u64 w) +{ + return __sw_hweight64(w); +} #endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */ diff --git a/lib/Makefile b/lib/Makefile index 2e152aed7198..abe63a8ad143 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -39,7 +39,10 @@ lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_GENERIC_FIND_FIRST_BIT) += find_next_bit.o lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o obj-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o + +CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o + obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o obj-$(CONFIG_BTREE) += btree.o obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o diff --git a/lib/hweight.c b/lib/hweight.c index a6927e76840f..3c79d50814cf 100644 --- a/lib/hweight.c +++ b/lib/hweight.c @@ -9,7 +9,7 @@ * The Hamming Weight of a number is the total number of bits set in it. */ -unsigned int __arch_hweight32(unsigned int w) +unsigned int __sw_hweight32(unsigned int w) { #ifdef ARCH_HAS_FAST_MULTIPLIER w -= (w >> 1) & 0x55555555; @@ -24,30 +24,30 @@ unsigned int __arch_hweight32(unsigned int w) return (res + (res >> 16)) & 0x000000FF; #endif } -EXPORT_SYMBOL(__arch_hweight32); +EXPORT_SYMBOL(__sw_hweight32); -unsigned int __arch_hweight16(unsigned int w) +unsigned int __sw_hweight16(unsigned int w) { unsigned int res = w - ((w >> 1) & 0x5555); res = (res & 0x3333) + ((res >> 2) & 0x3333); res = (res + (res >> 4)) & 0x0F0F; return (res + (res >> 8)) & 0x00FF; } -EXPORT_SYMBOL(__arch_hweight16); +EXPORT_SYMBOL(__sw_hweight16); -unsigned int __arch_hweight8(unsigned int w) +unsigned int __sw_hweight8(unsigned int w) { unsigned int res = w - ((w >> 1) & 0x55); res = (res & 0x33) + ((res >> 2) & 0x33); return (res + (res >> 4)) & 0x0F; } -EXPORT_SYMBOL(__arch_hweight8); +EXPORT_SYMBOL(__sw_hweight8); -unsigned long __arch_hweight64(__u64 w) +unsigned long __sw_hweight64(__u64 w) { #if BITS_PER_LONG == 32 - return __arch_hweight32((unsigned int)(w >> 32)) + - __arch_hweight32((unsigned int)w); + return __sw_hweight32((unsigned int)(w >> 32)) + + __sw_hweight32((unsigned int)w); #elif BITS_PER_LONG == 64 #ifdef ARCH_HAS_FAST_MULTIPLIER w -= (w >> 1) & 0x5555555555555555ul; @@ -64,4 +64,4 @@ unsigned long __arch_hweight64(__u64 w) #endif #endif } -EXPORT_SYMBOL(__arch_hweight64); +EXPORT_SYMBOL(__sw_hweight64); diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index f9bdf264473d..cbcd654215e6 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -245,3 +245,7 @@ quiet_cmd_lzo = LZO $@ cmd_lzo = (cat $(filter-out FORCE,$^) | \ lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ (rm -f $@ ; false) + +# misc stuff +# --------------------------------------------------------------------------- +quote:=" -- cgit v1.2.3-59-g8ed1b From 459569145516f7967b916c57445feb02c600668c Mon Sep 17 00:00:00 2001 From: John Linn Date: Tue, 6 Apr 2010 11:43:28 +0000 Subject: Add non-Virtex5 support for LL TEMAC driver This patch adds support for using the LL TEMAC Ethernet driver on non-Virtex 5 platforms by adding support for accessing the Soft DMA registers as if they were memory mapped instead of solely through the DCR's (available on the Virtex 5). The patch also updates the driver so that it runs on the MicroBlaze. The changes were tested on the PowerPC 440, PowerPC 405, and the MicroBlaze platforms. Signed-off-by: John Tyner Signed-off-by: John Linn Signed-off-by: David S. Miller --- arch/microblaze/include/asm/system.h | 11 +++ drivers/net/Kconfig | 2 +- drivers/net/ll_temac.h | 14 +++- drivers/net/ll_temac_main.c | 137 ++++++++++++++++++++++++++--------- 4 files changed, 126 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h index 157970688b2a..88fc92cdd8ce 100644 --- a/arch/microblaze/include/asm/system.h +++ b/arch/microblaze/include/asm/system.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -93,4 +94,14 @@ extern struct dentry *of_debugfs_root; #define arch_align_stack(x) (x) +/* + * MicroBlaze doesn't handle unaligned accesses in hardware. + * + * Based on this we force the IP header alignment in network drivers. + * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining + * cacheline alignment of buffers. + */ +#define NET_IP_ALIGN 2 +#define NET_SKB_PAD L1_CACHE_BYTES + #endif /* _ASM_MICROBLAZE_SYSTEM_H */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a55bff26a264..20e2dec1d534 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2435,8 +2435,8 @@ config MV643XX_ETH config XILINX_LL_TEMAC tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver" + depends on PPC || MICROBLAZE select PHYLIB - depends on PPC_DCR_NATIVE help This driver supports the Xilinx 10/100/1000 LocalLink TEMAC core used in Xilinx Spartan and Virtex FPGAs diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h index 1af66a1e6911..c03358434acb 100644 --- a/drivers/net/ll_temac.h +++ b/drivers/net/ll_temac.h @@ -5,8 +5,11 @@ #include #include #include + +#ifdef CONFIG_PPC_DCR #include #include +#endif /* packet size info */ #define XTE_HDR_SIZE 14 /* size of Ethernet header */ @@ -290,9 +293,6 @@ This option defaults to enabled (set) */ #define TX_CONTROL_CALC_CSUM_MASK 1 -#define XTE_ALIGN 32 -#define BUFFER_ALIGN(adr) ((XTE_ALIGN - ((u32) adr)) % XTE_ALIGN) - #define MULTICAST_CAM_TABLE_NUM 4 /* TX/RX CURDESC_PTR points to first descriptor */ @@ -335,9 +335,15 @@ struct temac_local { struct mii_bus *mii_bus; /* MII bus reference */ int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */ - /* IO registers and IRQs */ + /* IO registers, dma functions and IRQs */ void __iomem *regs; + void __iomem *sdma_regs; +#ifdef CONFIG_PPC_DCR dcr_host_t sdma_dcrs; +#endif + u32 (*dma_in)(struct temac_local *, int); + void (*dma_out)(struct temac_local *, int, u32); + int tx_irq; int rx_irq; int emac_num; diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 30474d6b15c3..b6edb2fd0a8a 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -20,9 +20,6 @@ * or rx, so this should be okay. * * TODO: - * - Fix driver to work on more than just Virtex5. Right now the driver - * assumes that the locallink DMA registers are accessed via DCR - * instructions. * - Factor out locallink DMA code into separate driver * - Fix multicast assignment. * - Fix support for hardware checksumming. @@ -115,16 +112,85 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value) temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); } +/** + * temac_dma_in32 - Memory mapped DMA read, this function expects a + * register input that is based on DCR word addresses which + * are then converted to memory mapped byte addresses + */ static u32 temac_dma_in32(struct temac_local *lp, int reg) { - return dcr_read(lp->sdma_dcrs, reg); + return in_be32((u32 *)(lp->sdma_regs + (reg << 2))); } +/** + * temac_dma_out32 - Memory mapped DMA read, this function expects a + * register input that is based on DCR word addresses which + * are then converted to memory mapped byte addresses + */ static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) +{ + out_be32((u32 *)(lp->sdma_regs + (reg << 2)), value); +} + +/* DMA register access functions can be DCR based or memory mapped. + * The PowerPC 440 is DCR based, the PowerPC 405 and MicroBlaze are both + * memory mapped. + */ +#ifdef CONFIG_PPC_DCR + +/** + * temac_dma_dcr_in32 - DCR based DMA read + */ +static u32 temac_dma_dcr_in(struct temac_local *lp, int reg) +{ + return dcr_read(lp->sdma_dcrs, reg); +} + +/** + * temac_dma_dcr_out32 - DCR based DMA write + */ +static void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value) { dcr_write(lp->sdma_dcrs, reg, value); } +/** + * temac_dcr_setup - If the DMA is DCR based, then setup the address and + * I/O functions + */ +static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, + struct device_node *np) +{ + unsigned int dcrs; + + /* setup the dcr address mapping if it's in the device tree */ + + dcrs = dcr_resource_start(np, 0); + if (dcrs != 0) { + lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); + lp->dma_in = temac_dma_dcr_in; + lp->dma_out = temac_dma_dcr_out; + dev_dbg(&op->dev, "DCR base: %x\n", dcrs); + return 0; + } + /* no DCR in the device tree, indicate a failure */ + return -1; +} + +#else + +/* + * temac_dcr_setup - This is a stub for when DCR is not supported, + * such as with MicroBlaze + */ +static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, + struct device_node *np) +{ + return -1; +} + +#endif + /** * temac_dma_bd_init - Setup buffer descriptor rings */ @@ -155,14 +221,14 @@ static int temac_dma_bd_init(struct net_device *ndev) lp->rx_bd_v[i].next = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM); - skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE - + XTE_ALIGN, GFP_ATOMIC); + skb = netdev_alloc_skb_ip_align(ndev, + XTE_MAX_JUMBO_FRAME_SIZE); + if (skb == 0) { dev_err(&ndev->dev, "alloc_skb error %d\n", i); return -1; } lp->rx_skb[i] = skb; - skb_reserve(skb, BUFFER_ALIGN(skb->data)); /* returns physical address of skb->data */ lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, skb->data, @@ -172,23 +238,23 @@ static int temac_dma_bd_init(struct net_device *ndev) lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND; } - temac_dma_out32(lp, TX_CHNL_CTRL, 0x10220400 | + lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 | CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN); /* 0x10220483 */ /* 0x00100483 */ - temac_dma_out32(lp, RX_CHNL_CTRL, 0xff010000 | + lp->dma_out(lp, RX_CHNL_CTRL, 0xff010000 | CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN | CHNL_CTRL_IRQ_IOE); /* 0xff010283 */ - temac_dma_out32(lp, RX_CURDESC_PTR, lp->rx_bd_p); - temac_dma_out32(lp, RX_TAILDESC_PTR, + lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p); + lp->dma_out(lp, RX_TAILDESC_PTR, lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); - temac_dma_out32(lp, TX_CURDESC_PTR, lp->tx_bd_p); + lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); return 0; } @@ -426,9 +492,9 @@ static void temac_device_reset(struct net_device *ndev) temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK); /* Reset Local Link (DMA) */ - temac_dma_out32(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); + lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); timeout = 1000; - while (temac_dma_in32(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { + while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { udelay(1); if (--timeout == 0) { dev_err(&ndev->dev, @@ -436,7 +502,7 @@ static void temac_device_reset(struct net_device *ndev) break; } } - temac_dma_out32(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); + lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); temac_dma_bd_init(ndev); @@ -597,7 +663,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) lp->tx_bd_tail = 0; /* Kick off the transfer */ - temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ + lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ return NETDEV_TX_OK; } @@ -639,16 +705,15 @@ static void ll_temac_recv(struct net_device *ndev) ndev->stats.rx_packets++; ndev->stats.rx_bytes += length; - new_skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN, - GFP_ATOMIC); + new_skb = netdev_alloc_skb_ip_align(ndev, + XTE_MAX_JUMBO_FRAME_SIZE); + if (new_skb == 0) { dev_err(&ndev->dev, "no memory for new sk_buff\n"); spin_unlock_irqrestore(&lp->rx_lock, flags); return; } - skb_reserve(new_skb, BUFFER_ALIGN(new_skb->data)); - cur_p->app0 = STS_CTRL_APP0_IRQONEND; cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, XTE_MAX_JUMBO_FRAME_SIZE, @@ -663,7 +728,7 @@ static void ll_temac_recv(struct net_device *ndev) cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; bdstat = cur_p->app0; } - temac_dma_out32(lp, RX_TAILDESC_PTR, tail_p); + lp->dma_out(lp, RX_TAILDESC_PTR, tail_p); spin_unlock_irqrestore(&lp->rx_lock, flags); } @@ -674,8 +739,8 @@ static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) struct temac_local *lp = netdev_priv(ndev); unsigned int status; - status = temac_dma_in32(lp, TX_IRQ_REG); - temac_dma_out32(lp, TX_IRQ_REG, status); + status = lp->dma_in(lp, TX_IRQ_REG); + lp->dma_out(lp, TX_IRQ_REG, status); if (status & (IRQ_COAL | IRQ_DLY)) temac_start_xmit_done(lp->ndev); @@ -692,8 +757,8 @@ static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev) unsigned int status; /* Read and clear the status registers */ - status = temac_dma_in32(lp, RX_IRQ_REG); - temac_dma_out32(lp, RX_IRQ_REG, status); + status = lp->dma_in(lp, RX_IRQ_REG); + lp->dma_out(lp, RX_IRQ_REG, status); if (status & (IRQ_COAL | IRQ_DLY)) ll_temac_recv(lp->ndev); @@ -794,7 +859,7 @@ static ssize_t temac_show_llink_regs(struct device *dev, int i, len = 0; for (i = 0; i < 0x11; i++) - len += sprintf(buf + len, "%.8x%s", temac_dma_in32(lp, i), + len += sprintf(buf + len, "%.8x%s", lp->dma_in(lp, i), (i % 8) == 7 ? "\n" : " "); len += sprintf(buf + len, "\n"); @@ -820,7 +885,6 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) struct net_device *ndev; const void *addr; int size, rc = 0; - unsigned int dcrs; /* Init network device structure */ ndev = alloc_etherdev(sizeof(*lp)); @@ -870,13 +934,20 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) goto nodev; } - dcrs = dcr_resource_start(np, 0); - if (dcrs == 0) { - dev_err(&op->dev, "could not get DMA register address\n"); - goto nodev; + /* Setup the DMA register accesses, could be DCR or memory mapped */ + if (temac_dcr_setup(lp, op, np)) { + + /* no DCR in the device tree, try non-DCR */ + lp->sdma_regs = of_iomap(np, 0); + if (lp->sdma_regs) { + lp->dma_in = temac_dma_in32; + lp->dma_out = temac_dma_out32; + dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs); + } else { + dev_err(&op->dev, "unable to map DMA registers\n"); + goto nodev; + } } - lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); - dev_dbg(&op->dev, "DCR base: %x\n", dcrs); lp->rx_irq = irq_of_parse_and_map(np, 0); lp->tx_irq = irq_of_parse_and_map(np, 1); -- cgit v1.2.3-59-g8ed1b From 58706ef96fa10edad1ce492313c8314cd5916fbe Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Fri, 29 Jan 2010 14:18:20 +0000 Subject: powerpc: Add a new zImage for maple using a different link address The maple platform failed to load because it's firmware could not take a link address of 0x4000000. A new platform type with a link address of 0x400000 had to be created for the maple. Signed-off-by: Corey Minyard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/boot/Makefile | 4 ++-- arch/powerpc/boot/wrapper | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index bb2465bcb327..25e889c0c06e 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -169,7 +169,7 @@ quiet_cmd_wrap = WRAP $@ $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux image-$(CONFIG_PPC_PSERIES) += zImage.pseries -image-$(CONFIG_PPC_MAPLE) += zImage.pseries +image-$(CONFIG_PPC_MAPLE) += zImage.maple image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries image-$(CONFIG_PPC_PS3) += dtbImage.ps3 image-$(CONFIG_PPC_CELLEB) += zImage.pseries @@ -351,7 +351,7 @@ install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \ zImage zImage.initrd zImage.chrp zImage.coff zImage.holly \ zImage.iseries zImage.miboot zImage.pmac zImage.pseries \ - simpleImage.* otheros.bld *.dtb + zImage.maple simpleImage.* otheros.bld *.dtb # clean up files cached by wrapper clean-kernel := vmlinux.strip vmlinux.bin diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index f4594ed09a20..7160b3b1fb35 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -149,6 +149,10 @@ pseries) platformo=$object/of.o link_address='0x4000000' ;; +maple) + platformo=$object/of.o + link_address='0x400000' + ;; pmac|chrp) platformo=$object/of.o ;; @@ -321,7 +325,7 @@ fi # post-processing needed for some platforms case "$platform" in -pseries|chrp) +pseries|chrp|maple) $objbin/addnote "$ofile" ;; coff) -- cgit v1.2.3-59-g8ed1b From 55052eeca6d71d76f7c3f156c0501814d8e5e6d3 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 7 Apr 2010 14:39:36 +1000 Subject: powerpc: Fix ioremap_flags() with book3e pte definition We can't just clear the user read permission in book3e pte, because that will also clear supervisor read permission. This surely isn't desired. Fix the problem by adding the supervisor read back. BenH: Slightly simplified the ifdef and applied to ppc64 too Signed-off-by: Li Yang Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/pgtable_32.c | 8 ++++++++ arch/powerpc/mm/pgtable_64.c | 8 ++++++++ 2 files changed, 16 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index b9243e7557ae..767b0cf17d33 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -146,6 +146,14 @@ ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags) /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */ flags &= ~(_PAGE_USER | _PAGE_EXEC); +#ifdef _PAGE_BAP_SR + /* _PAGE_USER contains _PAGE_BAP_SR on BookE using the new PTE format + * which means that we just cleared supervisor access... oops ;-) This + * restores it + */ + flags |= _PAGE_BAP_SR; +#endif + return __ioremap_caller(addr, size, flags, __builtin_return_address(0)); } EXPORT_SYMBOL(ioremap_flags); diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index d95679a5fb29..d050fc8d9714 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -265,6 +265,14 @@ void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size, /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */ flags &= ~(_PAGE_USER | _PAGE_EXEC); +#ifdef _PAGE_BAP_SR + /* _PAGE_USER contains _PAGE_BAP_SR on BookE using the new PTE format + * which means that we just cleared supervisor access... oops ;-) This + * restores it + */ + flags |= _PAGE_BAP_SR; +#endif + if (ppc_md.ioremap) return ppc_md.ioremap(addr, size, flags, caller); return __ioremap_caller(addr, size, flags, caller); -- cgit v1.2.3-59-g8ed1b From 578b7cd1518f8d1b17a7fb1671d3d756c9cb49f1 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 7 Apr 2010 14:44:28 +1000 Subject: powerpc/vio: Add modalias support BenH: Added to vio_cmo_dev_attrs as well Provide a modalias entry for VIO devices in sysfs. I believe this was another initrd generation bugfix for anaconda. Signed-off-by: David Woodhouse Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vio.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 82237176a2a3..2f57956714bd 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -958,9 +958,12 @@ viodev_cmo_rd_attr(allocated); static ssize_t name_show(struct device *, struct device_attribute *, char *); static ssize_t devspec_show(struct device *, struct device_attribute *, char *); +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, + char *buf); static struct device_attribute vio_cmo_dev_attrs[] = { __ATTR_RO(name), __ATTR_RO(devspec), + __ATTR_RO(modalias), __ATTR(cmo_desired, S_IWUSR|S_IRUSR|S_IWGRP|S_IRGRP|S_IROTH, viodev_cmo_desired_show, viodev_cmo_desired_set), __ATTR(cmo_entitled, S_IRUGO, viodev_cmo_entitled_show, NULL), @@ -1320,9 +1323,27 @@ static ssize_t devspec_show(struct device *dev, return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none"); } +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + const struct vio_dev *vio_dev = to_vio_dev(dev); + struct device_node *dn; + const char *cp; + + dn = dev->archdata.of_node; + if (!dn) + return -ENODEV; + cp = of_get_property(dn, "compatible", NULL); + if (!cp) + return -ENODEV; + + return sprintf(buf, "vio:T%sS%s\n", vio_dev->type, cp); +} + static struct device_attribute vio_dev_attrs[] = { __ATTR_RO(name), __ATTR_RO(devspec), + __ATTR_RO(modalias), __ATTR_NULL }; -- cgit v1.2.3-59-g8ed1b From 9c7cc234dc5edf5379fbbab4973f6704f59bc57b Mon Sep 17 00:00:00 2001 From: "K.Prasad" Date: Mon, 29 Mar 2010 23:59:25 +0000 Subject: powerpc: Disable interrupts for data breakpoint exceptions Data address breakpoint exceptions are currently handled along with page-faults which require interrupts to remain in enabled state. Since exception handling for data breakpoints aren't pre-empt safe, we handle them separately. Signed-off-by: K.Prasad Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/exceptions-64s.S | 13 ++++++++++++- arch/powerpc/mm/fault.c | 5 +++-- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index e3be98ffe2a7..3e423fbad6bc 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -735,8 +735,11 @@ _STATIC(do_hash_page) std r3,_DAR(r1) std r4,_DSISR(r1) - andis. r0,r4,0xa450 /* weird error? */ + andis. r0,r4,0xa410 /* weird error? */ bne- handle_page_fault /* if not, try to insert a HPTE */ + andis. r0,r4,DSISR_DABRMATCH@h + bne- handle_dabr_fault + BEGIN_FTR_SECTION andis. r0,r4,0x0020 /* Is it a segment table fault? */ bne- do_ste_alloc /* If so handle it */ @@ -823,6 +826,14 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) bl .raw_local_irq_restore b 11f +/* We have a data breakpoint exception - handle it */ +handle_dabr_fault: + ld r4,_DAR(r1) + ld r5,_DSISR(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_dabr + b .ret_from_except_lite + /* Here we have a page fault that hash_page can't handle. */ handle_page_fault: ENABLE_INTS diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 26fb6b990b0a..83ac4935eb10 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -151,13 +151,14 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, if (!user_mode(regs) && (address >= TASK_SIZE)) return SIGSEGV; -#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \ + defined(CONFIG_PPC_BOOK3S_64)) if (error_code & DSISR_DABRMATCH) { /* DABR match */ do_dabr(regs, address, error_code); return 0; } -#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ +#endif if (in_atomic() || mm == NULL) { if (!user_mode(regs)) -- cgit v1.2.3-59-g8ed1b From 6fe9d1facb5346a615f9b571df3b91593afb29c3 Mon Sep 17 00:00:00 2001 From: Vaidyanathan Srinivasan Date: Wed, 31 Mar 2010 21:39:24 +0000 Subject: powerpc/pseries: Export data from new hcall H_EM_GET_PARMS Add support for H_EM_GET_PARMS hcall that will return data related to power modes from the platform. Export the data directly to user space for administrative tools to interpret and use. cat /proc/powerpc/lparcfg will export power mode data Signed-off-by: Vaidyanathan Srinivasan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/hvcall.h | 1 + arch/powerpc/kernel/lparcfg.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index f0275818b95c..ebe7493e93e3 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -228,6 +228,7 @@ #define H_JOIN 0x298 #define H_VASI_STATE 0x2A4 #define H_ENABLE_CRQ 0x2B0 +#define H_GET_EM_PARMS 0x2B8 #define H_SET_MPP 0x2D0 #define H_GET_MPP 0x2D4 #define MAX_HCALL_OPCODE H_GET_MPP diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index c2c70e1b32cd..50362b6ef6e9 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -38,7 +38,7 @@ #include #include -#define MODULE_VERS "1.8" +#define MODULE_VERS "1.9" #define MODULE_NAME "lparcfg" /* #define LPARCFG_DEBUG */ @@ -487,6 +487,14 @@ static void splpar_dispatch_data(struct seq_file *m) seq_printf(m, "dispatch_dispersions=%lu\n", dispatch_dispersions); } +static void parse_em_data(struct seq_file *m) +{ + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + + if (plpar_hcall(H_GET_EM_PARMS, retbuf) == H_SUCCESS) + seq_printf(m, "power_mode_data=%016lx\n", retbuf[0]); +} + static int pseries_lparcfg_data(struct seq_file *m, void *v) { int partition_potential_processors; @@ -541,6 +549,8 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) seq_printf(m, "slb_size=%d\n", mmu_slb_size); + parse_em_data(m); + return 0; } -- cgit v1.2.3-59-g8ed1b From 43b5fefc24157def813154d1867d2960cefff837 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Tue, 9 Mar 2010 09:35:00 +0000 Subject: powerpc/ppc32: Fixup pmd_page to work when ARCH_PFN_OFFSET is non-zero Instead of referencing mem_map directly, use pfn_to_page. Otherwise the kernel crashes when trying to start userspace if ARCH_PFN_OFFSET is non-zero and CONFIG_BOOKE is not defined Signed-off-by: Jason Gunthorpe Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/pgtable-ppc32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h index 55646adfa843..a7db96f2b5c3 100644 --- a/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/arch/powerpc/include/asm/pgtable-ppc32.h @@ -287,7 +287,7 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) #define pmd_page_vaddr(pmd) \ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) #define pmd_page(pmd) \ - (mem_map + (pmd_val(pmd) >> PAGE_SHIFT)) + pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) #else #define pmd_page_vaddr(pmd) \ ((unsigned long) (pmd_val(pmd) & PAGE_MASK)) -- cgit v1.2.3-59-g8ed1b From fe1691e3f49d41452832f5aee2b952bd201ccab1 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Tue, 2 Mar 2010 05:37:09 +0000 Subject: powerpc/8xx: Optimze TLB Miss handlers This removes a couple of insn's from the TLB Miss handlers whithout changing functionality. Signed-off-by: Joakim Tjernlund Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_8xx.S | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 3ef743fa5d7c..ecc4a02277e3 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -343,17 +343,14 @@ InstructionTLBMiss: cmpwi cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT bne- cr0, 2f - /* Clear PP lsb, 0x400 */ - rlwinm r10, r10, 0, 22, 20 - /* The Linux PTE won't go exactly into the MMU TLB. - * Software indicator bits 22 and 28 must be clear. + * Software indicator bits 21 and 28 must be clear. * Software indicator bits 24, 25, 26, and 27 must be * set. All other Linux PTE bits control the behavior * of the MMU. */ li r11, 0x00f0 - rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ + rlwimi r10, r11, 0, 0x07f8 /* Set 24-27, clear 21-23,28 */ DO_8xx_CPU6(0x2d80, r3) mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ @@ -444,9 +441,7 @@ DataStoreTLBMiss: /* Honour kernel RO, User NA */ /* 0x200 == Extended encoding, bit 22 */ - /* r11 = (r10 & _PAGE_USER) >> 2 */ - rlwinm r11, r10, 32-2, 0x200 - or r10, r11, r10 + rlwimi r10, r10, 32-2, 0x200 /* Copy USER to bit 22, 0x200 */ /* r11 = (r10 & _PAGE_RW) >> 1 */ rlwinm r11, r10, 32-1, 0x200 or r10, r11, r10 -- cgit v1.2.3-59-g8ed1b From 4afb0be7ccda0ca551cc37572bab74ba4a3c18dd Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Tue, 2 Mar 2010 05:37:10 +0000 Subject: powerpc/8xx: Avoid testing for kernel space in ITLB Miss. Only modules will cause ITLB Misses as we always pin the first 8MB of kernel memory. Signed-off-by: Joakim Tjernlund Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_8xx.S | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index ecc4a02277e3..84ca1d9b9ed3 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -318,12 +318,16 @@ InstructionTLBMiss: /* If we are faulting a kernel address, we have to use the * kernel page tables. */ +#ifdef CONFIG_MODULES + /* Only modules will cause ITLB Misses as we always + * pin the first 8MB of kernel memory */ andi. r11, r10, 0x0800 /* Address >= 0x80000000 */ beq 3f lis r11, swapper_pg_dir@h ori r11, r11, swapper_pg_dir@l rlwimi r10, r11, 0, 2, 19 3: +#endif lwz r11, 0(r10) /* Get the level 1 entry */ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ beq 2f /* If zero, don't try to find a pte */ -- cgit v1.2.3-59-g8ed1b From d069cb4373fe0d451357c4d3769623a7564dfa9f Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Tue, 2 Mar 2010 05:37:11 +0000 Subject: powerpc/8xx: Don't touch ACCESSED when no SWAP. Only the swap function cares about the ACCESSED bit in the pte. Do not waste cycles updateting ACCESSED when swap is not compiled into the kernel. Signed-off-by: Joakim Tjernlund Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_8xx.S | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 84ca1d9b9ed3..6478a9632552 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -343,10 +343,11 @@ InstructionTLBMiss: mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ lwz r10, 0(r11) /* Get the pte */ +#ifdef CONFIG_SWAP andi. r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT cmpwi cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT bne- cr0, 2f - +#endif /* The Linux PTE won't go exactly into the MMU TLB. * Software indicator bits 21 and 28 must be clear. * Software indicator bits 24, 25, 26, and 27 must be @@ -439,10 +440,11 @@ DataStoreTLBMiss: * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5)); * r10 = (r10 & ~PRESENT) | r11; */ +#ifdef CONFIG_SWAP rlwinm r11, r10, 32-5, _PAGE_PRESENT and r11, r11, r10 rlwimi r10, r11, 0, _PAGE_PRESENT - +#endif /* Honour kernel RO, User NA */ /* 0x200 == Extended encoding, bit 22 */ rlwimi r10, r10, 32-2, 0x200 /* Copy USER to bit 22, 0x200 */ -- cgit v1.2.3-59-g8ed1b From 469d62be9263b92f2c3329540cbb1c076111f4f3 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Tue, 2 Mar 2010 05:37:12 +0000 Subject: powerpc/8xx: Use SPRG2 and DAR registers to stash r11 and cr. This avoids storing these registers in memory. CPU6 errata will still use the old way. Remove some G2 leftover accesses from 2.4 Signed-off-by: Joakim Tjernlund Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_8xx.S | 49 +++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 6478a9632552..1f1a04b5c2a4 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -71,9 +71,6 @@ _ENTRY(_start); * in the first level table, but that would require many changes to the * Linux page directory/table functions that I don't want to do right now. * - * I used to use SPRG2 for a temporary register in the TLB handler, but it - * has since been put to other uses. I now use a hack to save a register - * and the CCR at memory location 0.....Someday I'll fix this..... * -- Dan */ .globl __start @@ -302,8 +299,13 @@ InstructionTLBMiss: DO_8xx_CPU6(0x3f80, r3) mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ mfcr r10 +#ifdef CONFIG_8xx_CPU6 stw r10, 0(r0) stw r11, 4(r0) +#else + mtspr SPRN_DAR, r10 + mtspr SPRN_SPRG2, r11 +#endif mfspr r10, SPRN_SRR0 /* Get effective address of fault */ #ifdef CONFIG_8xx_CPU15 addi r11, r10, 0x1000 @@ -359,13 +361,19 @@ InstructionTLBMiss: DO_8xx_CPU6(0x2d80, r3) mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ - mfspr r10, SPRN_M_TW /* Restore registers */ + /* Restore registers */ +#ifndef CONFIG_8xx_CPU6 + mfspr r10, SPRN_DAR + mtcr r10 + mtspr SPRN_DAR, r11 /* Tag DAR */ + mfspr r11, SPRN_SPRG2 +#else lwz r11, 0(r0) mtcr r11 lwz r11, 4(r0) -#ifdef CONFIG_8xx_CPU6 lwz r3, 8(r0) #endif + mfspr r10, SPRN_M_TW rfi 2: mfspr r11, SPRN_SRR1 @@ -375,13 +383,20 @@ InstructionTLBMiss: rlwinm r11, r11, 0, 0xffff mtspr SPRN_SRR1, r11 - mfspr r10, SPRN_M_TW /* Restore registers */ + /* Restore registers */ +#ifndef CONFIG_8xx_CPU6 + mfspr r10, SPRN_DAR + mtcr r10 + li r11, 0x00f0 + mtspr SPRN_DAR, r11 /* Tag DAR */ + mfspr r11, SPRN_SPRG2 +#else lwz r11, 0(r0) mtcr r11 lwz r11, 4(r0) -#ifdef CONFIG_8xx_CPU6 lwz r3, 8(r0) #endif + mfspr r10, SPRN_M_TW b InstructionAccess . = 0x1200 @@ -392,8 +407,13 @@ DataStoreTLBMiss: DO_8xx_CPU6(0x3f80, r3) mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ mfcr r10 +#ifdef CONFIG_8xx_CPU6 stw r10, 0(r0) stw r11, 4(r0) +#else + mtspr SPRN_DAR, r10 + mtspr SPRN_SPRG2, r11 +#endif mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ /* If we are faulting a kernel address, we have to use the @@ -461,18 +481,24 @@ DataStoreTLBMiss: * of the MMU. */ 2: li r11, 0x00f0 - mtspr SPRN_DAR,r11 /* Tag DAR */ rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ DO_8xx_CPU6(0x3d80, r3) mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ - mfspr r10, SPRN_M_TW /* Restore registers */ + /* Restore registers */ +#ifndef CONFIG_8xx_CPU6 + mfspr r10, SPRN_DAR + mtcr r10 + mtspr SPRN_DAR, r11 /* Tag DAR */ + mfspr r11, SPRN_SPRG2 +#else + mtspr SPRN_DAR, r11 /* Tag DAR */ lwz r11, 0(r0) mtcr r11 lwz r11, 4(r0) -#ifdef CONFIG_8xx_CPU6 lwz r3, 8(r0) #endif + mfspr r10, SPRN_M_TW rfi /* This is an instruction TLB error on the MPC8xx. This could be due @@ -684,9 +710,6 @@ start_here: tophys(r4,r2) addi r4,r4,THREAD /* init task's THREAD */ mtspr SPRN_SPRG_THREAD,r4 - li r3,0 - /* XXX What is that for ? SPRG2 appears otherwise unused on 8xx */ - mtspr SPRN_SPRG2,r3 /* 0 => r1 has kernel sp */ /* stack */ lis r1,init_thread_union@ha -- cgit v1.2.3-59-g8ed1b From 213972e9faf8a16b27fee01ae7c7071de5080268 Mon Sep 17 00:00:00 2001 From: d binderman Date: Sat, 6 Feb 2010 02:13:29 +0000 Subject: powerpc/pmac/low_i2c.c: three minor problems Fix minor nits found by cppcheck [./arch/powerpc/platforms/powermac/low_i2c.c:594]: (style) The scope of the variable chans can be reduced [./arch/powerpc/platforms/powermac/low_i2c.c:594]: (style) The scope of the variable i can be reduced [./arch/powerpc/platforms/powermac/low_i2c.c:1260]: (style) Redundant condition. It is safe to deallocate a NULL pointer Signed-off-by: David Binderman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powermac/low_i2c.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index f45331ab97cb..06a137c5b8bb 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -592,7 +592,7 @@ static void __init kw_i2c_probe(void) /* Probe keywest-i2c busses */ for_each_compatible_node(np, "i2c","keywest-i2c") { struct pmac_i2c_host_kw *host; - int multibus, chans, i; + int multibus; /* Found one, init a host structure */ host = kw_i2c_host_init(np); @@ -614,6 +614,8 @@ static void __init kw_i2c_probe(void) * parent type */ if (multibus) { + int chans, i; + parent = of_get_parent(np); if (parent == NULL) continue; @@ -1258,8 +1260,7 @@ static void pmac_i2c_do_end(struct pmf_function *func, void *instdata) if (inst == NULL) return; pmac_i2c_close(inst->bus); - if (inst) - kfree(inst); + kfree(inst); } static int pmac_i2c_do_read(PMF_STD_ARGS, u32 len) -- cgit v1.2.3-59-g8ed1b From 637a99022fb119b90fb281715d13172f0394fc12 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 17 Mar 2010 10:55:51 +0000 Subject: powerpc: Fix handling of strncmp with zero len Commit 0119536c, which added the assembly version of strncmp to powerpc, mentions that it adds two instructions to the version from boot/string.S to allow it to handle len=0. Unfortunately, it doesn't always return 0 when that is the case. The length is passed in r5, but the return value is passed back in r3. In certain cases, this will happen to work. Otherwise it will pass back the address of the first string as the return value. This patch lifts the len <= 0 handling code from memcpy to handle that case. Reported by: Christian_Sellars@symantec.com Signed-off-by: Jeff Mahoney CC: Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/lib/string.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S index 64e2e499e32a..3ac0cd3a5373 100644 --- a/arch/powerpc/lib/string.S +++ b/arch/powerpc/lib/string.S @@ -71,7 +71,7 @@ _GLOBAL(strcmp) _GLOBAL(strncmp) PPC_LCMPI r5,0 - beqlr + ble- 2f mtctr r5 addi r5,r3,-1 addi r4,r4,-1 @@ -82,6 +82,8 @@ _GLOBAL(strncmp) beqlr 1 bdnzt eq,1b blr +2: li r3,0 + blr _GLOBAL(strlen) addi r4,r3,-1 -- cgit v1.2.3-59-g8ed1b From a7df5c5e52a545774c4db1f2adf09ede018ab139 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 2 Apr 2010 02:47:13 +0000 Subject: powerpc/pseries/dlpar: Eliminate use after free dlpar_free_cc_nodes frees its argument, so dlpar_online_cpu should not be called on the same value. Skip over the call to dlpar_online_cpu by jumping directly to out. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression E,E2; @@ dlpar_free_cc_nodes(E) ... ( E = E2 | * E ) // Signed-off-by: Julia Lawall Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/dlpar.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index e1682bc168a3..1540a41d1a85 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -433,6 +433,7 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) if (rc) { dlpar_release_drc(drc_index); dlpar_free_cc_nodes(dn); + goto out; } rc = dlpar_online_cpu(dn); -- cgit v1.2.3-59-g8ed1b From 43caa61f154da85a620965f3f61c2f45366d8dc7 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 10 Mar 2010 11:15:01 +0000 Subject: powerpc/pseries/dlpar: Use kasprintf kasprintf combines kmalloc and sprintf, and takes care of the size calculation itself. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression a,flag; expression list args; statement S; @@ a = - \(kmalloc\|kzalloc\)(...,flag) + kasprintf(flag,args) <... when != a if (a == NULL || ...) S ...> - sprintf(a,args); // Signed-off-by: Julia Lawall Acked-by: Nathan Fontenot Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/dlpar.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 1540a41d1a85..d71e58584086 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -79,13 +79,12 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa) * prepend this to the full_name. */ name = (char *)ccwa + ccwa->name_offset; - dn->full_name = kmalloc(strlen(name) + 2, GFP_KERNEL); + dn->full_name = kasprintf(GFP_KERNEL, "/%s", name); if (!dn->full_name) { kfree(dn); return NULL; } - sprintf(dn->full_name, "/%s", name); return dn; } @@ -410,15 +409,13 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) * directory of the device tree. CPUs actually live in the * cpus directory so we need to fixup the full_name. */ - cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus") + 1, - GFP_KERNEL); + cpu_name = kasprintf(GFP_KERNEL, "/cpus%s", dn->full_name); if (!cpu_name) { dlpar_free_cc_nodes(dn); rc = -ENOMEM; goto out; } - sprintf(cpu_name, "/cpus%s", dn->full_name); kfree(dn->full_name); dn->full_name = cpu_name; -- cgit v1.2.3-59-g8ed1b From f6d8c8bb1d360272d795927d39f3d2c5934e77d9 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 29 Mar 2010 05:33:34 +0000 Subject: powerpc/vio: Add missing unlock in error path Add an unlock before exiting the function. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E1; identifier f; @@ f (...) { <+... * spin_lock_irq (E1,...); ... when != E1 * return ...; ...+> } // Signed-off-by: Julia Lawall Acked-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 2f57956714bd..2a3428bef83a 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -645,8 +645,10 @@ void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired) found = 1; break; } - if (!found) + if (!found) { + spin_unlock_irqrestore(&vio_cmo.lock, flags); return; + } /* Increase/decrease in desired device entitlement */ if (desired >= viodev->cmo.desired) { -- cgit v1.2.3-59-g8ed1b From 21dbeb91a24d867af0e98ba155bfa80d2906344f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 26 Mar 2010 12:03:29 +0000 Subject: powerpc: Use set_cpus_allowed_ptr Use set_cpus_allowed_ptr rather than set_cpus_allowed. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression E1,E2; @@ - set_cpus_allowed(E1, cpumask_of_cpu(E2)) + set_cpus_allowed_ptr(E1, cpumask_of(E2)) @@ expression E; identifier I; @@ - set_cpus_allowed(E, I) + set_cpus_allowed_ptr(E, &I) // Signed-off-by: Julia Lawall Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/smp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index c2ee14498077..e36f94f7411a 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -561,12 +561,12 @@ void __init smp_cpus_done(unsigned int max_cpus) * se we pin us down to CPU 0 for a short while */ old_mask = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); + set_cpus_allowed_ptr(current, cpumask_of(boot_cpuid)); if (smp_ops && smp_ops->setup_cpu) smp_ops->setup_cpu(boot_cpuid); - set_cpus_allowed(current, old_mask); + set_cpus_allowed_ptr(current, &old_mask); snapshot_timebases(); -- cgit v1.2.3-59-g8ed1b From 27f10907b7cca57df5e2a9c94c14354dd1b7879d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 18 Feb 2010 12:29:23 +0000 Subject: powerpc/numa: Set a smaller value for RECLAIM_DISTANCE to enable zone reclaim I noticed /proc/sys/vm/zone_reclaim_mode was 0 on a ppc64 NUMA box. It gets enabled via this: /* * If another node is sufficiently far away then it is better * to reclaim pages in a zone before going off node. */ if (distance > RECLAIM_DISTANCE) zone_reclaim_mode = 1; Since we use the default value of 20 for REMOTE_DISTANCE and 20 for RECLAIM_DISTANCE it never kicks in. The local to remote bandwidth ratios can be quite large on System p machines so it makes sense for us to reclaim clean pagecache locally before going off node. The patch below sets a smaller value for RECLAIM_DISTANCE and thus enables zone reclaim. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/topology.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 8eaec310a25b..a7d769491555 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -8,6 +8,16 @@ struct device_node; #ifdef CONFIG_NUMA +/* + * Before going off node we want the VM to try and reclaim from the local + * node. It does this if the remote distance is larger than RECLAIM_DISTANCE. + * With the default REMOTE_DISTANCE of 20 and the default RECLAIM_DISTANCE of + * 20, we never reclaim and go off node straight away. + * + * To fix this we choose a smaller value of RECLAIM_DISTANCE. + */ +#define RECLAIM_DISTANCE 10 + #include static inline int cpu_to_node(int cpu) -- cgit v1.2.3-59-g8ed1b From e9bbc8cde0e3c33b42ddbe1b02108cb5c97275eb Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 18 Feb 2010 12:11:51 +0000 Subject: powerpc/pseries: Call ibm,os-term if the ibm,extended-os-term is present We have had issues in the past with ibm,os-term initiating shutdown of a partition. This is confusing to the user, especially if panic_timeout is non zero. The temporary fix was to avoid calling ibm,os-term if a panic_timeout was set and since we set it on every boot we basically never call ibm,os-term. An extended version of ibm,os-term has since been implemented which gives us the behaviour we want: "When the platform supports extended ibm,os-term behavior, the return to the RTAS will always occur unless there is a kernel assisted dump active as initiated by an ibm,configure-kernel-dump call." This patch checks for the ibm,extended-os-term property and calls ibm,os-term if it exists. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/rtas.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 74367841615a..0e1ec6f746f6 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -691,10 +691,14 @@ void rtas_os_term(char *str) { int status; - if (panic_timeout) - return; - - if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term")) + /* + * Firmware with the ibm,extended-os-term property is guaranteed + * to always return from an ibm,os-term call. Earlier versions without + * this property may terminate the partition which we want to avoid + * since it interferes with panic_timeout. + */ + if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term") || + RTAS_UNKNOWN_SERVICE == rtas_token("ibm,extended-os-term")) return; snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str); @@ -705,8 +709,7 @@ void rtas_os_term(char *str) } while (rtas_busy_delay(status)); if (status != 0) - printk(KERN_EMERG "ibm,os-term call failed %d\n", - status); + printk(KERN_EMERG "ibm,os-term call failed %d\n", status); } static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; -- cgit v1.2.3-59-g8ed1b From 7545ba6f82924d4523f8f8a2baf2e517a750265d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 25 Feb 2010 20:18:46 +0000 Subject: powerpc/mm: Bump SECTION_SIZE_BITS from 16MB to 256MB The current setting for SECTION_SIZE_BITS is quite small compared to everyone else: arch/powerpc/include/asm/sparsemem.h:#define SECTION_SIZE_BITS 24 arch/sparc/include/asm/sparsemem.h:#define SECTION_SIZE_BITS 30 arch/ia64/include/asm/sparsemem.h:#define SECTION_SIZE_BITS (30) arch/s390/include/asm/sparsemem.h:#define SECTION_SIZE_BITS 28 arch/x86/include/asm/sparsemem.h:# define SECTION_SIZE_BITS 27 And it has proven to be an issue during boot on very large machines. If hotplug memory is enabled, drivers/base/memory.c does this: for (i = 0; i < NR_MEM_SECTIONS; i++) { if (!present_section_nr(i)) continue; err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0, BOOT); if (!ret) ret = err; } Which creates a sysfs directory for every 16MB of memory. As a result I'm seeing up to 30 minutes spent here during boot: c000000000248ee0 .__sysfs_add_one+0x28/0x128 c0000000002492a8 .sysfs_add_one+0x38/0x188 c000000000249c88 .create_dir+0x70/0x138 c000000000249d98 .sysfs_create_dir+0x48/0x78 c00000000032bad8 .kobject_add_internal+0x140/0x308 c00000000032beb4 .kobject_init_and_add+0x4c/0x68 c00000000046c2c0 .sysdev_register+0xa0/0x220 c00000000047b1dc .add_memory_block+0x124/0x1e8 c0000000008d1f28 .memory_dev_init+0xf4/0x168 c0000000008d1b64 .driver_init+0x50/0x64 c000000000890378 .do_basic_setup+0x40/0xd4 I assume there are some O(n^2) issues in sysfs as we add all the memory nodes. Bumping SECTION_SIZE_BITS to 256 MB drops the time to about 10 seconds and results in a much smaller /sys. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/sparsemem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h index 54a47ea2c3aa..13fe0a0e5806 100644 --- a/arch/powerpc/include/asm/sparsemem.h +++ b/arch/powerpc/include/asm/sparsemem.h @@ -8,7 +8,7 @@ * MAX_PHYSADDR_BITS 2^N: how much physical address space we have * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space */ -#define SECTION_SIZE_BITS 24 +#define SECTION_SIZE_BITS 28 #define MAX_PHYSADDR_BITS 44 #define MAX_PHYSMEM_BITS 44 -- cgit v1.2.3-59-g8ed1b From 8260cf6f40014860cb857f5245194900dd6c9b94 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 28 Feb 2010 00:58:16 +0000 Subject: powerpc/iseries/pci: Use __ratelimit Replace open-coded rate limiting logic with __ratelimit(). Signed-off-by: Akinobu Mita Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: linuxppc-dev@ozlabs.org Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/iseries/pci.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index b841c9a9db87..3fc2e6494b8b 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -584,14 +585,9 @@ static inline struct device_node *xlate_iomm_address( orig_addr = (unsigned long __force)addr; if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) { - static unsigned long last_jiffies; - static int num_printed; + static DEFINE_RATELIMIT_STATE(ratelimit, 60 * HZ, 10); - if (time_after(jiffies, last_jiffies + 60 * HZ)) { - last_jiffies = jiffies; - num_printed = 0; - } - if (num_printed++ < 10) + if (__ratelimit(&ratelimit)) printk(KERN_ERR "iSeries_%s: invalid access at IO address %p\n", func, addr); -- cgit v1.2.3-59-g8ed1b From 99dc5c0ca953fb154a3c75ebc6801e0a3c2fe3fe Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 7 Apr 2010 17:08:32 +0900 Subject: sh: Disable MMUCR_AT for SH-4 nommu. Presently address translation is default-enabled regardless of whether CONFIG_MMU is set or not in the SH-4 case, this fixes it up, and also makes the control init word a bit more readable in the process. Signed-off-by: Paul Mundt --- arch/sh/include/cpu-sh4/cpu/mmu_context.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/cpu-sh4/cpu/mmu_context.h b/arch/sh/include/cpu-sh4/cpu/mmu_context.h index 2941be617a5f..e46ec708105a 100644 --- a/arch/sh/include/cpu-sh4/cpu/mmu_context.h +++ b/arch/sh/include/cpu-sh4/cpu/mmu_context.h @@ -32,7 +32,13 @@ #define MMU_UTLB_DATA_ARRAY2 0xF7800000 #define MMU_PAGE_ASSOC_BIT 0x80 -#define MMUCR_TI (1<<2) +#ifdef CONFIG_MMU +#define MMUCR_AT (1 << 0) +#else +#define MMUCR_AT (0) +#endif + +#define MMUCR_TI (1 << 2) #define MMUCR_URB 0x00FC0000 #define MMUCR_URB_SHIFT 18 @@ -65,7 +71,8 @@ #endif #define MMU_NTLB_ENTRIES 64 -#define MMU_CONTROL_INIT (0x05|MMUCR_SQMD|MMUCR_ME|MMUCR_SE|MMUCR_AEX) +#define MMU_CONTROL_INIT (MMUCR_AT | MMUCR_TI | MMUCR_SQMD | \ + MMUCR_ME | MMUCR_SE | MMUCR_AEX) #define TRA 0xff000020 #define EXPEVT 0xff000024 -- cgit v1.2.3-59-g8ed1b From a32aaf14513da776556ad9995de8d83cd76ae60a Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 7 Apr 2010 18:09:15 +1000 Subject: powerpc/vio: Add power management support Adds support for suspend/resume for VIO devices. This is needed for support for HMC initiated hibernation. Signed-off-by: Brian King Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vio.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 2a3428bef83a..b8e311d64ad5 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -1381,6 +1381,29 @@ static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env) return 0; } +static int vio_pm_suspend(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm && pm->suspend) + return pm->suspend(dev); + return 0; +} + +static int vio_pm_resume(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm && pm->resume) + return pm->resume(dev); + return 0; +} + +const struct dev_pm_ops vio_dev_pm_ops = { + .suspend = vio_pm_suspend, + .resume = vio_pm_resume, +}; + static struct bus_type vio_bus_type = { .name = "vio", .dev_attrs = vio_dev_attrs, @@ -1388,6 +1411,7 @@ static struct bus_type vio_bus_type = { .match = vio_bus_match, .probe = vio_bus_probe, .remove = vio_bus_remove, + .pm = &vio_dev_pm_ops, }; /** -- cgit v1.2.3-59-g8ed1b From 359e4284a3f37aba7fd06d993863de2509d86f54 Mon Sep 17 00:00:00 2001 From: Mahesh Salgaonkar Date: Wed, 7 Apr 2010 18:10:20 +1000 Subject: powerpc: Add kprobe-based event tracer This patch ports the kprobe-based event tracer to powerpc. This patch is based on x86 port. This brings powerpc on par with x86. Signed-off-by: Mahesh Salgaonkar Acked-by: Masami Hiramatsu Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/ptrace.h | 64 +++++++++++++++++++++++ arch/powerpc/kernel/ptrace.c | 103 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2e19500921f9..c4c4549c22bb 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -140,6 +140,7 @@ config PPC select HAVE_SYSCALL_WRAPPERS if PPC64 select GENERIC_ATOMIC64 if PPC32 select HAVE_PERF_EVENTS + select HAVE_REGS_AND_STACK_ACCESS_API config EARLY_PRINTK bool diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 9e2d84c06b74..5d8be0416227 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h @@ -89,6 +89,7 @@ struct pt_regs { #define instruction_pointer(regs) ((regs)->nip) #define user_stack_pointer(regs) ((regs)->gpr[1]) +#define kernel_stack_pointer(regs) ((regs)->gpr[1]) #define regs_return_value(regs) ((regs)->gpr[3]) #ifdef CONFIG_SMP @@ -141,6 +142,69 @@ do { \ #define arch_has_block_step() (!cpu_has_feature(CPU_FTR_601)) #define ARCH_HAS_USER_SINGLE_STEP_INFO +/* + * kprobe-based event tracer support + */ + +#include +#include +extern int regs_query_register_offset(const char *name); +extern const char *regs_query_register_name(unsigned int offset); +#define MAX_REG_OFFSET (offsetof(struct pt_regs, dsisr)) + +/** + * regs_get_register() - get register value from its offset + * @regs: pt_regs from which register value is gotten + * @offset: offset number of the register. + * + * regs_get_register returns the value of a register whose offset from @regs. + * The @offset is the offset of the register in struct pt_regs. + * If @offset is bigger than MAX_REG_OFFSET, this returns 0. + */ +static inline unsigned long regs_get_register(struct pt_regs *regs, + unsigned int offset) +{ + if (unlikely(offset > MAX_REG_OFFSET)) + return 0; + return *(unsigned long *)((unsigned long)regs + offset); +} + +/** + * regs_within_kernel_stack() - check the address in the stack + * @regs: pt_regs which contains kernel stack pointer. + * @addr: address which is checked. + * + * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). + * If @addr is within the kernel stack, it returns true. If not, returns false. + */ + +static inline bool regs_within_kernel_stack(struct pt_regs *regs, + unsigned long addr) +{ + return ((addr & ~(THREAD_SIZE - 1)) == + (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); +} + +/** + * regs_get_kernel_stack_nth() - get Nth entry of the stack + * @regs: pt_regs which contains kernel stack pointer. + * @n: stack entry number. + * + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which + * is specified by @regs. If the @n th entry is NOT in the kernel stack, + * this returns 0. + */ +static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, + unsigned int n) +{ + unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); + addr += n; + if (regs_within_kernel_stack(regs, (unsigned long)addr)) + return *addr; + else + return 0; +} + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index ed2cfe17d25e..7a0c0199ea28 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -38,6 +38,109 @@ #include #include +/* + * The parameter save area on the stack is used to store arguments being passed + * to callee function and is located at fixed offset from stack pointer. + */ +#ifdef CONFIG_PPC32 +#define PARAMETER_SAVE_AREA_OFFSET 24 /* bytes */ +#else /* CONFIG_PPC32 */ +#define PARAMETER_SAVE_AREA_OFFSET 48 /* bytes */ +#endif + +struct pt_regs_offset { + const char *name; + int offset; +}; + +#define STR(s) #s /* convert to string */ +#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)} +#define GPR_OFFSET_NAME(num) \ + {.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])} +#define REG_OFFSET_END {.name = NULL, .offset = 0} + +static const struct pt_regs_offset regoffset_table[] = { + GPR_OFFSET_NAME(0), + GPR_OFFSET_NAME(1), + GPR_OFFSET_NAME(2), + GPR_OFFSET_NAME(3), + GPR_OFFSET_NAME(4), + GPR_OFFSET_NAME(5), + GPR_OFFSET_NAME(6), + GPR_OFFSET_NAME(7), + GPR_OFFSET_NAME(8), + GPR_OFFSET_NAME(9), + GPR_OFFSET_NAME(10), + GPR_OFFSET_NAME(11), + GPR_OFFSET_NAME(12), + GPR_OFFSET_NAME(13), + GPR_OFFSET_NAME(14), + GPR_OFFSET_NAME(15), + GPR_OFFSET_NAME(16), + GPR_OFFSET_NAME(17), + GPR_OFFSET_NAME(18), + GPR_OFFSET_NAME(19), + GPR_OFFSET_NAME(20), + GPR_OFFSET_NAME(21), + GPR_OFFSET_NAME(22), + GPR_OFFSET_NAME(23), + GPR_OFFSET_NAME(24), + GPR_OFFSET_NAME(25), + GPR_OFFSET_NAME(26), + GPR_OFFSET_NAME(27), + GPR_OFFSET_NAME(28), + GPR_OFFSET_NAME(29), + GPR_OFFSET_NAME(30), + GPR_OFFSET_NAME(31), + REG_OFFSET_NAME(nip), + REG_OFFSET_NAME(msr), + REG_OFFSET_NAME(ctr), + REG_OFFSET_NAME(link), + REG_OFFSET_NAME(xer), + REG_OFFSET_NAME(ccr), +#ifdef CONFIG_PPC64 + REG_OFFSET_NAME(softe), +#else + REG_OFFSET_NAME(mq), +#endif + REG_OFFSET_NAME(trap), + REG_OFFSET_NAME(dar), + REG_OFFSET_NAME(dsisr), + REG_OFFSET_END, +}; + +/** + * regs_query_register_offset() - query register offset from its name + * @name: the name of a register + * + * regs_query_register_offset() returns the offset of a register in struct + * pt_regs from its name. If the name is invalid, this returns -EINVAL; + */ +int regs_query_register_offset(const char *name) +{ + const struct pt_regs_offset *roff; + for (roff = regoffset_table; roff->name != NULL; roff++) + if (!strcmp(roff->name, name)) + return roff->offset; + return -EINVAL; +} + +/** + * regs_query_register_name() - query register name from its offset + * @offset: the offset of a register in struct pt_regs. + * + * regs_query_register_name() returns the name of a register from its + * offset in struct pt_regs. If the @offset is invalid, this returns NULL; + */ +const char *regs_query_register_name(unsigned int offset) +{ + const struct pt_regs_offset *roff; + for (roff = regoffset_table; roff->name != NULL; roff++) + if (roff->offset == offset) + return roff->name; + return NULL; +} + /* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. -- cgit v1.2.3-59-g8ed1b From 4d8dc679084d8dd7b81b2ae245844246deb0759c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 7 Apr 2010 23:28:28 -0700 Subject: Revert "Add non-Virtex5 support for LL TEMAC driver" This reverts commit 459569145516f7967b916c57445feb02c600668c. Uses virt_to_bus() and breaks the build. Signed-off-by: David S. Miller --- arch/microblaze/include/asm/system.h | 11 --- drivers/net/Kconfig | 2 +- drivers/net/ll_temac.h | 14 +--- drivers/net/ll_temac_main.c | 137 +++++++++-------------------------- 4 files changed, 38 insertions(+), 126 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h index 48c4f0335e3f..59efb3fef957 100644 --- a/arch/microblaze/include/asm/system.h +++ b/arch/microblaze/include/asm/system.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -97,14 +96,4 @@ extern struct dentry *of_debugfs_root; #define arch_align_stack(x) (x) -/* - * MicroBlaze doesn't handle unaligned accesses in hardware. - * - * Based on this we force the IP header alignment in network drivers. - * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining - * cacheline alignment of buffers. - */ -#define NET_IP_ALIGN 2 -#define NET_SKB_PAD L1_CACHE_BYTES - #endif /* _ASM_MICROBLAZE_SYSTEM_H */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index dbd26f992158..49c372a5e0b7 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2435,8 +2435,8 @@ config MV643XX_ETH config XILINX_LL_TEMAC tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver" - depends on PPC || MICROBLAZE select PHYLIB + depends on PPC_DCR_NATIVE help This driver supports the Xilinx 10/100/1000 LocalLink TEMAC core used in Xilinx Spartan and Virtex FPGAs diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h index c03358434acb..1af66a1e6911 100644 --- a/drivers/net/ll_temac.h +++ b/drivers/net/ll_temac.h @@ -5,11 +5,8 @@ #include #include #include - -#ifdef CONFIG_PPC_DCR #include #include -#endif /* packet size info */ #define XTE_HDR_SIZE 14 /* size of Ethernet header */ @@ -293,6 +290,9 @@ This option defaults to enabled (set) */ #define TX_CONTROL_CALC_CSUM_MASK 1 +#define XTE_ALIGN 32 +#define BUFFER_ALIGN(adr) ((XTE_ALIGN - ((u32) adr)) % XTE_ALIGN) + #define MULTICAST_CAM_TABLE_NUM 4 /* TX/RX CURDESC_PTR points to first descriptor */ @@ -335,15 +335,9 @@ struct temac_local { struct mii_bus *mii_bus; /* MII bus reference */ int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */ - /* IO registers, dma functions and IRQs */ + /* IO registers and IRQs */ void __iomem *regs; - void __iomem *sdma_regs; -#ifdef CONFIG_PPC_DCR dcr_host_t sdma_dcrs; -#endif - u32 (*dma_in)(struct temac_local *, int); - void (*dma_out)(struct temac_local *, int, u32); - int tx_irq; int rx_irq; int emac_num; diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index b6edb2fd0a8a..30474d6b15c3 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -20,6 +20,9 @@ * or rx, so this should be okay. * * TODO: + * - Fix driver to work on more than just Virtex5. Right now the driver + * assumes that the locallink DMA registers are accessed via DCR + * instructions. * - Factor out locallink DMA code into separate driver * - Fix multicast assignment. * - Fix support for hardware checksumming. @@ -112,85 +115,16 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value) temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); } -/** - * temac_dma_in32 - Memory mapped DMA read, this function expects a - * register input that is based on DCR word addresses which - * are then converted to memory mapped byte addresses - */ static u32 temac_dma_in32(struct temac_local *lp, int reg) -{ - return in_be32((u32 *)(lp->sdma_regs + (reg << 2))); -} - -/** - * temac_dma_out32 - Memory mapped DMA read, this function expects a - * register input that is based on DCR word addresses which - * are then converted to memory mapped byte addresses - */ -static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) -{ - out_be32((u32 *)(lp->sdma_regs + (reg << 2)), value); -} - -/* DMA register access functions can be DCR based or memory mapped. - * The PowerPC 440 is DCR based, the PowerPC 405 and MicroBlaze are both - * memory mapped. - */ -#ifdef CONFIG_PPC_DCR - -/** - * temac_dma_dcr_in32 - DCR based DMA read - */ -static u32 temac_dma_dcr_in(struct temac_local *lp, int reg) { return dcr_read(lp->sdma_dcrs, reg); } -/** - * temac_dma_dcr_out32 - DCR based DMA write - */ -static void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value) +static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) { dcr_write(lp->sdma_dcrs, reg, value); } -/** - * temac_dcr_setup - If the DMA is DCR based, then setup the address and - * I/O functions - */ -static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, - struct device_node *np) -{ - unsigned int dcrs; - - /* setup the dcr address mapping if it's in the device tree */ - - dcrs = dcr_resource_start(np, 0); - if (dcrs != 0) { - lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); - lp->dma_in = temac_dma_dcr_in; - lp->dma_out = temac_dma_dcr_out; - dev_dbg(&op->dev, "DCR base: %x\n", dcrs); - return 0; - } - /* no DCR in the device tree, indicate a failure */ - return -1; -} - -#else - -/* - * temac_dcr_setup - This is a stub for when DCR is not supported, - * such as with MicroBlaze - */ -static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, - struct device_node *np) -{ - return -1; -} - -#endif - /** * temac_dma_bd_init - Setup buffer descriptor rings */ @@ -221,14 +155,14 @@ static int temac_dma_bd_init(struct net_device *ndev) lp->rx_bd_v[i].next = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM); - skb = netdev_alloc_skb_ip_align(ndev, - XTE_MAX_JUMBO_FRAME_SIZE); - + skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + + XTE_ALIGN, GFP_ATOMIC); if (skb == 0) { dev_err(&ndev->dev, "alloc_skb error %d\n", i); return -1; } lp->rx_skb[i] = skb; + skb_reserve(skb, BUFFER_ALIGN(skb->data)); /* returns physical address of skb->data */ lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, skb->data, @@ -238,23 +172,23 @@ static int temac_dma_bd_init(struct net_device *ndev) lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND; } - lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 | + temac_dma_out32(lp, TX_CHNL_CTRL, 0x10220400 | CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN); /* 0x10220483 */ /* 0x00100483 */ - lp->dma_out(lp, RX_CHNL_CTRL, 0xff010000 | + temac_dma_out32(lp, RX_CHNL_CTRL, 0xff010000 | CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN | CHNL_CTRL_IRQ_IOE); /* 0xff010283 */ - lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p); - lp->dma_out(lp, RX_TAILDESC_PTR, + temac_dma_out32(lp, RX_CURDESC_PTR, lp->rx_bd_p); + temac_dma_out32(lp, RX_TAILDESC_PTR, lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); - lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); + temac_dma_out32(lp, TX_CURDESC_PTR, lp->tx_bd_p); return 0; } @@ -492,9 +426,9 @@ static void temac_device_reset(struct net_device *ndev) temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK); /* Reset Local Link (DMA) */ - lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); + temac_dma_out32(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); timeout = 1000; - while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { + while (temac_dma_in32(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { udelay(1); if (--timeout == 0) { dev_err(&ndev->dev, @@ -502,7 +436,7 @@ static void temac_device_reset(struct net_device *ndev) break; } } - lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); + temac_dma_out32(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); temac_dma_bd_init(ndev); @@ -663,7 +597,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) lp->tx_bd_tail = 0; /* Kick off the transfer */ - lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ + temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ return NETDEV_TX_OK; } @@ -705,15 +639,16 @@ static void ll_temac_recv(struct net_device *ndev) ndev->stats.rx_packets++; ndev->stats.rx_bytes += length; - new_skb = netdev_alloc_skb_ip_align(ndev, - XTE_MAX_JUMBO_FRAME_SIZE); - + new_skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN, + GFP_ATOMIC); if (new_skb == 0) { dev_err(&ndev->dev, "no memory for new sk_buff\n"); spin_unlock_irqrestore(&lp->rx_lock, flags); return; } + skb_reserve(new_skb, BUFFER_ALIGN(new_skb->data)); + cur_p->app0 = STS_CTRL_APP0_IRQONEND; cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, XTE_MAX_JUMBO_FRAME_SIZE, @@ -728,7 +663,7 @@ static void ll_temac_recv(struct net_device *ndev) cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; bdstat = cur_p->app0; } - lp->dma_out(lp, RX_TAILDESC_PTR, tail_p); + temac_dma_out32(lp, RX_TAILDESC_PTR, tail_p); spin_unlock_irqrestore(&lp->rx_lock, flags); } @@ -739,8 +674,8 @@ static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) struct temac_local *lp = netdev_priv(ndev); unsigned int status; - status = lp->dma_in(lp, TX_IRQ_REG); - lp->dma_out(lp, TX_IRQ_REG, status); + status = temac_dma_in32(lp, TX_IRQ_REG); + temac_dma_out32(lp, TX_IRQ_REG, status); if (status & (IRQ_COAL | IRQ_DLY)) temac_start_xmit_done(lp->ndev); @@ -757,8 +692,8 @@ static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev) unsigned int status; /* Read and clear the status registers */ - status = lp->dma_in(lp, RX_IRQ_REG); - lp->dma_out(lp, RX_IRQ_REG, status); + status = temac_dma_in32(lp, RX_IRQ_REG); + temac_dma_out32(lp, RX_IRQ_REG, status); if (status & (IRQ_COAL | IRQ_DLY)) ll_temac_recv(lp->ndev); @@ -859,7 +794,7 @@ static ssize_t temac_show_llink_regs(struct device *dev, int i, len = 0; for (i = 0; i < 0x11; i++) - len += sprintf(buf + len, "%.8x%s", lp->dma_in(lp, i), + len += sprintf(buf + len, "%.8x%s", temac_dma_in32(lp, i), (i % 8) == 7 ? "\n" : " "); len += sprintf(buf + len, "\n"); @@ -885,6 +820,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) struct net_device *ndev; const void *addr; int size, rc = 0; + unsigned int dcrs; /* Init network device structure */ ndev = alloc_etherdev(sizeof(*lp)); @@ -934,20 +870,13 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) goto nodev; } - /* Setup the DMA register accesses, could be DCR or memory mapped */ - if (temac_dcr_setup(lp, op, np)) { - - /* no DCR in the device tree, try non-DCR */ - lp->sdma_regs = of_iomap(np, 0); - if (lp->sdma_regs) { - lp->dma_in = temac_dma_in32; - lp->dma_out = temac_dma_out32; - dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs); - } else { - dev_err(&op->dev, "unable to map DMA registers\n"); - goto nodev; - } + dcrs = dcr_resource_start(np, 0); + if (dcrs == 0) { + dev_err(&op->dev, "could not get DMA register address\n"); + goto nodev; } + lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); + dev_dbg(&op->dev, "DCR base: %x\n", dcrs); lp->rx_irq = irq_of_parse_and_map(np, 0); lp->tx_irq = irq_of_parse_and_map(np, 1); -- cgit v1.2.3-59-g8ed1b From 5958f1d5d722df7a9e5d129676614a8e5219bacd Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 31 Mar 2010 21:56:41 +0200 Subject: x86, cpu: Add AMD core boosting feature flag to /proc/cpuinfo By semi-popular demand, this adds the Core Performance Boost feature flag to /proc/cpuinfo. Possible use case for this is userspace tools like cpufreq-aperf, for example, so that they don't have to jump through hoops of accessing "/dev/cpu/%d/cpuid" in order to check for CPB hw support, or call cpuid from userspace. Signed-off-by: Borislav Petkov LKML-Reference: <1270065406-1814-2-git-send-email-bp@amd64.org> Reviewed-by: Thomas Renninger Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/cpufeature.h | 1 + arch/x86/kernel/cpu/addon_cpuid_features.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 0cd82d068613..630e623f61e0 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -161,6 +161,7 @@ */ #define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */ #define X86_FEATURE_ARAT (7*32+ 1) /* Always Running APIC Timer */ +#define X86_FEATURE_CPB (7*32+ 2) /* AMD Core Performance Boost */ /* Virtualization flags: Linux defined */ #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c index 97ad79cdf688..ead2a1cfa570 100644 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c +++ b/arch/x86/kernel/cpu/addon_cpuid_features.c @@ -30,8 +30,9 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) const struct cpuid_bit *cb; static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { - { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 }, - { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 }, + { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 }, + { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 }, + { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007 }, { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a }, { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a }, { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a }, -- cgit v1.2.3-59-g8ed1b From 73860c6b2fd159a35637e233d735e36887c266ad Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 31 Mar 2010 21:56:42 +0200 Subject: powernow-k8: Add core performance boost support Starting with F10h, revE, AMD processors add support for a dynamic core boosting feature called Core Performance Boost. When a specific condition is present, a subset of the cores on a system are boosted beyond their P0 operating frequency to speed up the performance of single-threaded applications. In the normal case, the system comes out of reset with core boosting enabled. This patch adds a sysfs knob with which core boosting can be switched on or off for benchmarking purposes. While at it, make the CPB code hotplug-aware so that taking cores offline wouldn't interfere with boosting the remaining online cores. Furthermore, add cpu_online_mask hotplug protection as suggested by Andrew. Finally, cleanup the driver init codepath and update copyrights. Signed-off-by: Borislav Petkov LKML-Reference: <1270065406-1814-3-git-send-email-bp@amd64.org> Reviewed-by: Thomas Renninger Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 161 ++++++++++++++++++++++++++++-- arch/x86/kernel/cpu/cpufreq/powernow-k8.h | 2 - 2 files changed, 151 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index d360b56e9825..74ca34b5c003 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -1,6 +1,5 @@ - /* - * (c) 2003-2006 Advanced Micro Devices, Inc. + * (c) 2003-2010 Advanced Micro Devices, Inc. * Your use of this code is subject to the terms and conditions of the * GNU general public license version 2. See "COPYING" or * http://www.gnu.org/licenses/gpl.html @@ -54,6 +53,10 @@ static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data); static int cpu_family = CPU_OPTERON; +/* core performance boost */ +static bool cpb_capable, cpb_enabled; +static struct msr __percpu *msrs; + #ifndef CONFIG_SMP static inline const struct cpumask *cpu_core_mask(int cpu) { @@ -1393,8 +1396,77 @@ out: return khz; } +static void _cpb_toggle_msrs(bool t) +{ + int cpu; + + get_online_cpus(); + + rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs); + + for_each_cpu(cpu, cpu_online_mask) { + struct msr *reg = per_cpu_ptr(msrs, cpu); + if (t) + reg->l &= ~BIT(25); + else + reg->l |= BIT(25); + } + wrmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs); + + put_online_cpus(); +} + +/* + * Switch on/off core performance boosting. + * + * 0=disable + * 1=enable. + */ +static void cpb_toggle(bool t) +{ + if (!cpb_capable) + return; + + if (t && !cpb_enabled) { + cpb_enabled = true; + _cpb_toggle_msrs(t); + printk(KERN_INFO PFX "Core Boosting enabled.\n"); + } else if (!t && cpb_enabled) { + cpb_enabled = false; + _cpb_toggle_msrs(t); + printk(KERN_INFO PFX "Core Boosting disabled.\n"); + } +} + +static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf, + size_t count) +{ + int ret = -EINVAL; + unsigned long val = 0; + + ret = strict_strtoul(buf, 10, &val); + if (!ret && (val == 0 || val == 1) && cpb_capable) + cpb_toggle(val); + else + return -EINVAL; + + return count; +} + +static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf) +{ + return sprintf(buf, "%u\n", cpb_enabled); +} + +#define define_one_rw(_name) \ +static struct freq_attr _name = \ +__ATTR(_name, 0644, show_##_name, store_##_name) + +define_one_rw(cpb); + static struct freq_attr *powernow_k8_attr[] = { &cpufreq_freq_attr_scaling_available_freqs, + &cpb, NULL, }; @@ -1410,10 +1482,51 @@ static struct cpufreq_driver cpufreq_amd64_driver = { .attr = powernow_k8_attr, }; +/* + * Clear the boost-disable flag on the CPU_DOWN path so that this cpu + * cannot block the remaining ones from boosting. On the CPU_UP path we + * simply keep the boost-disable flag in sync with the current global + * state. + */ +static int __cpuinit cpb_notify(struct notifier_block *nb, unsigned long action, + void *hcpu) +{ + unsigned cpu = (long)hcpu; + u32 lo, hi; + + switch (action) { + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: + + if (!cpb_enabled) { + rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi); + lo |= BIT(25); + wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi); + } + break; + + case CPU_DOWN_PREPARE: + case CPU_DOWN_PREPARE_FROZEN: + rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi); + lo &= ~BIT(25); + wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi); + break; + + default: + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block __cpuinitdata cpb_nb = { + .notifier_call = cpb_notify, +}; + /* driver entry point for init */ static int __cpuinit powernowk8_init(void) { - unsigned int i, supported_cpus = 0; + unsigned int i, supported_cpus = 0, cpu; for_each_online_cpu(i) { int rc; @@ -1422,15 +1535,36 @@ static int __cpuinit powernowk8_init(void) supported_cpus++; } - if (supported_cpus == num_online_cpus()) { - printk(KERN_INFO PFX "Found %d %s " - "processors (%d cpu cores) (" VERSION ")\n", - num_online_nodes(), - boot_cpu_data.x86_model_id, supported_cpus); - return cpufreq_register_driver(&cpufreq_amd64_driver); + if (supported_cpus != num_online_cpus()) + return -ENODEV; + + printk(KERN_INFO PFX "Found %d %s (%d cpu cores) (" VERSION ")\n", + num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus); + + if (boot_cpu_has(X86_FEATURE_CPB)) { + + cpb_capable = true; + + register_cpu_notifier(&cpb_nb); + + msrs = msrs_alloc(); + if (!msrs) { + printk(KERN_ERR "%s: Error allocating msrs!\n", __func__); + return -ENOMEM; + } + + rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs); + + for_each_cpu(cpu, cpu_online_mask) { + struct msr *reg = per_cpu_ptr(msrs, cpu); + cpb_enabled |= !(!!(reg->l & BIT(25))); + } + + printk(KERN_INFO PFX "Core Performance Boosting: %s.\n", + (cpb_enabled ? "on" : "off")); } - return -ENODEV; + return cpufreq_register_driver(&cpufreq_amd64_driver); } /* driver entry point for term */ @@ -1438,6 +1572,13 @@ static void __exit powernowk8_exit(void) { dprintk("exit\n"); + if (boot_cpu_has(X86_FEATURE_CPB)) { + msrs_free(msrs); + msrs = NULL; + + unregister_cpu_notifier(&cpb_nb); + } + cpufreq_unregister_driver(&cpufreq_amd64_driver); } diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h index 02ce824073cb..df3529b1c02d 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h @@ -5,7 +5,6 @@ * http://www.gnu.org/licenses/gpl.html */ - enum pstate { HW_PSTATE_INVALID = 0xff, HW_PSTATE_0 = 0, @@ -55,7 +54,6 @@ struct powernow_k8_data { struct cpumask *available_cores; }; - /* processor's cpuid instruction support */ #define CPUID_PROCESSOR_SIGNATURE 1 /* function 1 */ #define CPUID_XFAM 0x0ff00000 /* extended family */ -- cgit v1.2.3-59-g8ed1b From d65ad45cd82a0db9544469b8c54f5dc5cafbb2d8 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 31 Mar 2010 21:56:43 +0200 Subject: x86: Unify APERF/MPERF support Initialize this CPUID flag feature in common code. It could be made a standalone function later, maybe, if more functionality is duplicated. Signed-off-by: Borislav Petkov LKML-Reference: <1270065406-1814-4-git-send-email-bp@amd64.org> Reviewed-by: Thomas Renninger Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/addon_cpuid_features.c | 8 ++++++++ arch/x86/kernel/cpu/intel.c | 6 ------ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c index ead2a1cfa570..fd1fc1902a47 100644 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c +++ b/arch/x86/kernel/cpu/addon_cpuid_features.c @@ -54,6 +54,14 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) if (regs[cb->reg] & (1 << cb->bit)) set_cpu_cap(c, cb->feature); } + + /* + * common AMD/Intel features + */ + if (c->cpuid_level >= 6) { + if (cpuid_ecx(6) & 0x1) + set_cpu_cap(c, X86_FEATURE_APERFMPERF); + } } /* leaf 0xb SMT level */ diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 7e1cca13af35..3830258a5f53 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -352,12 +352,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON); } - if (c->cpuid_level > 6) { - unsigned ecx = cpuid_ecx(6); - if (ecx & 0x01) - set_cpu_cap(c, X86_FEATURE_APERFMPERF); - } - if (cpu_has_xmm2) set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); if (cpu_has_ds) { -- cgit v1.2.3-59-g8ed1b From a2fed573f065e526bfd5cbf26e5491973d9e9aaa Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Thu, 18 Mar 2010 18:41:46 +0100 Subject: x86, cpufreq: Add APERF/MPERF support for AMD processors Starting with model 10 of Family 0x10, AMD processors may have support for APERF/MPERF. Add support for identifying it and using it within cpufreq. Move the APERF/MPERF functions out of the acpi-cpufreq code and into their own file so they can easily be shared. Signed-off-by: Mark Langsdorf LKML-Reference: <20100401141956.GA1930@aftab> Signed-off-by: Borislav Petkov Reviewed-by: Thomas Renninger Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/cpufreq/Makefile | 4 +-- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 44 ++------------------------ arch/x86/kernel/cpu/cpufreq/mperf.c | 51 ++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/cpufreq/mperf.h | 9 ++++++ arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 8 +++++ 5 files changed, 72 insertions(+), 44 deletions(-) create mode 100644 arch/x86/kernel/cpu/cpufreq/mperf.c create mode 100644 arch/x86/kernel/cpu/cpufreq/mperf.h (limited to 'arch') diff --git a/arch/x86/kernel/cpu/cpufreq/Makefile b/arch/x86/kernel/cpu/cpufreq/Makefile index 1840c0a5170b..bd54bf67e6fb 100644 --- a/arch/x86/kernel/cpu/cpufreq/Makefile +++ b/arch/x86/kernel/cpu/cpufreq/Makefile @@ -2,8 +2,8 @@ # K8 systems. ACPI is preferred to all other hardware-specific drivers. # speedstep-* is preferred over p4-clockmod. -obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o -obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o +obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o mperf.o +obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o mperf.o obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 1b1920fa7c80..dc68e5c2c071 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -45,6 +45,7 @@ #include #include #include +#include "mperf.h" #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ "acpi-cpufreq", msg) @@ -70,8 +71,6 @@ struct acpi_cpufreq_data { static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data); -static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf); - /* acpi_perf_data is a pointer to percpu data. */ static struct acpi_processor_performance *acpi_perf_data; @@ -239,45 +238,6 @@ static u32 get_cur_val(const struct cpumask *mask) return cmd.val; } -/* Called via smp_call_function_single(), on the target CPU */ -static void read_measured_perf_ctrs(void *_cur) -{ - struct aperfmperf *am = _cur; - - get_aperfmperf(am); -} - -/* - * Return the measured active (C0) frequency on this CPU since last call - * to this function. - * Input: cpu number - * Return: Average CPU frequency in terms of max frequency (zero on error) - * - * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance - * over a period of time, while CPU is in C0 state. - * IA32_MPERF counts at the rate of max advertised frequency - * IA32_APERF counts at the rate of actual CPU frequency - * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and - * no meaning should be associated with absolute values of these MSRs. - */ -static unsigned int get_measured_perf(struct cpufreq_policy *policy, - unsigned int cpu) -{ - struct aperfmperf perf; - unsigned long ratio; - unsigned int retval; - - if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1)) - return 0; - - ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf); - per_cpu(acfreq_old_perf, cpu) = perf; - - retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT; - - return retval; -} - static unsigned int get_cur_freq_on_cpu(unsigned int cpu) { struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu); @@ -701,7 +661,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) /* Check for APERF/MPERF support in hardware */ if (cpu_has(c, X86_FEATURE_APERFMPERF)) - acpi_cpufreq_driver.getavg = get_measured_perf; + acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf; dprintk("CPU%u - ACPI performance management activated.\n", cpu); for (i = 0; i < perf->state_count; i++) diff --git a/arch/x86/kernel/cpu/cpufreq/mperf.c b/arch/x86/kernel/cpu/cpufreq/mperf.c new file mode 100644 index 000000000000..911e193018ae --- /dev/null +++ b/arch/x86/kernel/cpu/cpufreq/mperf.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include + +#include "mperf.h" + +static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf); + +/* Called via smp_call_function_single(), on the target CPU */ +static void read_measured_perf_ctrs(void *_cur) +{ + struct aperfmperf *am = _cur; + + get_aperfmperf(am); +} + +/* + * Return the measured active (C0) frequency on this CPU since last call + * to this function. + * Input: cpu number + * Return: Average CPU frequency in terms of max frequency (zero on error) + * + * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance + * over a period of time, while CPU is in C0 state. + * IA32_MPERF counts at the rate of max advertised frequency + * IA32_APERF counts at the rate of actual CPU frequency + * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and + * no meaning should be associated with absolute values of these MSRs. + */ +unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy, + unsigned int cpu) +{ + struct aperfmperf perf; + unsigned long ratio; + unsigned int retval; + + if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1)) + return 0; + + ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf); + per_cpu(acfreq_old_perf, cpu) = perf; + + retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT; + + return retval; +} +EXPORT_SYMBOL_GPL(cpufreq_get_measured_perf); +MODULE_LICENSE("GPL"); diff --git a/arch/x86/kernel/cpu/cpufreq/mperf.h b/arch/x86/kernel/cpu/cpufreq/mperf.h new file mode 100644 index 000000000000..5dbf2950dc22 --- /dev/null +++ b/arch/x86/kernel/cpu/cpufreq/mperf.h @@ -0,0 +1,9 @@ +/* + * (c) 2010 Advanced Micro Devices, Inc. + * Your use of this code is subject to the terms and conditions of the + * GNU general public license version 2. See "COPYING" or + * http://www.gnu.org/licenses/gpl.html + */ + +unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy, + unsigned int cpu); diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 74ca34b5c003..52fce638f444 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -45,6 +45,7 @@ #define PFX "powernow-k8: " #define VERSION "version 2.20.00" #include "powernow-k8.h" +#include "mperf.h" /* serialize freq changes */ static DEFINE_MUTEX(fidvid_mutex); @@ -57,6 +58,8 @@ static int cpu_family = CPU_OPTERON; static bool cpb_capable, cpb_enabled; static struct msr __percpu *msrs; +static struct cpufreq_driver cpufreq_amd64_driver; + #ifndef CONFIG_SMP static inline const struct cpumask *cpu_core_mask(int cpu) { @@ -1251,6 +1254,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) struct powernow_k8_data *data; struct init_on_cpu init_on_cpu; int rc; + struct cpuinfo_x86 *c = &cpu_data(pol->cpu); if (!cpu_online(pol->cpu)) return -ENODEV; @@ -1325,6 +1329,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) return -EINVAL; } + /* Check for APERF/MPERF support in hardware */ + if (cpu_has(c, X86_FEATURE_APERFMPERF)) + cpufreq_amd64_driver.getavg = cpufreq_get_measured_perf; + cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); if (cpu_family == CPU_HW_PSTATE) -- cgit v1.2.3-59-g8ed1b From 679370641e3675633cad222449262abbe93a4a2a Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Wed, 31 Mar 2010 21:56:45 +0200 Subject: powernow-k8: Fix frequency reporting With F10, model 10, all valid frequencies are in the ACPI _PST table. Cc: # 33.x 32.x Signed-off-by: Mark Langsdorf LKML-Reference: <1270065406-1814-6-git-send-email-bp@amd64.org> Signed-off-by: Borislav Petkov Reviewed-by: Thomas Renninger Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 52fce638f444..6f3dc8fbbfdc 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -935,7 +935,8 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, powernow_table[i].index = index; /* Frequency may be rounded for these */ - if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) { + if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) + || boot_cpu_data.x86 == 0x11) { powernow_table[i].frequency = freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7); } else -- cgit v1.2.3-59-g8ed1b From 050d4cc7029b73997d6821d89487b1f777d4873c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 13 Apr 2010 10:15:56 +0900 Subject: sh: dmaengine support for SH7786 DMAC0. Hook up DMAC0 on SH7786. Signed-off-by: Paul Mundt --- arch/sh/include/cpu-sh4/cpu/dma-register.h | 3 +- arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 82 +++++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/cpu-sh4/cpu/dma-register.h b/arch/sh/include/cpu-sh4/cpu/dma-register.h index 55f9fec082d4..5df4df0c08dd 100644 --- a/arch/sh/include/cpu-sh4/cpu/dma-register.h +++ b/arch/sh/include/cpu-sh4/cpu/dma-register.h @@ -23,7 +23,8 @@ #define CHCR_TS_HIGH_MASK 0 #define CHCR_TS_HIGH_SHIFT 0 #elif defined(CONFIG_CPU_SUBTYPE_SH7722) || \ - defined(CONFIG_CPU_SUBTYPE_SH7724) + defined(CONFIG_CPU_SUBTYPE_SH7724) || \ + defined(CONFIG_CPU_SUBTYPE_SH7786) #define CHCR_TS_LOW_MASK 0x00000018 #define CHCR_TS_LOW_SHIFT 3 #define CHCR_TS_HIGH_MASK 0x00300000 diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index f5599907ac3d..61e549190873 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -1,7 +1,7 @@ /* * SH7786 Setup * - * Copyright (C) 2009 Renesas Solutions Corp. + * Copyright (C) 2009 - 2010 Renesas Solutions Corp. * Kuninori Morimoto * Paul Mundt * @@ -21,7 +21,9 @@ #include #include #include +#include #include +#include static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffea0000, @@ -442,6 +444,83 @@ static struct platform_device tmu11_device = { .num_resources = ARRAY_SIZE(tmu11_resources), }; +static struct sh_dmae_channel dmac0_channels[] = { + { + .offset = 0, + .dmars = 0, + .dmars_bit = 0, + }, { + .offset = 0x10, + .dmars = 0, + .dmars_bit = 8, + }, { + .offset = 0x20, + .dmars = 4, + .dmars_bit = 0, + }, { + .offset = 0x30, + .dmars = 4, + .dmars_bit = 8, + }, { + .offset = 0x50, + .dmars = 8, + .dmars_bit = 0, + }, { + .offset = 0x60, + .dmars = 8, + .dmars_bit = 8, + } +}; + +static unsigned int ts_shift[] = TS_SHIFT; + +static struct sh_dmae_pdata dma0_platform_data = { + .channel = dmac0_channels, + .channel_num = ARRAY_SIZE(dmac0_channels), + .ts_low_shift = CHCR_TS_LOW_SHIFT, + .ts_low_mask = CHCR_TS_LOW_MASK, + .ts_high_shift = CHCR_TS_HIGH_SHIFT, + .ts_high_mask = CHCR_TS_HIGH_MASK, + .ts_shift = ts_shift, + .ts_shift_num = ARRAY_SIZE(ts_shift), + .dmaor_init = DMAOR_INIT, +}; + +/* Resource order important! */ +static struct resource dmac0_resources[] = { + { + /* Channel registers and DMAOR */ + .start = 0xfe008020, + .end = 0xfe00808f, + .flags = IORESOURCE_MEM, + }, { + /* DMARSx */ + .start = 0xfe009000, + .end = 0xfe00900b, + .flags = IORESOURCE_MEM, + }, { + /* DMA error IRQ */ + .start = evt2irq(0x5c0), + .end = evt2irq(0x5c0), + .flags = IORESOURCE_IRQ, + }, { + /* IRQ for channels 0-5 */ + .start = evt2irq(0x500), + .end = evt2irq(0x5a0), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dma0_device = { + .name = "sh-dma-engine", + .id = 0, + .resource = dmac0_resources, + .num_resources = ARRAY_SIZE(dmac0_resources), + .dev = { + .platform_data = &dma0_platform_data, + }, +}; + static struct resource usb_ohci_resources[] = { [0] = { .start = 0xffe70400, @@ -489,6 +568,7 @@ static struct platform_device *sh7786_early_devices[] __initdata = { }; static struct platform_device *sh7786_devices[] __initdata = { + &dma0_device, &usb_ohci_device, }; -- cgit v1.2.3-59-g8ed1b From cb694769f0d0c1f6fb8c9dc806c0a68da1056055 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 13 Apr 2010 13:54:39 +1000 Subject: Revert "powerpc/mm: Bump SECTION_SIZE_BITS from 16MB to 256MB" This reverts commit 7545ba6f82924d4523f8f8a2baf2e517a750265d. It breaks eHEA among other issues --- arch/powerpc/include/asm/sparsemem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h index 13fe0a0e5806..54a47ea2c3aa 100644 --- a/arch/powerpc/include/asm/sparsemem.h +++ b/arch/powerpc/include/asm/sparsemem.h @@ -8,7 +8,7 @@ * MAX_PHYSADDR_BITS 2^N: how much physical address space we have * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space */ -#define SECTION_SIZE_BITS 28 +#define SECTION_SIZE_BITS 24 #define MAX_PHYSADDR_BITS 44 #define MAX_PHYSMEM_BITS 44 -- cgit v1.2.3-59-g8ed1b From 43b8774dc409ea5d9369b978e2e7bc79289f0522 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 13 Apr 2010 14:43:03 +0900 Subject: sh: intc: userimask support. This adds support for hardware-assisted userspace irq masking for special priority levels. Due to the SR.IMASK interactivity, only some platforms implement this in hardware (including but not limited to SH-4A interrupt controllers, and ARM-based SH-Mobile CPUs). Each CPU needs to wire this up on its own, for now only SH7786 is wired up as an example. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 + arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 3 ++ drivers/sh/Kconfig | 13 +++++++ drivers/sh/intc.c | 69 +++++++++++++++++++++++++++++++++- include/linux/sh_intc.h | 9 +++++ 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 drivers/sh/Kconfig (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 8d90564c2bcf..ba86bfba95ac 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -732,6 +732,8 @@ config GUSA_RB LLSC, this should be more efficient than the other alternative of disabling interrupts around the atomic sequence. +source "drivers/sh/Kconfig" + endmenu menu "Boot options" diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 61e549190873..235edf8065df 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -907,6 +908,7 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567, #define INTC_INTMSK2 INTMSK2 #define INTC_INTMSKCLR1 CnINTMSKCLR1 #define INTC_INTMSKCLR2 INTMSKCLR2 +#define INTC_USERIMASK 0xfe411000 void __init plat_irq_setup(void) { @@ -921,6 +923,7 @@ void __init plat_irq_setup(void) __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); register_intc_controller(&intc_desc); + register_intc_userimask(INTC_USERIMASK); } void __init plat_irq_setup_pins(int mode) diff --git a/drivers/sh/Kconfig b/drivers/sh/Kconfig new file mode 100644 index 000000000000..22c3cdaf22fe --- /dev/null +++ b/drivers/sh/Kconfig @@ -0,0 +1,13 @@ +config INTC_USERIMASK + bool "Userspace interrupt masking support" + depends on ARCH_SHMOBILE || (SUPERH && CPU_SH4A) + help + This enables support for hardware-assisted userspace hardirq + masking. + + SH-4A and newer interrupt blocks all support a special shadowed + page with all non-masking registers obscured when mapped in to + userspace. This is primarily for use by userspace device + drivers that are using special priority levels. + + If in doubt, say N. diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index 65e15828faaa..77d10acf1884 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -27,6 +27,7 @@ #include #include #include +#include #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ @@ -94,7 +95,8 @@ static DEFINE_SPINLOCK(vector_lock); #define SMP_NR(d, x) 1 #endif -static unsigned int intc_prio_level[NR_IRQS]; /* for now */ +static unsigned int intc_prio_level[NR_IRQS]; /* for now */ +static unsigned int default_prio_level = 2; /* 2 - 16 */ static unsigned long ack_handle[NR_IRQS]; static inline struct intc_desc_int *get_intc_desc(unsigned int irq) @@ -787,7 +789,7 @@ static void __init intc_register_irq(struct intc_desc *desc, /* set priority level * - this needs to be at least 2 for 5-bit priorities on 7780 */ - intc_prio_level[irq] = 2; + intc_prio_level[irq] = default_prio_level; /* enable secondary masking method if present */ if (data[!primary]) @@ -1037,6 +1039,64 @@ err0: return -ENOMEM; } +#ifdef CONFIG_INTC_USERIMASK +static void __iomem *uimask; + +int register_intc_userimask(unsigned long addr) +{ + if (unlikely(uimask)) + return -EBUSY; + + uimask = ioremap_nocache(addr, SZ_4K); + if (unlikely(!uimask)) + return -ENOMEM; + + pr_info("intc: userimask support registered for levels 0 -> %d\n", + default_prio_level - 1); + + return 0; +} + +static ssize_t +show_intc_userimask(struct sysdev_class *cls, + struct sysdev_class_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf); +} + +static ssize_t +store_intc_userimask(struct sysdev_class *cls, + struct sysdev_class_attribute *attr, + const char *buf, size_t count) +{ + unsigned long level; + + level = simple_strtoul(buf, NULL, 10); + + /* + * Minimal acceptable IRQ levels are in the 2 - 16 range, but + * these are chomped so as to not interfere with normal IRQs. + * + * Level 1 is a special case on some CPUs in that it's not + * directly settable, but given that USERIMASK cuts off below a + * certain level, we don't care about this limitation here. + * Level 0 on the other hand equates to user masking disabled. + * + * We use default_prio_level as a cut off so that only special + * case opt-in IRQs can be mangled. + */ + if (level >= default_prio_level) + return -EINVAL; + + __raw_writel(0xa5 << 24 | level << 4, uimask); + + return count; +} + +static SYSDEV_CLASS_ATTR(userimask, S_IRUSR | S_IWUSR, + show_intc_userimask, store_intc_userimask); +#endif + static ssize_t show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { @@ -1108,6 +1168,11 @@ static int __init register_intc_sysdevs(void) int id = 0; error = sysdev_class_register(&intc_sysdev_class); +#ifdef CONFIG_INTC_USERIMASK + if (!error && uimask) + error = sysdev_class_create_file(&intc_sysdev_class, + &attr_userimask); +#endif if (!error) { list_for_each_entry(d, &intc_list, list) { d->sysdev.id = id; diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h index 01d8168c5a1b..f0e8cca199c7 100644 --- a/include/linux/sh_intc.h +++ b/include/linux/sh_intc.h @@ -99,6 +99,15 @@ struct intc_desc symbol __initdata = { \ int __init register_intc_controller(struct intc_desc *desc); int intc_set_priority(unsigned int irq, unsigned int prio); +#ifdef CONFIG_INTC_USERIMASK +int register_intc_userimask(unsigned long addr); +#else +static inline int register_intc_userimask(unsigned long addr) +{ + return 0; +} +#endif + int reserve_irq_vector(unsigned int irq); void reserve_irq_legacy(void); -- cgit v1.2.3-59-g8ed1b From e44171f115de3dedf34064646206deb91549865f Mon Sep 17 00:00:00 2001 From: John Linn Date: Thu, 8 Apr 2010 07:08:02 +0000 Subject: Add non-Virtex5 support for LL TEMAC driver This patch adds support for using the LL TEMAC Ethernet driver on non-Virtex 5 platforms by adding support for accessing the Soft DMA registers as if they were memory mapped instead of solely through the DCR's (available on the Virtex 5). The patch also updates the driver so that it runs on the MicroBlaze. The changes were tested on the PowerPC 440, PowerPC 405, and the MicroBlaze platforms. Signed-off-by: John Tyner Signed-off-by: John Linn Acked-by: Grant Likely Signed-off-by: David S. Miller --- arch/microblaze/include/asm/system.h | 11 +++ drivers/net/Kconfig | 2 +- drivers/net/ll_temac.h | 14 +++- drivers/net/ll_temac_main.c | 137 ++++++++++++++++++++++++++--------- 4 files changed, 126 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h index 59efb3fef957..48c4f0335e3f 100644 --- a/arch/microblaze/include/asm/system.h +++ b/arch/microblaze/include/asm/system.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -96,4 +97,14 @@ extern struct dentry *of_debugfs_root; #define arch_align_stack(x) (x) +/* + * MicroBlaze doesn't handle unaligned accesses in hardware. + * + * Based on this we force the IP header alignment in network drivers. + * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining + * cacheline alignment of buffers. + */ +#define NET_IP_ALIGN 2 +#define NET_SKB_PAD L1_CACHE_BYTES + #endif /* _ASM_MICROBLAZE_SYSTEM_H */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 49c372a5e0b7..dbd26f992158 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2435,8 +2435,8 @@ config MV643XX_ETH config XILINX_LL_TEMAC tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver" + depends on PPC || MICROBLAZE select PHYLIB - depends on PPC_DCR_NATIVE help This driver supports the Xilinx 10/100/1000 LocalLink TEMAC core used in Xilinx Spartan and Virtex FPGAs diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h index 1af66a1e6911..c03358434acb 100644 --- a/drivers/net/ll_temac.h +++ b/drivers/net/ll_temac.h @@ -5,8 +5,11 @@ #include #include #include + +#ifdef CONFIG_PPC_DCR #include #include +#endif /* packet size info */ #define XTE_HDR_SIZE 14 /* size of Ethernet header */ @@ -290,9 +293,6 @@ This option defaults to enabled (set) */ #define TX_CONTROL_CALC_CSUM_MASK 1 -#define XTE_ALIGN 32 -#define BUFFER_ALIGN(adr) ((XTE_ALIGN - ((u32) adr)) % XTE_ALIGN) - #define MULTICAST_CAM_TABLE_NUM 4 /* TX/RX CURDESC_PTR points to first descriptor */ @@ -335,9 +335,15 @@ struct temac_local { struct mii_bus *mii_bus; /* MII bus reference */ int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */ - /* IO registers and IRQs */ + /* IO registers, dma functions and IRQs */ void __iomem *regs; + void __iomem *sdma_regs; +#ifdef CONFIG_PPC_DCR dcr_host_t sdma_dcrs; +#endif + u32 (*dma_in)(struct temac_local *, int); + void (*dma_out)(struct temac_local *, int, u32); + int tx_irq; int rx_irq; int emac_num; diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 67765756577d..78c9a2e6e51e 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -20,9 +20,6 @@ * or rx, so this should be okay. * * TODO: - * - Fix driver to work on more than just Virtex5. Right now the driver - * assumes that the locallink DMA registers are accessed via DCR - * instructions. * - Factor out locallink DMA code into separate driver * - Fix multicast assignment. * - Fix support for hardware checksumming. @@ -116,16 +113,85 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value) temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); } +/** + * temac_dma_in32 - Memory mapped DMA read, this function expects a + * register input that is based on DCR word addresses which + * are then converted to memory mapped byte addresses + */ static u32 temac_dma_in32(struct temac_local *lp, int reg) { - return dcr_read(lp->sdma_dcrs, reg); + return in_be32((u32 *)(lp->sdma_regs + (reg << 2))); } +/** + * temac_dma_out32 - Memory mapped DMA read, this function expects a + * register input that is based on DCR word addresses which + * are then converted to memory mapped byte addresses + */ static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) +{ + out_be32((u32 *)(lp->sdma_regs + (reg << 2)), value); +} + +/* DMA register access functions can be DCR based or memory mapped. + * The PowerPC 440 is DCR based, the PowerPC 405 and MicroBlaze are both + * memory mapped. + */ +#ifdef CONFIG_PPC_DCR + +/** + * temac_dma_dcr_in32 - DCR based DMA read + */ +static u32 temac_dma_dcr_in(struct temac_local *lp, int reg) +{ + return dcr_read(lp->sdma_dcrs, reg); +} + +/** + * temac_dma_dcr_out32 - DCR based DMA write + */ +static void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value) { dcr_write(lp->sdma_dcrs, reg, value); } +/** + * temac_dcr_setup - If the DMA is DCR based, then setup the address and + * I/O functions + */ +static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, + struct device_node *np) +{ + unsigned int dcrs; + + /* setup the dcr address mapping if it's in the device tree */ + + dcrs = dcr_resource_start(np, 0); + if (dcrs != 0) { + lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); + lp->dma_in = temac_dma_dcr_in; + lp->dma_out = temac_dma_dcr_out; + dev_dbg(&op->dev, "DCR base: %x\n", dcrs); + return 0; + } + /* no DCR in the device tree, indicate a failure */ + return -1; +} + +#else + +/* + * temac_dcr_setup - This is a stub for when DCR is not supported, + * such as with MicroBlaze + */ +static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, + struct device_node *np) +{ + return -1; +} + +#endif + /** * temac_dma_bd_init - Setup buffer descriptor rings */ @@ -156,14 +222,14 @@ static int temac_dma_bd_init(struct net_device *ndev) lp->rx_bd_v[i].next = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM); - skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE - + XTE_ALIGN, GFP_ATOMIC); + skb = netdev_alloc_skb_ip_align(ndev, + XTE_MAX_JUMBO_FRAME_SIZE); + if (skb == 0) { dev_err(&ndev->dev, "alloc_skb error %d\n", i); return -1; } lp->rx_skb[i] = skb; - skb_reserve(skb, BUFFER_ALIGN(skb->data)); /* returns physical address of skb->data */ lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, skb->data, @@ -173,23 +239,23 @@ static int temac_dma_bd_init(struct net_device *ndev) lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND; } - temac_dma_out32(lp, TX_CHNL_CTRL, 0x10220400 | + lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 | CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN); /* 0x10220483 */ /* 0x00100483 */ - temac_dma_out32(lp, RX_CHNL_CTRL, 0xff010000 | + lp->dma_out(lp, RX_CHNL_CTRL, 0xff010000 | CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN | CHNL_CTRL_IRQ_IOE); /* 0xff010283 */ - temac_dma_out32(lp, RX_CURDESC_PTR, lp->rx_bd_p); - temac_dma_out32(lp, RX_TAILDESC_PTR, + lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p); + lp->dma_out(lp, RX_TAILDESC_PTR, lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); - temac_dma_out32(lp, TX_CURDESC_PTR, lp->tx_bd_p); + lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); return 0; } @@ -427,9 +493,9 @@ static void temac_device_reset(struct net_device *ndev) temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK); /* Reset Local Link (DMA) */ - temac_dma_out32(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); + lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); timeout = 1000; - while (temac_dma_in32(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { + while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { udelay(1); if (--timeout == 0) { dev_err(&ndev->dev, @@ -437,7 +503,7 @@ static void temac_device_reset(struct net_device *ndev) break; } } - temac_dma_out32(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); + lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); temac_dma_bd_init(ndev); @@ -598,7 +664,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) lp->tx_bd_tail = 0; /* Kick off the transfer */ - temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ + lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ return NETDEV_TX_OK; } @@ -638,16 +704,15 @@ static void ll_temac_recv(struct net_device *ndev) ndev->stats.rx_packets++; ndev->stats.rx_bytes += length; - new_skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN, - GFP_ATOMIC); + new_skb = netdev_alloc_skb_ip_align(ndev, + XTE_MAX_JUMBO_FRAME_SIZE); + if (new_skb == 0) { dev_err(&ndev->dev, "no memory for new sk_buff\n"); spin_unlock_irqrestore(&lp->rx_lock, flags); return; } - skb_reserve(new_skb, BUFFER_ALIGN(new_skb->data)); - cur_p->app0 = STS_CTRL_APP0_IRQONEND; cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, XTE_MAX_JUMBO_FRAME_SIZE, @@ -662,7 +727,7 @@ static void ll_temac_recv(struct net_device *ndev) cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; bdstat = cur_p->app0; } - temac_dma_out32(lp, RX_TAILDESC_PTR, tail_p); + lp->dma_out(lp, RX_TAILDESC_PTR, tail_p); spin_unlock_irqrestore(&lp->rx_lock, flags); } @@ -673,8 +738,8 @@ static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) struct temac_local *lp = netdev_priv(ndev); unsigned int status; - status = temac_dma_in32(lp, TX_IRQ_REG); - temac_dma_out32(lp, TX_IRQ_REG, status); + status = lp->dma_in(lp, TX_IRQ_REG); + lp->dma_out(lp, TX_IRQ_REG, status); if (status & (IRQ_COAL | IRQ_DLY)) temac_start_xmit_done(lp->ndev); @@ -691,8 +756,8 @@ static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev) unsigned int status; /* Read and clear the status registers */ - status = temac_dma_in32(lp, RX_IRQ_REG); - temac_dma_out32(lp, RX_IRQ_REG, status); + status = lp->dma_in(lp, RX_IRQ_REG); + lp->dma_out(lp, RX_IRQ_REG, status); if (status & (IRQ_COAL | IRQ_DLY)) ll_temac_recv(lp->ndev); @@ -793,7 +858,7 @@ static ssize_t temac_show_llink_regs(struct device *dev, int i, len = 0; for (i = 0; i < 0x11; i++) - len += sprintf(buf + len, "%.8x%s", temac_dma_in32(lp, i), + len += sprintf(buf + len, "%.8x%s", lp->dma_in(lp, i), (i % 8) == 7 ? "\n" : " "); len += sprintf(buf + len, "\n"); @@ -819,7 +884,6 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) struct net_device *ndev; const void *addr; int size, rc = 0; - unsigned int dcrs; /* Init network device structure */ ndev = alloc_etherdev(sizeof(*lp)); @@ -869,13 +933,20 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) goto nodev; } - dcrs = dcr_resource_start(np, 0); - if (dcrs == 0) { - dev_err(&op->dev, "could not get DMA register address\n"); - goto nodev; + /* Setup the DMA register accesses, could be DCR or memory mapped */ + if (temac_dcr_setup(lp, op, np)) { + + /* no DCR in the device tree, try non-DCR */ + lp->sdma_regs = of_iomap(np, 0); + if (lp->sdma_regs) { + lp->dma_in = temac_dma_in32; + lp->dma_out = temac_dma_out32; + dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs); + } else { + dev_err(&op->dev, "unable to map DMA registers\n"); + goto nodev; + } } - lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); - dev_dbg(&op->dev, "DCR base: %x\n", dcrs); lp->rx_irq = irq_of_parse_and_map(np, 0); lp->tx_irq = irq_of_parse_and_map(np, 1); -- cgit v1.2.3-59-g8ed1b From b0c4c898833250ed143e615c32ea1be0e2155fdc Mon Sep 17 00:00:00 2001 From: Hartley Sweeten Date: Fri, 2 Apr 2010 18:04:47 +0100 Subject: ARM: 6025/1: vic: factor out common init code This factors out the common initialization code for the two vic vendors into easier maintainable functions. Tested-by: Linus Walleij Tested-by: Alessandro Rubini Cc: Andrea Gallo Cc: Ben Dooks Signed-off-by: H Hartley Sweeten Signed-off-by: Russell King --- arch/arm/common/vic.c | 107 ++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 55 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index 1cf999ade4bc..ba65f6eedca6 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c @@ -266,13 +266,53 @@ static int vic_set_wake(unsigned int irq, unsigned int on) #endif /* CONFIG_PM */ static struct irq_chip vic_chip = { - .name = "VIC", - .ack = vic_ack_irq, - .mask = vic_mask_irq, - .unmask = vic_unmask_irq, - .set_wake = vic_set_wake, + .name = "VIC", + .ack = vic_ack_irq, + .mask = vic_mask_irq, + .unmask = vic_unmask_irq, + .set_wake = vic_set_wake, }; +static void __init vic_disable(void __iomem *base) +{ + writel(0, base + VIC_INT_SELECT); + writel(0, base + VIC_INT_ENABLE); + writel(~0, base + VIC_INT_ENABLE_CLEAR); + writel(0, base + VIC_IRQ_STATUS); + writel(0, base + VIC_ITCR); + writel(~0, base + VIC_INT_SOFT_CLEAR); +} + +static void __init vic_clear_interrupts(void __iomem *base) +{ + unsigned int i; + + writel(0, base + VIC_PL190_VECT_ADDR); + for (i = 0; i < 19; i++) { + unsigned int value; + + value = readl(base + VIC_PL190_VECT_ADDR); + writel(value, base + VIC_PL190_VECT_ADDR); + } +} + +static void __init vic_set_irq_sources(void __iomem *base, + unsigned int irq_start, u32 vic_sources) +{ + unsigned int i; + + for (i = 0; i < 32; i++) { + if (vic_sources & (1 << i)) { + unsigned int irq = irq_start + i; + + set_irq_chip(irq, &vic_chip); + set_irq_chip_data(irq, base); + set_irq_handler(irq, handle_level_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + } +} + /* * The PL190 cell from ARM has been modified by ST to handle 64 interrupts. * The original cell has 32 interrupts, while the modified one has 64, @@ -287,13 +327,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0; /* Disable all interrupts initially. */ - - writel(0, base + VIC_INT_SELECT); - writel(0, base + VIC_INT_ENABLE); - writel(~0, base + VIC_INT_ENABLE_CLEAR); - writel(0, base + VIC_IRQ_STATUS); - writel(0, base + VIC_ITCR); - writel(~0, base + VIC_INT_SOFT_CLEAR); + vic_disable(base); /* * Make sure we clear all existing interrupts. The vector registers @@ -302,13 +336,8 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, * the second base address, which is 0x20 in the page */ if (vic_2nd_block) { - writel(0, base + VIC_PL190_VECT_ADDR); - for (i = 0; i < 19; i++) { - unsigned int value; + vic_clear_interrupts(base); - value = readl(base + VIC_PL190_VECT_ADDR); - writel(value, base + VIC_PL190_VECT_ADDR); - } /* ST has 16 vectors as well, but we don't enable them by now */ for (i = 0; i < 16; i++) { void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4); @@ -318,16 +347,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, writel(32, base + VIC_PL190_DEF_VECT_ADDR); } - for (i = 0; i < 32; i++) { - if (vic_sources & (1 << i)) { - unsigned int irq = irq_start + i; - - set_irq_chip(irq, &vic_chip); - set_irq_chip_data(irq, base); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - } + vic_set_irq_sources(base, irq_start, vic_sources); } /** @@ -365,37 +385,14 @@ void __init vic_init(void __iomem *base, unsigned int irq_start, } /* Disable all interrupts initially. */ + vic_disable(base); - writel(0, base + VIC_INT_SELECT); - writel(0, base + VIC_INT_ENABLE); - writel(~0, base + VIC_INT_ENABLE_CLEAR); - writel(0, base + VIC_IRQ_STATUS); - writel(0, base + VIC_ITCR); - writel(~0, base + VIC_INT_SOFT_CLEAR); - - /* - * Make sure we clear all existing interrupts - */ - writel(0, base + VIC_PL190_VECT_ADDR); - for (i = 0; i < 19; i++) { - unsigned int value; - - value = readl(base + VIC_PL190_VECT_ADDR); - writel(value, base + VIC_PL190_VECT_ADDR); - } + /* Make sure we clear all existing interrupts */ + vic_clear_interrupts(base); vic_init2(base); - for (i = 0; i < 32; i++) { - if (vic_sources & (1 << i)) { - unsigned int irq = irq_start + i; - - set_irq_chip(irq, &vic_chip); - set_irq_chip_data(irq, base); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - } + vic_set_irq_sources(base, irq_start, vic_sources); vic_pm_register(base, irq_start, resume_sources); } -- cgit v1.2.3-59-g8ed1b From b370e082e7c4bd47195b2ec117ceeadd9286d8c0 Mon Sep 17 00:00:00 2001 From: Hartley Sweeten Date: Thu, 18 Mar 2010 18:04:06 +0100 Subject: ARM: 5992/1: ep93xx: pass platform startup data as __initdata A number of the peripherals for the ep93xx are registered at startup using platform_data that is passed from the board init code to the core code. This data is then copied to a local static variable in the core code. Since the data is copied, the original data can be marked as __initdata and discarded after startup is complete. This adds the __initdata tag to all the appropriate data in the various ep93xx board init's. Specifically, all the struct ep93xx_eth_data, struct ep93xxfb_mach_info, and struct i2c_gpio_platform_data. Also, document the various registration functions and note what data should be marked as __initdata. While here, also cleanup a couple over zealous whitespace tabs. Signed-off-by: H Hartley Sweeten Acked-by: Ryan Mallon Signed-off-by: Russell King --- arch/arm/mach-ep93xx/adssphere.c | 2 +- arch/arm/mach-ep93xx/core.c | 57 +++++++++++++++++++++++++++++--------- arch/arm/mach-ep93xx/edb93xx.c | 4 +-- arch/arm/mach-ep93xx/gesbc9312.c | 2 +- arch/arm/mach-ep93xx/micro9.c | 2 +- arch/arm/mach-ep93xx/simone.c | 6 ++-- arch/arm/mach-ep93xx/snappercl15.c | 6 ++-- arch/arm/mach-ep93xx/ts72xx.c | 2 +- 8 files changed, 56 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c index caf6d5154aec..3a1a855bfdca 100644 --- a/arch/arm/mach-ep93xx/adssphere.c +++ b/arch/arm/mach-ep93xx/adssphere.c @@ -41,7 +41,7 @@ static struct platform_device adssphere_flash = { .resource = &adssphere_flash_resource, }; -static struct ep93xx_eth_data adssphere_eth_data = { +static struct ep93xx_eth_data __initdata adssphere_eth_data = { .phy_id = 1, }; diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 90fb591cbffa..5b1d836c2f05 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -330,6 +330,10 @@ static struct platform_device ep93xx_ohci_device = { .resource = ep93xx_ohci_resources, }; + +/************************************************************************* + * EP93xx ethernet peripheral handling + *************************************************************************/ static struct ep93xx_eth_data ep93xx_eth_data; static struct resource ep93xx_eth_resource[] = { @@ -354,6 +358,12 @@ static struct platform_device ep93xx_eth_device = { .resource = ep93xx_eth_resource, }; +/** + * ep93xx_register_eth - Register the built-in ethernet platform device. + * @data: platform specific ethernet configuration (__initdata) + * @copy_addr: flag indicating that the MAC address should be copied + * from the IndAd registers (as programmed by the bootloader) + */ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr) { if (copy_addr) @@ -370,11 +380,19 @@ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr) static struct i2c_gpio_platform_data ep93xx_i2c_data; static struct platform_device ep93xx_i2c_device = { - .name = "i2c-gpio", - .id = 0, - .dev.platform_data = &ep93xx_i2c_data, + .name = "i2c-gpio", + .id = 0, + .dev = { + .platform_data = &ep93xx_i2c_data, + }, }; +/** + * ep93xx_register_i2c - Register the i2c platform device. + * @data: platform specific i2c-gpio configuration (__initdata) + * @devices: platform specific i2c bus device information (__initdata) + * @num: the number of devices on the i2c bus + */ void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data, struct i2c_board_info *devices, int num) { @@ -404,11 +422,11 @@ void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data, *************************************************************************/ static struct gpio_led ep93xx_led_pins[] = { { - .name = "platform:grled", - .gpio = EP93XX_GPIO_LINE_GRLED, + .name = "platform:grled", + .gpio = EP93XX_GPIO_LINE_GRLED, }, { - .name = "platform:rdled", - .gpio = EP93XX_GPIO_LINE_RDLED, + .name = "platform:rdled", + .gpio = EP93XX_GPIO_LINE_RDLED, }, }; @@ -528,7 +546,7 @@ static struct platform_device ep93xx_fb_device = { .name = "ep93xx-fb", .id = -1, .dev = { - .platform_data = &ep93xxfb_data, + .platform_data = &ep93xxfb_data, .coherent_dma_mask = DMA_BIT_MASK(32), .dma_mask = &ep93xx_fb_device.dev.coherent_dma_mask, }, @@ -536,6 +554,10 @@ static struct platform_device ep93xx_fb_device = { .resource = ep93xx_fb_resource, }; +/** + * ep93xx_register_fb - Register the framebuffer platform device. + * @data: platform specific framebuffer configuration (__initdata) + */ void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data) { ep93xxfb_data = *data; @@ -546,6 +568,8 @@ void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data) /************************************************************************* * EP93xx matrix keypad peripheral handling *************************************************************************/ +static struct ep93xx_keypad_platform_data ep93xx_keypad_data; + static struct resource ep93xx_keypad_resource[] = { { .start = EP93XX_KEY_MATRIX_PHYS_BASE, @@ -559,15 +583,22 @@ static struct resource ep93xx_keypad_resource[] = { }; static struct platform_device ep93xx_keypad_device = { - .name = "ep93xx-keypad", - .id = -1, - .num_resources = ARRAY_SIZE(ep93xx_keypad_resource), - .resource = ep93xx_keypad_resource, + .name = "ep93xx-keypad", + .id = -1, + .dev = { + .platform_data = &ep93xx_keypad_data, + }, + .num_resources = ARRAY_SIZE(ep93xx_keypad_resource), + .resource = ep93xx_keypad_resource, }; +/** + * ep93xx_register_keypad - Register the keypad platform device. + * @data: platform specific keypad configuration (__initdata) + */ void __init ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data) { - ep93xx_keypad_device.dev.platform_data = data; + ep93xx_keypad_data = *data; platform_device_register(&ep93xx_keypad_device); } diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index d22d67ac8b99..3884182cd362 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -74,7 +74,7 @@ static void __init edb93xx_register_flash(void) } } -static struct ep93xx_eth_data edb93xx_eth_data = { +static struct ep93xx_eth_data __initdata edb93xx_eth_data = { .phy_id = 1, }; @@ -82,7 +82,7 @@ static struct ep93xx_eth_data edb93xx_eth_data = { /************************************************************************* * EDB93xx i2c peripheral handling *************************************************************************/ -static struct i2c_gpio_platform_data edb93xx_i2c_gpio_data = { +static struct i2c_gpio_platform_data __initdata edb93xx_i2c_gpio_data = { .sda_pin = EP93XX_GPIO_LINE_EEDAT, .sda_is_open_drain = 0, .scl_pin = EP93XX_GPIO_LINE_EECLK, diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c index 3da7ca816d19..a809618e9f05 100644 --- a/arch/arm/mach-ep93xx/gesbc9312.c +++ b/arch/arm/mach-ep93xx/gesbc9312.c @@ -41,7 +41,7 @@ static struct platform_device gesbc9312_flash = { .resource = &gesbc9312_flash_resource, }; -static struct ep93xx_eth_data gesbc9312_eth_data = { +static struct ep93xx_eth_data __initdata gesbc9312_eth_data = { .phy_id = 1, }; diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c index c33360e82868..1cc911b4efa6 100644 --- a/arch/arm/mach-ep93xx/micro9.c +++ b/arch/arm/mach-ep93xx/micro9.c @@ -80,7 +80,7 @@ static void __init micro9_register_flash(void) /************************************************************************* * Micro9 Ethernet *************************************************************************/ -static struct ep93xx_eth_data micro9_eth_data = { +static struct ep93xx_eth_data __initdata micro9_eth_data = { .phy_id = 0x1f, }; diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index cd93990f1b99..388aec95f60e 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c @@ -49,17 +49,17 @@ static struct platform_device simone_flash = { }, }; -static struct ep93xx_eth_data simone_eth_data = { +static struct ep93xx_eth_data __initdata simone_eth_data = { .phy_id = 1, }; -static struct ep93xxfb_mach_info simone_fb_info = { +static struct ep93xxfb_mach_info __initdata simone_fb_info = { .num_modes = EP93XXFB_USE_MODEDB, .bpp = 16, .flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING, }; -static struct i2c_gpio_platform_data simone_i2c_gpio_data = { +static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = { .sda_pin = EP93XX_GPIO_LINE_EEDAT, .sda_is_open_drain = 0, .scl_pin = EP93XX_GPIO_LINE_EECLK, diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c index 51134b0382ca..38deaee40397 100644 --- a/arch/arm/mach-ep93xx/snappercl15.c +++ b/arch/arm/mach-ep93xx/snappercl15.c @@ -125,11 +125,11 @@ static struct platform_device snappercl15_nand_device = { .num_resources = ARRAY_SIZE(snappercl15_nand_resource), }; -static struct ep93xx_eth_data snappercl15_eth_data = { +static struct ep93xx_eth_data __initdata snappercl15_eth_data = { .phy_id = 1, }; -static struct i2c_gpio_platform_data snappercl15_i2c_gpio_data = { +static struct i2c_gpio_platform_data __initdata snappercl15_i2c_gpio_data = { .sda_pin = EP93XX_GPIO_LINE_EEDAT, .sda_is_open_drain = 0, .scl_pin = EP93XX_GPIO_LINE_EECLK, @@ -145,7 +145,7 @@ static struct i2c_board_info __initdata snappercl15_i2c_data[] = { }, }; -static struct ep93xxfb_mach_info snappercl15_fb_info = { +static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = { .num_modes = EP93XXFB_USE_MODEDB, .bpp = 16, }; diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index fac1ec7a60fb..9553031900b0 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -186,7 +186,7 @@ static struct platform_device ts72xx_wdt_device = { .resource = ts72xx_wdt_resources, }; -static struct ep93xx_eth_data ts72xx_eth_data = { +static struct ep93xx_eth_data __initdata ts72xx_eth_data = { .phy_id = 1, }; -- cgit v1.2.3-59-g8ed1b From 99e6a23adfadc2da2006f3715c4332c3bf502c07 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Sat, 27 Mar 2010 12:05:14 +0100 Subject: ARM: 5998/1: ep93xx: added chip revision reading function Added a new function: ep93xx_chip_revision() which reads chip revision from the sysconfig register. Signed-off-by: Mika Westerberg Acked-by: H Hartley Sweeten Signed-off-by: Russell King --- arch/arm/mach-ep93xx/core.c | 14 ++++++++++++++ arch/arm/mach-ep93xx/include/mach/platform.h | 8 ++++++++ 2 files changed, 22 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 5b1d836c2f05..8d3f77e9fa86 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -222,6 +222,20 @@ void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits) } EXPORT_SYMBOL(ep93xx_devcfg_set_clear); +/** + * ep93xx_chip_revision() - returns the EP93xx chip revision + * + * See for more information. + */ +unsigned int ep93xx_chip_revision(void) +{ + unsigned int v; + + v = __raw_readl(EP93XX_SYSCON_SYSCFG); + v &= EP93XX_SYSCON_SYSCFG_REV_MASK; + v >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT; + return v; +} /************************************************************************* * EP93xx peripheral handling diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index c6dc14dbca18..b663390b4d87 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -33,6 +33,14 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits) ep93xx_devcfg_set_clear(0x00, bits); } +#define EP93XX_CHIP_REV_D0 3 +#define EP93XX_CHIP_REV_D1 4 +#define EP93XX_CHIP_REV_E0 5 +#define EP93XX_CHIP_REV_E1 6 +#define EP93XX_CHIP_REV_E2 7 + +unsigned int ep93xx_chip_revision(void); + void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); void ep93xx_register_i2c(struct i2c_gpio_platform_data *data, struct i2c_board_info *devices, int num); -- cgit v1.2.3-59-g8ed1b From 9b404b7cc3b066c57078b87f475562c37a74b814 Mon Sep 17 00:00:00 2001 From: Christian Glindkamp Date: Tue, 13 Apr 2010 14:55:10 +0100 Subject: ARM: 6054/1: AT91: taskit PortuxG20 and Stamp9G20 board support Both boards share the same board file, as the PortuxG20 is basically an SBC based on the Stamp9G20. Signed-off-by: Christian Glindkamp Acked-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/Kconfig | 13 ++ arch/arm/mach-at91/Makefile | 2 + arch/arm/mach-at91/board-stamp9g20.c | 315 +++++++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+) create mode 100644 arch/arm/mach-at91/board-stamp9g20.c (limited to 'arch') diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 2db43a5ddd9b..2c27300f9daf 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -360,6 +360,19 @@ config MACH_CPU9G20 Select this if you are using a Eukrea Electromatique's CPU9G20 Board +config MACH_PORTUXG20 + bool "taskit PortuxG20" + help + Select this if you are using taskit's PortuxG20. + + +config MACH_STAMP9G20 + bool "taskit Stamp9G20 CPU module" + help + Select this if you are using taskit's Stamp9G20 CPU module on its + evaluation board. + + endif # ---------------------------------------------------------- diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 027dd570dcc3..1df9ee1ba040 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -63,6 +63,8 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o +obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o +obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o # AT91SAM9G45 board-specific support obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c new file mode 100644 index 000000000000..87958274290f --- /dev/null +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2010 Christian Glindkamp + * taskit GmbH + * + * 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 +#include +#include +#include + +#include +#include + +#include +#include + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init portuxg20_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR + | ATMEL_UART_DCD | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART4 on ttyS5. (Rx, Tx only) */ + at91_register_uart(AT91SAM9260_ID_US4, 5, 0); + + /* USART5 on ttyS6. (Rx, Tx only) */ + at91_register_uart(AT91SAM9260_ID_US5, 6, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init stamp9g20_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR + | ATMEL_UART_DCD | ATMEL_UART_RI); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * NAND flash + */ +static struct atmel_nand_data __initdata nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .bus_width_16 = 0, +}; + +static struct sam9_smc_config __initdata nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 2, + .ncs_write_setup = 0, + .nwe_setup = 2, + + .ncs_read_pulse = 4, + .nrd_pulse = 4, + .ncs_write_pulse = 4, + .nwe_pulse = 4, + + .read_cycle = 7, + .write_cycle = 7, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 3, +}; + +static void __init add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &nand_smc_config); + + at91_add_device_nand(&nand_data); +} + + +/* + * MCI (SD/MMC) + * det_pin, wp_pin and vcc_pin are not connected + */ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static struct mci_platform_data __initdata mmc_data = { + .slot[0] = { + .bus_width = 4, + }, +}; +#else +static struct at91_mmc_data __initdata mmc_data = { + .slot_b = 0, + .wire4 = 1, +}; +#endif + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata usbh_data = { + .ports = 2, +}; + + +/* + * USB Device port + */ +static struct at91_udc_data __initdata portuxg20_udc_data = { + .vbus_pin = AT91_PIN_PC7, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +static struct at91_udc_data __initdata stamp9g20_udc_data = { + .vbus_pin = AT91_PIN_PA22, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata macb_data = { + .phy_irq_pin = AT91_PIN_PA28, + .is_rmii = 1, +}; + + +/* + * LEDs + */ +static struct gpio_led portuxg20_leds[] = { + { + .name = "LED2", + .gpio = AT91_PIN_PC5, + .default_trigger = "none", + }, { + .name = "LED3", + .gpio = AT91_PIN_PC4, + .default_trigger = "none", + }, { + .name = "LED4", + .gpio = AT91_PIN_PC10, + .default_trigger = "heartbeat", + } +}; + +static struct gpio_led stamp9g20_leds[] = { + { + .name = "D8", + .gpio = AT91_PIN_PB18, + .active_low = 1, + .default_trigger = "none", + }, { + .name = "D9", + .gpio = AT91_PIN_PB19, + .active_low = 1, + .default_trigger = "none", + }, { + .name = "D10", + .gpio = AT91_PIN_PB20, + .active_low = 1, + .default_trigger = "heartbeat", + } +}; + + +/* + * SPI devices + */ +static struct spi_board_info portuxg20_spi_devices[] = { + { + .modalias = "spidev", + .chip_select = 0, + .max_speed_hz = 1 * 1000 * 1000, + .bus_num = 0, + }, { + .modalias = "spidev", + .chip_select = 0, + .max_speed_hz = 1 * 1000 * 1000, + .bus_num = 1, + }, +}; + + +/* + * Dallas 1-Wire + */ +static struct w1_gpio_platform_data w1_gpio_pdata = { + .pin = AT91_PIN_PA29, + .is_open_drain = 1, +}; + +static struct platform_device w1_device = { + .name = "w1-gpio", + .id = -1, + .dev.platform_data = &w1_gpio_pdata, +}; + +void add_w1(void) +{ + at91_set_GPIO_periph(w1_gpio_pdata.pin, 1); + at91_set_multi_drive(w1_gpio_pdata.pin, 1); + platform_device_register(&w1_device); +} + + +static void __init generic_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* NAND */ + add_device_nand(); + /* MMC */ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) + at91_add_device_mci(0, &mmc_data); +#else + at91_add_device_mmc(0, &mmc_data); +#endif + /* USB Host */ + at91_add_device_usbh(&usbh_data); + /* Ethernet */ + at91_add_device_eth(&macb_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* W1 */ + add_w1(); +} + +static void __init portuxg20_board_init(void) +{ + generic_board_init(); + /* SPI */ + at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices)); + /* USB Device */ + at91_add_device_udc(&portuxg20_udc_data); + /* LEDs */ + at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds)); +} + +static void __init stamp9g20_board_init(void) +{ + generic_board_init(); + /* USB Device */ + at91_add_device_udc(&stamp9g20_udc_data); + /* LEDs */ + at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds)); +} + +MACHINE_START(PORTUXG20, "taskit PortuxG20") + /* Maintainer: taskit GmbH */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = portuxg20_map_io, + .init_irq = init_irq, + .init_machine = portuxg20_board_init, +MACHINE_END + +MACHINE_START(STAMP9G20, "taskit Stamp9G20") + /* Maintainer: taskit GmbH */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = stamp9g20_map_io, + .init_irq = init_irq, + .init_machine = stamp9g20_board_init, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 67be0b8dbaffc5ecdcc4dae3c8824a5197204c55 Mon Sep 17 00:00:00 2001 From: Christian Glindkamp Date: Tue, 13 Apr 2010 14:55:27 +0100 Subject: ARM: 6055/1: AT91: add defconfig for taskit PortuxG20 and Stamp9G20 Support for both boards can easily be built into one kernel image, so there is no need to add one defconfig for each of them. Signed-off-by: Christian Glindkamp Acked-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/configs/stamp9g20_defconfig | 1456 ++++++++++++++++++++++++++++++++++ 1 file changed, 1456 insertions(+) create mode 100644 arch/arm/configs/stamp9g20_defconfig (limited to 'arch') diff --git a/arch/arm/configs/stamp9g20_defconfig b/arch/arm/configs/stamp9g20_defconfig new file mode 100644 index 000000000000..06a8293c61ca --- /dev/null +++ b/arch/arm/configs/stamp9g20_defconfig @@ -0,0 +1,1456 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.34-rc1 +# Wed Mar 17 16:38:03 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +# CONFIG_TREE_RCU is not set +CONFIG_TREE_PREEMPT_RCU=y +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_LZO=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +CONFIG_ARCH_AT91=y +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_U8500 is not set +CONFIG_HAVE_AT91_USART3=y +CONFIG_HAVE_AT91_USART4=y +CONFIG_HAVE_AT91_USART5=y + +# +# Atmel AT91 System-on-Chip +# +# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_AT91SAM9260 is not set +# CONFIG_ARCH_AT91SAM9261 is not set +# CONFIG_ARCH_AT91SAM9G10 is not set +# CONFIG_ARCH_AT91SAM9263 is not set +# CONFIG_ARCH_AT91SAM9RL is not set +CONFIG_ARCH_AT91SAM9G20=y +# CONFIG_ARCH_AT91SAM9G45 is not set +# CONFIG_ARCH_AT91CAP9 is not set +# CONFIG_ARCH_AT572D940HF is not set +# CONFIG_ARCH_AT91X40 is not set +CONFIG_AT91_PMC_UNIT=y + +# +# AT91SAM9G20 Board Type +# +# CONFIG_MACH_AT91SAM9G20EK is not set +# CONFIG_MACH_AT91SAM9G20EK_2MMC is not set +# CONFIG_MACH_CPU9G20 is not set +CONFIG_MACH_PORTUXG20=y +CONFIG_MACH_STAMP9G20=y + +# +# AT91 Board Options +# + +# +# AT91 Feature Selections +# +CONFIG_AT91_PROGRAMMABLE_CLOCKS=y +CONFIG_AT91_SLOW_CLOCK=y +CONFIG_AT91_TIMER_HZ=100 +CONFIG_AT91_EARLY_DBGU=y +# CONFIG_AT91_EARLY_USART0 is not set +# CONFIG_AT91_EARLY_USART1 is not set +# CONFIG_AT91_EARLY_USART2 is not set +# CONFIG_AT91_EARLY_USART3 is not set +# CONFIG_AT91_EARLY_USART4 is not set +# CONFIG_AT91_EARLY_USART5 is not set + +# +# Processor Type +# +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" +# CONFIG_XIP_KERNEL is not set +CONFIG_KEXEC=y +CONFIG_ATAGS_PROC=y + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +# CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_ATMEL=y +# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set +CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_MACB=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_SERIAL_ATMEL_PDC=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +CONFIG_I2C_GPIO=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=y +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +CONFIG_W1=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_GPIO=y + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=y +# CONFIG_W1_SLAVE_SMEM is not set +CONFIG_W1_SLAVE_DS2431=y +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set +CONFIG_AT91SAM9X_WATCHDOG=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_AT91=y +CONFIG_USB_AT91=m +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_MASS_STORAGE is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set +CONFIG_MMC_ATMELMCI=y +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT91SAM9=y +CONFIG_RTC_DRV_AT91SAM9_RTT=0 +CONFIG_RTC_DRV_AT91SAM9_GPBR=0 +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_FRAME_POINTER=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_ARM_UNWIND is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +# CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y -- cgit v1.2.3-59-g8ed1b From a7e9c45219b2d40a80fbd1b7337cbecab85be2bd Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:30:19 +0100 Subject: ARM: 6010/1: ST SPEAr: Added basic header files for SPEAr3xx machine family Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/mach-spear3xx/include/mach/debug-macro.S | 14 ++ arch/arm/mach-spear3xx/include/mach/entry-macro.S | 46 ++++++ arch/arm/mach-spear3xx/include/mach/generic.h | 58 ++++++++ arch/arm/mach-spear3xx/include/mach/gpio.h | 19 +++ arch/arm/mach-spear3xx/include/mach/hardware.h | 20 +++ arch/arm/mach-spear3xx/include/mach/io.h | 19 +++ arch/arm/mach-spear3xx/include/mach/irqs.h | 65 +++++++++ arch/arm/mach-spear3xx/include/mach/memory.h | 19 +++ arch/arm/mach-spear3xx/include/mach/misc_regs.h | 163 ++++++++++++++++++++++ arch/arm/mach-spear3xx/include/mach/spear.h | 144 +++++++++++++++++++ arch/arm/mach-spear3xx/include/mach/spear300.h | 67 +++++++++ arch/arm/mach-spear3xx/include/mach/spear310.h | 46 ++++++ arch/arm/mach-spear3xx/include/mach/spear320.h | 70 ++++++++++ arch/arm/mach-spear3xx/include/mach/system.h | 19 +++ arch/arm/mach-spear3xx/include/mach/timex.h | 19 +++ arch/arm/mach-spear3xx/include/mach/uncompress.h | 19 +++ arch/arm/mach-spear3xx/include/mach/vmalloc.h | 19 +++ 17 files changed, 826 insertions(+) create mode 100644 arch/arm/mach-spear3xx/include/mach/debug-macro.S create mode 100644 arch/arm/mach-spear3xx/include/mach/entry-macro.S create mode 100644 arch/arm/mach-spear3xx/include/mach/generic.h create mode 100644 arch/arm/mach-spear3xx/include/mach/gpio.h create mode 100644 arch/arm/mach-spear3xx/include/mach/hardware.h create mode 100644 arch/arm/mach-spear3xx/include/mach/io.h create mode 100644 arch/arm/mach-spear3xx/include/mach/irqs.h create mode 100644 arch/arm/mach-spear3xx/include/mach/memory.h create mode 100755 arch/arm/mach-spear3xx/include/mach/misc_regs.h create mode 100644 arch/arm/mach-spear3xx/include/mach/spear.h create mode 100644 arch/arm/mach-spear3xx/include/mach/spear300.h create mode 100644 arch/arm/mach-spear3xx/include/mach/spear310.h create mode 100644 arch/arm/mach-spear3xx/include/mach/spear320.h create mode 100644 arch/arm/mach-spear3xx/include/mach/system.h create mode 100644 arch/arm/mach-spear3xx/include/mach/timex.h create mode 100644 arch/arm/mach-spear3xx/include/mach/uncompress.h create mode 100644 arch/arm/mach-spear3xx/include/mach/vmalloc.h (limited to 'arch') diff --git a/arch/arm/mach-spear3xx/include/mach/debug-macro.S b/arch/arm/mach-spear3xx/include/mach/debug-macro.S new file mode 100644 index 000000000000..590519f10d6e --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/debug-macro.S @@ -0,0 +1,14 @@ +/* + * arch/arm/mach-spear3xx/include/mach/debug-macro.S + * + * Debugging macro include header spear3xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 diff --git a/arch/arm/mach-spear3xx/include/mach/entry-macro.S b/arch/arm/mach-spear3xx/include/mach/entry-macro.S new file mode 100644 index 000000000000..947625d6b48d --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/entry-macro.S @@ -0,0 +1,46 @@ +/* + * arch/arm/mach-spear3xx/include/mach/entry-macro.S + * + * Low-level IRQ helper macros for SPEAr3xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \base, =VA_SPEAR3XX_ML1_VIC_BASE + ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get status + teq \irqstat, #0 + beq 1001f @ this will set/reset + @ zero register + /* + * Following code will find bit position of least significang + * bit set in irqstat, using following equation + * least significant bit set in n = (n & ~(n-1)) + */ + sub \tmp, \irqstat, #1 @ tmp = irqstat - 1 + mvn \tmp, \tmp @ tmp = ~tmp + and \irqstat, \irqstat, \tmp @ irqstat &= tmp + /* Now, irqstat is = bit no. of 1st bit set in vic irq status */ + clz \tmp, \irqstat @ tmp = leading zeros + rsb \irqnr, \tmp, #0x1F @ irqnr = 32 - tmp - 1 + +1001: /* EQ will be set if no irqs pending */ + .endm diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h new file mode 100644 index 000000000000..aeea8453a9e2 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/generic.h @@ -0,0 +1,58 @@ +/* + * arch/arm/mach-spear3xx/generic.h + * + * SPEAr3XX machine family generic header file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_GENERIC_H +#define __MACH_GENERIC_H + +#include +#include +#include +#include +#include + +/* + * Each GPT has 2 timer channels + * Following GPT channels will be used as clock source and clockevent + */ +#define SPEAR_GPT0_BASE SPEAR3XX_ML1_TMR_BASE +#define SPEAR_GPT0_CHAN0_IRQ IRQ_CPU_GPT1_1 +#define SPEAR_GPT0_CHAN1_IRQ IRQ_CPU_GPT1_2 + +/* Add spear3xx family device structure declarations here */ +extern struct amba_device gpio_device; +extern struct amba_device uart_device; +extern struct sys_timer spear_sys_timer; + +/* Add spear3xx family function declarations here */ +void __init spear3xx_map_io(void); +void __init spear3xx_init_irq(void); +void __init spear3xx_init(void); +void __init spear300_init(void); +void __init spear310_init(void); +void __init spear320_init(void); +void __init clk_init(void); + +/* Add spear300 machine device structure declarations here */ +#ifdef CONFIG_MACH_SPEAR300 +extern struct amba_device gpio1_device; +#endif /* CONFIG_MACH_SPEAR300 */ + +/* Add spear310 machine device structure declarations here */ +#ifdef CONFIG_MACH_SPEAR310 +#endif /* CONFIG_MACH_SPEAR310 */ + +/* Add spear320 machine device structure declarations here */ +#ifdef CONFIG_MACH_SPEAR320 +#endif /* CONFIG_MACH_SPEAR320 */ + +#endif /* __MACH_GENERIC_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/gpio.h b/arch/arm/mach-spear3xx/include/mach/gpio.h new file mode 100644 index 000000000000..451b2081bfc9 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/gpio.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear3xx/include/mach/gpio.h + * + * GPIO macros for SPEAr3xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_GPIO_H +#define __MACH_GPIO_H + +#include + +#endif /* __MACH_GPIO_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/hardware.h b/arch/arm/mach-spear3xx/include/mach/hardware.h new file mode 100644 index 000000000000..4a86e6a3c444 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/hardware.h @@ -0,0 +1,20 @@ +/* + * arch/arm/mach-spear3xx/include/mach/hardware.h + * + * Hardware definitions for SPEAr3xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_HARDWARE_H +#define __MACH_HARDWARE_H + +/* Vitual to physical translation of statically mapped space */ +#define IO_ADDRESS(x) (x | 0xF0000000) + +#endif /* __MACH_HARDWARE_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/io.h b/arch/arm/mach-spear3xx/include/mach/io.h new file mode 100644 index 000000000000..30cff8a1f6b5 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/io.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear3xx/include/mach/io.h + * + * IO definitions for SPEAr3xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_IO_H +#define __MACH_IO_H + +#include + +#endif /* __MACH_IO_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h new file mode 100644 index 000000000000..fe980e07b6ab --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/irqs.h @@ -0,0 +1,65 @@ +/* + * arch/arm/mach-spear3xx/include/mach/irqs.h + * + * IRQ helper macros for SPEAr3xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_IRQS_H +#define __MACH_IRQS_H + +/* IRQ definitions */ +#define IRQ_HW_ACCEL_MOD_0 0 +#define IRQ_INTRCOMM_RAS_ARM 1 +#define IRQ_CPU_GPT1_1 2 +#define IRQ_CPU_GPT1_2 3 +#define IRQ_BASIC_GPT1_1 4 +#define IRQ_BASIC_GPT1_2 5 +#define IRQ_BASIC_GPT2_1 6 +#define IRQ_BASIC_GPT2_2 7 +#define IRQ_BASIC_DMA 8 +#define IRQ_BASIC_SMI 9 +#define IRQ_BASIC_RTC 10 +#define IRQ_BASIC_GPIO 11 +#define IRQ_BASIC_WDT 12 +#define IRQ_DDR_CONTROLLER 13 +#define IRQ_SYS_ERROR 14 +#define IRQ_WAKEUP_RCV 15 +#define IRQ_JPEG 16 +#define IRQ_IRDA 17 +#define IRQ_ADC 18 +#define IRQ_UART 19 +#define IRQ_SSP 20 +#define IRQ_I2C 21 +#define IRQ_MAC_1 22 +#define IRQ_MAC_2 23 +#define IRQ_USB_DEV 24 +#define IRQ_USB_H_OHCI_0 25 +#define IRQ_USB_H_EHCI_0 26 +#define IRQ_USB_H_EHCI_1 IRQ_USB_H_EHCI_0 +#define IRQ_USB_H_OHCI_1 27 +#define IRQ_GEN_RAS_1 28 +#define IRQ_GEN_RAS_2 29 +#define IRQ_GEN_RAS_3 30 +#define IRQ_HW_ACCEL_MOD_1 31 +#define IRQ_VIC_END 32 + +#define SPEAR_GPIO_INT_BASE IRQ_VIC_END + +#ifdef CONFIG_MACH_SPEAR300 +#define SPEAR_GPIO1_INT_BASE (SPEAR_GPIO_INT_BASE + 8) +#define SPEAR_GPIO_INT_END (SPEAR_GPIO1_INT_BASE + 8) +#else +#define SPEAR_GPIO_INT_END (SPEAR_GPIO_INT_BASE + 8) +#endif + +#define VIRTUAL_IRQS (SPEAR_GPIO_INT_END - IRQ_VIC_END) +#define NR_IRQS (IRQ_VIC_END + VIRTUAL_IRQS) + +#endif /* __MACH_IRQS_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/memory.h b/arch/arm/mach-spear3xx/include/mach/memory.h new file mode 100644 index 000000000000..51735221ea19 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/memory.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear3xx/include/mach/memory.h + * + * Memory map for SPEAr3xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_MEMORY_H +#define __MACH_MEMORY_H + +#include + +#endif /* __MACH_MEMORY_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h new file mode 100755 index 000000000000..38d767a1aba0 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/misc_regs.h @@ -0,0 +1,163 @@ +/* + * arch/arm/mach-spear3xx/include/mach/misc_regs.h + * + * Miscellaneous registers definitions for SPEAr3xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_MISC_REGS_H +#define __MACH_MISC_REGS_H + +#include + +#define MISC_BASE VA_SPEAR3XX_ICM3_MISC_REG_BASE + +#define SOC_CFG_CTR ((unsigned int *)(MISC_BASE + 0x000)) +#define DIAG_CFG_CTR ((unsigned int *)(MISC_BASE + 0x004)) +#define PLL1_CTR ((unsigned int *)(MISC_BASE + 0x008)) +#define PLL1_FRQ ((unsigned int *)(MISC_BASE + 0x00C)) +#define PLL1_MOD ((unsigned int *)(MISC_BASE + 0x010)) +#define PLL2_CTR ((unsigned int *)(MISC_BASE + 0x014)) +/* PLL_CTR register masks */ +#define PLL_ENABLE 2 +#define PLL_MODE_SHIFT 4 +#define PLL_MODE_MASK 0x3 +#define PLL_MODE_NORMAL 0 +#define PLL_MODE_FRACTION 1 +#define PLL_MODE_DITH_DSB 2 +#define PLL_MODE_DITH_SSB 3 + +#define PLL2_FRQ ((unsigned int *)(MISC_BASE + 0x018)) +/* PLL FRQ register masks */ +#define PLL_DIV_N_SHIFT 0 +#define PLL_DIV_N_MASK 0xFF +#define PLL_DIV_P_SHIFT 8 +#define PLL_DIV_P_MASK 0x7 +#define PLL_NORM_FDBK_M_SHIFT 24 +#define PLL_NORM_FDBK_M_MASK 0xFF +#define PLL_DITH_FDBK_M_SHIFT 16 +#define PLL_DITH_FDBK_M_MASK 0xFFFF + +#define PLL2_MOD ((unsigned int *)(MISC_BASE + 0x01C)) +#define PLL_CLK_CFG ((unsigned int *)(MISC_BASE + 0x020)) +#define CORE_CLK_CFG ((unsigned int *)(MISC_BASE + 0x024)) +/* CORE CLK CFG register masks */ +#define PLL_HCLK_RATIO_SHIFT 10 +#define PLL_HCLK_RATIO_MASK 0x3 +#define HCLK_PCLK_RATIO_SHIFT 8 +#define HCLK_PCLK_RATIO_MASK 0x3 + +#define PERIP_CLK_CFG ((unsigned int *)(MISC_BASE + 0x028)) +/* PERIP_CLK_CFG register masks */ +#define UART_CLK_SHIFT 4 +#define UART_CLK_MASK 0x1 +#define FIRDA_CLK_SHIFT 5 +#define FIRDA_CLK_MASK 0x3 +#define GPT0_CLK_SHIFT 8 +#define GPT1_CLK_SHIFT 11 +#define GPT2_CLK_SHIFT 12 +#define GPT_CLK_MASK 0x1 +#define AUX_CLK_PLL3_MASK 0 +#define AUX_CLK_PLL1_MASK 1 + +#define PERIP1_CLK_ENB ((unsigned int *)(MISC_BASE + 0x02C)) +/* PERIP1_CLK_ENB register masks */ +#define UART_CLK_ENB 3 +#define SSP_CLK_ENB 5 +#define I2C_CLK_ENB 7 +#define JPEG_CLK_ENB 8 +#define FIRDA_CLK_ENB 10 +#define GPT1_CLK_ENB 11 +#define GPT2_CLK_ENB 12 +#define ADC_CLK_ENB 15 +#define RTC_CLK_ENB 17 +#define GPIO_CLK_ENB 18 +#define DMA_CLK_ENB 19 +#define SMI_CLK_ENB 21 +#define GMAC_CLK_ENB 23 +#define USBD_CLK_ENB 24 +#define USBH_CLK_ENB 25 +#define C3_CLK_ENB 31 + +#define SOC_CORE_ID ((unsigned int *)(MISC_BASE + 0x030)) +#define RAS_CLK_ENB ((unsigned int *)(MISC_BASE + 0x034)) +#define PERIP1_SOF_RST ((unsigned int *)(MISC_BASE + 0x038)) +/* PERIP1_SOF_RST register masks */ +#define JPEG_SOF_RST 8 + +#define SOC_USER_ID ((unsigned int *)(MISC_BASE + 0x03C)) +#define RAS_SOF_RST ((unsigned int *)(MISC_BASE + 0x040)) +#define PRSC1_CLK_CFG ((unsigned int *)(MISC_BASE + 0x044)) +#define PRSC2_CLK_CFG ((unsigned int *)(MISC_BASE + 0x048)) +#define PRSC3_CLK_CFG ((unsigned int *)(MISC_BASE + 0x04C)) +/* gpt synthesizer register masks */ +#define GPT_MSCALE_SHIFT 0 +#define GPT_MSCALE_MASK 0xFFF +#define GPT_NSCALE_SHIFT 12 +#define GPT_NSCALE_MASK 0xF + +#define AMEM_CLK_CFG ((unsigned int *)(MISC_BASE + 0x050)) +#define EXPI_CLK_CFG ((unsigned int *)(MISC_BASE + 0x054)) +#define CLCD_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x05C)) +#define FIRDA_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x060)) +#define UART_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x064)) +#define GMAC_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x068)) +#define RAS1_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x06C)) +#define RAS2_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x070)) +#define RAS3_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x074)) +#define RAS4_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x078)) +/* aux clk synthesiser register masks for irda to ras4 */ +#define AUX_EQ_SEL_SHIFT 30 +#define AUX_EQ_SEL_MASK 1 +#define AUX_EQ1_SEL 0 +#define AUX_EQ2_SEL 1 +#define AUX_XSCALE_SHIFT 16 +#define AUX_XSCALE_MASK 0xFFF +#define AUX_YSCALE_SHIFT 0 +#define AUX_YSCALE_MASK 0xFFF + +#define ICM1_ARB_CFG ((unsigned int *)(MISC_BASE + 0x07C)) +#define ICM2_ARB_CFG ((unsigned int *)(MISC_BASE + 0x080)) +#define ICM3_ARB_CFG ((unsigned int *)(MISC_BASE + 0x084)) +#define ICM4_ARB_CFG ((unsigned int *)(MISC_BASE + 0x088)) +#define ICM5_ARB_CFG ((unsigned int *)(MISC_BASE + 0x08C)) +#define ICM6_ARB_CFG ((unsigned int *)(MISC_BASE + 0x090)) +#define ICM7_ARB_CFG ((unsigned int *)(MISC_BASE + 0x094)) +#define ICM8_ARB_CFG ((unsigned int *)(MISC_BASE + 0x098)) +#define ICM9_ARB_CFG ((unsigned int *)(MISC_BASE + 0x09C)) +#define DMA_CHN_CFG ((unsigned int *)(MISC_BASE + 0x0A0)) +#define USB2_PHY_CFG ((unsigned int *)(MISC_BASE + 0x0A4)) +#define GMAC_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0A8)) +#define EXPI_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0AC)) +#define PRC1_LOCK_CTR ((unsigned int *)(MISC_BASE + 0x0C0)) +#define PRC2_LOCK_CTR ((unsigned int *)(MISC_BASE + 0x0C4)) +#define PRC3_LOCK_CTR ((unsigned int *)(MISC_BASE + 0x0C8)) +#define PRC4_LOCK_CTR ((unsigned int *)(MISC_BASE + 0x0CC)) +#define PRC1_IRQ_CTR ((unsigned int *)(MISC_BASE + 0x0D0)) +#define PRC2_IRQ_CTR ((unsigned int *)(MISC_BASE + 0x0D4)) +#define PRC3_IRQ_CTR ((unsigned int *)(MISC_BASE + 0x0D8)) +#define PRC4_IRQ_CTR ((unsigned int *)(MISC_BASE + 0x0DC)) +#define PWRDOWN_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0E0)) +#define COMPSSTL_1V8_CFG ((unsigned int *)(MISC_BASE + 0x0E4)) +#define COMPSSTL_2V5_CFG ((unsigned int *)(MISC_BASE + 0x0E8)) +#define COMPCOR_3V3_CFG ((unsigned int *)(MISC_BASE + 0x0EC)) +#define SSTLPAD_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0F0)) +#define BIST1_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0F4)) +#define BIST2_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0F8)) +#define BIST3_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0FC)) +#define BIST4_CFG_CTR ((unsigned int *)(MISC_BASE + 0x100)) +#define BIST5_CFG_CTR ((unsigned int *)(MISC_BASE + 0x104)) +#define BIST1_STS_RES ((unsigned int *)(MISC_BASE + 0x108)) +#define BIST2_STS_RES ((unsigned int *)(MISC_BASE + 0x10C)) +#define BIST3_STS_RES ((unsigned int *)(MISC_BASE + 0x110)) +#define BIST4_STS_RES ((unsigned int *)(MISC_BASE + 0x114)) +#define BIST5_STS_RES ((unsigned int *)(MISC_BASE + 0x118)) +#define SYSERR_CFG_CTR ((unsigned int *)(MISC_BASE + 0x11C)) + +#endif /* __MACH_MISC_REGS_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/spear.h b/arch/arm/mach-spear3xx/include/mach/spear.h new file mode 100644 index 000000000000..dcca8568a486 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/spear.h @@ -0,0 +1,144 @@ +/* + * arch/arm/mach-spear3xx/include/mach/spear.h + * + * SPEAr3xx Machine family specific definition + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_SPEAR3XX_H +#define __MACH_SPEAR3XX_H + +#include +#include +#include +#include + +#define SPEAR3XX_ML_SDRAM_BASE 0x00000000 +#define SPEAR3XX_ML_SDRAM_SIZE 0x40000000 + +#define SPEAR3XX_ICM9_BASE 0xC0000000 +#define SPEAR3XX_ICM9_SIZE 0x10000000 + +/* ICM1 - Low speed connection */ +#define SPEAR3XX_ICM1_2_BASE 0xD0000000 +#define SPEAR3XX_ICM1_2_SIZE 0x10000000 + +#define SPEAR3XX_ICM1_UART_BASE 0xD0000000 +#define VA_SPEAR3XX_ICM1_UART_BASE IO_ADDRESS(SPEAR3XX_ICM1_UART_BASE) +#define SPEAR3XX_ICM1_UART_SIZE 0x00080000 + +#define SPEAR3XX_ICM1_ADC_BASE 0xD0080000 +#define SPEAR3XX_ICM1_ADC_SIZE 0x00080000 + +#define SPEAR3XX_ICM1_SSP_BASE 0xD0100000 +#define SPEAR3XX_ICM1_SSP_SIZE 0x00080000 + +#define SPEAR3XX_ICM1_I2C_BASE 0xD0180000 +#define SPEAR3XX_ICM1_I2C_SIZE 0x00080000 + +#define SPEAR3XX_ICM1_JPEG_BASE 0xD0800000 +#define SPEAR3XX_ICM1_JPEG_SIZE 0x00800000 + +#define SPEAR3XX_ICM1_IRDA_BASE 0xD1000000 +#define SPEAR3XX_ICM1_IRDA_SIZE 0x00080000 + +#define SPEAR3XX_ICM1_SRAM_BASE 0xD2800000 +#define SPEAR3XX_ICM1_SRAM_SIZE 0x05800000 + +/* ICM2 - Application Subsystem */ +#define SPEAR3XX_ICM2_HWACCEL0_BASE 0xD8800000 +#define SPEAR3XX_ICM2_HWACCEL0_SIZE 0x00800000 + +#define SPEAR3XX_ICM2_HWACCEL1_BASE 0xD9000000 +#define SPEAR3XX_ICM2_HWACCEL1_SIZE 0x00800000 + +/* ICM4 - High Speed Connection */ +#define SPEAR3XX_ICM4_BASE 0xE0000000 +#define SPEAR3XX_ICM4_SIZE 0x08000000 + +#define SPEAR3XX_ICM4_MII_BASE 0xE0800000 +#define SPEAR3XX_ICM4_MII_SIZE 0x00800000 + +#define SPEAR3XX_ICM4_USBD_FIFO_BASE 0xE1000000 +#define SPEAR3XX_ICM4_USBD_FIFO_SIZE 0x00100000 + +#define SPEAR3XX_ICM4_USBD_CSR_BASE 0xE1100000 +#define SPEAR3XX_ICM4_USBD_CSR_SIZE 0x00100000 + +#define SPEAR3XX_ICM4_USBD_PLDT_BASE 0xE1200000 +#define SPEAR3XX_ICM4_USBD_PLDT_SIZE 0x00100000 + +#define SPEAR3XX_ICM4_USB_EHCI0_1_BASE 0xE1800000 +#define SPEAR3XX_ICM4_USB_EHCI0_1_SIZE 0x00100000 + +#define SPEAR3XX_ICM4_USB_OHCI0_BASE 0xE1900000 +#define SPEAR3XX_ICM4_USB_OHCI0_SIZE 0x00100000 + +#define SPEAR3XX_ICM4_USB_OHCI1_BASE 0xE2100000 +#define SPEAR3XX_ICM4_USB_OHCI1_SIZE 0x00100000 + +#define SPEAR3XX_ICM4_USB_ARB_BASE 0xE2800000 +#define SPEAR3XX_ICM4_USB_ARB_SIZE 0x00010000 + +/* ML1 - Multi Layer CPU Subsystem */ +#define SPEAR3XX_ICM3_ML1_2_BASE 0xF0000000 +#define SPEAR3XX_ICM3_ML1_2_SIZE 0x0F000000 + +#define SPEAR3XX_ML1_TMR_BASE 0xF0000000 +#define SPEAR3XX_ML1_TMR_SIZE 0x00100000 + +#define SPEAR3XX_ML1_VIC_BASE 0xF1100000 +#define VA_SPEAR3XX_ML1_VIC_BASE IO_ADDRESS(SPEAR3XX_ML1_VIC_BASE) +#define SPEAR3XX_ML1_VIC_SIZE 0x00100000 + +/* ICM3 - Basic Subsystem */ +#define SPEAR3XX_ICM3_SMEM_BASE 0xF8000000 +#define SPEAR3XX_ICM3_SMEM_SIZE 0x04000000 + +#define SPEAR3XX_ICM3_SMI_CTRL_BASE 0xFC000000 +#define SPEAR3XX_ICM3_SMI_CTRL_SIZE 0x00200000 + +#define SPEAR3XX_ICM3_DMA_BASE 0xFC400000 +#define SPEAR3XX_ICM3_DMA_SIZE 0x00200000 + +#define SPEAR3XX_ICM3_SDRAM_CTRL_BASE 0xFC600000 +#define SPEAR3XX_ICM3_SDRAM_CTRL_SIZE 0x00200000 + +#define SPEAR3XX_ICM3_TMR0_BASE 0xFC800000 +#define SPEAR3XX_ICM3_TMR0_SIZE 0x00080000 + +#define SPEAR3XX_ICM3_WDT_BASE 0xFC880000 +#define SPEAR3XX_ICM3_WDT_SIZE 0x00080000 + +#define SPEAR3XX_ICM3_RTC_BASE 0xFC900000 +#define SPEAR3XX_ICM3_RTC_SIZE 0x00080000 + +#define SPEAR3XX_ICM3_GPIO_BASE 0xFC980000 +#define SPEAR3XX_ICM3_GPIO_SIZE 0x00080000 + +#define SPEAR3XX_ICM3_SYS_CTRL_BASE 0xFCA00000 +#define VA_SPEAR3XX_ICM3_SYS_CTRL_BASE IO_ADDRESS(SPEAR3XX_ICM3_SYS_CTRL_BASE) +#define SPEAR3XX_ICM3_SYS_CTRL_SIZE 0x00080000 + +#define SPEAR3XX_ICM3_MISC_REG_BASE 0xFCA80000 +#define VA_SPEAR3XX_ICM3_MISC_REG_BASE IO_ADDRESS(SPEAR3XX_ICM3_MISC_REG_BASE) +#define SPEAR3XX_ICM3_MISC_REG_SIZE 0x00080000 + +#define SPEAR3XX_ICM3_TMR1_BASE 0xFCB00000 +#define SPEAR3XX_ICM3_TMR1_SIZE 0x00080000 + +/* Debug uart for linux, will be used for debug and uncompress messages */ +#define SPEAR_DBG_UART_BASE SPEAR3XX_ICM1_UART_BASE +#define VA_SPEAR_DBG_UART_BASE VA_SPEAR3XX_ICM1_UART_BASE + +/* Sysctl base for spear platform */ +#define SPEAR_SYS_CTRL_BASE SPEAR3XX_ICM3_SYS_CTRL_BASE +#define VA_SPEAR_SYS_CTRL_BASE VA_SPEAR3XX_ICM3_SYS_CTRL_BASE + +#endif /* __MACH_SPEAR3XX_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h new file mode 100644 index 000000000000..40c16f385cfa --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/spear300.h @@ -0,0 +1,67 @@ +/* + * arch/arm/mach-spear3xx/include/mach/spear300.h + * + * SPEAr300 Machine specific definition + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifdef CONFIG_MACH_SPEAR300 + +#ifndef __MACH_SPEAR300_H +#define __MACH_SPEAR300_H + +/* Base address of various IPs */ +#define SPEAR300_TELECOM_BASE 0x50000000 +#define SPEAR300_TELECOM_SIZE 0x10000000 + +#define SPEAR300_CLCD_BASE 0x60000000 +#define SPEAR300_CLCD_SIZE 0x10000000 + +#define SPEAR300_SDIO_BASE 0x70000000 +#define SPEAR300_SDIO_SIZE 0x10000000 + +#define SPEAR300_NAND_0_BASE 0x80000000 +#define SPEAR300_NAND_0_SIZE 0x04000000 + +#define SPEAR300_NAND_1_BASE 0x84000000 +#define SPEAR300_NAND_1_SIZE 0x04000000 + +#define SPEAR300_NAND_2_BASE 0x88000000 +#define SPEAR300_NAND_2_SIZE 0x04000000 + +#define SPEAR300_NAND_3_BASE 0x8c000000 +#define SPEAR300_NAND_3_SIZE 0x04000000 + +#define SPEAR300_NOR_0_BASE 0x90000000 +#define SPEAR300_NOR_0_SIZE 0x01000000 + +#define SPEAR300_NOR_1_BASE 0x91000000 +#define SPEAR300_NOR_1_SIZE 0x01000000 + +#define SPEAR300_NOR_2_BASE 0x92000000 +#define SPEAR300_NOR_2_SIZE 0x01000000 + +#define SPEAR300_NOR_3_BASE 0x93000000 +#define SPEAR300_NOR_3_SIZE 0x01000000 + +#define SPEAR300_FSMC_BASE 0x94000000 +#define SPEAR300_FSMC_SIZE 0x05000000 + +#define SPEAR300_SOC_CONFIG_BASE 0x99000000 +#define SPEAR300_SOC_CONFIG_SIZE 0x00000008 + +#define SPEAR300_KEYBOARD_BASE 0xA0000000 +#define SPEAR300_KEYBOARD_SIZE 0x09000000 + +#define SPEAR300_GPIO_BASE 0xA9000000 +#define SPEAR300_GPIO_SIZE 0x07000000 + +#endif /* __MACH_SPEAR300_H */ + +#endif /* CONFIG_MACH_SPEAR300 */ diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h new file mode 100644 index 000000000000..d4f58d6469d9 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/spear310.h @@ -0,0 +1,46 @@ +/* + * arch/arm/mach-spear3xx/include/mach/spear310.h + * + * SPEAr310 Machine specific definition + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifdef CONFIG_MACH_SPEAR310 + +#ifndef __MACH_SPEAR310_H +#define __MACH_SPEAR310_H + +#define SPEAR310_NAND_BASE 0x40000000 +#define SPEAR310_NAND_SIZE 0x04000000 + +#define SPEAR310_FSMC_BASE 0x44000000 +#define SPEAR310_FSMC_SIZE 0x01000000 + +#define SPEAR310_UART1_BASE 0xB2000000 +#define SPEAR310_UART2_BASE 0xB2080000 +#define SPEAR310_UART3_BASE 0xB2100000 +#define SPEAR310_UART4_BASE 0xB2180000 +#define SPEAR310_UART5_BASE 0xB2200000 +#define SPEAR310_UART_SIZE 0x00080000 + +#define SPEAR310_HDLC_BASE 0xB2800000 +#define SPEAR310_HDLC_SIZE 0x00800000 + +#define SPEAR310_RS485_0_BASE 0xB3000000 +#define SPEAR310_RS485_0_SIZE 0x00800000 + +#define SPEAR310_RS485_1_BASE 0xB3800000 +#define SPEAR310_RS485_1_SIZE 0x00800000 + +#define SPEAR310_SOC_CONFIG_BASE 0xB4000000 +#define SPEAR310_SOC_CONFIG_SIZE 0x00000070 + +#endif /* __MACH_SPEAR310_H */ + +#endif /* CONFIG_MACH_SPEAR310 */ diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h new file mode 100644 index 000000000000..e8ad2ed82e24 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/spear320.h @@ -0,0 +1,70 @@ +/* + * arch/arm/mach-spear3xx/include/mach/spear320.h + * + * SPEAr320 Machine specific definition + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifdef CONFIG_MACH_SPEAR320 + +#ifndef __MACH_SPEAR320_H +#define __MACH_SPEAR320_H + +#define SPEAR320_EMI_CTRL_BASE 0x40000000 +#define SPEAR320_EMI_CTRL_SIZE 0x08000000 + +#define SPEAR320_FSMC_BASE 0x4C000000 +#define SPEAR320_FSMC_SIZE 0x01000000 + +#define SPEAR320_I2S_BASE 0x60000000 +#define SPEAR320_I2S_SIZE 0x10000000 + +#define SPEAR320_SDIO_BASE 0x70000000 +#define SPEAR320_SDIO_SIZE 0x10000000 + +#define SPEAR320_CLCD_BASE 0x90000000 +#define SPEAR320_CLCD_SIZE 0x10000000 + +#define SPEAR320_PAR_PORT_BASE 0xA0000000 +#define SPEAR320_PAR_PORT_SIZE 0x01000000 + +#define SPEAR320_CAN0_BASE 0xA1000000 +#define SPEAR320_CAN0_SIZE 0x01000000 + +#define SPEAR320_CAN1_BASE 0xA2000000 +#define SPEAR320_CAN1_SIZE 0x01000000 + +#define SPEAR320_UART1_BASE 0xA3000000 +#define SPEAR320_UART2_BASE 0xA4000000 +#define SPEAR320_UART_SIZE 0x01000000 + +#define SPEAR320_SSP0_BASE 0xA5000000 +#define SPEAR320_SSP0_SIZE 0x01000000 + +#define SPEAR320_SSP1_BASE 0xA6000000 +#define SPEAR320_SSP1_SIZE 0x01000000 + +#define SPEAR320_I2C_BASE 0xA7000000 +#define SPEAR320_I2C_SIZE 0x01000000 + +#define SPEAR320_PWM_BASE 0xA8000000 +#define SPEAR320_PWM_SIZE 0x01000000 + +#define SPEAR320_SMII0_BASE 0xAA000000 +#define SPEAR320_SMII0_SIZE 0x01000000 + +#define SPEAR320_SMII1_BASE 0xAB000000 +#define SPEAR320_SMII1_SIZE 0x01000000 + +#define SPEAR320_SOC_CONFIG_BASE 0xB4000000 +#define SPEAR320_SOC_CONFIG_SIZE 0x00000070 + +#endif /* __MACH_SPEAR320_H */ + +#endif /* CONFIG_MACH_SPEAR320 */ diff --git a/arch/arm/mach-spear3xx/include/mach/system.h b/arch/arm/mach-spear3xx/include/mach/system.h new file mode 100644 index 000000000000..92cee6335c90 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/system.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear3xx/include/mach/system.h + * + * SPEAr3xx Machine family specific architecture functions + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_SYSTEM_H +#define __MACH_SYSTEM_H + +#include + +#endif /* __MACH_SYSTEM_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/timex.h b/arch/arm/mach-spear3xx/include/mach/timex.h new file mode 100644 index 000000000000..a38cc9de876f --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/timex.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear3xx/include/mach/timex.h + * + * SPEAr3XX machine family specific timex definitions + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_TIMEX_H +#define __MACH_TIMEX_H + +#include + +#endif /* __MACH_TIMEX_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/uncompress.h b/arch/arm/mach-spear3xx/include/mach/uncompress.h new file mode 100644 index 000000000000..53ba8bbc0dfa --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/uncompress.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear3xx/include/mach/uncompress.h + * + * Serial port stubs for kernel decompress status messages + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_UNCOMPRESS_H +#define __MACH_UNCOMPRESS_H + +#include + +#endif /* __MACH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/vmalloc.h b/arch/arm/mach-spear3xx/include/mach/vmalloc.h new file mode 100644 index 000000000000..df977b3c9a63 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/vmalloc.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear3xx/include/mach/vmalloc.h + * + * Defining Vmalloc area for SPEAr3xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_VMALLOC_H +#define __MACH_VMALLOC_H + +#include + +#endif /* __MACH_VMALLOC_H */ -- cgit v1.2.3-59-g8ed1b From 3f10940e4fb69d312602078f2c5234206797ca31 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 10 Apr 2010 16:46:21 +0200 Subject: x86/microcode: Use nonseekable_open() No need to seek on this file, so prevent it outright so we can avoid using default_llseek - removes one more BKL usage. Signed-off-by: Arnd Bergmann [drop useless llseek = no_llseek and smp_lock.h inclusion] Signed-off-by: Frederic Weisbecker Cc: Arnd Bergmann Cc: H. Peter Anvin Cc: Dmitry Adamushko LKML-Reference: <1270910781-8786-1-git-send-regression-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/microcode_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index cceb5bc3c3c2..2cd8c544e41a 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c @@ -201,9 +201,9 @@ static int do_microcode_update(const void __user *buf, size_t size) return error; } -static int microcode_open(struct inode *unused1, struct file *unused2) +static int microcode_open(struct inode *inode, struct file *file) { - return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; + return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM; } static ssize_t microcode_write(struct file *file, const char __user *buf, -- cgit v1.2.3-59-g8ed1b From e024c3d50c53999d15e3b8a21e0abbbf74c32140 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:30:31 +0100 Subject: ARM: 6011/1: ST SPEAr: Added basic header files for SPEAr6xx machine family Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Rajeev Kumar Signed-off-by: Russell King --- arch/arm/mach-spear6xx/include/mach/debug-macro.S | 14 ++ arch/arm/mach-spear6xx/include/mach/entry-macro.S | 55 +++++++ arch/arm/mach-spear6xx/include/mach/generic.h | 45 ++++++ arch/arm/mach-spear6xx/include/mach/gpio.h | 19 +++ arch/arm/mach-spear6xx/include/mach/hardware.h | 21 +++ arch/arm/mach-spear6xx/include/mach/io.h | 20 +++ arch/arm/mach-spear6xx/include/mach/irqs.h | 96 ++++++++++++ arch/arm/mach-spear6xx/include/mach/memory.h | 19 +++ arch/arm/mach-spear6xx/include/mach/misc_regs.h | 173 ++++++++++++++++++++++ arch/arm/mach-spear6xx/include/mach/spear.h | 173 ++++++++++++++++++++++ arch/arm/mach-spear6xx/include/mach/spear600.h | 21 +++ arch/arm/mach-spear6xx/include/mach/system.h | 19 +++ arch/arm/mach-spear6xx/include/mach/timex.h | 19 +++ arch/arm/mach-spear6xx/include/mach/uncompress.h | 19 +++ arch/arm/mach-spear6xx/include/mach/vmalloc.h | 19 +++ 15 files changed, 732 insertions(+) create mode 100644 arch/arm/mach-spear6xx/include/mach/debug-macro.S create mode 100644 arch/arm/mach-spear6xx/include/mach/entry-macro.S create mode 100644 arch/arm/mach-spear6xx/include/mach/generic.h create mode 100644 arch/arm/mach-spear6xx/include/mach/gpio.h create mode 100644 arch/arm/mach-spear6xx/include/mach/hardware.h create mode 100644 arch/arm/mach-spear6xx/include/mach/io.h create mode 100644 arch/arm/mach-spear6xx/include/mach/irqs.h create mode 100644 arch/arm/mach-spear6xx/include/mach/memory.h create mode 100644 arch/arm/mach-spear6xx/include/mach/misc_regs.h create mode 100644 arch/arm/mach-spear6xx/include/mach/spear.h create mode 100644 arch/arm/mach-spear6xx/include/mach/spear600.h create mode 100644 arch/arm/mach-spear6xx/include/mach/system.h create mode 100644 arch/arm/mach-spear6xx/include/mach/timex.h create mode 100644 arch/arm/mach-spear6xx/include/mach/uncompress.h create mode 100644 arch/arm/mach-spear6xx/include/mach/vmalloc.h (limited to 'arch') diff --git a/arch/arm/mach-spear6xx/include/mach/debug-macro.S b/arch/arm/mach-spear6xx/include/mach/debug-macro.S new file mode 100644 index 000000000000..0f3ea39edd96 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/debug-macro.S @@ -0,0 +1,14 @@ +/* + * arch/arm/mach-spear6xx/include/mach/debug-macro.S + * + * Debugging macro include header for SPEAr6xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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 diff --git a/arch/arm/mach-spear6xx/include/mach/entry-macro.S b/arch/arm/mach-spear6xx/include/mach/entry-macro.S new file mode 100644 index 000000000000..9eaecaeafcf0 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/entry-macro.S @@ -0,0 +1,55 @@ +/* + * arch/arm/mach-spear6xx/include/mach/entry-macro.S + * + * Low-level IRQ helper macros for SPEAr6xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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 +#include +#include + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \base, =VA_SPEAR6XX_CPU_VIC_PRI_BASE + ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get status + mov \irqnr, #0 + teq \irqstat, #0 + bne 1001f + ldr \base, =VA_SPEAR6XX_CPU_VIC_SEC_BASE + ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get status + teq \irqstat, #0 + beq 1002f @ this will set/reset + @ zero register + mov \irqnr, #32 +1001: + /* + * Following code will find bit position of least significang + * bit set in irqstat, using following equation + * least significant bit set in n = (n & ~(n-1)) + */ + sub \tmp, \irqstat, #1 @ tmp = irqstat - 1 + mvn \tmp, \tmp @ tmp = ~tmp + and \irqstat, \irqstat, \tmp @ irqstat &= tmp + /* Now, irqstat is = bit no. of 1st bit set in vic irq status */ + clz \tmp, \irqstat @ tmp = leading zeros + + rsb \tmp, \tmp, #0x1F @ tmp = 32 - tmp - 1 + add \irqnr, \irqnr, \tmp + +1002: /* EQ will be set if no irqs pending */ + .endm diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h new file mode 100644 index 000000000000..16205a538756 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/generic.h @@ -0,0 +1,45 @@ +/* + * arch/arm/mach-spear6xx/include/mach/generic.h + * + * SPEAr6XX machine family specific generic header file + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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. + */ + +#ifndef __MACH_GENERIC_H +#define __MACH_GENERIC_H + +#include +#include +#include +#include +#include + +/* + * Each GPT has 2 timer channels + * Following GPT channels will be used as clock source and clockevent + */ +#define SPEAR_GPT0_BASE SPEAR6XX_CPU_TMR_BASE +#define SPEAR_GPT0_CHAN0_IRQ IRQ_CPU_GPT1_1 +#define SPEAR_GPT0_CHAN1_IRQ IRQ_CPU_GPT1_2 + +/* Add spear6xx family device structure declarations here */ +extern struct amba_device gpio_device[]; +extern struct amba_device uart_device[]; +extern struct sys_timer spear_sys_timer; + +/* Add spear6xx family function declarations here */ +void __init spear6xx_map_io(void); +void __init spear6xx_init_irq(void); +void __init spear6xx_init(void); +void __init spear600_init(void); +void __init clk_init(void); + +/* Add spear600 machine device structure declarations here */ + +#endif /* __MACH_GENERIC_H */ diff --git a/arch/arm/mach-spear6xx/include/mach/gpio.h b/arch/arm/mach-spear6xx/include/mach/gpio.h new file mode 100644 index 000000000000..3a789dbb69f7 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/gpio.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear6xx/include/mach/gpio.h + * + * GPIO macros for SPEAr6xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_GPIO_H +#define __MACH_GPIO_H + +#include + +#endif /* __MACH_GPIO_H */ diff --git a/arch/arm/mach-spear6xx/include/mach/hardware.h b/arch/arm/mach-spear6xx/include/mach/hardware.h new file mode 100644 index 000000000000..7545116deca9 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/hardware.h @@ -0,0 +1,21 @@ +/* + * arch/arm/mach-spear6xx/include/mach/hardware.h + * + * Hardware definitions for SPEAr6xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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. + */ + +#ifndef __MACH_HARDWARE_H +#define __MACH_HARDWARE_H + +/* Vitual to physical translation of statically mapped space */ +#define IO_ADDRESS(x) (x | 0xF0000000) + +#endif /* __MACH_HARDWARE_H */ + diff --git a/arch/arm/mach-spear6xx/include/mach/io.h b/arch/arm/mach-spear6xx/include/mach/io.h new file mode 100644 index 000000000000..fb7c106cea94 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/io.h @@ -0,0 +1,20 @@ +/* + * arch/arm/mach-spear6xx/include/mach/io.h + * + * IO definitions for SPEAr6xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar Kumar + * + * 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. + */ + +#ifndef __MACH_IO_H +#define __MACH_IO_H + +#include + +#endif /* __MACH_IO_H */ + diff --git a/arch/arm/mach-spear6xx/include/mach/irqs.h b/arch/arm/mach-spear6xx/include/mach/irqs.h new file mode 100644 index 000000000000..08a3abced750 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/irqs.h @@ -0,0 +1,96 @@ +/* + * arch/arm/mach-spear6xx/include/mach/irqs.h + * + * IRQ helper macros for SPEAr6xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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. + */ + +#ifndef __MACH_IRQS_H +#define __MACH_IRQS_H + +/* IRQ definitions */ +/* VIC 1 */ +#define IRQ_INTRCOMM_SW_IRQ 0 +#define IRQ_INTRCOMM_CPU_1 1 +#define IRQ_INTRCOMM_CPU_2 2 +#define IRQ_INTRCOMM_RAS2A11_1 3 +#define IRQ_INTRCOMM_RAS2A11_2 4 +#define IRQ_INTRCOMM_RAS2A12_1 5 +#define IRQ_INTRCOMM_RAS2A12_2 6 +#define IRQ_GEN_RAS_0 7 +#define IRQ_GEN_RAS_1 8 +#define IRQ_GEN_RAS_2 9 +#define IRQ_GEN_RAS_3 10 +#define IRQ_GEN_RAS_4 11 +#define IRQ_GEN_RAS_5 12 +#define IRQ_GEN_RAS_6 13 +#define IRQ_GEN_RAS_7 14 +#define IRQ_GEN_RAS_8 15 +#define IRQ_CPU_GPT1_1 16 +#define IRQ_CPU_GPT1_2 17 +#define IRQ_LOCAL_GPIO 18 +#define IRQ_PLL_UNLOCK 19 +#define IRQ_JPEG 20 +#define IRQ_FSMC 21 +#define IRQ_IRDA 22 +#define IRQ_RESERVED 23 +#define IRQ_UART_0 24 +#define IRQ_UART_1 25 +#define IRQ_SSP_1 26 +#define IRQ_SSP_2 27 +#define IRQ_I2C 28 +#define IRQ_GEN_RAS_9 29 +#define IRQ_GEN_RAS_10 30 +#define IRQ_GEN_RAS_11 31 + +/* VIC 2 */ +#define IRQ_APPL_GPT1_1 32 +#define IRQ_APPL_GPT1_2 33 +#define IRQ_APPL_GPT2_1 34 +#define IRQ_APPL_GPT2_2 35 +#define IRQ_APPL_GPIO 36 +#define IRQ_APPL_SSP 37 +#define IRQ_APPL_ADC 38 +#define IRQ_APPL_RESERVED 39 +#define IRQ_AHB_EXP_MASTER 40 +#define IRQ_DDR_CONTROLLER 41 +#define IRQ_BASIC_DMA 42 +#define IRQ_BASIC_RESERVED1 43 +#define IRQ_BASIC_SMI 44 +#define IRQ_BASIC_CLCD 45 +#define IRQ_EXP_AHB_1 46 +#define IRQ_EXP_AHB_2 47 +#define IRQ_BASIC_GPT1_1 48 +#define IRQ_BASIC_GPT1_2 49 +#define IRQ_BASIC_RTC 50 +#define IRQ_BASIC_GPIO 51 +#define IRQ_BASIC_WDT 52 +#define IRQ_BASIC_RESERVED 53 +#define IRQ_AHB_EXP_SLAVE 54 +#define IRQ_GMAC_1 55 +#define IRQ_GMAC_2 56 +#define IRQ_USB_DEV 57 +#define IRQ_USB_H_OHCI_0 58 +#define IRQ_USB_H_EHCI_0 59 +#define IRQ_USB_H_OHCI_1 60 +#define IRQ_USB_H_EHCI_1 61 +#define IRQ_EXP_AHB_3 62 +#define IRQ_EXP_AHB_4 63 + +#define IRQ_VIC_END 64 + +#define SPEAR_GPIO_INT_BASE IRQ_VIC_END +#define SPEAR_GPIO0_INT_BASE SPEAR_GPIO_INT_BASE +#define SPEAR_GPIO1_INT_BASE (SPEAR_GPIO0_INT_BASE + 8) +#define SPEAR_GPIO2_INT_BASE (SPEAR_GPIO1_INT_BASE + 8) +#define SPEAR_GPIO_INT_END (SPEAR_GPIO2_INT_BASE + 8) +#define VIRTUAL_IRQS (SPEAR_GPIO_INT_END - IRQ_VIC_END) +#define NR_IRQS (IRQ_VIC_END + VIRTUAL_IRQS) + +#endif /* __MACH_IRQS_H */ diff --git a/arch/arm/mach-spear6xx/include/mach/memory.h b/arch/arm/mach-spear6xx/include/mach/memory.h new file mode 100644 index 000000000000..781f088fc228 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/memory.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear6xx/include/mach/memory.h + * + * Memory map for SPEAr6xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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. + */ + +#ifndef __MACH_MEMORY_H +#define __MACH_MEMORY_H + +#include + +#endif /* __MACH_MEMORY_H */ diff --git a/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/arch/arm/mach-spear6xx/include/mach/misc_regs.h new file mode 100644 index 000000000000..03908036b0d0 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/misc_regs.h @@ -0,0 +1,173 @@ +/* + * arch/arm/mach-spear6xx/include/mach/misc_regs.h + * + * Miscellaneous registers definitions for SPEAr6xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_MISC_REGS_H +#define __MACH_MISC_REGS_H + +#include + +#define MISC_BASE VA_SPEAR6XX_ICM3_MISC_REG_BASE + +#define SOC_CFG_CTR ((unsigned int *)(MISC_BASE + 0x000)) +#define DIAG_CFG_CTR ((unsigned int *)(MISC_BASE + 0x004)) +#define PLL1_CTR ((unsigned int *)(MISC_BASE + 0x008)) +#define PLL1_FRQ ((unsigned int *)(MISC_BASE + 0x00C)) +#define PLL1_MOD ((unsigned int *)(MISC_BASE + 0x010)) +#define PLL2_CTR ((unsigned int *)(MISC_BASE + 0x014)) +/* PLL_CTR register masks */ +#define PLL_ENABLE 2 +#define PLL_MODE_SHIFT 4 +#define PLL_MODE_MASK 0x3 +#define PLL_MODE_NORMAL 0 +#define PLL_MODE_FRACTION 1 +#define PLL_MODE_DITH_DSB 2 +#define PLL_MODE_DITH_SSB 3 + +#define PLL2_FRQ ((unsigned int *)(MISC_BASE + 0x018)) +/* PLL FRQ register masks */ +#define PLL_DIV_N_SHIFT 0 +#define PLL_DIV_N_MASK 0xFF +#define PLL_DIV_P_SHIFT 8 +#define PLL_DIV_P_MASK 0x7 +#define PLL_NORM_FDBK_M_SHIFT 24 +#define PLL_NORM_FDBK_M_MASK 0xFF +#define PLL_DITH_FDBK_M_SHIFT 16 +#define PLL_DITH_FDBK_M_MASK 0xFFFF + +#define PLL2_MOD ((unsigned int *)(MISC_BASE + 0x01C)) +#define PLL_CLK_CFG ((unsigned int *)(MISC_BASE + 0x020)) +#define CORE_CLK_CFG ((unsigned int *)(MISC_BASE + 0x024)) +/* CORE CLK CFG register masks */ +#define PLL_HCLK_RATIO_SHIFT 10 +#define PLL_HCLK_RATIO_MASK 0x3 +#define HCLK_PCLK_RATIO_SHIFT 8 +#define HCLK_PCLK_RATIO_MASK 0x3 + +#define PERIP_CLK_CFG ((unsigned int *)(MISC_BASE + 0x028)) +/* PERIP_CLK_CFG register masks */ +#define CLCD_CLK_SHIFT 2 +#define CLCD_CLK_MASK 0x3 +#define UART_CLK_SHIFT 4 +#define UART_CLK_MASK 0x1 +#define FIRDA_CLK_SHIFT 5 +#define FIRDA_CLK_MASK 0x3 +#define GPT0_CLK_SHIFT 8 +#define GPT1_CLK_SHIFT 10 +#define GPT2_CLK_SHIFT 11 +#define GPT3_CLK_SHIFT 12 +#define GPT_CLK_MASK 0x1 +#define AUX_CLK_PLL3_MASK 0 +#define AUX_CLK_PLL1_MASK 1 + +#define PERIP1_CLK_ENB ((unsigned int *)(MISC_BASE + 0x02C)) +/* PERIP1_CLK_ENB register masks */ +#define UART0_CLK_ENB 3 +#define UART1_CLK_ENB 4 +#define SSP0_CLK_ENB 5 +#define SSP1_CLK_ENB 6 +#define I2C_CLK_ENB 7 +#define JPEG_CLK_ENB 8 +#define FSMC_CLK_ENB 9 +#define FIRDA_CLK_ENB 10 +#define GPT2_CLK_ENB 11 +#define GPT3_CLK_ENB 12 +#define GPIO2_CLK_ENB 13 +#define SSP2_CLK_ENB 14 +#define ADC_CLK_ENB 15 +#define GPT1_CLK_ENB 11 +#define RTC_CLK_ENB 17 +#define GPIO1_CLK_ENB 18 +#define DMA_CLK_ENB 19 +#define SMI_CLK_ENB 21 +#define CLCD_CLK_ENB 22 +#define GMAC_CLK_ENB 23 +#define USBD_CLK_ENB 24 +#define USBH0_CLK_ENB 25 +#define USBH1_CLK_ENB 26 + +#define SOC_CORE_ID ((unsigned int *)(MISC_BASE + 0x030)) +#define RAS_CLK_ENB ((unsigned int *)(MISC_BASE + 0x034)) +#define PERIP1_SOF_RST ((unsigned int *)(MISC_BASE + 0x038)) +/* PERIP1_SOF_RST register masks */ +#define JPEG_SOF_RST 8 + +#define SOC_USER_ID ((unsigned int *)(MISC_BASE + 0x03C)) +#define RAS_SOF_RST ((unsigned int *)(MISC_BASE + 0x040)) +#define PRSC1_CLK_CFG ((unsigned int *)(MISC_BASE + 0x044)) +#define PRSC2_CLK_CFG ((unsigned int *)(MISC_BASE + 0x048)) +#define PRSC3_CLK_CFG ((unsigned int *)(MISC_BASE + 0x04C)) +/* gpt synthesizer register masks */ +#define GPT_MSCALE_SHIFT 0 +#define GPT_MSCALE_MASK 0xFFF +#define GPT_NSCALE_SHIFT 12 +#define GPT_NSCALE_MASK 0xF + +#define AMEM_CLK_CFG ((unsigned int *)(MISC_BASE + 0x050)) +#define EXPI_CLK_CFG ((unsigned int *)(MISC_BASE + 0x054)) +#define CLCD_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x05C)) +#define FIRDA_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x060)) +#define UART_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x064)) +#define GMAC_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x068)) +#define RAS1_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x06C)) +#define RAS2_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x070)) +#define RAS3_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x074)) +#define RAS4_CLK_SYNT ((unsigned int *)(MISC_BASE + 0x078)) +/* aux clk synthesiser register masks for irda to ras4 */ +#define AUX_EQ_SEL_SHIFT 30 +#define AUX_EQ_SEL_MASK 1 +#define AUX_EQ1_SEL 0 +#define AUX_EQ2_SEL 1 +#define AUX_XSCALE_SHIFT 16 +#define AUX_XSCALE_MASK 0xFFF +#define AUX_YSCALE_SHIFT 0 +#define AUX_YSCALE_MASK 0xFFF + +#define ICM1_ARB_CFG ((unsigned int *)(MISC_BASE + 0x07C)) +#define ICM2_ARB_CFG ((unsigned int *)(MISC_BASE + 0x080)) +#define ICM3_ARB_CFG ((unsigned int *)(MISC_BASE + 0x084)) +#define ICM4_ARB_CFG ((unsigned int *)(MISC_BASE + 0x088)) +#define ICM5_ARB_CFG ((unsigned int *)(MISC_BASE + 0x08C)) +#define ICM6_ARB_CFG ((unsigned int *)(MISC_BASE + 0x090)) +#define ICM7_ARB_CFG ((unsigned int *)(MISC_BASE + 0x094)) +#define ICM8_ARB_CFG ((unsigned int *)(MISC_BASE + 0x098)) +#define ICM9_ARB_CFG ((unsigned int *)(MISC_BASE + 0x09C)) +#define DMA_CHN_CFG ((unsigned int *)(MISC_BASE + 0x0A0)) +#define USB2_PHY_CFG ((unsigned int *)(MISC_BASE + 0x0A4)) +#define GMAC_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0A8)) +#define EXPI_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0AC)) +#define PRC1_LOCK_CTR ((unsigned int *)(MISC_BASE + 0x0C0)) +#define PRC2_LOCK_CTR ((unsigned int *)(MISC_BASE + 0x0C4)) +#define PRC3_LOCK_CTR ((unsigned int *)(MISC_BASE + 0x0C8)) +#define PRC4_LOCK_CTR ((unsigned int *)(MISC_BASE + 0x0CC)) +#define PRC1_IRQ_CTR ((unsigned int *)(MISC_BASE + 0x0D0)) +#define PRC2_IRQ_CTR ((unsigned int *)(MISC_BASE + 0x0D4)) +#define PRC3_IRQ_CTR ((unsigned int *)(MISC_BASE + 0x0D8)) +#define PRC4_IRQ_CTR ((unsigned int *)(MISC_BASE + 0x0DC)) +#define PWRDOWN_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0E0)) +#define COMPSSTL_1V8_CFG ((unsigned int *)(MISC_BASE + 0x0E4)) +#define COMPSSTL_2V5_CFG ((unsigned int *)(MISC_BASE + 0x0E8)) +#define COMPCOR_3V3_CFG ((unsigned int *)(MISC_BASE + 0x0EC)) +#define SSTLPAD_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0F0)) +#define BIST1_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0F4)) +#define BIST2_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0F8)) +#define BIST3_CFG_CTR ((unsigned int *)(MISC_BASE + 0x0FC)) +#define BIST4_CFG_CTR ((unsigned int *)(MISC_BASE + 0x100)) +#define BIST5_CFG_CTR ((unsigned int *)(MISC_BASE + 0x104)) +#define BIST1_STS_RES ((unsigned int *)(MISC_BASE + 0x108)) +#define BIST2_STS_RES ((unsigned int *)(MISC_BASE + 0x10C)) +#define BIST3_STS_RES ((unsigned int *)(MISC_BASE + 0x110)) +#define BIST4_STS_RES ((unsigned int *)(MISC_BASE + 0x114)) +#define BIST5_STS_RES ((unsigned int *)(MISC_BASE + 0x118)) +#define SYSERR_CFG_CTR ((unsigned int *)(MISC_BASE + 0x11C)) + +#endif /* __MACH_MISC_REGS_H */ diff --git a/arch/arm/mach-spear6xx/include/mach/spear.h b/arch/arm/mach-spear6xx/include/mach/spear.h new file mode 100644 index 000000000000..a835f5b6b182 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/spear.h @@ -0,0 +1,173 @@ +/* + * arch/arm/mach-spear6xx/include/mach/spear.h + * + * SPEAr6xx Machine family specific definition + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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. + */ + +#ifndef __MACH_SPEAR6XX_H +#define __MACH_SPEAR6XX_H + +#include +#include + +#define SPEAR6XX_ML_SDRAM_BASE 0x00000000 +#define SPEAR6XX_ML_SDRAM_SIZE 0x40000000 + +/* ICM1 - Low speed connection */ +#define SPEAR6XX_ICM1_BASE 0xD0000000 +#define SPEAR6XX_ICM1_SIZE 0x08000000 + +#define SPEAR6XX_ICM1_UART0_BASE 0xD0000000 +#define VA_SPEAR6XX_ICM1_UART0_BASE IO_ADDRESS(SPEAR6XX_ICM1_UART0_BASE) +#define SPEAR6XX_ICM1_UART0_SIZE 0x00080000 + +#define SPEAR6XX_ICM1_UART1_BASE 0xD0080000 +#define SPEAR6XX_ICM1_UART1_SIZE 0x00080000 + +#define SPEAR6XX_ICM1_SSP0_BASE 0xD0100000 +#define SPEAR6XX_ICM1_SSP0_SIZE 0x00080000 + +#define SPEAR6XX_ICM1_SSP1_BASE 0xD0180000 +#define SPEAR6XX_ICM1_SSP1_SIZE 0x00080000 + +#define SPEAR6XX_ICM1_I2C_BASE 0xD0200000 +#define SPEAR6XX_ICM1_I2C_SIZE 0x00080000 + +#define SPEAR6XX_ICM1_JPEG_BASE 0xD0800000 +#define SPEAR6XX_ICM1_JPEG_SIZE 0x00800000 + +#define SPEAR6XX_ICM1_IRDA_BASE 0xD1000000 +#define SPEAR6XX_ICM1_IRDA_SIZE 0x00800000 + +#define SPEAR6XX_ICM1_FSMC_BASE 0xD1800000 +#define SPEAR6XX_ICM1_FSMC_SIZE 0x00800000 + +#define SPEAR6XX_ICM1_NAND_BASE 0xD2000000 +#define SPEAR6XX_ICM1_NAND_SIZE 0x00800000 + +#define SPEAR6XX_ICM1_SRAM_BASE 0xD2800000 +#define SPEAR6XX_ICM1_SRAM_SIZE 0x00800000 + +/* ICM2 - Application Subsystem */ +#define SPEAR6XX_ICM2_BASE 0xD8000000 +#define SPEAR6XX_ICM2_SIZE 0x08000000 + +#define SPEAR6XX_ICM2_TMR0_BASE 0xD8000000 +#define SPEAR6XX_ICM2_TMR0_SIZE 0x00080000 + +#define SPEAR6XX_ICM2_TMR1_BASE 0xD8080000 +#define SPEAR6XX_ICM2_TMR1_SIZE 0x00080000 + +#define SPEAR6XX_ICM2_GPIO_BASE 0xD8100000 +#define SPEAR6XX_ICM2_GPIO_SIZE 0x00080000 + +#define SPEAR6XX_ICM2_SPI2_BASE 0xD8180000 +#define SPEAR6XX_ICM2_SPI2_SIZE 0x00080000 + +#define SPEAR6XX_ICM2_ADC_BASE 0xD8200000 +#define SPEAR6XX_ICM2_ADC_SIZE 0x00080000 + +/* ML-1, 2 - Multi Layer CPU Subsystem */ +#define SPEAR6XX_ML_CPU_BASE 0xF0000000 +#define SPEAR6XX_ML_CPU_SIZE 0x08000000 + +#define SPEAR6XX_CPU_TMR_BASE 0xF0000000 +#define SPEAR6XX_CPU_TMR_SIZE 0x00100000 + +#define SPEAR6XX_CPU_GPIO_BASE 0xF0100000 +#define SPEAR6XX_CPU_GPIO_SIZE 0x00100000 + +#define SPEAR6XX_CPU_VIC_SEC_BASE 0xF1000000 +#define VA_SPEAR6XX_CPU_VIC_SEC_BASE IO_ADDRESS(SPEAR6XX_CPU_VIC_SEC_BASE) +#define SPEAR6XX_CPU_VIC_SEC_SIZE 0x00100000 + +#define SPEAR6XX_CPU_VIC_PRI_BASE 0xF1100000 +#define VA_SPEAR6XX_CPU_VIC_PRI_BASE IO_ADDRESS(SPEAR6XX_CPU_VIC_PRI_BASE) +#define SPEAR6XX_CPU_VIC_PRI_SIZE 0x00100000 + +/* ICM3 - Basic Subsystem */ +#define SPEAR6XX_ICM3_BASE 0xF8000000 +#define SPEAR6XX_ICM3_SIZE 0x08000000 + +#define SPEAR6XX_ICM3_SMEM_BASE 0xF8000000 +#define SPEAR6XX_ICM3_SMEM_SIZE 0x04000000 + +#define SPEAR6XX_ICM3_SMI_CTRL_BASE 0xFC000000 +#define SPEAR6XX_ICM3_SMI_CTRL_SIZE 0x00200000 + +#define SPEAR6XX_ICM3_CLCD_BASE 0xFC200000 +#define SPEAR6XX_ICM3_CLCD_SIZE 0x00200000 + +#define SPEAR6XX_ICM3_DMA_BASE 0xFC400000 +#define SPEAR6XX_ICM3_DMA_SIZE 0x00200000 + +#define SPEAR6XX_ICM3_SDRAM_CTRL_BASE 0xFC600000 +#define SPEAR6XX_ICM3_SDRAM_CTRL_SIZE 0x00200000 + +#define SPEAR6XX_ICM3_TMR_BASE 0xFC800000 +#define SPEAR6XX_ICM3_TMR_SIZE 0x00080000 + +#define SPEAR6XX_ICM3_WDT_BASE 0xFC880000 +#define SPEAR6XX_ICM3_WDT_SIZE 0x00080000 + +#define SPEAR6XX_ICM3_RTC_BASE 0xFC900000 +#define SPEAR6XX_ICM3_RTC_SIZE 0x00080000 + +#define SPEAR6XX_ICM3_GPIO_BASE 0xFC980000 +#define SPEAR6XX_ICM3_GPIO_SIZE 0x00080000 + +#define SPEAR6XX_ICM3_SYS_CTRL_BASE 0xFCA00000 +#define VA_SPEAR6XX_ICM3_SYS_CTRL_BASE IO_ADDRESS(SPEAR6XX_ICM3_SYS_CTRL_BASE) +#define SPEAR6XX_ICM3_SYS_CTRL_SIZE 0x00080000 + +#define SPEAR6XX_ICM3_MISC_REG_BASE 0xFCA80000 +#define VA_SPEAR6XX_ICM3_MISC_REG_BASE IO_ADDRESS(SPEAR6XX_ICM3_MISC_REG_BASE) +#define SPEAR6XX_ICM3_MISC_REG_SIZE 0x00080000 + +/* ICM4 - High Speed Connection */ +#define SPEAR6XX_ICM4_BASE 0xE0000000 +#define SPEAR6XX_ICM4_SIZE 0x08000000 + +#define SPEAR6XX_ICM4_GMAC_BASE 0xE0800000 +#define SPEAR6XX_ICM4_GMAC_SIZE 0x00800000 + +#define SPEAR6XX_ICM4_USBD_FIFO_BASE 0xE1000000 +#define SPEAR6XX_ICM4_USBD_FIFO_SIZE 0x00100000 + +#define SPEAR6XX_ICM4_USBD_CSR_BASE 0xE1100000 +#define SPEAR6XX_ICM4_USBD_CSR_SIZE 0x00100000 + +#define SPEAR6XX_ICM4_USBD_PLDT_BASE 0xE1200000 +#define SPEAR6XX_ICM4_USBD_PLDT_SIZE 0x00100000 + +#define SPEAR6XX_ICM4_USB_EHCI0_BASE 0xE1800000 +#define SPEAR6XX_ICM4_USB_EHCI0_SIZE 0x00100000 + +#define SPEAR6XX_ICM4_USB_OHCI0_BASE 0xE1900000 +#define SPEAR6XX_ICM4_USB_OHCI0_SIZE 0x00100000 + +#define SPEAR6XX_ICM4_USB_EHCI1_BASE 0xE2000000 +#define SPEAR6XX_ICM4_USB_EHCI1_SIZE 0x00100000 + +#define SPEAR6XX_ICM4_USB_OHCI1_BASE 0xE2100000 +#define SPEAR6XX_ICM4_USB_OHCI1_SIZE 0x00100000 + +#define SPEAR6XX_ICM4_USB_ARB_BASE 0xE2800000 +#define SPEAR6XX_ICM4_USB_ARB_SIZE 0x00010000 + +/* Debug uart for linux, will be used for debug and uncompress messages */ +#define SPEAR_DBG_UART_BASE SPEAR6XX_ICM1_UART0_BASE +#define VA_SPEAR_DBG_UART_BASE VA_SPEAR6XX_ICM1_UART0_BASE + +/* Sysctl base for spear platform */ +#define SPEAR_SYS_CTRL_BASE SPEAR6XX_ICM3_SYS_CTRL_BASE +#define VA_SPEAR_SYS_CTRL_BASE VA_SPEAR6XX_ICM3_SYS_CTRL_BASE + +#endif /* __MACH_SPEAR6XX_H */ diff --git a/arch/arm/mach-spear6xx/include/mach/spear600.h b/arch/arm/mach-spear6xx/include/mach/spear600.h new file mode 100644 index 000000000000..c068cc50b0fb --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/spear600.h @@ -0,0 +1,21 @@ +/* + * arch/arm/mach-spear66xx/include/mach/spear600.h + * + * SPEAr600 Machine specific definition + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifdef CONFIG_MACH_SPEAR600 + +#ifndef __MACH_SPEAR600_H +#define __MACH_SPEAR600_H + +#endif /* __MACH_SPEAR600_H */ + +#endif /* CONFIG_MACH_SPEAR600 */ diff --git a/arch/arm/mach-spear6xx/include/mach/system.h b/arch/arm/mach-spear6xx/include/mach/system.h new file mode 100644 index 000000000000..0b1d2be81cfb --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/system.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear6xx/include/mach/system.h + * + * SPEAr6xx Machine family specific architecture functions + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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. + */ + +#ifndef __MACH_SYSTEM_H +#define __MACH_SYSTEM_H + +#include + +#endif /* __MACH_SYSTEM_H */ diff --git a/arch/arm/mach-spear6xx/include/mach/timex.h b/arch/arm/mach-spear6xx/include/mach/timex.h new file mode 100644 index 000000000000..ac1c5b005695 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/timex.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear6xx/include/mach/timex.h + * + * SPEAr6XX machine family specific timex definitions + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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. + */ + +#ifndef __MACH_TIMEX_H +#define __MACH_TIMEX_H + +#include + +#endif /* __MACH_TIMEX_H */ diff --git a/arch/arm/mach-spear6xx/include/mach/uncompress.h b/arch/arm/mach-spear6xx/include/mach/uncompress.h new file mode 100644 index 000000000000..77f0765e21e1 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/uncompress.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear6xx/include/mach/uncompress.h + * + * Serial port stubs for kernel decompress status messages + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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. + */ + +#ifndef __MACH_UNCOMPRESS_H +#define __MACH_UNCOMPRESS_H + +#include + +#endif /* __MACH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-spear6xx/include/mach/vmalloc.h b/arch/arm/mach-spear6xx/include/mach/vmalloc.h new file mode 100644 index 000000000000..4a0b56cb2a91 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/vmalloc.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear6xx/include/mach/vmalloc.h + * + * Defining Vmalloc area for SPEAr6xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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. + */ + +#ifndef __MACH_VMALLOC_H +#define __MACH_VMALLOC_H + +#include + +#endif /* __MACH_VMALLOC_H */ -- cgit v1.2.3-59-g8ed1b From bf976b51a32e255523c69022c1f21bf9ad527fc5 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:30:42 +0100 Subject: ARM: 6012/1: ST SPEAr: Added basic header files for SPEAr platform Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Shiraz Hashim Signed-off-by: Russell King --- arch/arm/plat-spear/include/plat/debug-macro.S | 38 +++++++++++++++++++++++ arch/arm/plat-spear/include/plat/gpio.h | 24 ++++++++++++++ arch/arm/plat-spear/include/plat/io.h | 22 +++++++++++++ arch/arm/plat-spear/include/plat/memory.h | 20 ++++++++++++ arch/arm/plat-spear/include/plat/system.h | 41 ++++++++++++++++++++++++ arch/arm/plat-spear/include/plat/timex.h | 19 ++++++++++++ arch/arm/plat-spear/include/plat/uncompress.h | 43 ++++++++++++++++++++++++++ arch/arm/plat-spear/include/plat/vmalloc.h | 19 ++++++++++++ 8 files changed, 226 insertions(+) create mode 100644 arch/arm/plat-spear/include/plat/debug-macro.S create mode 100644 arch/arm/plat-spear/include/plat/gpio.h create mode 100644 arch/arm/plat-spear/include/plat/io.h create mode 100644 arch/arm/plat-spear/include/plat/memory.h create mode 100644 arch/arm/plat-spear/include/plat/system.h create mode 100644 arch/arm/plat-spear/include/plat/timex.h create mode 100644 arch/arm/plat-spear/include/plat/uncompress.h create mode 100644 arch/arm/plat-spear/include/plat/vmalloc.h (limited to 'arch') diff --git a/arch/arm/plat-spear/include/plat/debug-macro.S b/arch/arm/plat-spear/include/plat/debug-macro.S new file mode 100644 index 000000000000..1670734b7e51 --- /dev/null +++ b/arch/arm/plat-spear/include/plat/debug-macro.S @@ -0,0 +1,38 @@ +/* + * arch/arm/plat-spear/include/plat/debug-macro.S + * + * Debugging macro include header for spear platform + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include + + .macro addruart, rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, =SPEAR_DBG_UART_BASE @ Physical base + movne \rx, =VA_SPEAR_DBG_UART_BASE @ Virtual base + .endm + + .macro senduart, rd, rx + strb \rd, [\rx, #UART01x_DR] @ ASC_TX_BUFFER + .endm + + .macro waituart, rd, rx +1001: ldr \rd, [\rx, #UART01x_FR] @ FLAG REGISTER + tst \rd, #UART01x_FR_TXFF @ TX_FULL + bne 1001b + .endm + + .macro busyuart, rd, rx +1002: ldr \rd, [\rx, #UART01x_FR] @ FLAG REGISTER + tst \rd, #UART011_FR_TXFE @ TX_EMPTY + beq 1002b + .endm diff --git a/arch/arm/plat-spear/include/plat/gpio.h b/arch/arm/plat-spear/include/plat/gpio.h new file mode 100644 index 000000000000..b857c91257dd --- /dev/null +++ b/arch/arm/plat-spear/include/plat/gpio.h @@ -0,0 +1,24 @@ +/* + * arch/arm/plat-spear/include/plat/gpio.h + * + * GPIO macros for SPEAr platform + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __PLAT_GPIO_H +#define __PLAT_GPIO_H + +#include + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep +#define gpio_to_irq __gpio_to_irq + +#endif /* __PLAT_GPIO_H */ diff --git a/arch/arm/plat-spear/include/plat/io.h b/arch/arm/plat-spear/include/plat/io.h new file mode 100644 index 000000000000..4d4ba822b3eb --- /dev/null +++ b/arch/arm/plat-spear/include/plat/io.h @@ -0,0 +1,22 @@ +/* + * arch/arm/plat-spear/include/plat/io.h + * + * IO definitions for SPEAr platform + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __PLAT_IO_H +#define __PLAT_IO_H + +#define IO_SPACE_LIMIT 0xFFFFFFFF + +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#endif /* __PLAT_IO_H */ diff --git a/arch/arm/plat-spear/include/plat/memory.h b/arch/arm/plat-spear/include/plat/memory.h new file mode 100644 index 000000000000..27a4aba77343 --- /dev/null +++ b/arch/arm/plat-spear/include/plat/memory.h @@ -0,0 +1,20 @@ +/* + * arch/arm/plat-spear/include/plat/memory.h + * + * Memory map for SPEAr platform + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __PLAT_MEMORY_H +#define __PLAT_MEMORY_H + +/* Physical DRAM offset */ +#define PHYS_OFFSET UL(0x00000000) + +#endif /* __PLAT_MEMORY_H */ diff --git a/arch/arm/plat-spear/include/plat/system.h b/arch/arm/plat-spear/include/plat/system.h new file mode 100644 index 000000000000..55a4e405d578 --- /dev/null +++ b/arch/arm/plat-spear/include/plat/system.h @@ -0,0 +1,41 @@ +/* + * arch/arm/plat-spear/include/plat/system.h + * + * SPEAr platform specific architecture functions + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __PLAT_SYSTEM_H +#define __PLAT_SYSTEM_H + +#include +#include +#include + +static inline void arch_idle(void) +{ + /* + * This should do all the clock switching + * and wait for interrupt tricks + */ + cpu_do_idle(); +} + +static inline void arch_reset(char mode, const char *cmd) +{ + if (mode == 's') { + /* software reset, Jump into ROM at address 0 */ + cpu_reset(0); + } else { + /* hardware reset, Use on-chip reset capability */ + sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE); + } +} + +#endif /* __PLAT_SYSTEM_H */ diff --git a/arch/arm/plat-spear/include/plat/timex.h b/arch/arm/plat-spear/include/plat/timex.h new file mode 100644 index 000000000000..914d09dd50fd --- /dev/null +++ b/arch/arm/plat-spear/include/plat/timex.h @@ -0,0 +1,19 @@ +/* + * arch/arm/plat-spear/include/plat/timex.h + * + * SPEAr platform specific timex definitions + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __PLAT_TIMEX_H +#define __PLAT_TIMEX_H + +#define CLOCK_TICK_RATE 48000000 + +#endif /* __PLAT_TIMEX_H */ diff --git a/arch/arm/plat-spear/include/plat/uncompress.h b/arch/arm/plat-spear/include/plat/uncompress.h new file mode 100644 index 000000000000..99ba6789cc97 --- /dev/null +++ b/arch/arm/plat-spear/include/plat/uncompress.h @@ -0,0 +1,43 @@ +/* + * arch/arm/plat-spear/include/plat/uncompress.h + * + * Serial port stubs for kernel decompress status messages + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include + +#ifndef __PLAT_UNCOMPRESS_H +#define __PLAT_UNCOMPRESS_H +/* + * This does not append a newline + */ +static inline void putc(int c) +{ + void __iomem *base = (void __iomem *)SPEAR_DBG_UART_BASE; + + while (readl(base + UART01x_FR) & UART01x_FR_TXFF) + barrier(); + + writel(c, base + UART01x_DR); +} + +static inline void flush(void) +{ +} + +/* + * nothing to do + */ +#define arch_decomp_setup() +#define arch_decomp_wdog() + +#endif /* __PLAT_UNCOMPRESS_H */ diff --git a/arch/arm/plat-spear/include/plat/vmalloc.h b/arch/arm/plat-spear/include/plat/vmalloc.h new file mode 100644 index 000000000000..09e9372aea21 --- /dev/null +++ b/arch/arm/plat-spear/include/plat/vmalloc.h @@ -0,0 +1,19 @@ +/* + * arch/arm/plat-spear/include/plat/vmalloc.h + * + * Defining Vmalloc area for SPEAr platform + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __PLAT_VMALLOC_H +#define __PLAT_VMALLOC_H + +#define VMALLOC_END 0xF0000000 + +#endif /* __PLAT_VMALLOC_H */ -- cgit v1.2.3-59-g8ed1b From 986435e3596cbae662b86812e4563fbb6013b994 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:30:49 +0100 Subject: ARM: 6013/1: ST SPEAr: Added source files for SPEAr platform Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Shiraz Hashim Signed-off-by: Russell King --- arch/arm/plat-spear/Kconfig | 31 +++++ arch/arm/plat-spear/Makefile | 6 + arch/arm/plat-spear/time.c | 292 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 329 insertions(+) create mode 100644 arch/arm/plat-spear/Kconfig create mode 100644 arch/arm/plat-spear/Makefile create mode 100644 arch/arm/plat-spear/time.c (limited to 'arch') diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig new file mode 100644 index 000000000000..1bb3dbce8810 --- /dev/null +++ b/arch/arm/plat-spear/Kconfig @@ -0,0 +1,31 @@ +# +# SPEAr Platform configuration file +# + +if PLAT_SPEAR + +choice + prompt "ST SPEAr Family" + default ARCH_SPEAR3XX + +config ARCH_SPEAR3XX + bool "SPEAr3XX" + select ARM_VIC + select CPU_ARM926T + help + Supports for ARM's SPEAR3XX family + +config ARCH_SPEAR6XX + bool "SPEAr6XX" + select ARM_VIC + select CPU_ARM926T + help + Supports for ARM's SPEAR6XX family + +endchoice + +# Adding SPEAr machine specific configuration files +source "arch/arm/mach-spear3xx/Kconfig" +source "arch/arm/mach-spear6xx/Kconfig" + +endif diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile new file mode 100644 index 000000000000..96f9ac3d4b81 --- /dev/null +++ b/arch/arm/plat-spear/Makefile @@ -0,0 +1,6 @@ +# +# SPEAr Platform specific Makefile +# + +# Common support +obj-y := clock.o time.o diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c new file mode 100644 index 000000000000..a1025d38f383 --- /dev/null +++ b/arch/arm/plat-spear/time.c @@ -0,0 +1,292 @@ +/* + * arch/arm/plat-spear/time.c + * + * Copyright (C) 2009 ST Microelectronics + * Shiraz Hashim + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * We would use TIMER0 and TIMER1 as clockevent and clocksource. + * Timer0 and Timer1 both belong to same gpt block in cpu subbsystem. Further + * they share same functional clock. Any change in one's functional clock will + * also affect other timer. + */ + +#define CLKEVT 0 /* gpt0, channel0 as clockevent */ +#define CLKSRC 1 /* gpt0, channel1 as clocksource */ + +/* Register offsets, x is channel number */ +#define CR(x) ((x) * 0x80 + 0x80) +#define IR(x) ((x) * 0x80 + 0x84) +#define LOAD(x) ((x) * 0x80 + 0x88) +#define COUNT(x) ((x) * 0x80 + 0x8C) + +/* Reg bit definitions */ +#define CTRL_INT_ENABLE 0x0100 +#define CTRL_ENABLE 0x0020 +#define CTRL_ONE_SHOT 0x0010 + +#define CTRL_PRESCALER1 0x0 +#define CTRL_PRESCALER2 0x1 +#define CTRL_PRESCALER4 0x2 +#define CTRL_PRESCALER8 0x3 +#define CTRL_PRESCALER16 0x4 +#define CTRL_PRESCALER32 0x5 +#define CTRL_PRESCALER64 0x6 +#define CTRL_PRESCALER128 0x7 +#define CTRL_PRESCALER256 0x8 + +#define INT_STATUS 0x1 + +static __iomem void *gpt_base; +static struct clk *gpt_clk; + +static void clockevent_set_mode(enum clock_event_mode mode, + struct clock_event_device *clk_event_dev); +static int clockevent_next_event(unsigned long evt, + struct clock_event_device *clk_event_dev); + +/* + * Following clocksource_set_clock and clockevent_set_clock picked + * from arch/mips/kernel/time.c + */ + +void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock) +{ + u64 temp; + u32 shift; + + /* Find a shift value */ + for (shift = 32; shift > 0; shift--) { + temp = (u64) NSEC_PER_SEC << shift; + do_div(temp, clock); + if ((temp >> 32) == 0) + break; + } + cs->shift = shift; + cs->mult = (u32) temp; +} + +void __init clockevent_set_clock(struct clock_event_device *cd, + unsigned int clock) +{ + u64 temp; + u32 shift; + + /* Find a shift value */ + for (shift = 32; shift > 0; shift--) { + temp = (u64) clock << shift; + do_div(temp, NSEC_PER_SEC); + if ((temp >> 32) == 0) + break; + } + cd->shift = shift; + cd->mult = (u32) temp; +} + +static cycle_t clocksource_read_cycles(struct clocksource *cs) +{ + return (cycle_t) readw(gpt_base + COUNT(CLKSRC)); +} + +static struct clocksource clksrc = { + .name = "tmr1", + .rating = 200, /* its a pretty decent clock */ + .read = clocksource_read_cycles, + .mask = 0xFFFF, /* 16 bits */ + .mult = 0, /* to be computed */ + .shift = 0, /* to be computed */ + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static void spear_clocksource_init(void) +{ + u32 tick_rate; + u16 val; + + /* program the prescaler (/256)*/ + writew(CTRL_PRESCALER256, gpt_base + CR(CLKSRC)); + + /* find out actual clock driving Timer */ + tick_rate = clk_get_rate(gpt_clk); + tick_rate >>= CTRL_PRESCALER256; + + writew(0xFFFF, gpt_base + LOAD(CLKSRC)); + + val = readw(gpt_base + CR(CLKSRC)); + val &= ~CTRL_ONE_SHOT; /* autoreload mode */ + val |= CTRL_ENABLE ; + writew(val, gpt_base + CR(CLKSRC)); + + clocksource_set_clock(&clksrc, tick_rate); + + /* register the clocksource */ + clocksource_register(&clksrc); +} + +static struct clock_event_device clkevt = { + .name = "tmr0", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_mode = clockevent_set_mode, + .set_next_event = clockevent_next_event, + .shift = 0, /* to be computed */ +}; + +static void clockevent_set_mode(enum clock_event_mode mode, + struct clock_event_device *clk_event_dev) +{ + u32 period; + u16 val; + + /* stop the timer */ + val = readw(gpt_base + CR(CLKEVT)); + val &= ~CTRL_ENABLE; + writew(val, gpt_base + CR(CLKEVT)); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + period = clk_get_rate(gpt_clk) / HZ; + period >>= CTRL_PRESCALER16; + writew(period, gpt_base + LOAD(CLKEVT)); + + val = readw(gpt_base + CR(CLKEVT)); + val &= ~CTRL_ONE_SHOT; + val |= CTRL_ENABLE | CTRL_INT_ENABLE; + writew(val, gpt_base + CR(CLKEVT)); + + break; + case CLOCK_EVT_MODE_ONESHOT: + val = readw(gpt_base + CR(CLKEVT)); + val |= CTRL_ONE_SHOT; + writew(val, gpt_base + CR(CLKEVT)); + + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_RESUME: + + break; + default: + pr_err("Invalid mode requested\n"); + break; + } +} + +static int clockevent_next_event(unsigned long cycles, + struct clock_event_device *clk_event_dev) +{ + u16 val; + + writew(cycles, gpt_base + LOAD(CLKEVT)); + + val = readw(gpt_base + CR(CLKEVT)); + val |= CTRL_ENABLE | CTRL_INT_ENABLE; + writew(val, gpt_base + CR(CLKEVT)); + + return 0; +} + +static irqreturn_t spear_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &clkevt; + + writew(INT_STATUS, gpt_base + IR(CLKEVT)); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction spear_timer_irq = { + .name = "timer", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = spear_timer_interrupt +}; + +static void __init spear_clockevent_init(void) +{ + u32 tick_rate; + + /* program the prescaler */ + writew(CTRL_PRESCALER16, gpt_base + CR(CLKEVT)); + + tick_rate = clk_get_rate(gpt_clk); + tick_rate >>= CTRL_PRESCALER16; + + clockevent_set_clock(&clkevt, tick_rate); + + clkevt.max_delta_ns = clockevent_delta2ns(0xfff0, + &clkevt); + clkevt.min_delta_ns = clockevent_delta2ns(3, &clkevt); + + clkevt.cpumask = cpumask_of(0); + + clockevents_register_device(&clkevt); + + setup_irq(SPEAR_GPT0_CHAN0_IRQ, &spear_timer_irq); +} + +void __init spear_setup_timer(void) +{ + struct clk *pll3_clk; + + if (!request_mem_region(SPEAR_GPT0_BASE, SZ_1K, "gpt0")) { + pr_err("%s:cannot get IO addr\n", __func__); + return; + } + + gpt_base = (void __iomem *)ioremap(SPEAR_GPT0_BASE, SZ_1K); + if (!gpt_base) { + pr_err("%s:ioremap failed for gpt\n", __func__); + goto err_mem; + } + + gpt_clk = clk_get_sys("gpt0", NULL); + if (!gpt_clk) { + pr_err("%s:couldn't get clk for gpt\n", __func__); + goto err_iomap; + } + + pll3_clk = clk_get(NULL, "pll3_48m_clk"); + if (!pll3_clk) { + pr_err("%s:couldn't get PLL3 as parent for gpt\n", __func__); + goto err_iomap; + } + + clk_set_parent(gpt_clk, pll3_clk); + + spear_clockevent_init(); + spear_clocksource_init(); + + return; + +err_iomap: + iounmap(gpt_base); + +err_mem: + release_mem_region(SPEAR_GPT0_BASE, SZ_1K); +} + +struct sys_timer spear_sys_timer = { + .init = spear_setup_timer, +}; -- cgit v1.2.3-59-g8ed1b From 8c0236fc465c71d98203bcf5609db01b9cf5f70f Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:30:46 +0100 Subject: ARM: 6014/1: ST SPEAr: Added clock framework for SPEAr platform and machines Clock framework for SPEAr is based upon clkdev framework for ARM Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/mach-spear3xx/clock.c | 389 +++++++++++++++++++ arch/arm/mach-spear3xx/include/mach/clkdev.h | 19 + arch/arm/mach-spear3xx/include/mach/misc_regs.h | 0 arch/arm/mach-spear6xx/clock.c | 483 ++++++++++++++++++++++++ arch/arm/mach-spear6xx/include/mach/clkdev.h | 19 + arch/arm/plat-spear/clock.c | 435 +++++++++++++++++++++ arch/arm/plat-spear/include/plat/clkdev.h | 20 + arch/arm/plat-spear/include/plat/clock.h | 126 +++++++ 8 files changed, 1491 insertions(+) create mode 100644 arch/arm/mach-spear3xx/clock.c create mode 100644 arch/arm/mach-spear3xx/include/mach/clkdev.h mode change 100755 => 100644 arch/arm/mach-spear3xx/include/mach/misc_regs.h create mode 100644 arch/arm/mach-spear6xx/clock.c create mode 100644 arch/arm/mach-spear6xx/include/mach/clkdev.h create mode 100644 arch/arm/plat-spear/clock.c create mode 100644 arch/arm/plat-spear/include/plat/clkdev.h create mode 100644 arch/arm/plat-spear/include/plat/clock.h (limited to 'arch') diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c new file mode 100644 index 000000000000..39f6ccf22294 --- /dev/null +++ b/arch/arm/mach-spear3xx/clock.c @@ -0,0 +1,389 @@ +/* + * arch/arm/mach-spear3xx/clock.c + * + * SPEAr3xx machines clock framework source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include + +/* root clks */ +/* 32 KHz oscillator clock */ +static struct clk osc_32k_clk = { + .flags = ALWAYS_ENABLED, + .rate = 32000, +}; + +/* 24 MHz oscillator clock */ +static struct clk osc_24m_clk = { + .flags = ALWAYS_ENABLED, + .rate = 24000000, +}; + +/* clock derived from 32 KHz osc clk */ +/* rtc clock */ +static struct clk rtc_clk = { + .pclk = &osc_32k_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = RTC_CLK_ENB, + .recalc = &follow_parent, +}; + +/* clock derived from 24 MHz osc clk */ +/* pll1 configuration structure */ +static struct pll_clk_config pll1_config = { + .mode_reg = PLL1_CTR, + .cfg_reg = PLL1_FRQ, +}; + +/* PLL1 clock */ +static struct clk pll1_clk = { + .pclk = &osc_24m_clk, + .en_reg = PLL1_CTR, + .en_reg_bit = PLL_ENABLE, + .recalc = &pll1_clk_recalc, + .private_data = &pll1_config, +}; + +/* PLL3 48 MHz clock */ +static struct clk pll3_48m_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &osc_24m_clk, + .rate = 48000000, +}; + +/* watch dog timer clock */ +static struct clk wdt_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &osc_24m_clk, + .recalc = &follow_parent, +}; + +/* clock derived from pll1 clk */ +/* cpu clock */ +static struct clk cpu_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &pll1_clk, + .recalc = &follow_parent, +}; + +/* ahb configuration structure */ +static struct bus_clk_config ahb_config = { + .reg = CORE_CLK_CFG, + .mask = PLL_HCLK_RATIO_MASK, + .shift = PLL_HCLK_RATIO_SHIFT, +}; + +/* ahb clock */ +static struct clk ahb_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &pll1_clk, + .recalc = &bus_clk_recalc, + .private_data = &ahb_config, +}; + +/* uart configurations */ +static struct aux_clk_config uart_config = { + .synth_reg = UART_CLK_SYNT, +}; + +/* uart parents */ +static struct pclk_info uart_pclk_info[] = { + { + .pclk = &pll1_clk, + .pclk_mask = AUX_CLK_PLL1_MASK, + .scalable = 1, + }, { + .pclk = &pll3_48m_clk, + .pclk_mask = AUX_CLK_PLL3_MASK, + .scalable = 0, + }, +}; + +/* uart parent select structure */ +static struct pclk_sel uart_pclk_sel = { + .pclk_info = uart_pclk_info, + .pclk_count = ARRAY_SIZE(uart_pclk_info), + .pclk_sel_reg = PERIP_CLK_CFG, + .pclk_sel_mask = UART_CLK_MASK, +}; + +/* uart clock */ +static struct clk uart_clk = { + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = UART_CLK_ENB, + .pclk_sel = &uart_pclk_sel, + .pclk_sel_shift = UART_CLK_SHIFT, + .recalc = &aux_clk_recalc, + .private_data = &uart_config, +}; + +/* firda configurations */ +static struct aux_clk_config firda_config = { + .synth_reg = FIRDA_CLK_SYNT, +}; + +/* firda parents */ +static struct pclk_info firda_pclk_info[] = { + { + .pclk = &pll1_clk, + .pclk_mask = AUX_CLK_PLL1_MASK, + .scalable = 1, + }, { + .pclk = &pll3_48m_clk, + .pclk_mask = AUX_CLK_PLL3_MASK, + .scalable = 0, + }, +}; + +/* firda parent select structure */ +static struct pclk_sel firda_pclk_sel = { + .pclk_info = firda_pclk_info, + .pclk_count = ARRAY_SIZE(firda_pclk_info), + .pclk_sel_reg = PERIP_CLK_CFG, + .pclk_sel_mask = FIRDA_CLK_MASK, +}; + +/* firda clock */ +static struct clk firda_clk = { + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = FIRDA_CLK_ENB, + .pclk_sel = &firda_pclk_sel, + .pclk_sel_shift = FIRDA_CLK_SHIFT, + .recalc = &aux_clk_recalc, + .private_data = &firda_config, +}; + +/* gpt parents */ +static struct pclk_info gpt_pclk_info[] = { + { + .pclk = &pll1_clk, + .pclk_mask = AUX_CLK_PLL1_MASK, + .scalable = 1, + }, { + .pclk = &pll3_48m_clk, + .pclk_mask = AUX_CLK_PLL3_MASK, + .scalable = 0, + }, +}; + +/* gpt parent select structure */ +static struct pclk_sel gpt_pclk_sel = { + .pclk_info = gpt_pclk_info, + .pclk_count = ARRAY_SIZE(gpt_pclk_info), + .pclk_sel_reg = PERIP_CLK_CFG, + .pclk_sel_mask = GPT_CLK_MASK, +}; + +/* gpt0 configurations */ +static struct aux_clk_config gpt0_config = { + .synth_reg = PRSC1_CLK_CFG, +}; + +/* gpt0 timer clock */ +static struct clk gpt0_clk = { + .flags = ALWAYS_ENABLED, + .pclk_sel = &gpt_pclk_sel, + .pclk_sel_shift = GPT0_CLK_SHIFT, + .recalc = &gpt_clk_recalc, + .private_data = &gpt0_config, +}; + +/* gpt1 configurations */ +static struct aux_clk_config gpt1_config = { + .synth_reg = PRSC2_CLK_CFG, +}; + +/* gpt1 timer clock */ +static struct clk gpt1_clk = { + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = GPT1_CLK_ENB, + .pclk_sel = &gpt_pclk_sel, + .pclk_sel_shift = GPT1_CLK_SHIFT, + .recalc = &gpt_clk_recalc, + .private_data = &gpt1_config, +}; + +/* gpt2 configurations */ +static struct aux_clk_config gpt2_config = { + .synth_reg = PRSC3_CLK_CFG, +}; + +/* gpt2 timer clock */ +static struct clk gpt2_clk = { + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = GPT2_CLK_ENB, + .pclk_sel = &gpt_pclk_sel, + .pclk_sel_shift = GPT2_CLK_SHIFT, + .recalc = &gpt_clk_recalc, + .private_data = &gpt2_config, +}; + +/* clock derived from pll3 clk */ +/* usbh clock */ +static struct clk usbh_clk = { + .pclk = &pll3_48m_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = USBH_CLK_ENB, + .recalc = &follow_parent, +}; + +/* usbd clock */ +static struct clk usbd_clk = { + .pclk = &pll3_48m_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = USBD_CLK_ENB, + .recalc = &follow_parent, +}; + +/* clcd clock */ +static struct clk clcd_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &pll3_48m_clk, + .recalc = &follow_parent, +}; + +/* clock derived from ahb clk */ +/* apb configuration structure */ +static struct bus_clk_config apb_config = { + .reg = CORE_CLK_CFG, + .mask = HCLK_PCLK_RATIO_MASK, + .shift = HCLK_PCLK_RATIO_SHIFT, +}; + +/* apb clock */ +static struct clk apb_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &ahb_clk, + .recalc = &bus_clk_recalc, + .private_data = &apb_config, +}; + +/* i2c clock */ +static struct clk i2c_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = I2C_CLK_ENB, + .recalc = &follow_parent, +}; + +/* dma clock */ +static struct clk dma_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = DMA_CLK_ENB, + .recalc = &follow_parent, +}; + +/* jpeg clock */ +static struct clk jpeg_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = JPEG_CLK_ENB, + .recalc = &follow_parent, +}; + +/* gmac clock */ +static struct clk gmac_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = GMAC_CLK_ENB, + .recalc = &follow_parent, +}; + +/* smi clock */ +static struct clk smi_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = SMI_CLK_ENB, + .recalc = &follow_parent, +}; + +/* c3 clock */ +static struct clk c3_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = C3_CLK_ENB, + .recalc = &follow_parent, +}; + +/* clock derived from apb clk */ +/* adc clock */ +static struct clk adc_clk = { + .pclk = &apb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = ADC_CLK_ENB, + .recalc = &follow_parent, +}; + +/* ssp clock */ +static struct clk ssp_clk = { + .pclk = &apb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = SSP_CLK_ENB, + .recalc = &follow_parent, +}; + +/* gpio clock */ +static struct clk gpio_clk = { + .pclk = &apb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = GPIO_CLK_ENB, + .recalc = &follow_parent, +}; + +/* array of all spear 3xx clock lookups */ +static struct clk_lookup spear_clk_lookups[] = { + /* root clks */ + { .con_id = "osc_32k_clk", .clk = &osc_32k_clk}, + { .con_id = "osc_24m_clk", .clk = &osc_24m_clk}, + /* clock derived from 32 KHz osc clk */ + { .dev_id = "rtc", .clk = &rtc_clk}, + /* clock derived from 24 MHz osc clk */ + { .con_id = "pll1_clk", .clk = &pll1_clk}, + { .con_id = "pll3_48m_clk", .clk = &pll3_48m_clk}, + { .dev_id = "wdt", .clk = &wdt_clk}, + /* clock derived from pll1 clk */ + { .con_id = "cpu_clk", .clk = &cpu_clk}, + { .con_id = "ahb_clk", .clk = &ahb_clk}, + { .dev_id = "uart", .clk = &uart_clk}, + { .dev_id = "firda", .clk = &firda_clk}, + { .dev_id = "gpt0", .clk = &gpt0_clk}, + { .dev_id = "gpt1", .clk = &gpt1_clk}, + { .dev_id = "gpt2", .clk = &gpt2_clk}, + /* clock derived from pll3 clk */ + { .dev_id = "usbh", .clk = &usbh_clk}, + { .dev_id = "usbd", .clk = &usbd_clk}, + { .dev_id = "clcd", .clk = &clcd_clk}, + /* clock derived from ahb clk */ + { .con_id = "apb_clk", .clk = &apb_clk}, + { .dev_id = "i2c", .clk = &i2c_clk}, + { .dev_id = "dma", .clk = &dma_clk}, + { .dev_id = "jpeg", .clk = &jpeg_clk}, + { .dev_id = "gmac", .clk = &gmac_clk}, + { .dev_id = "smi", .clk = &smi_clk}, + { .dev_id = "c3", .clk = &c3_clk}, + /* clock derived from apb clk */ + { .dev_id = "adc", .clk = &adc_clk}, + { .dev_id = "ssp", .clk = &ssp_clk}, + { .dev_id = "gpio", .clk = &gpio_clk}, +}; + +void __init clk_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++) + clk_register(&spear_clk_lookups[i]); + + recalc_root_clocks(); +} diff --git a/arch/arm/mach-spear3xx/include/mach/clkdev.h b/arch/arm/mach-spear3xx/include/mach/clkdev.h new file mode 100644 index 000000000000..a3d07339d9f1 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/clkdev.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear3xx/include/mach/clkdev.h + * + * Clock Dev framework definitions for SPEAr3xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_CLKDEV_H +#define __MACH_CLKDEV_H + +#include + +#endif /* __MACH_CLKDEV_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h old mode 100755 new mode 100644 diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c new file mode 100644 index 000000000000..13e27c769685 --- /dev/null +++ b/arch/arm/mach-spear6xx/clock.c @@ -0,0 +1,483 @@ +/* + * arch/arm/mach-spear6xx/clock.c + * + * SPEAr6xx machines clock framework source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include + +/* root clks */ +/* 32 KHz oscillator clock */ +static struct clk osc_32k_clk = { + .flags = ALWAYS_ENABLED, + .rate = 32000, +}; + +/* 30 MHz oscillator clock */ +static struct clk osc_30m_clk = { + .flags = ALWAYS_ENABLED, + .rate = 30000000, +}; + +/* clock derived from 32 KHz osc clk */ +/* rtc clock */ +static struct clk rtc_clk = { + .pclk = &osc_32k_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = RTC_CLK_ENB, + .recalc = &follow_parent, +}; + +/* clock derived from 30 MHz osc clk */ +/* pll1 configuration structure */ +static struct pll_clk_config pll1_config = { + .mode_reg = PLL1_CTR, + .cfg_reg = PLL1_FRQ, +}; + +/* PLL1 clock */ +static struct clk pll1_clk = { + .pclk = &osc_30m_clk, + .en_reg = PLL1_CTR, + .en_reg_bit = PLL_ENABLE, + .recalc = &pll1_clk_recalc, + .private_data = &pll1_config, +}; + +/* PLL3 48 MHz clock */ +static struct clk pll3_48m_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &osc_30m_clk, + .rate = 48000000, +}; + +/* watch dog timer clock */ +static struct clk wdt_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &osc_30m_clk, + .recalc = &follow_parent, +}; + +/* clock derived from pll1 clk */ +/* cpu clock */ +static struct clk cpu_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &pll1_clk, + .recalc = &follow_parent, +}; + +/* ahb configuration structure */ +static struct bus_clk_config ahb_config = { + .reg = CORE_CLK_CFG, + .mask = PLL_HCLK_RATIO_MASK, + .shift = PLL_HCLK_RATIO_SHIFT, +}; + +/* ahb clock */ +static struct clk ahb_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &pll1_clk, + .recalc = &bus_clk_recalc, + .private_data = &ahb_config, +}; + +/* uart parents */ +static struct pclk_info uart_pclk_info[] = { + { + .pclk = &pll1_clk, + .pclk_mask = AUX_CLK_PLL1_MASK, + .scalable = 1, + }, { + .pclk = &pll3_48m_clk, + .pclk_mask = AUX_CLK_PLL3_MASK, + .scalable = 0, + }, +}; + +/* uart parent select structure */ +static struct pclk_sel uart_pclk_sel = { + .pclk_info = uart_pclk_info, + .pclk_count = ARRAY_SIZE(uart_pclk_info), + .pclk_sel_reg = PERIP_CLK_CFG, + .pclk_sel_mask = UART_CLK_MASK, +}; + +/* uart configurations */ +static struct aux_clk_config uart_config = { + .synth_reg = UART_CLK_SYNT, +}; + +/* uart0 clock */ +static struct clk uart0_clk = { + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = UART0_CLK_ENB, + .pclk_sel = &uart_pclk_sel, + .pclk_sel_shift = UART_CLK_SHIFT, + .recalc = &aux_clk_recalc, + .private_data = &uart_config, +}; + +/* uart1 clock */ +static struct clk uart1_clk = { + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = UART1_CLK_ENB, + .pclk_sel = &uart_pclk_sel, + .pclk_sel_shift = UART_CLK_SHIFT, + .recalc = &aux_clk_recalc, + .private_data = &uart_config, +}; + +/* firda configurations */ +static struct aux_clk_config firda_config = { + .synth_reg = FIRDA_CLK_SYNT, +}; + +/* firda parents */ +static struct pclk_info firda_pclk_info[] = { + { + .pclk = &pll1_clk, + .pclk_mask = AUX_CLK_PLL1_MASK, + .scalable = 1, + }, { + .pclk = &pll3_48m_clk, + .pclk_mask = AUX_CLK_PLL3_MASK, + .scalable = 0, + }, +}; + +/* firda parent select structure */ +static struct pclk_sel firda_pclk_sel = { + .pclk_info = firda_pclk_info, + .pclk_count = ARRAY_SIZE(firda_pclk_info), + .pclk_sel_reg = PERIP_CLK_CFG, + .pclk_sel_mask = FIRDA_CLK_MASK, +}; + +/* firda clock */ +static struct clk firda_clk = { + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = FIRDA_CLK_ENB, + .pclk_sel = &firda_pclk_sel, + .pclk_sel_shift = FIRDA_CLK_SHIFT, + .recalc = &aux_clk_recalc, + .private_data = &firda_config, +}; + +/* clcd configurations */ +static struct aux_clk_config clcd_config = { + .synth_reg = CLCD_CLK_SYNT, +}; + +/* clcd parents */ +static struct pclk_info clcd_pclk_info[] = { + { + .pclk = &pll1_clk, + .pclk_mask = AUX_CLK_PLL1_MASK, + .scalable = 1, + }, { + .pclk = &pll3_48m_clk, + .pclk_mask = AUX_CLK_PLL3_MASK, + .scalable = 0, + }, +}; + +/* clcd parent select structure */ +static struct pclk_sel clcd_pclk_sel = { + .pclk_info = clcd_pclk_info, + .pclk_count = ARRAY_SIZE(clcd_pclk_info), + .pclk_sel_reg = PERIP_CLK_CFG, + .pclk_sel_mask = CLCD_CLK_MASK, +}; + +/* clcd clock */ +static struct clk clcd_clk = { + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = CLCD_CLK_ENB, + .pclk_sel = &clcd_pclk_sel, + .pclk_sel_shift = CLCD_CLK_SHIFT, + .recalc = &aux_clk_recalc, + .private_data = &clcd_config, +}; + +/* gpt parents */ +static struct pclk_info gpt_pclk_info[] = { + { + .pclk = &pll1_clk, + .pclk_mask = AUX_CLK_PLL1_MASK, + .scalable = 1, + }, { + .pclk = &pll3_48m_clk, + .pclk_mask = AUX_CLK_PLL3_MASK, + .scalable = 0, + }, +}; + +/* gpt parent select structure */ +static struct pclk_sel gpt_pclk_sel = { + .pclk_info = gpt_pclk_info, + .pclk_count = ARRAY_SIZE(gpt_pclk_info), + .pclk_sel_reg = PERIP_CLK_CFG, + .pclk_sel_mask = GPT_CLK_MASK, +}; + +/* gpt0_1 configurations */ +static struct aux_clk_config gpt0_1_config = { + .synth_reg = PRSC1_CLK_CFG, +}; + +/* gpt0 ARM1 subsystem timer clock */ +static struct clk gpt0_clk = { + .flags = ALWAYS_ENABLED, + .pclk_sel = &gpt_pclk_sel, + .pclk_sel_shift = GPT0_CLK_SHIFT, + .recalc = &gpt_clk_recalc, + .private_data = &gpt0_1_config, +}; + +/* gpt1 timer clock */ +static struct clk gpt1_clk = { + .flags = ALWAYS_ENABLED, + .pclk_sel = &gpt_pclk_sel, + .pclk_sel_shift = GPT1_CLK_SHIFT, + .recalc = &gpt_clk_recalc, + .private_data = &gpt0_1_config, +}; + +/* gpt2 configurations */ +static struct aux_clk_config gpt2_config = { + .synth_reg = PRSC2_CLK_CFG, +}; + +/* gpt2 timer clock */ +static struct clk gpt2_clk = { + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = GPT2_CLK_ENB, + .pclk_sel = &gpt_pclk_sel, + .pclk_sel_shift = GPT2_CLK_SHIFT, + .recalc = &gpt_clk_recalc, + .private_data = &gpt2_config, +}; + +/* gpt3 configurations */ +static struct aux_clk_config gpt3_config = { + .synth_reg = PRSC3_CLK_CFG, +}; + +/* gpt3 timer clock */ +static struct clk gpt3_clk = { + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = GPT3_CLK_ENB, + .pclk_sel = &gpt_pclk_sel, + .pclk_sel_shift = GPT3_CLK_SHIFT, + .recalc = &gpt_clk_recalc, + .private_data = &gpt3_config, +}; + +/* clock derived from pll3 clk */ +/* usbh0 clock */ +static struct clk usbh0_clk = { + .pclk = &pll3_48m_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = USBH0_CLK_ENB, + .recalc = &follow_parent, +}; + +/* usbh1 clock */ +static struct clk usbh1_clk = { + .pclk = &pll3_48m_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = USBH1_CLK_ENB, + .recalc = &follow_parent, +}; + +/* usbd clock */ +static struct clk usbd_clk = { + .pclk = &pll3_48m_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = USBD_CLK_ENB, + .recalc = &follow_parent, +}; + +/* clock derived from ahb clk */ +/* apb configuration structure */ +static struct bus_clk_config apb_config = { + .reg = CORE_CLK_CFG, + .mask = HCLK_PCLK_RATIO_MASK, + .shift = HCLK_PCLK_RATIO_SHIFT, +}; + +/* apb clock */ +static struct clk apb_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &ahb_clk, + .recalc = &bus_clk_recalc, + .private_data = &apb_config, +}; + +/* i2c clock */ +static struct clk i2c_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = I2C_CLK_ENB, + .recalc = &follow_parent, +}; + +/* dma clock */ +static struct clk dma_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = DMA_CLK_ENB, + .recalc = &follow_parent, +}; + +/* jpeg clock */ +static struct clk jpeg_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = JPEG_CLK_ENB, + .recalc = &follow_parent, +}; + +/* gmac clock */ +static struct clk gmac_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = GMAC_CLK_ENB, + .recalc = &follow_parent, +}; + +/* smi clock */ +static struct clk smi_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = SMI_CLK_ENB, + .recalc = &follow_parent, +}; + +/* fsmc clock */ +static struct clk fsmc_clk = { + .pclk = &ahb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = FSMC_CLK_ENB, + .recalc = &follow_parent, +}; + +/* clock derived from apb clk */ +/* adc clock */ +static struct clk adc_clk = { + .pclk = &apb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = ADC_CLK_ENB, + .recalc = &follow_parent, +}; + +/* ssp0 clock */ +static struct clk ssp0_clk = { + .pclk = &apb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = SSP0_CLK_ENB, + .recalc = &follow_parent, +}; + +/* ssp1 clock */ +static struct clk ssp1_clk = { + .pclk = &apb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = SSP1_CLK_ENB, + .recalc = &follow_parent, +}; + +/* ssp2 clock */ +static struct clk ssp2_clk = { + .pclk = &apb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = SSP2_CLK_ENB, + .recalc = &follow_parent, +}; + +/* gpio0 ARM subsystem clock */ +static struct clk gpio0_clk = { + .flags = ALWAYS_ENABLED, + .pclk = &apb_clk, + .recalc = &follow_parent, +}; + +/* gpio1 clock */ +static struct clk gpio1_clk = { + .pclk = &apb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = GPIO1_CLK_ENB, + .recalc = &follow_parent, +}; + +/* gpio2 clock */ +static struct clk gpio2_clk = { + .pclk = &apb_clk, + .en_reg = PERIP1_CLK_ENB, + .en_reg_bit = GPIO2_CLK_ENB, + .recalc = &follow_parent, +}; + +/* array of all spear 6xx clock lookups */ +static struct clk_lookup spear_clk_lookups[] = { + /* root clks */ + { .con_id = "osc_32k_clk", .clk = &osc_32k_clk}, + { .con_id = "osc_30m_clk", .clk = &osc_30m_clk}, + /* clock derived from 32 KHz os clk */ + { .dev_id = "rtc", .clk = &rtc_clk}, + /* clock derived from 30 MHz os clk */ + { .con_id = "pll1_clk", .clk = &pll1_clk}, + { .con_id = "pll3_48m_clk", .clk = &pll3_48m_clk}, + { .dev_id = "wdt", .clk = &wdt_clk}, + /* clock derived from pll1 clk */ + { .con_id = "cpu_clk", .clk = &cpu_clk}, + { .con_id = "ahb_clk", .clk = &ahb_clk}, + { .dev_id = "uart0", .clk = &uart0_clk}, + { .dev_id = "uart1", .clk = &uart1_clk}, + { .dev_id = "firda", .clk = &firda_clk}, + { .dev_id = "clcd", .clk = &clcd_clk}, + { .dev_id = "gpt0", .clk = &gpt0_clk}, + { .dev_id = "gpt1", .clk = &gpt1_clk}, + { .dev_id = "gpt2", .clk = &gpt2_clk}, + { .dev_id = "gpt3", .clk = &gpt3_clk}, + /* clock derived from pll3 clk */ + { .dev_id = "usbh0", .clk = &usbh0_clk}, + { .dev_id = "usbh1", .clk = &usbh1_clk}, + { .dev_id = "usbd", .clk = &usbd_clk}, + /* clock derived from ahb clk */ + { .con_id = "apb_clk", .clk = &apb_clk}, + { .dev_id = "i2c", .clk = &i2c_clk}, + { .dev_id = "dma", .clk = &dma_clk}, + { .dev_id = "jpeg", .clk = &jpeg_clk}, + { .dev_id = "gmac", .clk = &gmac_clk}, + { .dev_id = "smi", .clk = &smi_clk}, + { .dev_id = "fsmc", .clk = &fsmc_clk}, + /* clock derived from apb clk */ + { .dev_id = "adc", .clk = &adc_clk}, + { .dev_id = "ssp0", .clk = &ssp0_clk}, + { .dev_id = "ssp1", .clk = &ssp1_clk}, + { .dev_id = "ssp2", .clk = &ssp2_clk}, + { .dev_id = "gpio0", .clk = &gpio0_clk}, + { .dev_id = "gpio1", .clk = &gpio1_clk}, + { .dev_id = "gpio2", .clk = &gpio2_clk}, +}; + +void __init clk_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++) + clk_register(&spear_clk_lookups[i]); + + recalc_root_clocks(); +} diff --git a/arch/arm/mach-spear6xx/include/mach/clkdev.h b/arch/arm/mach-spear6xx/include/mach/clkdev.h new file mode 100644 index 000000000000..05676bf440d3 --- /dev/null +++ b/arch/arm/mach-spear6xx/include/mach/clkdev.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-spear6xx/include/mach/clkdev.h + * + * Clock Dev framework definitions for SPEAr6xx machine family + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __MACH_CLKDEV_H +#define __MACH_CLKDEV_H + +#include + +#endif /* __MACH_CLKDEV_H */ diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c new file mode 100644 index 000000000000..ee4f90e534d8 --- /dev/null +++ b/arch/arm/plat-spear/clock.c @@ -0,0 +1,435 @@ +/* + * arch/arm/plat-spear/clock.c + * + * Clock framework for SPEAr platform + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(clocks_lock); +static LIST_HEAD(root_clks); + +static void propagate_rate(struct list_head *); + +static int generic_clk_enable(struct clk *clk) +{ + unsigned int val; + + if (!clk->en_reg) + return -EFAULT; + + val = readl(clk->en_reg); + if (unlikely(clk->flags & RESET_TO_ENABLE)) + val &= ~(1 << clk->en_reg_bit); + else + val |= 1 << clk->en_reg_bit; + + writel(val, clk->en_reg); + + return 0; +} + +static void generic_clk_disable(struct clk *clk) +{ + unsigned int val; + + if (!clk->en_reg) + return; + + val = readl(clk->en_reg); + if (unlikely(clk->flags & RESET_TO_ENABLE)) + val |= 1 << clk->en_reg_bit; + else + val &= ~(1 << clk->en_reg_bit); + + writel(val, clk->en_reg); +} + +/* generic clk ops */ +static struct clkops generic_clkops = { + .enable = generic_clk_enable, + .disable = generic_clk_disable, +}; + +/* + * clk_enable - inform the system when the clock source should be running. + * @clk: clock source + * + * If the clock can not be enabled/disabled, this should return success. + * + * Returns success (0) or negative errno. + */ +int clk_enable(struct clk *clk) +{ + unsigned long flags; + int ret = 0; + + if (!clk || IS_ERR(clk)) + return -EFAULT; + + spin_lock_irqsave(&clocks_lock, flags); + if (clk->usage_count == 0) { + if (clk->ops && clk->ops->enable) + ret = clk->ops->enable(clk); + } + clk->usage_count++; + spin_unlock_irqrestore(&clocks_lock, flags); + + return ret; +} +EXPORT_SYMBOL(clk_enable); + +/* + * clk_disable - inform the system when the clock source is no longer required. + * @clk: clock source + * + * Inform the system that a clock source is no longer required by + * a driver and may be shut down. + * + * Implementation detail: if the clock source is shared between + * multiple drivers, clk_enable() calls must be balanced by the + * same number of clk_disable() calls for the clock source to be + * disabled. + */ +void clk_disable(struct clk *clk) +{ + unsigned long flags; + + if (!clk || IS_ERR(clk)) + return; + + WARN_ON(clk->usage_count == 0); + + spin_lock_irqsave(&clocks_lock, flags); + clk->usage_count--; + if (clk->usage_count == 0) { + if (clk->ops && clk->ops->disable) + clk->ops->disable(clk); + } + spin_unlock_irqrestore(&clocks_lock, flags); +} +EXPORT_SYMBOL(clk_disable); + +/** + * clk_get_rate - obtain the current clock rate (in Hz) for a clock source. + * This is only valid once the clock source has been enabled. + * @clk: clock source + */ +unsigned long clk_get_rate(struct clk *clk) +{ + unsigned long flags, rate; + + spin_lock_irqsave(&clocks_lock, flags); + rate = clk->rate; + spin_unlock_irqrestore(&clocks_lock, flags); + + return rate; +} +EXPORT_SYMBOL(clk_get_rate); + +/** + * clk_set_parent - set the parent clock source for this clock + * @clk: clock source + * @parent: parent clock source + * + * Returns success (0) or negative errno. + */ +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + int i, found = 0, val = 0; + unsigned long flags; + + if (!clk || IS_ERR(clk) || !parent || IS_ERR(parent)) + return -EFAULT; + if (clk->usage_count) + return -EBUSY; + if (!clk->pclk_sel) + return -EPERM; + if (clk->pclk == parent) + return 0; + + for (i = 0; i < clk->pclk_sel->pclk_count; i++) { + if (clk->pclk_sel->pclk_info[i].pclk == parent) { + found = 1; + break; + } + } + + if (!found) + return -EINVAL; + + spin_lock_irqsave(&clocks_lock, flags); + /* reflect parent change in hardware */ + val = readl(clk->pclk_sel->pclk_sel_reg); + val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift); + val |= clk->pclk_sel->pclk_info[i].pclk_mask << clk->pclk_sel_shift; + writel(val, clk->pclk_sel->pclk_sel_reg); + spin_unlock_irqrestore(&clocks_lock, flags); + + /* reflect parent change in software */ + clk->recalc(clk); + propagate_rate(&clk->children); + return 0; +} +EXPORT_SYMBOL(clk_set_parent); + +/* registers clock in platform clock framework */ +void clk_register(struct clk_lookup *cl) +{ + struct clk *clk = cl->clk; + unsigned long flags; + + if (!clk || IS_ERR(clk)) + return; + + spin_lock_irqsave(&clocks_lock, flags); + + INIT_LIST_HEAD(&clk->children); + if (clk->flags & ALWAYS_ENABLED) + clk->ops = NULL; + else if (!clk->ops) + clk->ops = &generic_clkops; + + /* root clock don't have any parents */ + if (!clk->pclk && !clk->pclk_sel) { + list_add(&clk->sibling, &root_clks); + /* add clocks with only one parent to parent's children list */ + } else if (clk->pclk && !clk->pclk_sel) { + list_add(&clk->sibling, &clk->pclk->children); + } else { + /* add clocks with > 1 parent to 1st parent's children list */ + list_add(&clk->sibling, + &clk->pclk_sel->pclk_info[0].pclk->children); + } + spin_unlock_irqrestore(&clocks_lock, flags); + + /* add clock to arm clockdev framework */ + clkdev_add(cl); +} + +/** + * propagate_rate - recalculate and propagate all clocks in list head + * + * Recalculates all root clocks in list head, which if the clock's .recalc is + * set correctly, should also propagate their rates. + */ +static void propagate_rate(struct list_head *lhead) +{ + struct clk *clkp, *_temp; + + list_for_each_entry_safe(clkp, _temp, lhead, sibling) { + if (clkp->recalc) + clkp->recalc(clkp); + propagate_rate(&clkp->children); + } +} + +/* returns current programmed clocks clock info structure */ +static struct pclk_info *pclk_info_get(struct clk *clk) +{ + unsigned int mask, i; + unsigned long flags; + struct pclk_info *info = NULL; + + spin_lock_irqsave(&clocks_lock, flags); + mask = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift) + & clk->pclk_sel->pclk_sel_mask; + + for (i = 0; i < clk->pclk_sel->pclk_count; i++) { + if (clk->pclk_sel->pclk_info[i].pclk_mask == mask) + info = &clk->pclk_sel->pclk_info[i]; + } + spin_unlock_irqrestore(&clocks_lock, flags); + + return info; +} + +/* + * Set pclk as cclk's parent and add clock sibling node to current parents + * children list + */ +static void change_parent(struct clk *cclk, struct clk *pclk) +{ + unsigned long flags; + + spin_lock_irqsave(&clocks_lock, flags); + list_del(&cclk->sibling); + list_add(&cclk->sibling, &pclk->children); + + cclk->pclk = pclk; + spin_unlock_irqrestore(&clocks_lock, flags); +} + +/* + * calculates current programmed rate of pll1 + * + * In normal mode + * rate = (2 * M[15:8] * Fin)/(N * 2^P) + * + * In Dithered mode + * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P) + */ +void pll1_clk_recalc(struct clk *clk) +{ + struct pll_clk_config *config = clk->private_data; + unsigned int num = 2, den = 0, val, mode = 0; + unsigned long flags; + + spin_lock_irqsave(&clocks_lock, flags); + mode = (readl(config->mode_reg) >> PLL_MODE_SHIFT) & + PLL_MODE_MASK; + + val = readl(config->cfg_reg); + /* calculate denominator */ + den = (val >> PLL_DIV_P_SHIFT) & PLL_DIV_P_MASK; + den = 1 << den; + den *= (val >> PLL_DIV_N_SHIFT) & PLL_DIV_N_MASK; + + /* calculate numerator & denominator */ + if (!mode) { + /* Normal mode */ + num *= (val >> PLL_NORM_FDBK_M_SHIFT) & PLL_NORM_FDBK_M_MASK; + } else { + /* Dithered mode */ + num *= (val >> PLL_DITH_FDBK_M_SHIFT) & PLL_DITH_FDBK_M_MASK; + den *= 256; + } + + clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000; + spin_unlock_irqrestore(&clocks_lock, flags); +} + +/* calculates current programmed rate of ahb or apb bus */ +void bus_clk_recalc(struct clk *clk) +{ + struct bus_clk_config *config = clk->private_data; + unsigned int div; + unsigned long flags; + + spin_lock_irqsave(&clocks_lock, flags); + div = ((readl(config->reg) >> config->shift) & config->mask) + 1; + clk->rate = (unsigned long)clk->pclk->rate / div; + spin_unlock_irqrestore(&clocks_lock, flags); +} + +/* + * calculates current programmed rate of auxiliary synthesizers + * used by: UART, FIRDA + * + * Fout from synthesizer can be given from two equations: + * Fout1 = (Fin * X/Y)/2 + * Fout2 = Fin * X/Y + * + * Selection of eqn 1 or 2 is programmed in register + */ +void aux_clk_recalc(struct clk *clk) +{ + struct aux_clk_config *config = clk->private_data; + struct pclk_info *pclk_info = NULL; + unsigned int num = 1, den = 1, val, eqn; + unsigned long flags; + + /* get current programmed parent */ + pclk_info = pclk_info_get(clk); + if (!pclk_info) { + spin_lock_irqsave(&clocks_lock, flags); + clk->pclk = NULL; + clk->rate = 0; + spin_unlock_irqrestore(&clocks_lock, flags); + return; + } + + change_parent(clk, pclk_info->pclk); + + spin_lock_irqsave(&clocks_lock, flags); + if (pclk_info->scalable) { + val = readl(config->synth_reg); + + eqn = (val >> AUX_EQ_SEL_SHIFT) & AUX_EQ_SEL_MASK; + if (eqn == AUX_EQ1_SEL) + den *= 2; + + /* calculate numerator */ + num = (val >> AUX_XSCALE_SHIFT) & AUX_XSCALE_MASK; + + /* calculate denominator */ + den *= (val >> AUX_YSCALE_SHIFT) & AUX_YSCALE_MASK; + val = (((clk->pclk->rate/10000) * num) / den) * 10000; + } else + val = clk->pclk->rate; + + clk->rate = val; + spin_unlock_irqrestore(&clocks_lock, flags); +} + +/* + * calculates current programmed rate of gpt synthesizers + * Fout from synthesizer can be given from below equations: + * Fout= Fin/((2 ^ (N+1)) * (M+1)) + */ +void gpt_clk_recalc(struct clk *clk) +{ + struct aux_clk_config *config = clk->private_data; + struct pclk_info *pclk_info = NULL; + unsigned int div = 1, val; + unsigned long flags; + + pclk_info = pclk_info_get(clk); + if (!pclk_info) { + spin_lock_irqsave(&clocks_lock, flags); + clk->pclk = NULL; + clk->rate = 0; + spin_unlock_irqrestore(&clocks_lock, flags); + return; + } + + change_parent(clk, pclk_info->pclk); + + spin_lock_irqsave(&clocks_lock, flags); + if (pclk_info->scalable) { + val = readl(config->synth_reg); + div += (val >> GPT_MSCALE_SHIFT) & GPT_MSCALE_MASK; + div *= 1 << (((val >> GPT_NSCALE_SHIFT) & GPT_NSCALE_MASK) + 1); + } + + clk->rate = (unsigned long)clk->pclk->rate / div; + spin_unlock_irqrestore(&clocks_lock, flags); +} + +/* + * Used for clocks that always have same value as the parent clock divided by a + * fixed divisor + */ +void follow_parent(struct clk *clk) +{ + unsigned long flags; + + spin_lock_irqsave(&clocks_lock, flags); + clk->rate = clk->pclk->rate; + spin_unlock_irqrestore(&clocks_lock, flags); +} + +/** + * recalc_root_clocks - recalculate and propagate all root clocks + * + * Recalculates all root clocks (clocks with no parent), which if the + * clock's .recalc is set correctly, should also propagate their rates. + */ +void recalc_root_clocks(void) +{ + propagate_rate(&root_clks); +} diff --git a/arch/arm/plat-spear/include/plat/clkdev.h b/arch/arm/plat-spear/include/plat/clkdev.h new file mode 100644 index 000000000000..a2d0112fcaf7 --- /dev/null +++ b/arch/arm/plat-spear/include/plat/clkdev.h @@ -0,0 +1,20 @@ +/* + * arch/arm/plat-spear/include/plat/clkdev.h + * + * Clock Dev framework definitions for SPEAr platform + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __PLAT_CLKDEV_H +#define __PLAT_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif /* __PLAT_CLKDEV_H */ diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h new file mode 100644 index 000000000000..298bafc0a52f --- /dev/null +++ b/arch/arm/plat-spear/include/plat/clock.h @@ -0,0 +1,126 @@ +/* + * arch/arm/plat-spear/include/plat/clock.h + * + * Clock framework definitions for SPEAr platform + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __PLAT_CLOCK_H +#define __PLAT_CLOCK_H + +#include +#include +#include + +/* clk structure flags */ +#define ALWAYS_ENABLED (1 << 0) /* clock always enabled */ +#define RESET_TO_ENABLE (1 << 1) /* reset register bit to enable clk */ + +/** + * struct clkops - clock operations + * @enable: pointer to clock enable function + * @disable: pointer to clock disable function + */ +struct clkops { + int (*enable) (struct clk *); + void (*disable) (struct clk *); +}; + +/** + * struct pclk_info - parents info + * @pclk: pointer to parent clk + * @pclk_mask: value to be written for selecting this parent + * @scalable: Is parent scalable (1 - YES, 0 - NO) + */ +struct pclk_info { + struct clk *pclk; + u8 pclk_mask; + u8 scalable; +}; + +/** + * struct pclk_sel - parents selection configuration + * @pclk_info: pointer to array of parent clock info + * @pclk_count: number of parents + * @pclk_sel_reg: register for selecting a parent + * @pclk_sel_mask: mask for selecting parent (can be used to clear bits also) + */ +struct pclk_sel { + struct pclk_info *pclk_info; + u8 pclk_count; + unsigned int *pclk_sel_reg; + unsigned int pclk_sel_mask; +}; + +/** + * struct clk - clock structure + * @usage_count: num of users who enabled this clock + * @flags: flags for clock properties + * @rate: programmed clock rate in Hz + * @en_reg: clk enable/disable reg + * @en_reg_bit: clk enable/disable bit + * @ops: clk enable/disable ops - generic_clkops selected if NULL + * @recalc: pointer to clock rate recalculate function + * @pclk: current parent clk + * @pclk_sel: pointer to parent selection structure + * @pclk_sel_shift: register shift for selecting parent of this clock + * @children: list for childrens or this clock + * @sibling: node for list of clocks having same parents + * @private_data: clock specific private data + */ +struct clk { + unsigned int usage_count; + unsigned int flags; + unsigned long rate; + unsigned int *en_reg; + u8 en_reg_bit; + const struct clkops *ops; + void (*recalc) (struct clk *); + + struct clk *pclk; + struct pclk_sel *pclk_sel; + unsigned int pclk_sel_shift; + + struct list_head children; + struct list_head sibling; + void *private_data; +}; + +/* pll configuration structure */ +struct pll_clk_config { + unsigned int *mode_reg; + unsigned int *cfg_reg; +}; + +/* ahb and apb bus configuration structure */ +struct bus_clk_config { + unsigned int *reg; + unsigned int mask; + unsigned int shift; +}; + +/* + * Aux clk configuration structure: applicable to GPT, UART and FIRDA + */ +struct aux_clk_config { + unsigned int *synth_reg; +}; + +/* platform specific clock functions */ +void clk_register(struct clk_lookup *cl); +void recalc_root_clocks(void); + +/* clock recalc functions */ +void follow_parent(struct clk *clk); +void pll1_clk_recalc(struct clk *clk); +void bus_clk_recalc(struct clk *clk); +void gpt_clk_recalc(struct clk *clk); +void aux_clk_recalc(struct clk *clk); + +#endif /* __PLAT_CLOCK_H */ -- cgit v1.2.3-59-g8ed1b From 8f590d4541fb678a638777ab987709217cb71365 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:31:01 +0100 Subject: ARM: 6015/1: ST SPEAr: Added source files for SPEAr6xx machine family Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/mach-spear6xx/Kconfig | 20 +++++ arch/arm/mach-spear6xx/Kconfig600 | 17 ++++ arch/arm/mach-spear6xx/Makefile | 12 +++ arch/arm/mach-spear6xx/Makefile.boot | 3 + arch/arm/mach-spear6xx/spear600.c | 25 ++++++ arch/arm/mach-spear6xx/spear600_evb.c | 51 +++++++++++ arch/arm/mach-spear6xx/spear6xx.c | 158 ++++++++++++++++++++++++++++++++++ 7 files changed, 286 insertions(+) create mode 100644 arch/arm/mach-spear6xx/Kconfig create mode 100644 arch/arm/mach-spear6xx/Kconfig600 create mode 100644 arch/arm/mach-spear6xx/Makefile create mode 100644 arch/arm/mach-spear6xx/Makefile.boot create mode 100644 arch/arm/mach-spear6xx/spear600.c create mode 100644 arch/arm/mach-spear6xx/spear600_evb.c create mode 100644 arch/arm/mach-spear6xx/spear6xx.c (limited to 'arch') diff --git a/arch/arm/mach-spear6xx/Kconfig b/arch/arm/mach-spear6xx/Kconfig new file mode 100644 index 000000000000..bddba034f862 --- /dev/null +++ b/arch/arm/mach-spear6xx/Kconfig @@ -0,0 +1,20 @@ +# +# SPEAr6XX Machine configuration file +# + +if ARCH_SPEAR6XX + +choice + prompt "SPEAr6XX Family" + default MACH_SPEAR600 + +config MACH_SPEAR600 + bool "SPEAr600" + help + Supports ST SPEAr600 Machine +endchoice + +# Adding SPEAr6XX machine specific configuration files +source "arch/arm/mach-spear6xx/Kconfig600" + +endif #ARCH_SPEAR6XX diff --git a/arch/arm/mach-spear6xx/Kconfig600 b/arch/arm/mach-spear6xx/Kconfig600 new file mode 100644 index 000000000000..9e19f65eb78e --- /dev/null +++ b/arch/arm/mach-spear6xx/Kconfig600 @@ -0,0 +1,17 @@ +# +# SPEAr600 machine configuration file +# + +if MACH_SPEAR600 + +choice + prompt "SPEAr600 Boards" + default BOARD_SPEAR600_EVB + +config BOARD_SPEAR600_EVB + bool "SPEAr600 Evaluation Board" + help + Supports ST SPEAr600 Evaluation Board +endchoice + +endif #MACH_SPEAR600 diff --git a/arch/arm/mach-spear6xx/Makefile b/arch/arm/mach-spear6xx/Makefile new file mode 100644 index 000000000000..cc1a4d82d459 --- /dev/null +++ b/arch/arm/mach-spear6xx/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for SPEAr6XX machine series +# + +# common files +obj-y += clock.o spear6xx.o + +# spear600 specific files +obj-$(CONFIG_MACH_SPEAR600) += spear600.o + +# spear600 boards files +obj-$(CONFIG_BOARD_SPEAR600_EVB) += spear600_evb.o diff --git a/arch/arm/mach-spear6xx/Makefile.boot b/arch/arm/mach-spear6xx/Makefile.boot new file mode 100644 index 000000000000..7a1f3c0eadb8 --- /dev/null +++ b/arch/arm/mach-spear6xx/Makefile.boot @@ -0,0 +1,3 @@ +zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-spear6xx/spear600.c b/arch/arm/mach-spear6xx/spear600.c new file mode 100644 index 000000000000..5c484c433dc1 --- /dev/null +++ b/arch/arm/mach-spear6xx/spear600.c @@ -0,0 +1,25 @@ +/* + * arch/arm/mach-spear6xx/spear600.c + * + * SPEAr600 machine source file + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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 +#include +#include +#include + +/* Add spear600 specific devices here */ + +void __init spear600_init(void) +{ + /* call spear6xx family common init function */ + spear6xx_init(); +} diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c new file mode 100644 index 000000000000..daff8d04f7b6 --- /dev/null +++ b/arch/arm/mach-spear6xx/spear600_evb.c @@ -0,0 +1,51 @@ +/* + * arch/arm/mach-spear6xx/spear600_evb.c + * + * SPEAr600 evaluation board source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include + +static struct amba_device *amba_devs[] __initdata = { + &gpio_device[0], + &gpio_device[1], + &gpio_device[2], + &uart_device[0], + &uart_device[1], +}; + +static struct platform_device *plat_devs[] __initdata = { +}; + +static void __init spear600_evb_init(void) +{ + unsigned int i; + + /* call spear600 machine init function */ + spear600_init(); + + /* Add Platform Devices */ + platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); + + /* Add Amba Devices */ + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) + amba_device_register(amba_devs[i], &iomem_resource); +} + +MACHINE_START(SPEAR600, "ST-SPEAR600-EVB") + .boot_params = 0x00000100, + .map_io = spear6xx_map_io, + .init_irq = spear6xx_init_irq, + .timer = &spear_sys_timer, + .init_machine = spear600_evb_init, +MACHINE_END diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c new file mode 100644 index 000000000000..b67e571d4bf7 --- /dev/null +++ b/arch/arm/mach-spear6xx/spear6xx.c @@ -0,0 +1,158 @@ +/* + * arch/arm/mach-spear6xx/spear6xx.c + * + * SPEAr6XX machines common source file + * + * Copyright (C) 2009 ST Microelectronics + * Rajeev Kumar + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Add spear6xx machines common devices here */ +/* uart device registeration */ +struct amba_device uart_device[] = { + { + .dev = { + .init_name = "uart0", + }, + .res = { + .start = SPEAR6XX_ICM1_UART0_BASE, + .end = SPEAR6XX_ICM1_UART0_BASE + + SPEAR6XX_ICM1_UART0_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_UART_0, NO_IRQ}, + }, { + .dev = { + .init_name = "uart1", + }, + .res = { + .start = SPEAR6XX_ICM1_UART1_BASE, + .end = SPEAR6XX_ICM1_UART1_BASE + + SPEAR6XX_ICM1_UART1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_UART_1, NO_IRQ}, + } +}; + +/* gpio device registeration */ +static struct pl061_platform_data gpio_plat_data[] = { + { + .gpio_base = 0, + .irq_base = SPEAR_GPIO0_INT_BASE, + }, { + .gpio_base = 8, + .irq_base = SPEAR_GPIO1_INT_BASE, + }, { + .gpio_base = 16, + .irq_base = SPEAR_GPIO2_INT_BASE, + }, +}; + +struct amba_device gpio_device[] = { + { + .dev = { + .init_name = "gpio0", + .platform_data = &gpio_plat_data[0], + }, + .res = { + .start = SPEAR6XX_CPU_GPIO_BASE, + .end = SPEAR6XX_CPU_GPIO_BASE + + SPEAR6XX_CPU_GPIO_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_LOCAL_GPIO, NO_IRQ}, + }, { + .dev = { + .init_name = "gpio1", + .platform_data = &gpio_plat_data[1], + }, + .res = { + .start = SPEAR6XX_ICM3_GPIO_BASE, + .end = SPEAR6XX_ICM3_GPIO_BASE + + SPEAR6XX_ICM3_GPIO_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_BASIC_GPIO, NO_IRQ}, + }, { + .dev = { + .init_name = "gpio2", + .platform_data = &gpio_plat_data[2], + }, + .res = { + .start = SPEAR6XX_ICM2_GPIO_BASE, + .end = SPEAR6XX_ICM2_GPIO_BASE + + SPEAR6XX_ICM2_GPIO_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_APPL_GPIO, NO_IRQ}, + } +}; + +/* This will add devices, and do machine specific tasks */ +void __init spear6xx_init(void) +{ + /* nothing to do for now */ +} + +/* This will initialize vic */ +void __init spear6xx_init_irq(void) +{ + vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_PRI_BASE, 0, ~0, 0); + vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_SEC_BASE, 32, ~0, 0); +} + +/* Following will create static virtual/physical mappings */ +static struct map_desc spear6xx_io_desc[] __initdata = { + { + .virtual = VA_SPEAR6XX_ICM1_UART0_BASE, + .pfn = __phys_to_pfn(SPEAR6XX_ICM1_UART0_BASE), + .length = SPEAR6XX_ICM1_UART0_SIZE, + .type = MT_DEVICE + }, { + .virtual = VA_SPEAR6XX_CPU_VIC_PRI_BASE, + .pfn = __phys_to_pfn(SPEAR6XX_CPU_VIC_PRI_BASE), + .length = SPEAR6XX_CPU_VIC_PRI_SIZE, + .type = MT_DEVICE + }, { + .virtual = VA_SPEAR6XX_CPU_VIC_SEC_BASE, + .pfn = __phys_to_pfn(SPEAR6XX_CPU_VIC_SEC_BASE), + .length = SPEAR6XX_CPU_VIC_SEC_SIZE, + .type = MT_DEVICE + }, { + .virtual = VA_SPEAR6XX_ICM3_SYS_CTRL_BASE, + .pfn = __phys_to_pfn(SPEAR6XX_ICM3_SYS_CTRL_BASE), + .length = SPEAR6XX_ICM3_MISC_REG_BASE, + .type = MT_DEVICE + }, { + .virtual = VA_SPEAR6XX_ICM3_MISC_REG_BASE, + .pfn = __phys_to_pfn(SPEAR6XX_ICM3_MISC_REG_BASE), + .length = SPEAR6XX_ICM3_MISC_REG_SIZE, + .type = MT_DEVICE + }, +}; + +/* This will create static memory mapping for selected devices */ +void __init spear6xx_map_io(void) +{ + iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc)); + + /* This will initialize clock framework */ + clk_init(); +} -- cgit v1.2.3-59-g8ed1b From cee37e501ea34958d6d33d75d2bd21d9c343e379 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:31:05 +0100 Subject: ARM: 6016/1: ST SPEAr: Added support for SPEAr platform and machines in arch/arm/ Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/Kconfig | 13 +++++++++++++ arch/arm/Makefile | 5 +++++ 2 files changed, 18 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5408bf1bf43..1459231bcbb3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -801,6 +801,18 @@ config ARCH_OMAP help Support for TI's OMAP platform (OMAP1 and OMAP2). +config PLAT_SPEAR + bool "ST SPEAr" + select ARM_AMBA + select ARCH_REQUIRE_GPIOLIB + select COMMON_CLKDEV + select GENERIC_CLOCKEVENTS + select GENERIC_GPIO + select GENERIC_TIME + select HAVE_CLK + help + Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx). + endchoice # @@ -886,6 +898,7 @@ source "arch/arm/plat-samsung/Kconfig" source "arch/arm/plat-s3c24xx/Kconfig" source "arch/arm/plat-s5p/Kconfig" source "arch/arm/plat-s5pc1xx/Kconfig" +source "arch/arm/plat-spear/Kconfig" if ARCH_S3C2410 source "arch/arm/mach-s3c2400/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ed820e737a8a..b3a3518a36fd 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -178,6 +178,10 @@ machine-$(CONFIG_ARCH_VERSATILE) := versatile machine-$(CONFIG_ARCH_W90X900) := w90x900 machine-$(CONFIG_ARCH_NUC93X) := nuc93x machine-$(CONFIG_FOOTBRIDGE) := footbridge +machine-$(CONFIG_MACH_SPEAR300) := spear3xx +machine-$(CONFIG_MACH_SPEAR310) := spear3xx +machine-$(CONFIG_MACH_SPEAR320) := spear3xx +machine-$(CONFIG_MACH_SPEAR600) := spear6xx # Platform directory name. This list is sorted alphanumerically # by CONFIG_* macro name. @@ -192,6 +196,7 @@ plat-$(CONFIG_PLAT_PXA) := pxa plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx samsung plat-$(CONFIG_PLAT_S5P) := s5p samsung +plat-$(CONFIG_PLAT_SPEAR) := spear ifeq ($(CONFIG_ARCH_EBSA110),y) # This is what happens if you forget the IOCS16 line. -- cgit v1.2.3-59-g8ed1b From bc4e814e5d5e2851f0a0679eaad14f60abae2a6d Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:30:58 +0100 Subject: ARM: 6017/1: ST SPEAr: Added source files for SPEAr3xx machine family Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/mach-spear3xx/Kconfig | 33 +++++++++++ arch/arm/mach-spear3xx/Kconfig300 | 17 ++++++ arch/arm/mach-spear3xx/Kconfig310 | 17 ++++++ arch/arm/mach-spear3xx/Kconfig320 | 17 ++++++ arch/arm/mach-spear3xx/Makefile | 26 +++++++++ arch/arm/mach-spear3xx/Makefile.boot | 3 + arch/arm/mach-spear3xx/spear300.c | 45 +++++++++++++++ arch/arm/mach-spear3xx/spear300_evb.c | 55 ++++++++++++++++++ arch/arm/mach-spear3xx/spear310.c | 25 +++++++++ arch/arm/mach-spear3xx/spear310_evb.c | 54 ++++++++++++++++++ arch/arm/mach-spear3xx/spear320.c | 25 +++++++++ arch/arm/mach-spear3xx/spear320_evb.c | 54 ++++++++++++++++++ arch/arm/mach-spear3xx/spear3xx.c | 101 ++++++++++++++++++++++++++++++++++ 13 files changed, 472 insertions(+) create mode 100644 arch/arm/mach-spear3xx/Kconfig create mode 100644 arch/arm/mach-spear3xx/Kconfig300 create mode 100644 arch/arm/mach-spear3xx/Kconfig310 create mode 100644 arch/arm/mach-spear3xx/Kconfig320 create mode 100644 arch/arm/mach-spear3xx/Makefile create mode 100644 arch/arm/mach-spear3xx/Makefile.boot create mode 100644 arch/arm/mach-spear3xx/spear300.c create mode 100644 arch/arm/mach-spear3xx/spear300_evb.c create mode 100644 arch/arm/mach-spear3xx/spear310.c create mode 100644 arch/arm/mach-spear3xx/spear310_evb.c create mode 100644 arch/arm/mach-spear3xx/spear320.c create mode 100644 arch/arm/mach-spear3xx/spear320_evb.c create mode 100644 arch/arm/mach-spear3xx/spear3xx.c (limited to 'arch') diff --git a/arch/arm/mach-spear3xx/Kconfig b/arch/arm/mach-spear3xx/Kconfig new file mode 100644 index 000000000000..20d1317cc486 --- /dev/null +++ b/arch/arm/mach-spear3xx/Kconfig @@ -0,0 +1,33 @@ +# +# SPEAr3XX Machine configuration file +# + +if ARCH_SPEAR3XX + +choice + prompt "SPEAr3XX Family" + default MACH_SPEAR300 + +config MACH_SPEAR300 + bool "SPEAr300" + help + Supports ST SPEAr300 Machine + +config MACH_SPEAR310 + bool "SPEAr310" + help + Supports ST SPEAr310 Machine + +config MACH_SPEAR320 + bool "SPEAr320" + help + Supports ST SPEAr320 Machine + +endchoice + +# Adding SPEAr3XX machine specific configuration files +source "arch/arm/mach-spear3xx/Kconfig300" +source "arch/arm/mach-spear3xx/Kconfig310" +source "arch/arm/mach-spear3xx/Kconfig320" + +endif #ARCH_SPEAR3XX diff --git a/arch/arm/mach-spear3xx/Kconfig300 b/arch/arm/mach-spear3xx/Kconfig300 new file mode 100644 index 000000000000..c519a05b4ab4 --- /dev/null +++ b/arch/arm/mach-spear3xx/Kconfig300 @@ -0,0 +1,17 @@ +# +# SPEAr300 machine configuration file +# + +if MACH_SPEAR300 + +choice + prompt "SPEAr300 Boards" + default BOARD_SPEAR300_EVB + +config BOARD_SPEAR300_EVB + bool "SPEAr300 Evaluation Board" + help + Supports ST SPEAr300 Evaluation Board +endchoice + +endif #MACH_SPEAR300 diff --git a/arch/arm/mach-spear3xx/Kconfig310 b/arch/arm/mach-spear3xx/Kconfig310 new file mode 100644 index 000000000000..60e7442d75bd --- /dev/null +++ b/arch/arm/mach-spear3xx/Kconfig310 @@ -0,0 +1,17 @@ +# +# SPEAr310 machine configuration file +# + +if MACH_SPEAR310 + +choice + prompt "SPEAr310 Boards" + default BOARD_SPEAR310_EVB + +config BOARD_SPEAR310_EVB + bool "SPEAr310 Evaluation Board" + help + Supports ST SPEAr310 Evaluation Board +endchoice + +endif #MACH_SPEAR310 diff --git a/arch/arm/mach-spear3xx/Kconfig320 b/arch/arm/mach-spear3xx/Kconfig320 new file mode 100644 index 000000000000..1c1d438399b8 --- /dev/null +++ b/arch/arm/mach-spear3xx/Kconfig320 @@ -0,0 +1,17 @@ +# +# SPEAr320 machine configuration file +# + +if MACH_SPEAR320 + +choice + prompt "SPEAr320 Boards" + default BOARD_SPEAR320_EVB + +config BOARD_SPEAR320_EVB + bool "SPEAr320 Evaluation Board" + help + Supports ST SPEAr320 Evaluation Board +endchoice + +endif #MACH_SPEAR320 diff --git a/arch/arm/mach-spear3xx/Makefile b/arch/arm/mach-spear3xx/Makefile new file mode 100644 index 000000000000..b24862489704 --- /dev/null +++ b/arch/arm/mach-spear3xx/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for SPEAr3XX machine series +# + +# common files +obj-y += spear3xx.o clock.o + +# spear300 specific files +obj-$(CONFIG_MACH_SPEAR300) += spear300.o + +# spear300 boards files +obj-$(CONFIG_BOARD_SPEAR300_EVB) += spear300_evb.o + + +# spear310 specific files +obj-$(CONFIG_MACH_SPEAR310) += spear310.o + +# spear310 boards files +obj-$(CONFIG_BOARD_SPEAR310_EVB) += spear310_evb.o + + +# spear320 specific files +obj-$(CONFIG_MACH_SPEAR320) += spear320.o + +# spear320 boards files +obj-$(CONFIG_BOARD_SPEAR320_EVB) += spear320_evb.o diff --git a/arch/arm/mach-spear3xx/Makefile.boot b/arch/arm/mach-spear3xx/Makefile.boot new file mode 100644 index 000000000000..7a1f3c0eadb8 --- /dev/null +++ b/arch/arm/mach-spear3xx/Makefile.boot @@ -0,0 +1,3 @@ +zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c new file mode 100644 index 000000000000..63aca8fc3ebb --- /dev/null +++ b/arch/arm/mach-spear3xx/spear300.c @@ -0,0 +1,45 @@ +/* + * arch/arm/mach-spear3xx/spear300.c + * + * SPEAr300 machine source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include +#include +#include + +/* Add spear300 specific devices here */ +/* arm gpio1 device registeration */ +static struct pl061_platform_data gpio1_plat_data = { + .gpio_base = 8, + .irq_base = SPEAR_GPIO1_INT_BASE, +}; + +struct amba_device gpio1_device = { + .dev = { + .init_name = "gpio1", + .platform_data = &gpio1_plat_data, + }, + .res = { + .start = SPEAR300_GPIO_BASE, + .end = SPEAR300_GPIO_BASE + SPEAR300_GPIO_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_GEN_RAS_1, NO_IRQ}, +}; + +void __init spear300_init(void) +{ + /* call spear3xx family common init function */ + spear3xx_init(); +} diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c new file mode 100644 index 000000000000..1272a385c208 --- /dev/null +++ b/arch/arm/mach-spear3xx/spear300_evb.c @@ -0,0 +1,55 @@ +/* + * arch/arm/mach-spear3xx/spear300_evb.c + * + * SPEAr300 evaluation board source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include + +static struct amba_device *amba_devs[] __initdata = { + /* spear3xx specific devices */ + &gpio_device, + &uart_device, + + /* spear300 specific devices */ + &gpio1_device, +}; + +static struct platform_device *plat_devs[] __initdata = { + /* spear3xx specific devices */ + + /* spear300 specific devices */ +}; + +static void __init spear300_evb_init(void) +{ + unsigned int i; + + /* call spear300 machine init function */ + spear300_init(); + + /* Add Platform Devices */ + platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); + + /* Add Amba Devices */ + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) + amba_device_register(amba_devs[i], &iomem_resource); +} + +MACHINE_START(SPEAR300, "ST-SPEAR300-EVB") + .boot_params = 0x00000100, + .map_io = spear3xx_map_io, + .init_irq = spear3xx_init_irq, + .timer = &spear_sys_timer, + .init_machine = spear300_evb_init, +MACHINE_END diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c new file mode 100644 index 000000000000..6eb62f9de7ee --- /dev/null +++ b/arch/arm/mach-spear3xx/spear310.c @@ -0,0 +1,25 @@ +/* + * arch/arm/mach-spear3xx/spear310.c + * + * SPEAr310 machine source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include + +/* Add spear310 specific devices here */ + +void __init spear310_init(void) +{ + /* call spear3xx family common init function */ + spear3xx_init(); +} diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c new file mode 100644 index 000000000000..e781b2b7f137 --- /dev/null +++ b/arch/arm/mach-spear3xx/spear310_evb.c @@ -0,0 +1,54 @@ +/* + * arch/arm/mach-spear3xx/spear310_evb.c + * + * SPEAr310 evaluation board source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include + +static struct amba_device *amba_devs[] __initdata = { + /* spear3xx specific devices */ + &gpio_device, + &uart_device, + + /* spear310 specific devices */ +}; + +static struct platform_device *plat_devs[] __initdata = { + /* spear3xx specific devices */ + + /* spear310 specific devices */ +}; + +static void __init spear310_evb_init(void) +{ + unsigned int i; + + /* call spear310 machine init function */ + spear310_init(); + + /* Add Platform Devices */ + platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); + + /* Add Amba Devices */ + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) + amba_device_register(amba_devs[i], &iomem_resource); +} + +MACHINE_START(SPEAR310, "ST-SPEAR310-EVB") + .boot_params = 0x00000100, + .map_io = spear3xx_map_io, + .init_irq = spear3xx_init_irq, + .timer = &spear_sys_timer, + .init_machine = spear310_evb_init, +MACHINE_END diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c new file mode 100644 index 000000000000..72d45489dcb0 --- /dev/null +++ b/arch/arm/mach-spear3xx/spear320.c @@ -0,0 +1,25 @@ +/* + * arch/arm/mach-spear3xx/spear320.c + * + * SPEAr320 machine source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include + +/* Add spear320 specific devices here */ + +void __init spear320_init(void) +{ + /* call spear3xx family common init function */ + spear3xx_init(); +} diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c new file mode 100644 index 000000000000..85bc4d226212 --- /dev/null +++ b/arch/arm/mach-spear3xx/spear320_evb.c @@ -0,0 +1,54 @@ +/* + * arch/arm/mach-spear3xx/spear320_evb.c + * + * SPEAr320 evaluation board source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include + +static struct amba_device *amba_devs[] __initdata = { + /* spear3xx specific devices */ + &gpio_device, + &uart_device, + + /* spear320 specific devices */ +}; + +static struct platform_device *plat_devs[] __initdata = { + /* spear3xx specific devices */ + + /* spear320 specific devices */ +}; + +static void __init spear320_evb_init(void) +{ + unsigned int i; + + /* call spear320 machine init function */ + spear320_init(); + + /* Add Platform Devices */ + platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); + + /* Add Amba Devices */ + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) + amba_device_register(amba_devs[i], &iomem_resource); +} + +MACHINE_START(SPEAR320, "ST-SPEAR320-EVB") + .boot_params = 0x00000100, + .map_io = spear3xx_map_io, + .init_irq = spear3xx_init_irq, + .timer = &spear_sys_timer, + .init_machine = spear320_evb_init, +MACHINE_END diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c new file mode 100644 index 000000000000..82ebcd30465e --- /dev/null +++ b/arch/arm/mach-spear3xx/spear3xx.c @@ -0,0 +1,101 @@ +/* + * arch/arm/mach-spear3xx/spear3xx.c + * + * SPEAr3XX machines common source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +/* Add spear3xx machines common devices here */ +/* gpio device registeration */ +static struct pl061_platform_data gpio_plat_data = { + .gpio_base = 0, + .irq_base = SPEAR_GPIO_INT_BASE, +}; + +struct amba_device gpio_device = { + .dev = { + .init_name = "gpio", + .platform_data = &gpio_plat_data, + }, + .res = { + .start = SPEAR3XX_ICM3_GPIO_BASE, + .end = SPEAR3XX_ICM3_GPIO_BASE + SPEAR3XX_ICM3_GPIO_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_BASIC_GPIO, NO_IRQ}, +}; + +/* uart device registeration */ +struct amba_device uart_device = { + .dev = { + .init_name = "uart", + }, + .res = { + .start = SPEAR3XX_ICM1_UART_BASE, + .end = SPEAR3XX_ICM1_UART_BASE + SPEAR3XX_ICM1_UART_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_UART, NO_IRQ}, +}; + +/* Do spear3xx familiy common initialization part here */ +void __init spear3xx_init(void) +{ + /* nothing to do for now */ +} + +/* This will initialize vic */ +void __init spear3xx_init_irq(void) +{ + vic_init((void __iomem *)VA_SPEAR3XX_ML1_VIC_BASE, 0, ~0, 0); +} + +/* Following will create static virtual/physical mappings */ +struct map_desc spear3xx_io_desc[] __initdata = { + { + .virtual = VA_SPEAR3XX_ICM1_UART_BASE, + .pfn = __phys_to_pfn(SPEAR3XX_ICM1_UART_BASE), + .length = SPEAR3XX_ICM1_UART_SIZE, + .type = MT_DEVICE + }, { + .virtual = VA_SPEAR3XX_ML1_VIC_BASE, + .pfn = __phys_to_pfn(SPEAR3XX_ML1_VIC_BASE), + .length = SPEAR3XX_ML1_VIC_SIZE, + .type = MT_DEVICE + }, { + .virtual = VA_SPEAR3XX_ICM3_SYS_CTRL_BASE, + .pfn = __phys_to_pfn(SPEAR3XX_ICM3_SYS_CTRL_BASE), + .length = SPEAR3XX_ICM3_SYS_CTRL_SIZE, + .type = MT_DEVICE + }, { + .virtual = VA_SPEAR3XX_ICM3_MISC_REG_BASE, + .pfn = __phys_to_pfn(SPEAR3XX_ICM3_MISC_REG_BASE), + .length = SPEAR3XX_ICM3_MISC_REG_SIZE, + .type = MT_DEVICE + }, +}; + +/* This will create static memory mapping for selected devices */ +void __init spear3xx_map_io(void) +{ + iotable_init(spear3xx_io_desc, ARRAY_SIZE(spear3xx_io_desc)); + + /* This will initialize clock framework */ + clk_init(); +} -- cgit v1.2.3-59-g8ed1b From b77932a4d265586748f05a8c8fad7ef4174c0296 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:31:17 +0100 Subject: ARM: 6019/1: ST SPEAr: Added default configuration files for SPEAr machines Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/configs/spear300_defconfig | 773 +++++++++++++++++++++++++++++++++++ arch/arm/configs/spear310_defconfig | 775 ++++++++++++++++++++++++++++++++++++ arch/arm/configs/spear320_defconfig | 775 ++++++++++++++++++++++++++++++++++++ arch/arm/configs/spear600_defconfig | 760 +++++++++++++++++++++++++++++++++++ 4 files changed, 3083 insertions(+) create mode 100644 arch/arm/configs/spear300_defconfig create mode 100644 arch/arm/configs/spear310_defconfig create mode 100644 arch/arm/configs/spear320_defconfig create mode 100644 arch/arm/configs/spear600_defconfig (limited to 'arch') diff --git a/arch/arm/configs/spear300_defconfig b/arch/arm/configs/spear300_defconfig new file mode 100644 index 000000000000..35e64d1cb750 --- /dev/null +++ b/arch/arm/configs/spear300_defconfig @@ -0,0 +1,773 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32 +# Tue Mar 23 14:36:23 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_BCMRING is not set +CONFIG_PLAT_SPEAR=y +CONFIG_ARCH_SPEAR3XX=y +# CONFIG_ARCH_SPEAR6XX is not set +CONFIG_MACH_SPEAR300=y +# CONFIG_MACH_SPEAR310 is not set +# CONFIG_MACH_SPEAR320 is not set +CONFIG_BOARD_SPEAR300_EVB=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_VIC=y +CONFIG_ARM_VIC_NR=2 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +CONFIG_GPIO_PL061=y + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +# CONFIG_INOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_DETECTOR=y +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC32 is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/configs/spear310_defconfig b/arch/arm/configs/spear310_defconfig new file mode 100644 index 000000000000..cbbfd290bba8 --- /dev/null +++ b/arch/arm/configs/spear310_defconfig @@ -0,0 +1,775 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32 +# Tue Mar 23 14:37:01 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_BCMRING is not set +CONFIG_PLAT_SPEAR=y +CONFIG_ARCH_SPEAR3XX=y +# CONFIG_ARCH_SPEAR6XX is not set +# CONFIG_MACH_SPEAR300 is not set +CONFIG_MACH_SPEAR310=y +# CONFIG_MACH_SPEAR320 is not set +# CONFIG_BOARD_SPEAR300_EVB is not set +CONFIG_BOARD_SPEAR310_EVB=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_VIC=y +CONFIG_ARM_VIC_NR=2 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +CONFIG_GPIO_PL061=y + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +# CONFIG_INOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_DETECTOR=y +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC32 is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/configs/spear320_defconfig b/arch/arm/configs/spear320_defconfig new file mode 100644 index 000000000000..2ae3c110a21a --- /dev/null +++ b/arch/arm/configs/spear320_defconfig @@ -0,0 +1,775 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32 +# Tue Mar 23 14:37:12 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_BCMRING is not set +CONFIG_PLAT_SPEAR=y +CONFIG_ARCH_SPEAR3XX=y +# CONFIG_ARCH_SPEAR6XX is not set +# CONFIG_MACH_SPEAR300 is not set +# CONFIG_MACH_SPEAR310 is not set +CONFIG_MACH_SPEAR320=y +# CONFIG_BOARD_SPEAR300_EVB is not set +CONFIG_BOARD_SPEAR320_EVB=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_VIC=y +CONFIG_ARM_VIC_NR=2 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +CONFIG_GPIO_PL061=y + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +# CONFIG_INOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_DETECTOR=y +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC32 is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/configs/spear600_defconfig b/arch/arm/configs/spear600_defconfig new file mode 100644 index 000000000000..c85a02924ec5 --- /dev/null +++ b/arch/arm/configs/spear600_defconfig @@ -0,0 +1,760 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32 +# Tue Mar 23 14:37:26 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_BCMRING is not set +CONFIG_PLAT_SPEAR=y +# CONFIG_ARCH_SPEAR3XX is not set +CONFIG_ARCH_SPEAR6XX=y +# CONFIG_MACH_SPEAR300 is not set +# CONFIG_MACH_SPEAR310 is not set +# CONFIG_MACH_SPEAR320 is not set +# CONFIG_BOARD_SPEAR300_EVB is not set +CONFIG_MACH_SPEAR600=y +CONFIG_BOARD_SPEAR600_EVB=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_VIC=y +CONFIG_ARM_VIC_NR=2 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_R3964 is not set +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +CONFIG_GPIO_PL061=y + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +# CONFIG_INOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_DETECTOR=y +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC32 is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y -- cgit v1.2.3-59-g8ed1b From 70f4c0bf9e4d067744ee453bc37c0c4adcea6e53 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:31:29 +0100 Subject: ARM: 6020/1: ST SPEAr: Adding gpio pad multiplexing support GPIO Pads in spear platform are are multiplexed in various machines. This patch adds support for this pad multiplexing. Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/mach-spear3xx/include/mach/generic.h | 161 +++++++++- arch/arm/mach-spear3xx/spear300.c | 358 +++++++++++++++++++++ arch/arm/mach-spear3xx/spear300_evb.c | 22 ++ arch/arm/mach-spear3xx/spear310.c | 129 ++++++++ arch/arm/mach-spear3xx/spear310_evb.c | 30 ++ arch/arm/mach-spear3xx/spear320.c | 374 +++++++++++++++++++++ arch/arm/mach-spear3xx/spear320_evb.c | 27 ++ arch/arm/mach-spear3xx/spear3xx.c | 447 ++++++++++++++++++++++++++ arch/arm/plat-spear/Makefile | 2 +- arch/arm/plat-spear/include/plat/padmux.h | 92 ++++++ arch/arm/plat-spear/padmux.c | 164 ++++++++++ 11 files changed, 1798 insertions(+), 8 deletions(-) create mode 100644 arch/arm/plat-spear/include/plat/padmux.h create mode 100644 arch/arm/plat-spear/padmux.c (limited to 'arch') diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h index aeea8453a9e2..af7e02c909a3 100644 --- a/arch/arm/mach-spear3xx/include/mach/generic.h +++ b/arch/arm/mach-spear3xx/include/mach/generic.h @@ -19,7 +19,9 @@ #include #include #include +#include +/* spear3xx declarations */ /* * Each GPT has 2 timer channels * Following GPT channels will be used as clock source and clockevent @@ -34,25 +36,170 @@ extern struct amba_device uart_device; extern struct sys_timer spear_sys_timer; /* Add spear3xx family function declarations here */ +void __init clk_init(void); void __init spear3xx_map_io(void); void __init spear3xx_init_irq(void); void __init spear3xx_init(void); -void __init spear300_init(void); -void __init spear310_init(void); -void __init spear320_init(void); -void __init clk_init(void); +void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size); -/* Add spear300 machine device structure declarations here */ +/* pad mux declarations */ +#define PMX_FIRDA_MASK (1 << 14) +#define PMX_I2C_MASK (1 << 13) +#define PMX_SSP_CS_MASK (1 << 12) +#define PMX_SSP_MASK (1 << 11) +#define PMX_MII_MASK (1 << 10) +#define PMX_GPIO_PIN0_MASK (1 << 9) +#define PMX_GPIO_PIN1_MASK (1 << 8) +#define PMX_GPIO_PIN2_MASK (1 << 7) +#define PMX_GPIO_PIN3_MASK (1 << 6) +#define PMX_GPIO_PIN4_MASK (1 << 5) +#define PMX_GPIO_PIN5_MASK (1 << 4) +#define PMX_UART0_MODEM_MASK (1 << 3) +#define PMX_UART0_MASK (1 << 2) +#define PMX_TIMER_3_4_MASK (1 << 1) +#define PMX_TIMER_1_2_MASK (1 << 0) + +/* pad mux devices */ +extern struct pmx_dev pmx_firda; +extern struct pmx_dev pmx_i2c; +extern struct pmx_dev pmx_ssp_cs; +extern struct pmx_dev pmx_ssp; +extern struct pmx_dev pmx_mii; +extern struct pmx_dev pmx_gpio_pin0; +extern struct pmx_dev pmx_gpio_pin1; +extern struct pmx_dev pmx_gpio_pin2; +extern struct pmx_dev pmx_gpio_pin3; +extern struct pmx_dev pmx_gpio_pin4; +extern struct pmx_dev pmx_gpio_pin5; +extern struct pmx_dev pmx_uart0_modem; +extern struct pmx_dev pmx_uart0; +extern struct pmx_dev pmx_timer_3_4; +extern struct pmx_dev pmx_timer_1_2; + +#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320) +/* padmux plgpio devices */ +extern struct pmx_dev pmx_plgpio_0_1; +extern struct pmx_dev pmx_plgpio_2_3; +extern struct pmx_dev pmx_plgpio_4_5; +extern struct pmx_dev pmx_plgpio_6_9; +extern struct pmx_dev pmx_plgpio_10_27; +extern struct pmx_dev pmx_plgpio_28; +extern struct pmx_dev pmx_plgpio_29; +extern struct pmx_dev pmx_plgpio_30; +extern struct pmx_dev pmx_plgpio_31; +extern struct pmx_dev pmx_plgpio_32; +extern struct pmx_dev pmx_plgpio_33; +extern struct pmx_dev pmx_plgpio_34_36; +extern struct pmx_dev pmx_plgpio_37_42; +extern struct pmx_dev pmx_plgpio_43_44_47_48; +extern struct pmx_dev pmx_plgpio_45_46_49_50; +#endif + +extern struct pmx_driver pmx_driver; + +/* spear300 declarations */ #ifdef CONFIG_MACH_SPEAR300 +/* Add spear300 machine device structure declarations here */ extern struct amba_device gpio1_device; + +/* pad mux modes */ +extern struct pmx_mode nand_mode; +extern struct pmx_mode nor_mode; +extern struct pmx_mode photo_frame_mode; +extern struct pmx_mode lend_ip_phone_mode; +extern struct pmx_mode hend_ip_phone_mode; +extern struct pmx_mode lend_wifi_phone_mode; +extern struct pmx_mode hend_wifi_phone_mode; +extern struct pmx_mode ata_pabx_wi2s_mode; +extern struct pmx_mode ata_pabx_i2s_mode; +extern struct pmx_mode caml_lcdw_mode; +extern struct pmx_mode camu_lcd_mode; +extern struct pmx_mode camu_wlcd_mode; +extern struct pmx_mode caml_lcd_mode; + +/* pad mux devices */ +extern struct pmx_dev pmx_fsmc_2_chips; +extern struct pmx_dev pmx_fsmc_4_chips; +extern struct pmx_dev pmx_keyboard; +extern struct pmx_dev pmx_clcd; +extern struct pmx_dev pmx_telecom_gpio; +extern struct pmx_dev pmx_telecom_tdm; +extern struct pmx_dev pmx_telecom_spi_cs_i2c_clk; +extern struct pmx_dev pmx_telecom_camera; +extern struct pmx_dev pmx_telecom_dac; +extern struct pmx_dev pmx_telecom_i2s; +extern struct pmx_dev pmx_telecom_boot_pins; +extern struct pmx_dev pmx_telecom_sdio_4bit; +extern struct pmx_dev pmx_telecom_sdio_8bit; +extern struct pmx_dev pmx_gpio1; + +void spear300_pmx_init(void); + +/* Add spear300 machine function declarations here */ +void __init spear300_init(void); + #endif /* CONFIG_MACH_SPEAR300 */ -/* Add spear310 machine device structure declarations here */ +/* spear310 declarations */ #ifdef CONFIG_MACH_SPEAR310 +/* Add spear310 machine device structure declarations here */ + +/* pad mux devices */ +extern struct pmx_dev pmx_emi_cs_0_1_4_5; +extern struct pmx_dev pmx_emi_cs_2_3; +extern struct pmx_dev pmx_uart1; +extern struct pmx_dev pmx_uart2; +extern struct pmx_dev pmx_uart3_4_5; +extern struct pmx_dev pmx_fsmc; +extern struct pmx_dev pmx_rs485_0_1; +extern struct pmx_dev pmx_tdm0; + +void spear310_pmx_init(void); + +/* Add spear310 machine function declarations here */ +void __init spear310_init(void); + #endif /* CONFIG_MACH_SPEAR310 */ -/* Add spear320 machine device structure declarations here */ +/* spear320 declarations */ #ifdef CONFIG_MACH_SPEAR320 +/* Add spear320 machine device structure declarations here */ + +/* pad mux modes */ +extern struct pmx_mode auto_net_smii_mode; +extern struct pmx_mode auto_net_mii_mode; +extern struct pmx_mode auto_exp_mode; +extern struct pmx_mode small_printers_mode; + +/* pad mux devices */ +extern struct pmx_dev pmx_clcd; +extern struct pmx_dev pmx_emi; +extern struct pmx_dev pmx_fsmc; +extern struct pmx_dev pmx_spp; +extern struct pmx_dev pmx_sdio; +extern struct pmx_dev pmx_i2s; +extern struct pmx_dev pmx_uart1; +extern struct pmx_dev pmx_uart1_modem; +extern struct pmx_dev pmx_uart2; +extern struct pmx_dev pmx_touchscreen; +extern struct pmx_dev pmx_can; +extern struct pmx_dev pmx_sdio_led; +extern struct pmx_dev pmx_pwm0; +extern struct pmx_dev pmx_pwm1; +extern struct pmx_dev pmx_pwm2; +extern struct pmx_dev pmx_pwm3; +extern struct pmx_dev pmx_ssp1; +extern struct pmx_dev pmx_ssp2; +extern struct pmx_dev pmx_mii1; +extern struct pmx_dev pmx_smii0; +extern struct pmx_dev pmx_smii1; +extern struct pmx_dev pmx_i2c1; + +void spear320_pmx_init(void); + +/* Add spear320 machine function declarations here */ +void __init spear320_init(void); + #endif /* CONFIG_MACH_SPEAR320 */ #endif /* __MACH_GENERIC_H */ diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index 63aca8fc3ebb..66e7fcd8baf8 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c @@ -18,6 +18,357 @@ #include #include +/* pad multiplexing support */ +/* muxing registers */ +#define PAD_MUX_CONFIG_REG 0x00 +#define MODE_CONFIG_REG 0x04 + +/* modes */ +#define NAND_MODE (1 << 0) +#define NOR_MODE (1 << 1) +#define PHOTO_FRAME_MODE (1 << 2) +#define LEND_IP_PHONE_MODE (1 << 3) +#define HEND_IP_PHONE_MODE (1 << 4) +#define LEND_WIFI_PHONE_MODE (1 << 5) +#define HEND_WIFI_PHONE_MODE (1 << 6) +#define ATA_PABX_WI2S_MODE (1 << 7) +#define ATA_PABX_I2S_MODE (1 << 8) +#define CAML_LCDW_MODE (1 << 9) +#define CAMU_LCD_MODE (1 << 10) +#define CAMU_WLCD_MODE (1 << 11) +#define CAML_LCD_MODE (1 << 12) +#define ALL_MODES 0x1FFF + +struct pmx_mode nand_mode = { + .id = NAND_MODE, + .name = "nand mode", + .mask = 0x00, +}; + +struct pmx_mode nor_mode = { + .id = NOR_MODE, + .name = "nor mode", + .mask = 0x01, +}; + +struct pmx_mode photo_frame_mode = { + .id = PHOTO_FRAME_MODE, + .name = "photo frame mode", + .mask = 0x02, +}; + +struct pmx_mode lend_ip_phone_mode = { + .id = LEND_IP_PHONE_MODE, + .name = "lend ip phone mode", + .mask = 0x03, +}; + +struct pmx_mode hend_ip_phone_mode = { + .id = HEND_IP_PHONE_MODE, + .name = "hend ip phone mode", + .mask = 0x04, +}; + +struct pmx_mode lend_wifi_phone_mode = { + .id = LEND_WIFI_PHONE_MODE, + .name = "lend wifi phone mode", + .mask = 0x05, +}; + +struct pmx_mode hend_wifi_phone_mode = { + .id = HEND_WIFI_PHONE_MODE, + .name = "hend wifi phone mode", + .mask = 0x06, +}; + +struct pmx_mode ata_pabx_wi2s_mode = { + .id = ATA_PABX_WI2S_MODE, + .name = "ata pabx wi2s mode", + .mask = 0x07, +}; + +struct pmx_mode ata_pabx_i2s_mode = { + .id = ATA_PABX_I2S_MODE, + .name = "ata pabx i2s mode", + .mask = 0x08, +}; + +struct pmx_mode caml_lcdw_mode = { + .id = CAML_LCDW_MODE, + .name = "caml lcdw mode", + .mask = 0x0C, +}; + +struct pmx_mode camu_lcd_mode = { + .id = CAMU_LCD_MODE, + .name = "camu lcd mode", + .mask = 0x0D, +}; + +struct pmx_mode camu_wlcd_mode = { + .id = CAMU_WLCD_MODE, + .name = "camu wlcd mode", + .mask = 0x0E, +}; + +struct pmx_mode caml_lcd_mode = { + .id = CAML_LCD_MODE, + .name = "caml lcd mode", + .mask = 0x0F, +}; + +/* devices */ +struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = { + { + .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE | + ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE, + .mask = PMX_FIRDA_MASK, + }, +}; + +struct pmx_dev pmx_fsmc_2_chips = { + .name = "fsmc_2_chips", + .modes = pmx_fsmc_2_chips_modes, + .mode_count = ARRAY_SIZE(pmx_fsmc_2_chips_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = { + { + .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE | + ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE, + .mask = PMX_FIRDA_MASK | PMX_UART0_MASK, + }, +}; + +struct pmx_dev pmx_fsmc_4_chips = { + .name = "fsmc_4_chips", + .modes = pmx_fsmc_4_chips_modes, + .mode_count = ARRAY_SIZE(pmx_fsmc_4_chips_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_keyboard_modes[] = { + { + .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | + LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | + CAML_LCDW_MODE | CAMU_LCD_MODE | CAMU_WLCD_MODE | + CAML_LCD_MODE, + .mask = 0x0, + }, +}; + +struct pmx_dev pmx_keyboard = { + .name = "keyboard", + .modes = pmx_keyboard_modes, + .mode_count = ARRAY_SIZE(pmx_keyboard_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_clcd_modes[] = { + { + .ids = PHOTO_FRAME_MODE, + .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK , + }, { + .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE | + CAMU_LCD_MODE | CAML_LCD_MODE, + .mask = PMX_TIMER_3_4_MASK, + }, +}; + +struct pmx_dev pmx_clcd = { + .name = "clcd", + .modes = pmx_clcd_modes, + .mode_count = ARRAY_SIZE(pmx_clcd_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_telecom_gpio_modes[] = { + { + .ids = PHOTO_FRAME_MODE | CAMU_LCD_MODE | CAML_LCD_MODE, + .mask = PMX_MII_MASK, + }, { + .ids = LEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE, + .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK, + }, { + .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_WLCD_MODE, + .mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK, + }, { + .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE, + .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK, + }, { + .ids = ATA_PABX_WI2S_MODE, + .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK + | PMX_UART0_MODEM_MASK, + }, +}; + +struct pmx_dev pmx_telecom_gpio = { + .name = "telecom_gpio", + .modes = pmx_telecom_gpio_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_telecom_tdm_modes[] = { + { + .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | + HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE + | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE + | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE + | CAMU_WLCD_MODE | CAML_LCD_MODE, + .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK, + }, +}; + +struct pmx_dev pmx_telecom_tdm = { + .name = "telecom_tdm", + .modes = pmx_telecom_tdm_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = { + { + .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | + LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE + | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE | + CAML_LCDW_MODE | CAML_LCD_MODE, + .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK, + }, +}; + +struct pmx_dev pmx_telecom_spi_cs_i2c_clk = { + .name = "telecom_spi_cs_i2c_clk", + .modes = pmx_telecom_spi_cs_i2c_clk_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_spi_cs_i2c_clk_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_telecom_camera_modes[] = { + { + .ids = CAML_LCDW_MODE | CAML_LCD_MODE, + .mask = PMX_MII_MASK, + }, { + .ids = CAMU_LCD_MODE | CAMU_WLCD_MODE, + .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_telecom_camera = { + .name = "telecom_camera", + .modes = pmx_telecom_camera_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_camera_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_telecom_dac_modes[] = { + { + .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE + | CAMU_WLCD_MODE | CAML_LCD_MODE, + .mask = PMX_TIMER_1_2_MASK, + }, +}; + +struct pmx_dev pmx_telecom_dac = { + .name = "telecom_dac", + .modes = pmx_telecom_dac_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_dac_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_telecom_i2s_modes[] = { + { + .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE + | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | + ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE + | CAMU_WLCD_MODE | CAML_LCD_MODE, + .mask = PMX_UART0_MODEM_MASK, + }, +}; + +struct pmx_dev pmx_telecom_i2s = { + .name = "telecom_i2s", + .modes = pmx_telecom_i2s_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = { + { + .ids = NAND_MODE | NOR_MODE, + .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK | + PMX_TIMER_3_4_MASK, + }, +}; + +struct pmx_dev pmx_telecom_boot_pins = { + .name = "telecom_boot_pins", + .modes = pmx_telecom_boot_pins_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_boot_pins_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_telecom_sdio_4bit_modes[] = { + { + .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | + HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | + HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | + CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE | + ATA_PABX_I2S_MODE, + .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK | + PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | + PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK, + }, +}; + +struct pmx_dev pmx_telecom_sdio_4bit = { + .name = "telecom_sdio_4bit", + .modes = pmx_telecom_sdio_4bit_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_sdio_4bit_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_telecom_sdio_8bit_modes[] = { + { + .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | + HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | + HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | + CAMU_WLCD_MODE | CAML_LCD_MODE, + .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK | + PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | + PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_telecom_sdio_8bit = { + .name = "telecom_sdio_8bit", + .modes = pmx_telecom_sdio_8bit_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_sdio_8bit_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_gpio1_modes[] = { + { + .ids = PHOTO_FRAME_MODE, + .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK | + PMX_TIMER_3_4_MASK, + }, +}; + +struct pmx_dev pmx_gpio1 = { + .name = "arm gpio1", + .modes = pmx_gpio1_modes, + .mode_count = ARRAY_SIZE(pmx_gpio1_modes), + .enb_on_reset = 1, +}; + +/* pmx driver structure */ +struct pmx_driver pmx_driver = { + .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f}, + .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff}, +}; + /* Add spear300 specific devices here */ /* arm gpio1 device registeration */ static struct pl061_platform_data gpio1_plat_data = { @@ -38,8 +389,15 @@ struct amba_device gpio1_device = { .irq = {IRQ_GEN_RAS_1, NO_IRQ}, }; +/* spear300 routines */ void __init spear300_init(void) { /* call spear3xx family common init function */ spear3xx_init(); } + +void spear300_pmx_init(void) +{ + spear_pmx_init(&pmx_driver, SPEAR300_SOC_CONFIG_BASE, + SPEAR300_SOC_CONFIG_SIZE); +} diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c index 1272a385c208..bb21db152a23 100644 --- a/arch/arm/mach-spear3xx/spear300_evb.c +++ b/arch/arm/mach-spear3xx/spear300_evb.c @@ -16,6 +16,22 @@ #include #include +/* padmux devices to enable */ +static struct pmx_dev *pmx_devs[] = { + /* spear3xx specific devices */ + &pmx_i2c, + &pmx_ssp_cs, + &pmx_ssp, + &pmx_mii, + &pmx_uart0, + + /* spear300 specific devices */ + &pmx_fsmc_2_chips, + &pmx_clcd, + &pmx_telecom_sdio_4bit, + &pmx_gpio1, +}; + static struct amba_device *amba_devs[] __initdata = { /* spear3xx specific devices */ &gpio_device, @@ -38,6 +54,12 @@ static void __init spear300_evb_init(void) /* call spear300 machine init function */ spear300_init(); + /* padmux initialization */ + pmx_driver.mode = &photo_frame_mode; + pmx_driver.devs = pmx_devs; + pmx_driver.devs_count = ARRAY_SIZE(pmx_devs); + spear300_pmx_init(); + /* Add Platform Devices */ platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index 6eb62f9de7ee..dd5a57282711 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c @@ -16,10 +16,139 @@ #include #include +/* pad multiplexing support */ +/* muxing registers */ +#define PAD_MUX_CONFIG_REG 0x08 + +/* devices */ +struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = { + { + .ids = 0x00, + .mask = PMX_TIMER_3_4_MASK, + }, +}; + +struct pmx_dev pmx_emi_cs_0_1_4_5 = { + .name = "emi_cs_0_1_4_5", + .modes = pmx_emi_cs_0_1_4_5_modes, + .mode_count = ARRAY_SIZE(pmx_emi_cs_0_1_4_5_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = { + { + .ids = 0x00, + .mask = PMX_TIMER_1_2_MASK, + }, +}; + +struct pmx_dev pmx_emi_cs_2_3 = { + .name = "emi_cs_2_3", + .modes = pmx_emi_cs_2_3_modes, + .mode_count = ARRAY_SIZE(pmx_emi_cs_2_3_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_uart1_modes[] = { + { + .ids = 0x00, + .mask = PMX_FIRDA_MASK, + }, +}; + +struct pmx_dev pmx_uart1 = { + .name = "uart1", + .modes = pmx_uart1_modes, + .mode_count = ARRAY_SIZE(pmx_uart1_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_uart2_modes[] = { + { + .ids = 0x00, + .mask = PMX_TIMER_1_2_MASK, + }, +}; + +struct pmx_dev pmx_uart2 = { + .name = "uart2", + .modes = pmx_uart2_modes, + .mode_count = ARRAY_SIZE(pmx_uart2_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_uart3_4_5_modes[] = { + { + .ids = 0x00, + .mask = PMX_UART0_MODEM_MASK, + }, +}; + +struct pmx_dev pmx_uart3_4_5 = { + .name = "uart3_4_5", + .modes = pmx_uart3_4_5_modes, + .mode_count = ARRAY_SIZE(pmx_uart3_4_5_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_fsmc_modes[] = { + { + .ids = 0x00, + .mask = PMX_SSP_CS_MASK, + }, +}; + +struct pmx_dev pmx_fsmc = { + .name = "fsmc", + .modes = pmx_fsmc_modes, + .mode_count = ARRAY_SIZE(pmx_fsmc_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_rs485_0_1_modes[] = { + { + .ids = 0x00, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_rs485_0_1 = { + .name = "rs485_0_1", + .modes = pmx_rs485_0_1_modes, + .mode_count = ARRAY_SIZE(pmx_rs485_0_1_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_tdm0_modes[] = { + { + .ids = 0x00, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_tdm0 = { + .name = "tdm0", + .modes = pmx_tdm0_modes, + .mode_count = ARRAY_SIZE(pmx_tdm0_modes), + .enb_on_reset = 1, +}; + +/* pmx driver structure */ +struct pmx_driver pmx_driver = { + .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff}, +}; + /* Add spear310 specific devices here */ +/* spear310 routines */ void __init spear310_init(void) { /* call spear3xx family common init function */ spear3xx_init(); } + +void spear310_pmx_init(void) +{ + spear_pmx_init(&pmx_driver, SPEAR310_SOC_CONFIG_BASE, + SPEAR310_SOC_CONFIG_SIZE); +} diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c index e781b2b7f137..7facf6643199 100644 --- a/arch/arm/mach-spear3xx/spear310_evb.c +++ b/arch/arm/mach-spear3xx/spear310_evb.c @@ -16,6 +16,30 @@ #include #include +/* padmux devices to enable */ +static struct pmx_dev *pmx_devs[] = { + /* spear3xx specific devices */ + &pmx_i2c, + &pmx_ssp, + &pmx_gpio_pin0, + &pmx_gpio_pin1, + &pmx_gpio_pin2, + &pmx_gpio_pin3, + &pmx_gpio_pin4, + &pmx_gpio_pin5, + &pmx_uart0, + + /* spear310 specific devices */ + &pmx_emi_cs_0_1_4_5, + &pmx_emi_cs_2_3, + &pmx_uart1, + &pmx_uart2, + &pmx_uart3_4_5, + &pmx_fsmc, + &pmx_rs485_0_1, + &pmx_tdm0, +}; + static struct amba_device *amba_devs[] __initdata = { /* spear3xx specific devices */ &gpio_device, @@ -37,6 +61,12 @@ static void __init spear310_evb_init(void) /* call spear310 machine init function */ spear310_init(); + /* padmux initialization */ + pmx_driver.mode = NULL; + pmx_driver.devs = pmx_devs; + pmx_driver.devs_count = ARRAY_SIZE(pmx_devs); + spear310_pmx_init(); + /* Add Platform Devices */ platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index 72d45489dcb0..2cedf5eb9ec9 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c @@ -16,10 +16,384 @@ #include #include +/* pad multiplexing support */ +/* muxing registers */ +#define PAD_MUX_CONFIG_REG 0x0C +#define MODE_CONFIG_REG 0x10 + +/* modes */ +#define AUTO_NET_SMII_MODE (1 << 0) +#define AUTO_NET_MII_MODE (1 << 1) +#define AUTO_EXP_MODE (1 << 2) +#define SMALL_PRINTERS_MODE (1 << 3) +#define ALL_MODES 0xF + +struct pmx_mode auto_net_smii_mode = { + .id = AUTO_NET_SMII_MODE, + .name = "Automation Networking SMII Mode", + .mask = 0x00, +}; + +struct pmx_mode auto_net_mii_mode = { + .id = AUTO_NET_MII_MODE, + .name = "Automation Networking MII Mode", + .mask = 0x01, +}; + +struct pmx_mode auto_exp_mode = { + .id = AUTO_EXP_MODE, + .name = "Automation Expanded Mode", + .mask = 0x02, +}; + +struct pmx_mode small_printers_mode = { + .id = SMALL_PRINTERS_MODE, + .name = "Small Printers Mode", + .mask = 0x03, +}; + +/* devices */ +struct pmx_dev_mode pmx_clcd_modes[] = { + { + .ids = AUTO_NET_SMII_MODE, + .mask = 0x0, + }, +}; + +struct pmx_dev pmx_clcd = { + .name = "clcd", + .modes = pmx_clcd_modes, + .mode_count = ARRAY_SIZE(pmx_clcd_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_emi_modes[] = { + { + .ids = AUTO_EXP_MODE, + .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK, + }, +}; + +struct pmx_dev pmx_emi = { + .name = "emi", + .modes = pmx_emi_modes, + .mode_count = ARRAY_SIZE(pmx_emi_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_fsmc_modes[] = { + { + .ids = ALL_MODES, + .mask = 0x0, + }, +}; + +struct pmx_dev pmx_fsmc = { + .name = "fsmc", + .modes = pmx_fsmc_modes, + .mode_count = ARRAY_SIZE(pmx_fsmc_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_spp_modes[] = { + { + .ids = SMALL_PRINTERS_MODE, + .mask = 0x0, + }, +}; + +struct pmx_dev pmx_spp = { + .name = "spp", + .modes = pmx_spp_modes, + .mode_count = ARRAY_SIZE(pmx_spp_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_sdio_modes[] = { + { + .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | + SMALL_PRINTERS_MODE, + .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK, + }, +}; + +struct pmx_dev pmx_sdio = { + .name = "sdio", + .modes = pmx_sdio_modes, + .mode_count = ARRAY_SIZE(pmx_sdio_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_i2s_modes[] = { + { + .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, + .mask = PMX_UART0_MODEM_MASK, + }, +}; + +struct pmx_dev pmx_i2s = { + .name = "i2s", + .modes = pmx_i2s_modes, + .mode_count = ARRAY_SIZE(pmx_i2s_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_uart1_modes[] = { + { + .ids = ALL_MODES, + .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK, + }, +}; + +struct pmx_dev pmx_uart1 = { + .name = "uart1", + .modes = pmx_uart1_modes, + .mode_count = ARRAY_SIZE(pmx_uart1_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_uart1_modem_modes[] = { + { + .ids = AUTO_EXP_MODE, + .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | + PMX_SSP_CS_MASK, + }, { + .ids = SMALL_PRINTERS_MODE, + .mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK | + PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK, + }, +}; + +struct pmx_dev pmx_uart1_modem = { + .name = "uart1_modem", + .modes = pmx_uart1_modem_modes, + .mode_count = ARRAY_SIZE(pmx_uart1_modem_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_uart2_modes[] = { + { + .ids = ALL_MODES, + .mask = PMX_FIRDA_MASK, + }, +}; + +struct pmx_dev pmx_uart2 = { + .name = "uart2", + .modes = pmx_uart2_modes, + .mode_count = ARRAY_SIZE(pmx_uart2_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_touchscreen_modes[] = { + { + .ids = AUTO_NET_SMII_MODE, + .mask = PMX_SSP_CS_MASK, + }, +}; + +struct pmx_dev pmx_touchscreen = { + .name = "touchscreen", + .modes = pmx_touchscreen_modes, + .mode_count = ARRAY_SIZE(pmx_touchscreen_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_can_modes[] = { + { + .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE, + .mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | + PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK, + }, +}; + +struct pmx_dev pmx_can = { + .name = "can", + .modes = pmx_can_modes, + .mode_count = ARRAY_SIZE(pmx_can_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_sdio_led_modes[] = { + { + .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, + .mask = PMX_SSP_CS_MASK, + }, +}; + +struct pmx_dev pmx_sdio_led = { + .name = "sdio_led", + .modes = pmx_sdio_led_modes, + .mode_count = ARRAY_SIZE(pmx_sdio_led_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_pwm0_modes[] = { + { + .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, + .mask = PMX_UART0_MODEM_MASK, + }, { + .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_pwm0 = { + .name = "pwm0", + .modes = pmx_pwm0_modes, + .mode_count = ARRAY_SIZE(pmx_pwm0_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_pwm1_modes[] = { + { + .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, + .mask = PMX_UART0_MODEM_MASK, + }, { + .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_pwm1 = { + .name = "pwm1", + .modes = pmx_pwm1_modes, + .mode_count = ARRAY_SIZE(pmx_pwm1_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_pwm2_modes[] = { + { + .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, + .mask = PMX_SSP_CS_MASK, + }, { + .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_pwm2 = { + .name = "pwm2", + .modes = pmx_pwm2_modes, + .mode_count = ARRAY_SIZE(pmx_pwm2_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_pwm3_modes[] = { + { + .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_pwm3 = { + .name = "pwm3", + .modes = pmx_pwm3_modes, + .mode_count = ARRAY_SIZE(pmx_pwm3_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_ssp1_modes[] = { + { + .ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_ssp1 = { + .name = "ssp1", + .modes = pmx_ssp1_modes, + .mode_count = ARRAY_SIZE(pmx_ssp1_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_ssp2_modes[] = { + { + .ids = AUTO_NET_SMII_MODE, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_ssp2 = { + .name = "ssp2", + .modes = pmx_ssp2_modes, + .mode_count = ARRAY_SIZE(pmx_ssp2_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_mii1_modes[] = { + { + .ids = AUTO_NET_MII_MODE, + .mask = 0x0, + }, +}; + +struct pmx_dev pmx_mii1 = { + .name = "mii1", + .modes = pmx_mii1_modes, + .mode_count = ARRAY_SIZE(pmx_mii1_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_smii0_modes[] = { + { + .ids = AUTO_NET_SMII_MODE | AUTO_EXP_MODE | SMALL_PRINTERS_MODE, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_smii0 = { + .name = "smii0", + .modes = pmx_smii0_modes, + .mode_count = ARRAY_SIZE(pmx_smii0_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_smii1_modes[] = { + { + .ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_smii1 = { + .name = "smii1", + .modes = pmx_smii1_modes, + .mode_count = ARRAY_SIZE(pmx_smii1_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_i2c1_modes[] = { + { + .ids = AUTO_EXP_MODE, + .mask = 0x0, + }, +}; + +struct pmx_dev pmx_i2c1 = { + .name = "i2c1", + .modes = pmx_i2c1_modes, + .mode_count = ARRAY_SIZE(pmx_i2c1_modes), + .enb_on_reset = 1, +}; + +/* pmx driver structure */ +struct pmx_driver pmx_driver = { + .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x00000007}, + .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff}, +}; + /* Add spear320 specific devices here */ +/* spear320 routines */ void __init spear320_init(void) { /* call spear3xx family common init function */ spear3xx_init(); } + +void spear320_pmx_init(void) +{ + spear_pmx_init(&pmx_driver, SPEAR320_SOC_CONFIG_BASE, + SPEAR320_SOC_CONFIG_SIZE); +} diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c index 85bc4d226212..62ac685a4135 100644 --- a/arch/arm/mach-spear3xx/spear320_evb.c +++ b/arch/arm/mach-spear3xx/spear320_evb.c @@ -16,6 +16,27 @@ #include #include +/* padmux devices to enable */ +static struct pmx_dev *pmx_devs[] = { + /* spear3xx specific devices */ + &pmx_i2c, + &pmx_ssp, + &pmx_mii, + &pmx_uart0, + + /* spear320 specific devices */ + &pmx_fsmc, + &pmx_sdio, + &pmx_i2s, + &pmx_uart1, + &pmx_uart2, + &pmx_can, + &pmx_pwm0, + &pmx_pwm1, + &pmx_pwm2, + &pmx_mii1, +}; + static struct amba_device *amba_devs[] __initdata = { /* spear3xx specific devices */ &gpio_device, @@ -37,6 +58,12 @@ static void __init spear320_evb_init(void) /* call spear320 machine init function */ spear320_init(); + /* padmux initialization */ + pmx_driver.mode = &auto_net_mii_mode; + pmx_driver.devs = pmx_devs; + pmx_driver.devs_count = ARRAY_SIZE(pmx_devs); + spear320_pmx_init(); + /* Add Platform Devices */ platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index 82ebcd30465e..e87313aeae20 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c @@ -99,3 +99,450 @@ void __init spear3xx_map_io(void) /* This will initialize clock framework */ clk_init(); } + +/* pad multiplexing support */ +/* devices */ +struct pmx_dev_mode pmx_firda_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_FIRDA_MASK, + }, +}; + +struct pmx_dev pmx_firda = { + .name = "firda", + .modes = pmx_firda_modes, + .mode_count = ARRAY_SIZE(pmx_firda_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_i2c_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_I2C_MASK, + }, +}; + +struct pmx_dev pmx_i2c = { + .name = "i2c", + .modes = pmx_i2c_modes, + .mode_count = ARRAY_SIZE(pmx_i2c_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_ssp_cs_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_SSP_CS_MASK, + }, +}; + +struct pmx_dev pmx_ssp_cs = { + .name = "ssp_chip_selects", + .modes = pmx_ssp_cs_modes, + .mode_count = ARRAY_SIZE(pmx_ssp_cs_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_ssp_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_SSP_MASK, + }, +}; + +struct pmx_dev pmx_ssp = { + .name = "ssp", + .modes = pmx_ssp_modes, + .mode_count = ARRAY_SIZE(pmx_ssp_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_mii_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_mii = { + .name = "mii", + .modes = pmx_mii_modes, + .mode_count = ARRAY_SIZE(pmx_mii_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_gpio_pin0_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_GPIO_PIN0_MASK, + }, +}; + +struct pmx_dev pmx_gpio_pin0 = { + .name = "gpio_pin0", + .modes = pmx_gpio_pin0_modes, + .mode_count = ARRAY_SIZE(pmx_gpio_pin0_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_gpio_pin1_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_GPIO_PIN1_MASK, + }, +}; + +struct pmx_dev pmx_gpio_pin1 = { + .name = "gpio_pin1", + .modes = pmx_gpio_pin1_modes, + .mode_count = ARRAY_SIZE(pmx_gpio_pin1_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_gpio_pin2_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_GPIO_PIN2_MASK, + }, +}; + +struct pmx_dev pmx_gpio_pin2 = { + .name = "gpio_pin2", + .modes = pmx_gpio_pin2_modes, + .mode_count = ARRAY_SIZE(pmx_gpio_pin2_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_gpio_pin3_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_GPIO_PIN3_MASK, + }, +}; + +struct pmx_dev pmx_gpio_pin3 = { + .name = "gpio_pin3", + .modes = pmx_gpio_pin3_modes, + .mode_count = ARRAY_SIZE(pmx_gpio_pin3_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_gpio_pin4_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_GPIO_PIN4_MASK, + }, +}; + +struct pmx_dev pmx_gpio_pin4 = { + .name = "gpio_pin4", + .modes = pmx_gpio_pin4_modes, + .mode_count = ARRAY_SIZE(pmx_gpio_pin4_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_gpio_pin5_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_GPIO_PIN5_MASK, + }, +}; + +struct pmx_dev pmx_gpio_pin5 = { + .name = "gpio_pin5", + .modes = pmx_gpio_pin5_modes, + .mode_count = ARRAY_SIZE(pmx_gpio_pin5_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_uart0_modem_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_UART0_MODEM_MASK, + }, +}; + +struct pmx_dev pmx_uart0_modem = { + .name = "uart0_modem", + .modes = pmx_uart0_modem_modes, + .mode_count = ARRAY_SIZE(pmx_uart0_modem_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_uart0_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_UART0_MASK, + }, +}; + +struct pmx_dev pmx_uart0 = { + .name = "uart0", + .modes = pmx_uart0_modes, + .mode_count = ARRAY_SIZE(pmx_uart0_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_timer_3_4_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_TIMER_3_4_MASK, + }, +}; + +struct pmx_dev pmx_timer_3_4 = { + .name = "timer_3_4", + .modes = pmx_timer_3_4_modes, + .mode_count = ARRAY_SIZE(pmx_timer_3_4_modes), + .enb_on_reset = 0, +}; + +struct pmx_dev_mode pmx_timer_1_2_modes[] = { + { + .ids = 0xffffffff, + .mask = PMX_TIMER_1_2_MASK, + }, +}; + +struct pmx_dev pmx_timer_1_2 = { + .name = "timer_1_2", + .modes = pmx_timer_1_2_modes, + .mode_count = ARRAY_SIZE(pmx_timer_1_2_modes), + .enb_on_reset = 0, +}; + +#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320) +/* plgpios devices */ +struct pmx_dev_mode pmx_plgpio_0_1_modes[] = { + { + .ids = 0x00, + .mask = PMX_FIRDA_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_0_1 = { + .name = "plgpio 0 and 1", + .modes = pmx_plgpio_0_1_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_0_1_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_2_3_modes[] = { + { + .ids = 0x00, + .mask = PMX_UART0_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_2_3 = { + .name = "plgpio 2 and 3", + .modes = pmx_plgpio_2_3_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_2_3_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_4_5_modes[] = { + { + .ids = 0x00, + .mask = PMX_I2C_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_4_5 = { + .name = "plgpio 4 and 5", + .modes = pmx_plgpio_4_5_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_4_5_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_6_9_modes[] = { + { + .ids = 0x00, + .mask = PMX_SSP_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_6_9 = { + .name = "plgpio 6 to 9", + .modes = pmx_plgpio_6_9_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_6_9_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_10_27_modes[] = { + { + .ids = 0x00, + .mask = PMX_MII_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_10_27 = { + .name = "plgpio 10 to 27", + .modes = pmx_plgpio_10_27_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_10_27_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_28_modes[] = { + { + .ids = 0x00, + .mask = PMX_GPIO_PIN0_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_28 = { + .name = "plgpio 28", + .modes = pmx_plgpio_28_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_28_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_29_modes[] = { + { + .ids = 0x00, + .mask = PMX_GPIO_PIN1_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_29 = { + .name = "plgpio 29", + .modes = pmx_plgpio_29_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_29_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_30_modes[] = { + { + .ids = 0x00, + .mask = PMX_GPIO_PIN2_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_30 = { + .name = "plgpio 30", + .modes = pmx_plgpio_30_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_30_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_31_modes[] = { + { + .ids = 0x00, + .mask = PMX_GPIO_PIN3_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_31 = { + .name = "plgpio 31", + .modes = pmx_plgpio_31_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_31_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_32_modes[] = { + { + .ids = 0x00, + .mask = PMX_GPIO_PIN4_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_32 = { + .name = "plgpio 32", + .modes = pmx_plgpio_32_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_32_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_33_modes[] = { + { + .ids = 0x00, + .mask = PMX_GPIO_PIN5_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_33 = { + .name = "plgpio 33", + .modes = pmx_plgpio_33_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_33_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_34_36_modes[] = { + { + .ids = 0x00, + .mask = PMX_SSP_CS_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_34_36 = { + .name = "plgpio 34 to 36", + .modes = pmx_plgpio_34_36_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_34_36_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_37_42_modes[] = { + { + .ids = 0x00, + .mask = PMX_UART0_MODEM_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_37_42 = { + .name = "plgpio 37 to 42", + .modes = pmx_plgpio_37_42_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_37_42_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = { + { + .ids = 0x00, + .mask = PMX_TIMER_1_2_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_43_44_47_48 = { + .name = "plgpio 43, 44, 47 and 48", + .modes = pmx_plgpio_43_44_47_48_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_43_44_47_48_modes), + .enb_on_reset = 1, +}; + +struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = { + { + .ids = 0x00, + .mask = PMX_TIMER_3_4_MASK, + }, +}; + +struct pmx_dev pmx_plgpio_45_46_49_50 = { + .name = "plgpio 45, 46, 49 and 50", + .modes = pmx_plgpio_45_46_49_50_modes, + .mode_count = ARRAY_SIZE(pmx_plgpio_45_46_49_50_modes), + .enb_on_reset = 1, +}; + +#endif + +/* spear padmux initialization function */ +void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size) +{ + int ret = 0; + + /* pad mux initialization */ + pmx_driver->base = ioremap(base, size); + if (!pmx_driver->base) { + ret = -ENOMEM; + goto pmx_fail; + } + + ret = pmx_register(pmx_driver); + iounmap(pmx_driver->base); + +pmx_fail: + if (ret) + printk(KERN_ERR "padmux: registeration failed. err no: %d\n", + ret); +} diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile index 96f9ac3d4b81..6f4ad5e9462e 100644 --- a/arch/arm/plat-spear/Makefile +++ b/arch/arm/plat-spear/Makefile @@ -3,4 +3,4 @@ # # Common support -obj-y := clock.o time.o +obj-y := clock.o padmux.o time.o diff --git a/arch/arm/plat-spear/include/plat/padmux.h b/arch/arm/plat-spear/include/plat/padmux.h new file mode 100644 index 000000000000..877f3adcf610 --- /dev/null +++ b/arch/arm/plat-spear/include/plat/padmux.h @@ -0,0 +1,92 @@ +/* + * arch/arm/plat-spear/include/plat/padmux.h + * + * SPEAr platform specific gpio pads muxing file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __PLAT_PADMUX_H +#define __PLAT_PADMUX_H + +#include + +/* + * struct pmx_reg: configuration structure for mode reg and mux reg + * + * offset: offset of mode reg + * mask: mask of mode reg + */ +struct pmx_reg { + u32 offset; + u32 mask; +}; + +/* + * struct pmx_dev_mode: configuration structure every group of modes of a device + * + * ids: all modes for this configuration + * mask: mask for supported mode + */ +struct pmx_dev_mode { + u32 ids; + u32 mask; +}; + +/* + * struct pmx_mode: mode definition structure + * + * name: mode name + * mask: mode mask + */ +struct pmx_mode { + char *name; + u32 id; + u32 mask; +}; + +/* + * struct pmx_dev: device definition structure + * + * name: device name + * modes: device configuration array for different modes supported + * mode_count: size of modes array + * is_active: is peripheral active/enabled + * enb_on_reset: if 1, mask bits to be cleared in reg otherwise to be set in reg + */ +struct pmx_dev { + char *name; + struct pmx_dev_mode *modes; + u8 mode_count; + bool is_active; + bool enb_on_reset; +}; + +/* + * struct pmx_driver: driver definition structure + * + * mode: mode to be set + * devs: array of pointer to pmx devices + * devs_count: ARRAY_SIZE of devs + * base: base address of soc config registers + * mode_reg: structure of mode config register + * mux_reg: structure of device mux config register + */ +struct pmx_driver { + struct pmx_mode *mode; + struct pmx_dev **devs; + u8 devs_count; + u32 *base; + struct pmx_reg mode_reg; + struct pmx_reg mux_reg; +}; + +/* pmx functions */ +int pmx_register(struct pmx_driver *driver); + +#endif /* __PLAT_PADMUX_H */ diff --git a/arch/arm/plat-spear/padmux.c b/arch/arm/plat-spear/padmux.c new file mode 100644 index 000000000000..d2aab3adcdeb --- /dev/null +++ b/arch/arm/plat-spear/padmux.c @@ -0,0 +1,164 @@ +/* + * arch/arm/plat-spear/include/plat/padmux.c + * + * SPEAr platform specific gpio pads muxing source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include + +/* + * struct pmx: pmx definition structure + * + * base: base address of configuration registers + * mode_reg: mode configurations + * mux_reg: muxing configurations + * active_mode: pointer to current active mode + */ +struct pmx { + u32 base; + struct pmx_reg mode_reg; + struct pmx_reg mux_reg; + struct pmx_mode *active_mode; +}; + +static struct pmx *pmx; + +/** + * pmx_mode_set - Enables an multiplexing mode + * @mode - pointer to pmx mode + * + * It will set mode of operation in hardware. + * Returns -ve on Err otherwise 0 + */ +static int pmx_mode_set(struct pmx_mode *mode) +{ + u32 val; + + if (!mode->name) + return -EFAULT; + + pmx->active_mode = mode; + + val = readl(pmx->base + pmx->mode_reg.offset); + val &= ~pmx->mode_reg.mask; + val |= mode->mask & pmx->mode_reg.mask; + writel(val, pmx->base + pmx->mode_reg.offset); + + return 0; +} + +/** + * pmx_devs_enable - Enables list of devices + * @devs - pointer to pmx device array + * @count - number of devices to enable + * + * It will enable pads for all required peripherals once and only once. + * If peripheral is not supported by current mode then request is rejected. + * Conflicts between peripherals are not handled and peripherals will be + * enabled in the order they are present in pmx_dev array. + * In case of conflicts last peripheral enalbed will be present. + * Returns -ve on Err otherwise 0 + */ +static int pmx_devs_enable(struct pmx_dev **devs, u8 count) +{ + u32 val, i, mask; + + if (!count) + return -EINVAL; + + val = readl(pmx->base + pmx->mux_reg.offset); + for (i = 0; i < count; i++) { + u8 j = 0; + + if (!devs[i]->name || !devs[i]->modes) { + printk(KERN_ERR "padmux: dev name or modes is null\n"); + continue; + } + /* check if peripheral exists in active mode */ + if (pmx->active_mode) { + bool found = false; + for (j = 0; j < devs[i]->mode_count; j++) { + if (devs[i]->modes[j].ids & + pmx->active_mode->id) { + found = true; + break; + } + } + if (found == false) { + printk(KERN_ERR "%s device not available in %s"\ + "mode\n", devs[i]->name, + pmx->active_mode->name); + continue; + } + } + + /* enable peripheral */ + mask = devs[i]->modes[j].mask & pmx->mux_reg.mask; + if (devs[i]->enb_on_reset) + val &= ~mask; + else + val |= mask; + + devs[i]->is_active = true; + } + writel(val, pmx->base + pmx->mux_reg.offset); + kfree(pmx); + + /* this will ensure that multiplexing can't be changed now */ + pmx = (struct pmx *)-1; + + return 0; +} + +/** + * pmx_register - registers a platform requesting pad mux feature + * @driver - pointer to driver structure containing driver specific parameters + * + * Also this must be called only once. This will allocate memory for pmx + * structure, will call pmx_mode_set, will call pmx_devs_enable. + * Returns -ve on Err otherwise 0 + */ +int pmx_register(struct pmx_driver *driver) +{ + int ret = 0; + + if (pmx) + return -EPERM; + if (!driver->base || !driver->devs) + return -EFAULT; + + pmx = kzalloc(sizeof(*pmx), GFP_KERNEL); + if (!pmx) + return -ENOMEM; + + pmx->base = (u32)driver->base; + pmx->mode_reg.offset = driver->mode_reg.offset; + pmx->mode_reg.mask = driver->mode_reg.mask; + pmx->mux_reg.offset = driver->mux_reg.offset; + pmx->mux_reg.mask = driver->mux_reg.mask; + + /* choose mode to enable */ + if (driver->mode) { + ret = pmx_mode_set(driver->mode); + if (ret) + goto pmx_fail; + } + ret = pmx_devs_enable(driver->devs, driver->devs_count); + if (ret) + goto pmx_fail; + + return 0; + +pmx_fail: + return ret; +} -- cgit v1.2.3-59-g8ed1b From ff37f6e5910c4fd7ad42063d89c0687def665941 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:49:09 +0100 Subject: ARM: 6021/1: ST SPEAr: Added ARM PrimeXsys System Controller SP810 header file Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/include/asm/hardware/sp810.h | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 arch/arm/include/asm/hardware/sp810.h (limited to 'arch') diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h new file mode 100644 index 000000000000..a101f10bb5b1 --- /dev/null +++ b/arch/arm/include/asm/hardware/sp810.h @@ -0,0 +1,59 @@ +/* + * arch/arm/include/asm/hardware/sp810.h + * + * ARM PrimeXsys System Controller SP810 header file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __ASM_ARM_SP810_H +#define __ASM_ARM_SP810_H + +#include + +/* sysctl registers offset */ +#define SCCTRL 0x000 +#define SCSYSSTAT 0x004 +#define SCIMCTRL 0x008 +#define SCIMSTAT 0x00C +#define SCXTALCTRL 0x010 +#define SCPLLCTRL 0x014 +#define SCPLLFCTRL 0x018 +#define SCPERCTRL0 0x01C +#define SCPERCTRL1 0x020 +#define SCPEREN 0x024 +#define SCPERDIS 0x028 +#define SCPERCLKEN 0x02C +#define SCPERSTAT 0x030 +#define SCSYSID0 0xEE0 +#define SCSYSID1 0xEE4 +#define SCSYSID2 0xEE8 +#define SCSYSID3 0xEEC +#define SCITCR 0xF00 +#define SCITIR0 0xF04 +#define SCITIR1 0xF08 +#define SCITOR 0xF0C +#define SCCNTCTRL 0xF10 +#define SCCNTDATA 0xF14 +#define SCCNTSTEP 0xF18 +#define SCPERIPHID0 0xFE0 +#define SCPERIPHID1 0xFE4 +#define SCPERIPHID2 0xFE8 +#define SCPERIPHID3 0xFEC +#define SCPCELLID0 0xFF0 +#define SCPCELLID1 0xFF4 +#define SCPCELLID2 0xFF8 +#define SCPCELLID3 0xFFC + +static inline void sysctl_soft_reset(void __iomem *base) +{ + /* writing any value to SCSYSSTAT reg will reset system */ + writel(0, base + SCSYSSTAT); +} + +#endif /* __ASM_ARM_SP810_H */ -- cgit v1.2.3-59-g8ed1b From 6e8699f7d68589e0e9ab324f598a3357bceb40bc Mon Sep 17 00:00:00 2001 From: Albin Tonnerre Date: Sat, 3 Apr 2010 11:40:28 +0100 Subject: ARM: 6026/1: ARM: Add support for LZMA-compressed kernel images This patch allows using a kernel image compressed with LZMA on ARM. Extracting the image is fairly slow, but it might be useful on machines with a very limited amount of storage, as the size benefit is quite significant (about 25% smaller with LZMA compared to GZIP) Tested-by: Martin Michlmayr Tested-by: Paulius Zaleckas Signed-off-by: Albin Tonnerre Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/boot/compressed/Makefile | 1 + arch/arm/boot/compressed/decompress.c | 4 ++++ arch/arm/boot/compressed/piggy.lzma.S | 6 ++++++ 4 files changed, 12 insertions(+) create mode 100644 arch/arm/boot/compressed/piggy.lzma.S (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bf856f492eb5..5c8128c76996 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -21,6 +21,7 @@ config ARM select HAVE_GENERIC_DMA_COHERENT select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZO + select HAVE_KERNEL_LZMA select HAVE_PERF_EVENTS select PERF_USE_VMALLOC help diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 97c89e7de7d3..53faa9063a03 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -65,6 +65,7 @@ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ suffix_$(CONFIG_KERNEL_GZIP) = gzip suffix_$(CONFIG_KERNEL_LZO) = lzo +suffix_$(CONFIG_KERNEL_LZMA) = lzma targets := vmlinux vmlinux.lds \ piggy.$(suffix_y) piggy.$(suffix_y).o \ diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c index 9c097073ce4c..4c72a97bc3e1 100644 --- a/arch/arm/boot/compressed/decompress.c +++ b/arch/arm/boot/compressed/decompress.c @@ -40,6 +40,10 @@ extern void error(char *); #include "../../../../lib/decompress_unlzo.c" #endif +#ifdef CONFIG_KERNEL_LZMA +#include "../../../../lib/decompress_unlzma.c" +#endif + void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) { decompress(input, len, NULL, NULL, output, NULL, error); diff --git a/arch/arm/boot/compressed/piggy.lzma.S b/arch/arm/boot/compressed/piggy.lzma.S new file mode 100644 index 000000000000..d7e69cffbc0a --- /dev/null +++ b/arch/arm/boot/compressed/piggy.lzma.S @@ -0,0 +1,6 @@ + .section .piggydata,#alloc + .globl input_data +input_data: + .incbin "arch/arm/boot/compressed/piggy.lzma" + .globl input_data_end +input_data_end: -- cgit v1.2.3-59-g8ed1b From f76348a360fe92063e07a8f54b0c1ea67f91e76c Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Dec 2009 12:57:01 +0000 Subject: ARM: remove unnecessary cache flush This cache flush occurs when we first insert a page into the page tables, where a page did not exist previously. There can be no cache lines associated with this virtual mapping, so this cache flush is redundant. Tested-by: Mike Rapoport Tested-by: Mikael Pettersson Signed-off-by: Russell King --- arch/arm/mm/fault-armv.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index c9b97e9836a2..82df01a72f4a 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -133,8 +133,6 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma, flush_dcache_mmap_unlock(mapping); if (aliases) do_adjust_pte(vma, addr, pfn, ptep); - else - flush_cache_page(vma, addr, pfn); } /* -- cgit v1.2.3-59-g8ed1b From e193ba290f0228453341b41ab2bbdd963259f97e Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Dec 2009 18:32:13 +0000 Subject: ARM: dma: add /proc/dma support to arch/arm/kernel/dma.c We have our own private implementation for ISA-like DMA which has been missing exposure via the /proc/dma interface. Add support for this. Signed-off-by: Russell King --- arch/arm/kernel/dma.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'arch') diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c index 7d5b9fb01e71..2c4a185f92cd 100644 --- a/arch/arm/kernel/dma.c +++ b/arch/arm/kernel/dma.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include @@ -264,3 +266,37 @@ int get_dma_residue(unsigned int chan) return ret; } EXPORT_SYMBOL(get_dma_residue); + +#ifdef CONFIG_PROC_FS +static int proc_dma_show(struct seq_file *m, void *v) +{ + int i; + + for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) { + dma_t *dma = dma_channel(i); + if (dma && dma->lock) + seq_printf(m, "%2d: %s\n", i, dma->device_id); + } + return 0; +} + +static int proc_dma_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_dma_show, NULL); +} + +static const struct file_operations proc_dma_operations = { + .open = proc_dma_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init proc_dma_init(void) +{ + proc_create("dma", 0, NULL, &proc_dma_operations); + return 0; +} + +__initcall(proc_dma_init); +#endif -- cgit v1.2.3-59-g8ed1b From 8e797a7e4f588fb3b9cfe9860b00dcd3b14f8b60 Mon Sep 17 00:00:00 2001 From: Srinidhi Kasagar Date: Sat, 3 Apr 2010 19:10:45 +0100 Subject: ARM: 6027/1: ux500: enable l2x0 support This enables the l2x0 support and ensures that the secondary CPU can see the page table and secondary data at this point. Signed-off-by: srinidhi kasagar Acked-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/mach-ux500/cpu-u8500.c | 17 +++++++++++++++++ arch/arm/mach-ux500/platsmp.c | 3 ++- arch/arm/mm/Kconfig | 3 ++- 3 files changed, 21 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index 5fb44661adaf..979f1c32ad09 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -127,6 +128,7 @@ static struct map_desc u8500_io_desc[] __initdata = { __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO5_BASE, SZ_4K), + __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K), }; static struct map_desc u8500ed_io_desc[] __initdata = { @@ -183,3 +185,18 @@ static void __init u8500_timer_init(void) struct sys_timer u8500_timer = { .init = u8500_timer_init, }; + +#ifdef CONFIG_CACHE_L2X0 +static int u8500_l2x0_init(void) +{ + void __iomem *l2x0_base; + + l2x0_base = __io_address(U8500_L2CC_BASE); + + /* 64KB way size, 8 way associativity, force WA */ + l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); + + return 0; +} +early_initcall(u8500_l2x0_init); +#endif diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 8dfe7ca245d8..76dd9354bd18 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -75,7 +75,8 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) * that it has been released by resetting pen_release. */ pen_release = cpu; - flush_cache_all(); + __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); + outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c4ed9f93f646..22c1c839306a 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -754,7 +754,8 @@ config CACHE_FEROCEON_L2_WRITETHROUGH config CACHE_L2X0 bool "Enable the L2x0 outer cache controller" depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ - REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4 + REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \ + ARCH_NOMADIK || ARCH_OMAP4 || ARCH_U8500 default y select OUTER_CACHE help -- cgit v1.2.3-59-g8ed1b From 771dc157e06d69fcece0b2c8a29b9010345d8e9a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 8 Apr 2010 07:38:52 +0100 Subject: ARM: 6032/1: ARM: MMCI: support 8bit mode on the ST Micro version This adds support for an 8bit wide bus to the card (data lines MCIDAT0 through 7 exist) on the ST Micro version and alters the U300 platform to support this. Also add some ST_ prefix to the ST-specific registers. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/mach-u300/mmc.c | 2 +- drivers/mmc/host/mmci.c | 6 ++++-- drivers/mmc/host/mmci.h | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c index 109f5a6e71c7..ef8032d2f5bf 100644 --- a/arch/arm/mach-u300/mmc.c +++ b/arch/arm/mach-u300/mmc.c @@ -105,7 +105,7 @@ int __devinit mmc_init(struct amba_device *adev) mmci_card->mmc0_plat_data.gpio_wp = -1; mmci_card->mmc0_plat_data.gpio_cd = -1; mmci_card->mmc0_plat_data.capabilities = MMC_CAP_MMC_HIGHSPEED | - MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA; + MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data; diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 84c103a7ee13..7e70c1a06d8a 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -55,14 +55,16 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) host->cclk = host->mclk / (2 * (clk + 1)); } if (host->hw_designer == AMBA_VENDOR_ST) - clk |= MCI_FCEN; /* Bug fix in ST IP block */ + clk |= MCI_ST_FCEN; /* Bug fix in ST IP block */ clk |= MCI_CLK_ENABLE; /* This hasn't proven to be worthwhile */ /* clk |= MCI_CLK_PWRSAVE; */ } if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) - clk |= MCI_WIDE_BUS; + clk |= MCI_4BIT_BUS; + if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) + clk |= MCI_ST_8BIT_BUS; writel(clk, host->base + MMCICLOCK); } diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 1ceb9a90f59b..d77062e5e3af 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -25,9 +25,11 @@ #define MCI_CLK_ENABLE (1 << 8) #define MCI_CLK_PWRSAVE (1 << 9) #define MCI_CLK_BYPASS (1 << 10) -#define MCI_WIDE_BUS (1 << 11) +#define MCI_4BIT_BUS (1 << 11) +/* 8bit wide buses supported in ST Micro versions */ +#define MCI_ST_8BIT_BUS (1 << 12) /* HW flow control on the ST Micro version */ -#define MCI_FCEN (1 << 13) +#define MCI_ST_FCEN (1 << 13) #define MMCIARGUMENT 0x008 #define MMCICOMMAND 0x00c -- cgit v1.2.3-59-g8ed1b From 72638ddd1422df38d1b1b269038cfc8d66152c10 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 8 Apr 2010 07:40:13 +0100 Subject: ARM: 6034/1: ARM: U300: set f_max to 24 MHz for MMCI This employs the frequency setting mechanism introduced to the MMCI to specify that this system can actually be clocked at 24 MHz. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/mach-u300/mmc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c index ef8032d2f5bf..783f1236fe1b 100644 --- a/arch/arm/mach-u300/mmc.c +++ b/arch/arm/mach-u300/mmc.c @@ -101,6 +101,7 @@ int __devinit mmc_init(struct amba_device *adev) * we have a regulator we can control instead. */ /* Nominally 2.85V on our platform */ + mmci_card->mmc0_plat_data.f_max = 24000000; mmci_card->mmc0_plat_data.status = mmc_status; mmci_card->mmc0_plat_data.gpio_wp = -1; mmci_card->mmc0_plat_data.gpio_cd = -1; -- cgit v1.2.3-59-g8ed1b From e2941054ed596dd67a6094b7aca165af1b1f9926 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 14 Apr 2010 17:54:04 +0100 Subject: ARM: 6056/1: AT91: at91sam9g10 chip identification changed A bit in the at91sam9g10 identification number changed between Engineering Sample and final product. This patch will identify both as being at91sam9g10. Signed-off-by: Nicolas Ferre Acked-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/include/mach/cpu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index 5a0650101d45..833659d1200a 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h @@ -21,7 +21,7 @@ #define ARCH_ID_AT91SAM9260 0x019803a0 #define ARCH_ID_AT91SAM9261 0x019703a0 #define ARCH_ID_AT91SAM9263 0x019607a0 -#define ARCH_ID_AT91SAM9G10 0x819903a0 +#define ARCH_ID_AT91SAM9G10 0x019903a0 #define ARCH_ID_AT91SAM9G20 0x019905a0 #define ARCH_ID_AT91SAM9RL64 0x019b03a0 #define ARCH_ID_AT91SAM9G45 0x819b05a0 @@ -108,7 +108,7 @@ static inline unsigned long at91cap9_rev_identify(void) #endif #ifdef CONFIG_ARCH_AT91SAM9G10 -#define cpu_is_at91sam9g10() (at91_cpu_identify() == ARCH_ID_AT91SAM9G10) +#define cpu_is_at91sam9g10() ((at91_cpu_identify() & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) #else #define cpu_is_at91sam9g10() (0) #endif -- cgit v1.2.3-59-g8ed1b From b8f7fb13d2d7ff14818fd1d3edd8b834d38b0217 Mon Sep 17 00:00:00 2001 From: Cliff Wickman Date: Wed, 14 Apr 2010 11:35:46 -0500 Subject: x86, UV: Improve BAU performance and error recovery - increase performance of the interrupt handler - release timed-out software acknowledge resources - recover from continuous-busy status due to a hardware issue - add a 'throttle' to keep a uvhub from sending more than a specified number of broadcasts concurrently (work around the hardware issue) - provide a 'nobau' boot command line option - rename 'pnode' and 'node' to 'uvhub' (the 'node' terminology is ambiguous) - add some new statistics about the scope of broadcasts, retries, the hardware issue and the 'throttle' - split off new function uv_bau_retry_msg() from uv_bau_process_message() per community coding style feedback. - simplify the argument list to uv_bau_process_message(), per community coding style feedback. Signed-off-by: Cliff Wickman Cc: linux-mm@kvack.org Cc: Jack Steiner Cc: Russ Anderson Cc: Mike Travis Cc: "H. Peter Anvin" Cc: Thomas Gleixner LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/include/asm/uv/uv_bau.h | 247 +++++--- arch/x86/kernel/tlb_uv.c | 1270 +++++++++++++++++++++++++++----------- 2 files changed, 1075 insertions(+), 442 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index b414d2b401f6..aa558ac0306e 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h @@ -27,13 +27,14 @@ * set 2 is at BASE + 2*512, set 3 at BASE + 3*512, and so on. * * We will use 31 sets, one for sending BAU messages from each of the 32 - * cpu's on the node. + * cpu's on the uvhub. * * TLB shootdown will use the first of the 8 descriptors of each set. * Each of the descriptors is 64 bytes in size (8*64 = 512 bytes in a set). */ #define UV_ITEMS_PER_DESCRIPTOR 8 +#define MAX_BAU_CONCURRENT 3 #define UV_CPUS_PER_ACT_STATUS 32 #define UV_ACT_STATUS_MASK 0x3 #define UV_ACT_STATUS_SIZE 2 @@ -45,6 +46,9 @@ #define UV_PAYLOADQ_PNODE_SHIFT 49 #define UV_PTC_BASENAME "sgi_uv/ptc_statistics" #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) +#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15 +#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16 +#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL /* * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 @@ -55,15 +59,29 @@ #define DESC_STATUS_SOURCE_TIMEOUT 3 /* - * source side thresholds at which message retries print a warning + * source side threshholds at which message retries print a warning */ #define SOURCE_TIMEOUT_LIMIT 20 #define DESTINATION_TIMEOUT_LIMIT 20 +/* + * misc. delays, in microseconds + */ +#define THROTTLE_DELAY 10 +#define TIMEOUT_DELAY 10 +#define BIOS_TO 1000 +/* BIOS is assumed to set the destination timeout to 1003520 nanoseconds */ + +/* + * threshholds at which to use IPI to free resources + */ +#define PLUGSB4RESET 100 +#define TIMEOUTSB4RESET 100 + /* * number of entries in the destination side payload queue */ -#define DEST_Q_SIZE 17 +#define DEST_Q_SIZE 20 /* * number of destination side software ack resources */ @@ -72,9 +90,10 @@ /* * completion statuses for sending a TLB flush message */ -#define FLUSH_RETRY 1 -#define FLUSH_GIVEUP 2 -#define FLUSH_COMPLETE 3 +#define FLUSH_RETRY_PLUGGED 1 +#define FLUSH_RETRY_TIMEOUT 2 +#define FLUSH_GIVEUP 3 +#define FLUSH_COMPLETE 4 /* * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor) @@ -86,14 +105,14 @@ * 'base_dest_nodeid' field of the header corresponds to the * destination nodeID associated with that specified bit. */ -struct bau_target_nodemask { - unsigned long bits[BITS_TO_LONGS(256)]; +struct bau_target_uvhubmask { + unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)]; }; /* - * mask of cpu's on a node + * mask of cpu's on a uvhub * (during initialization we need to check that unsigned long has - * enough bits for max. cpu's per node) + * enough bits for max. cpu's per uvhub) */ struct bau_local_cpumask { unsigned long bits; @@ -135,8 +154,8 @@ struct bau_msg_payload { struct bau_msg_header { unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ /* bits 5:0 */ - unsigned int base_dest_nodeid:15; /* nasid>>1 (pnode) of */ - /* bits 20:6 */ /* first bit in node_map */ + unsigned int base_dest_nodeid:15; /* nasid (pnode<<1) of */ + /* bits 20:6 */ /* first bit in uvhub map */ unsigned int command:8; /* message type */ /* bits 28:21 */ /* 0x38: SN3net EndPoint Message */ @@ -146,26 +165,38 @@ struct bau_msg_header { unsigned int rsvd_2:9; /* must be zero */ /* bits 40:32 */ /* Suppl_A is 56-41 */ - unsigned int payload_2a:8;/* becomes byte 16 of msg */ - /* bits 48:41 */ /* not currently using */ - unsigned int payload_2b:8;/* becomes byte 17 of msg */ - /* bits 56:49 */ /* not currently using */ + unsigned int sequence:16;/* message sequence number */ + /* bits 56:41 */ /* becomes bytes 16-17 of msg */ /* Address field (96:57) is never used as an address (these are address bits 42:3) */ + unsigned int rsvd_3:1; /* must be zero */ /* bit 57 */ /* address bits 27:4 are payload */ - /* these 24 bits become bytes 12-14 of msg */ + /* these next 24 (58-81) bits become bytes 12-14 of msg */ + + /* bits 65:58 land in byte 12 */ unsigned int replied_to:1;/* sent as 0 by the source to byte 12 */ /* bit 58 */ - - unsigned int payload_1a:5;/* not currently used */ - /* bits 63:59 */ - unsigned int payload_1b:8;/* not currently used */ - /* bits 71:64 */ - unsigned int payload_1c:8;/* not currently used */ - /* bits 79:72 */ - unsigned int payload_1d:2;/* not currently used */ + unsigned int msg_type:3; /* software type of the message*/ + /* bits 61:59 */ + unsigned int canceled:1; /* message canceled, resource to be freed*/ + /* bit 62 */ + unsigned int payload_1a:1;/* not currently used */ + /* bit 63 */ + unsigned int payload_1b:2;/* not currently used */ + /* bits 65:64 */ + + /* bits 73:66 land in byte 13 */ + unsigned int payload_1ca:6;/* not currently used */ + /* bits 71:66 */ + unsigned int payload_1c:2;/* not currently used */ + /* bits 73:72 */ + + /* bits 81:74 land in byte 14 */ + unsigned int payload_1d:6;/* not currently used */ + /* bits 79:74 */ + unsigned int payload_1e:2;/* not currently used */ /* bits 81:80 */ unsigned int rsvd_4:7; /* must be zero */ @@ -178,7 +209,7 @@ struct bau_msg_header { /* bits 95:90 */ unsigned int rsvd_6:5; /* must be zero */ /* bits 100:96 */ - unsigned int int_both:1;/* if 1, interrupt both sockets on the blade */ + unsigned int int_both:1;/* if 1, interrupt both sockets on the uvhub */ /* bit 101*/ unsigned int fairness:3;/* usually zero */ /* bits 104:102 */ @@ -191,13 +222,18 @@ struct bau_msg_header { /* bits 127:107 */ }; +/* see msg_type: */ +#define MSG_NOOP 0 +#define MSG_REGULAR 1 +#define MSG_RETRY 2 + /* * The activation descriptor: * The format of the message to send, plus all accompanying control * Should be 64 bytes */ struct bau_desc { - struct bau_target_nodemask distribution; + struct bau_target_uvhubmask distribution; /* * message template, consisting of header and payload: */ @@ -237,19 +273,25 @@ struct bau_payload_queue_entry { unsigned short acknowledge_count; /* filled in by destination */ /* 16 bits, bytes 10-11 */ - unsigned short replied_to:1; /* sent as 0 by the source */ - /* 1 bit */ - unsigned short unused1:7; /* not currently using */ - /* 7 bits: byte 12) */ + /* these next 3 bytes come from bits 58-81 of the message header */ + unsigned short replied_to:1; /* sent as 0 by the source */ + unsigned short msg_type:3; /* software message type */ + unsigned short canceled:1; /* sent as 0 by the source */ + unsigned short unused1:3; /* not currently using */ + /* byte 12 */ - unsigned char unused2[2]; /* not currently using */ - /* bytes 13-14 */ + unsigned char unused2a; /* not currently using */ + /* byte 13 */ + unsigned char unused2; /* not currently using */ + /* byte 14 */ unsigned char sw_ack_vector; /* filled in by the hardware */ /* byte 15 (bits 127:120) */ - unsigned char unused4[3]; /* not currently using bytes 17-19 */ - /* bytes 17-19 */ + unsigned short sequence; /* message sequence number */ + /* bytes 16-17 */ + unsigned char unused4[2]; /* not currently using bytes 18-19 */ + /* bytes 18-19 */ int number_of_cpus; /* filled in at destination */ /* 32 bits, bytes 20-23 (aligned) */ @@ -259,63 +301,93 @@ struct bau_payload_queue_entry { }; /* - * one for every slot in the destination payload queue - */ -struct bau_msg_status { - struct bau_local_cpumask seen_by; /* map of cpu's */ -}; - -/* - * one for every slot in the destination software ack resources - */ -struct bau_sw_ack_status { - struct bau_payload_queue_entry *msg; /* associated message */ - int watcher; /* cpu monitoring, or -1 */ -}; - -/* - * one on every node and per-cpu; to locate the software tables + * one per-cpu; to locate the software tables */ struct bau_control { struct bau_desc *descriptor_base; - struct bau_payload_queue_entry *bau_msg_head; struct bau_payload_queue_entry *va_queue_first; struct bau_payload_queue_entry *va_queue_last; - struct bau_msg_status *msg_statuses; - int *watching; /* pointer to array */ + struct bau_payload_queue_entry *bau_msg_head; + struct bau_control *uvhub_master; + struct bau_control *socket_master; + unsigned long timeout_interval; + atomic_t active_descriptor_count; + int max_concurrent; + int max_concurrent_constant; + int retry_message_scans; + int plugged_tries; + int timeout_tries; + int ipi_attempts; + int conseccompletes; + short cpu; + short uvhub_cpu; + short uvhub; + short cpus_in_socket; + short cpus_in_uvhub; + unsigned short message_number; + unsigned short uvhub_quiesce; + short socket_acknowledge_count[DEST_Q_SIZE]; + cycles_t send_message; + spinlock_t masks_lock; + spinlock_t uvhub_lock; + spinlock_t queue_lock; }; /* * This structure is allocated per_cpu for UV TLB shootdown statistics. */ struct ptc_stats { - unsigned long ptc_i; /* number of IPI-style flushes */ - unsigned long requestor; /* number of nodes this cpu sent to */ - unsigned long requestee; /* times cpu was remotely requested */ - unsigned long alltlb; /* times all tlb's on this cpu were flushed */ - unsigned long onetlb; /* times just one tlb on this cpu was flushed */ - unsigned long s_retry; /* retries on source side timeouts */ - unsigned long d_retry; /* retries on destination side timeouts */ - unsigned long sflush; /* cycles spent in uv_flush_tlb_others */ - unsigned long dflush; /* cycles spent on destination side */ - unsigned long retriesok; /* successes on retries */ - unsigned long nomsg; /* interrupts with no message */ - unsigned long multmsg; /* interrupts with multiple messages */ - unsigned long ntargeted;/* nodes targeted */ + /* sender statistics */ + unsigned long s_giveup; /* number of fall backs to IPI-style flushes */ + unsigned long s_requestor; /* number of shootdown requests */ + unsigned long s_stimeout; /* source side timeouts */ + unsigned long s_dtimeout; /* destination side timeouts */ + unsigned long s_time; /* time spent in sending side */ + unsigned long s_retriesok; /* successful retries */ + unsigned long s_ntargcpu; /* number of cpus targeted */ + unsigned long s_ntarguvhub; /* number of uvhubs targeted */ + unsigned long s_ntarguvhub16; /* number of times >= 16 target hubs */ + unsigned long s_ntarguvhub8; /* number of times >= 8 target hubs */ + unsigned long s_ntarguvhub4; /* number of times >= 4 target hubs */ + unsigned long s_ntarguvhub2; /* number of times >= 2 target hubs */ + unsigned long s_ntarguvhub1; /* number of times == 1 target hub */ + unsigned long s_resets_plug; /* ipi-style resets from plug state */ + unsigned long s_resets_timeout; /* ipi-style resets from timeouts */ + unsigned long s_busy; /* status stayed busy past s/w timer */ + unsigned long s_throttles; /* waits in throttle */ + unsigned long s_retry_messages; /* retry broadcasts */ + /* destination statistics */ + unsigned long d_alltlb; /* times all tlb's on this cpu were flushed */ + unsigned long d_onetlb; /* times just one tlb on this cpu was flushed */ + unsigned long d_multmsg; /* interrupts with multiple messages */ + unsigned long d_nomsg; /* interrupts with no message */ + unsigned long d_time; /* time spent on destination side */ + unsigned long d_requestee; /* number of messages processed */ + unsigned long d_retries; /* number of retry messages processed */ + unsigned long d_canceled; /* number of messages canceled by retries */ + unsigned long d_nocanceled; /* retries that found nothing to cancel */ + unsigned long d_resets; /* number of ipi-style requests processed */ + unsigned long d_rcanceled; /* number of messages canceled by resets */ }; -static inline int bau_node_isset(int node, struct bau_target_nodemask *dstp) +static inline int bau_uvhub_isset(int uvhub, struct bau_target_uvhubmask *dstp) { - return constant_test_bit(node, &dstp->bits[0]); + return constant_test_bit(uvhub, &dstp->bits[0]); } -static inline void bau_node_set(int node, struct bau_target_nodemask *dstp) +static inline void bau_uvhub_set(int uvhub, struct bau_target_uvhubmask *dstp) { - __set_bit(node, &dstp->bits[0]); + __set_bit(uvhub, &dstp->bits[0]); } -static inline void bau_nodes_clear(struct bau_target_nodemask *dstp, int nbits) +static inline void bau_uvhubs_clear(struct bau_target_uvhubmask *dstp, + int nbits) { bitmap_zero(&dstp->bits[0], nbits); } +static inline int bau_uvhub_weight(struct bau_target_uvhubmask *dstp) +{ + return bitmap_weight((unsigned long *)&dstp->bits[0], + UV_DISTRIBUTION_SIZE); +} static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) { @@ -328,4 +400,35 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) extern void uv_bau_message_intr1(void); extern void uv_bau_timeout_intr1(void); +struct atomic_short { + short counter; +}; + +/** + * atomic_read_short - read a short atomic variable + * @v: pointer of type atomic_short + * + * Atomically reads the value of @v. + */ +static inline int atomic_read_short(const struct atomic_short *v) +{ + return v->counter; +} + +/** + * atomic_add_short_return - add and return a short int + * @i: short value to add + * @v: pointer of type atomic_short + * + * Atomically adds @i to @v and returns @i + @v + */ +static inline int atomic_add_short_return(short i, struct atomic_short *v) +{ + short __i = i; + asm volatile(LOCK_PREFIX "xaddw %0, %1" + : "+r" (i), "+m" (v->counter) + : : "memory"); + return i + __i; +} + #endif /* _ASM_X86_UV_UV_BAU_H */ diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index ef68ba48564b..414f7c4fe76c 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c @@ -1,7 +1,7 @@ /* * SGI UltraViolet TLB flush routines. * - * (c) 2008 Cliff Wickman , SGI. + * (c) 2008-2010 Cliff Wickman , SGI. * * This code is released under the GNU General Public License version 2 or * later. @@ -19,44 +19,67 @@ #include #include #include +#include + +struct msg_desc { + struct bau_payload_queue_entry *msg; + int msg_slot; + int sw_ack_slot; + struct bau_payload_queue_entry *va_queue_first; + struct bau_payload_queue_entry *va_queue_last; +}; #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL -static struct bau_control **uv_bau_table_bases __read_mostly; -static int uv_bau_retry_limit __read_mostly; +static int uv_bau_max_concurrent __read_mostly; -/* base pnode in this partition */ -static int uv_partition_base_pnode __read_mostly; +static int nobau; +static int __init setup_nobau(char *arg) +{ + nobau = 1; + return 0; +} +early_param("nobau", setup_nobau); -static unsigned long uv_mmask __read_mostly; +/* base pnode in this partition */ +static int uv_partition_base_pnode __read_mostly; +/* position of pnode (which is nasid>>1): */ +static int uv_nshift __read_mostly; +static unsigned long uv_mmask __read_mostly; static DEFINE_PER_CPU(struct ptc_stats, ptcstats); static DEFINE_PER_CPU(struct bau_control, bau_control); +static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask); + +struct reset_args { + int sender; +}; /* - * Determine the first node on a blade. + * Determine the first node on a uvhub. 'Nodes' are used for kernel + * memory allocation. */ -static int __init blade_to_first_node(int blade) +static int __init uvhub_to_first_node(int uvhub) { int node, b; for_each_online_node(node) { b = uv_node_to_blade_id(node); - if (blade == b) + if (uvhub == b) return node; } - return -1; /* shouldn't happen */ + return -1; } /* - * Determine the apicid of the first cpu on a blade. + * Determine the apicid of the first cpu on a uvhub. */ -static int __init blade_to_first_apicid(int blade) +static int __init uvhub_to_first_apicid(int uvhub) { int cpu; for_each_present_cpu(cpu) - if (blade == uv_cpu_to_blade_id(cpu)) + if (uvhub == uv_cpu_to_blade_id(cpu)) return per_cpu(x86_cpu_to_apicid, cpu); return -1; } @@ -69,195 +92,459 @@ static int __init blade_to_first_apicid(int blade) * clear of the Timeout bit (as well) will free the resource. No reply will * be sent (the hardware will only do one reply per message). */ -static void uv_reply_to_message(int resource, - struct bau_payload_queue_entry *msg, - struct bau_msg_status *msp) +static inline void uv_reply_to_message(struct msg_desc *mdp, + struct bau_control *bcp) { unsigned long dw; + struct bau_payload_queue_entry *msg; - dw = (1 << (resource + UV_SW_ACK_NPENDING)) | (1 << resource); + msg = mdp->msg; + if (!msg->canceled) { + dw = (msg->sw_ack_vector << UV_SW_ACK_NPENDING) | + msg->sw_ack_vector; + uv_write_local_mmr( + UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, dw); + } msg->replied_to = 1; msg->sw_ack_vector = 0; - if (msp) - msp->seen_by.bits = 0; - uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, dw); } /* - * Do all the things a cpu should do for a TLB shootdown message. - * Other cpu's may come here at the same time for this message. + * Process the receipt of a RETRY message */ -static void uv_bau_process_message(struct bau_payload_queue_entry *msg, - int msg_slot, int sw_ack_slot) +static inline void uv_bau_process_retry_msg(struct msg_desc *mdp, + struct bau_control *bcp) { - unsigned long this_cpu_mask; - struct bau_msg_status *msp; - int cpu; + int i; + int cancel_count = 0; + int slot2; + unsigned long msg_res; + unsigned long mmr = 0; + struct bau_payload_queue_entry *msg; + struct bau_payload_queue_entry *msg2; + struct ptc_stats *stat; - msp = __get_cpu_var(bau_control).msg_statuses + msg_slot; - cpu = uv_blade_processor_id(); - msg->number_of_cpus = - uv_blade_nr_online_cpus(uv_node_to_blade_id(numa_node_id())); - this_cpu_mask = 1UL << cpu; - if (msp->seen_by.bits & this_cpu_mask) - return; - atomic_or_long(&msp->seen_by.bits, this_cpu_mask); + msg = mdp->msg; + stat = &per_cpu(ptcstats, bcp->cpu); + stat->d_retries++; + /* + * cancel any message from msg+1 to the retry itself + */ + for (msg2 = msg+1, i = 0; i < DEST_Q_SIZE; msg2++, i++) { + if (msg2 > mdp->va_queue_last) + msg2 = mdp->va_queue_first; + if (msg2 == msg) + break; + + /* same conditions for cancellation as uv_do_reset */ + if ((msg2->replied_to == 0) && (msg2->canceled == 0) && + (msg2->sw_ack_vector) && ((msg2->sw_ack_vector & + msg->sw_ack_vector) == 0) && + (msg2->sending_cpu == msg->sending_cpu) && + (msg2->msg_type != MSG_NOOP)) { + slot2 = msg2 - mdp->va_queue_first; + mmr = uv_read_local_mmr + (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); + msg_res = ((msg2->sw_ack_vector << 8) | + msg2->sw_ack_vector); + /* + * This is a message retry; clear the resources held + * by the previous message only if they timed out. + * If it has not timed out we have an unexpected + * situation to report. + */ + if (mmr & (msg_res << 8)) { + /* + * is the resource timed out? + * make everyone ignore the cancelled message. + */ + msg2->canceled = 1; + stat->d_canceled++; + cancel_count++; + uv_write_local_mmr( + UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, + (msg_res << 8) | msg_res); + } else + printk(KERN_INFO "note bau retry: no effect\n"); + } + } + if (!cancel_count) + stat->d_nocanceled++; +} - if (msg->replied_to == 1) - return; +/* + * Do all the things a cpu should do for a TLB shootdown message. + * Other cpu's may come here at the same time for this message. + */ +static void uv_bau_process_message(struct msg_desc *mdp, + struct bau_control *bcp) +{ + int msg_ack_count; + short socket_ack_count = 0; + struct ptc_stats *stat; + struct bau_payload_queue_entry *msg; + struct bau_control *smaster = bcp->socket_master; + /* + * This must be a normal message, or retry of a normal message + */ + msg = mdp->msg; + stat = &per_cpu(ptcstats, bcp->cpu); if (msg->address == TLB_FLUSH_ALL) { local_flush_tlb(); - __get_cpu_var(ptcstats).alltlb++; + stat->d_alltlb++; } else { __flush_tlb_one(msg->address); - __get_cpu_var(ptcstats).onetlb++; + stat->d_onetlb++; } + stat->d_requestee++; + + /* + * One cpu on each uvhub has the additional job on a RETRY + * of releasing the resource held by the message that is + * being retried. That message is identified by sending + * cpu number. + */ + if (msg->msg_type == MSG_RETRY && bcp == bcp->uvhub_master) + uv_bau_process_retry_msg(mdp, bcp); - __get_cpu_var(ptcstats).requestee++; + /* + * This is a sw_ack message, so we have to reply to it. + * Count each responding cpu on the socket. This avoids + * pinging the count's cache line back and forth between + * the sockets. + */ + socket_ack_count = atomic_add_short_return(1, (struct atomic_short *) + &smaster->socket_acknowledge_count[mdp->msg_slot]); + if (socket_ack_count == bcp->cpus_in_socket) { + /* + * Both sockets dump their completed count total into + * the message's count. + */ + smaster->socket_acknowledge_count[mdp->msg_slot] = 0; + msg_ack_count = atomic_add_short_return(socket_ack_count, + (struct atomic_short *)&msg->acknowledge_count); + + if (msg_ack_count == bcp->cpus_in_uvhub) { + /* + * All cpus in uvhub saw it; reply + */ + uv_reply_to_message(mdp, bcp); + } + } - atomic_inc_short(&msg->acknowledge_count); - if (msg->number_of_cpus == msg->acknowledge_count) - uv_reply_to_message(sw_ack_slot, msg, msp); + return; } /* - * Examine the payload queue on one distribution node to see - * which messages have not been seen, and which cpu(s) have not seen them. + * Determine the first cpu on a uvhub. + */ +static int uvhub_to_first_cpu(int uvhub) +{ + int cpu; + for_each_present_cpu(cpu) + if (uvhub == uv_cpu_to_blade_id(cpu)) + return cpu; + return -1; +} + +/* + * Last resort when we get a large number of destination timeouts is + * to clear resources held by a given cpu. + * Do this with IPI so that all messages in the BAU message queue + * can be identified by their nonzero sw_ack_vector field. * - * Returns the number of cpu's that have not responded. + * This is entered for a single cpu on the uvhub. + * The sender want's this uvhub to free a specific message's + * sw_ack resources. */ -static int uv_examine_destination(struct bau_control *bau_tablesp, int sender) +static void +uv_do_reset(void *ptr) { - struct bau_payload_queue_entry *msg; - struct bau_msg_status *msp; - int count = 0; int i; - int j; + int slot; + int count = 0; + unsigned long mmr; + unsigned long msg_res; + struct bau_control *bcp; + struct reset_args *rap; + struct bau_payload_queue_entry *msg; + struct ptc_stats *stat; - for (msg = bau_tablesp->va_queue_first, i = 0; i < DEST_Q_SIZE; - msg++, i++) { - if ((msg->sending_cpu == sender) && (!msg->replied_to)) { - msp = bau_tablesp->msg_statuses + i; - printk(KERN_DEBUG - "blade %d: address:%#lx %d of %d, not cpu(s): ", - i, msg->address, msg->acknowledge_count, - msg->number_of_cpus); - for (j = 0; j < msg->number_of_cpus; j++) { - if (!((1L << j) & msp->seen_by.bits)) { - count++; - printk("%d ", j); - } + bcp = &per_cpu(bau_control, smp_processor_id()); + rap = (struct reset_args *)ptr; + stat = &per_cpu(ptcstats, bcp->cpu); + stat->d_resets++; + + /* + * We're looking for the given sender, and + * will free its sw_ack resource. + * If all cpu's finally responded after the timeout, its + * message 'replied_to' was set. + */ + for (msg = bcp->va_queue_first, i = 0; i < DEST_Q_SIZE; msg++, i++) { + /* uv_do_reset: same conditions for cancellation as + uv_bau_process_retry_msg() */ + if ((msg->replied_to == 0) && + (msg->canceled == 0) && + (msg->sending_cpu == rap->sender) && + (msg->sw_ack_vector) && + (msg->msg_type != MSG_NOOP)) { + /* + * make everyone else ignore this message + */ + msg->canceled = 1; + slot = msg - bcp->va_queue_first; + count++; + /* + * only reset the resource if it is still pending + */ + mmr = uv_read_local_mmr + (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); + msg_res = ((msg->sw_ack_vector << 8) | + msg->sw_ack_vector); + if (mmr & msg_res) { + stat->d_rcanceled++; + uv_write_local_mmr( + UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, + msg_res); } - printk("\n"); } } - return count; + return; } /* - * Examine the payload queue on all the distribution nodes to see - * which messages have not been seen, and which cpu(s) have not seen them. - * - * Returns the number of cpu's that have not responded. + * Use IPI to get all target uvhubs to release resources held by + * a given sending cpu number. */ -static int uv_examine_destinations(struct bau_target_nodemask *distribution) +static void uv_reset_with_ipi(struct bau_target_uvhubmask *distribution, + int sender) { - int sender; - int i; - int count = 0; + int uvhub; + int cpu; + cpumask_t mask; + struct reset_args reset_args; - sender = smp_processor_id(); - for (i = 0; i < sizeof(struct bau_target_nodemask) * BITSPERBYTE; i++) { - if (!bau_node_isset(i, distribution)) + reset_args.sender = sender; + + cpus_clear(mask); + /* find a single cpu for each uvhub in this distribution mask */ + for (uvhub = 0; + uvhub < sizeof(struct bau_target_uvhubmask) * BITSPERBYTE; + uvhub++) { + if (!bau_uvhub_isset(uvhub, distribution)) continue; - count += uv_examine_destination(uv_bau_table_bases[i], sender); + /* find a cpu for this uvhub */ + cpu = uvhub_to_first_cpu(uvhub); + cpu_set(cpu, mask); } - return count; + /* IPI all cpus; Preemption is already disabled */ + smp_call_function_many(&mask, uv_do_reset, (void *)&reset_args, 1); + return; +} + +static inline unsigned long +cycles_2_us(unsigned long long cyc) +{ + unsigned long long ns; + unsigned long us; + ns = (cyc * per_cpu(cyc2ns, smp_processor_id())) + >> CYC2NS_SCALE_FACTOR; + us = ns / 1000; + return us; } /* - * wait for completion of a broadcast message - * - * return COMPLETE, RETRY or GIVEUP + * wait for all cpus on this hub to finish their sends and go quiet + * leaves uvhub_quiesce set so that no new broadcasts are started by + * bau_flush_send_and_wait() + */ +static inline void +quiesce_local_uvhub(struct bau_control *hmaster) +{ + atomic_add_short_return(1, (struct atomic_short *) + &hmaster->uvhub_quiesce); +} + +/* + * mark this quiet-requestor as done + */ +static inline void +end_uvhub_quiesce(struct bau_control *hmaster) +{ + atomic_add_short_return(-1, (struct atomic_short *) + &hmaster->uvhub_quiesce); +} + +/* + * Wait for completion of a broadcast software ack message + * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP */ static int uv_wait_completion(struct bau_desc *bau_desc, - unsigned long mmr_offset, int right_shift) + unsigned long mmr_offset, int right_shift, int this_cpu, + struct bau_control *bcp, struct bau_control *smaster, long try) { - int exams = 0; - long destination_timeouts = 0; - long source_timeouts = 0; + int relaxes = 0; unsigned long descriptor_status; + unsigned long mmr; + unsigned long mask; + cycles_t ttime; + cycles_t timeout_time; + struct ptc_stats *stat = &per_cpu(ptcstats, this_cpu); + struct bau_control *hmaster; + hmaster = bcp->uvhub_master; + timeout_time = get_cycles() + bcp->timeout_interval; + + /* spin on the status MMR, waiting for it to go idle */ while ((descriptor_status = (((unsigned long) uv_read_local_mmr(mmr_offset) >> right_shift) & UV_ACT_STATUS_MASK)) != DESC_STATUS_IDLE) { - if (descriptor_status == DESC_STATUS_SOURCE_TIMEOUT) { - source_timeouts++; - if (source_timeouts > SOURCE_TIMEOUT_LIMIT) - source_timeouts = 0; - __get_cpu_var(ptcstats).s_retry++; - return FLUSH_RETRY; - } /* - * spin here looking for progress at the destinations + * Our software ack messages may be blocked because there are + * no swack resources available. As long as none of them + * has timed out hardware will NACK our message and its + * state will stay IDLE. */ - if (descriptor_status == DESC_STATUS_DESTINATION_TIMEOUT) { - destination_timeouts++; - if (destination_timeouts > DESTINATION_TIMEOUT_LIMIT) { - /* - * returns number of cpus not responding - */ - if (uv_examine_destinations - (&bau_desc->distribution) == 0) { - __get_cpu_var(ptcstats).d_retry++; - return FLUSH_RETRY; - } - exams++; - if (exams >= uv_bau_retry_limit) { - printk(KERN_DEBUG - "uv_flush_tlb_others"); - printk("giving up on cpu %d\n", - smp_processor_id()); + if (descriptor_status == DESC_STATUS_SOURCE_TIMEOUT) { + stat->s_stimeout++; + return FLUSH_GIVEUP; + } else if (descriptor_status == + DESC_STATUS_DESTINATION_TIMEOUT) { + stat->s_dtimeout++; + ttime = get_cycles(); + + /* + * Our retries may be blocked by all destination + * swack resources being consumed, and a timeout + * pending. In that case hardware returns the + * ERROR that looks like a destination timeout. + */ + if (cycles_2_us(ttime - bcp->send_message) < BIOS_TO) { + bcp->conseccompletes = 0; + return FLUSH_RETRY_PLUGGED; + } + + bcp->conseccompletes = 0; + return FLUSH_RETRY_TIMEOUT; + } else { + /* + * descriptor_status is still BUSY + */ + cpu_relax(); + relaxes++; + if (relaxes >= 10000) { + relaxes = 0; + if (get_cycles() > timeout_time) { + quiesce_local_uvhub(hmaster); + + /* single-thread the register change */ + spin_lock(&hmaster->masks_lock); + mmr = uv_read_local_mmr(mmr_offset); + mask = 0UL; + mask |= (3UL < right_shift); + mask = ~mask; + mmr &= mask; + uv_write_local_mmr(mmr_offset, mmr); + spin_unlock(&hmaster->masks_lock); + end_uvhub_quiesce(hmaster); + stat->s_busy++; return FLUSH_GIVEUP; } - /* - * delays can hang the simulator - udelay(1000); - */ - destination_timeouts = 0; } } - cpu_relax(); } + bcp->conseccompletes++; return FLUSH_COMPLETE; } +static inline cycles_t +sec_2_cycles(unsigned long sec) +{ + unsigned long ns; + cycles_t cyc; + + ns = sec * 1000000000; + cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id())); + return cyc; +} + +/* + * conditionally add 1 to *v, unless *v is >= u + * return 0 if we cannot add 1 to *v because it is >= u + * return 1 if we can add 1 to *v because it is < u + * the add is atomic + * + * This is close to atomic_add_unless(), but this allows the 'u' value + * to be lowered below the current 'v'. atomic_add_unless can only stop + * on equal. + */ +static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) +{ + spin_lock(lock); + if (atomic_read(v) >= u) { + spin_unlock(lock); + return 0; + } + atomic_inc(v); + spin_unlock(lock); + return 1; +} + /** * uv_flush_send_and_wait * - * Send a broadcast and wait for a broadcast message to complete. + * Send a broadcast and wait for it to complete. * - * The flush_mask contains the cpus the broadcast was sent to. + * The flush_mask contains the cpus the broadcast is to be sent to, plus + * cpus that are on the local uvhub. * - * Returns NULL if all remote flushing was done. The mask is zeroed. + * Returns NULL if all flushing represented in the mask was done. The mask + * is zeroed. * Returns @flush_mask if some remote flushing remains to be done. The - * mask will have some bits still set. + * mask will have some bits still set, representing any cpus on the local + * uvhub (not current cpu) and any on remote uvhubs if the broadcast failed. */ -const struct cpumask *uv_flush_send_and_wait(int cpu, int this_pnode, - struct bau_desc *bau_desc, - struct cpumask *flush_mask) +const struct cpumask *uv_flush_send_and_wait(struct bau_desc *bau_desc, + struct cpumask *flush_mask, + struct bau_control *bcp) { - int completion_status = 0; int right_shift; - int tries = 0; - int pnode; + int uvhub; int bit; + int completion_status = 0; + int seq_number = 0; + long try = 0; + int cpu = bcp->uvhub_cpu; + int this_cpu = bcp->cpu; + int this_uvhub = bcp->uvhub; unsigned long mmr_offset; unsigned long index; cycles_t time1; cycles_t time2; + struct ptc_stats *stat = &per_cpu(ptcstats, bcp->cpu); + struct bau_control *smaster = bcp->socket_master; + struct bau_control *hmaster = bcp->uvhub_master; + + /* + * Spin here while there are hmaster->max_concurrent or more active + * descriptors. This is the per-uvhub 'throttle'. + */ + if (!atomic_inc_unless_ge(&hmaster->uvhub_lock, + &hmaster->active_descriptor_count, + hmaster->max_concurrent)) { + stat->s_throttles++; + do { + cpu_relax(); + } while (!atomic_inc_unless_ge(&hmaster->uvhub_lock, + &hmaster->active_descriptor_count, + hmaster->max_concurrent)); + } + + while (hmaster->uvhub_quiesce) + cpu_relax(); if (cpu < UV_CPUS_PER_ACT_STATUS) { mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0; @@ -269,24 +556,108 @@ const struct cpumask *uv_flush_send_and_wait(int cpu, int this_pnode, } time1 = get_cycles(); do { - tries++; + /* + * Every message from any given cpu gets a unique message + * sequence number. But retries use that same number. + * Our message may have timed out at the destination because + * all sw-ack resources are in use and there is a timeout + * pending there. In that case, our last send never got + * placed into the queue and we need to persist until it + * does. + * + * Make any retry a type MSG_RETRY so that the destination will + * free any resource held by a previous message from this cpu. + */ + if (try == 0) { + /* use message type set by the caller the first time */ + seq_number = bcp->message_number++; + } else { + /* use RETRY type on all the rest; same sequence */ + bau_desc->header.msg_type = MSG_RETRY; + stat->s_retry_messages++; + } + bau_desc->header.sequence = seq_number; index = (1UL << UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT) | - cpu; + bcp->uvhub_cpu; + bcp->send_message = get_cycles(); + uv_write_local_mmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index); + + try++; completion_status = uv_wait_completion(bau_desc, mmr_offset, - right_shift); - } while (completion_status == FLUSH_RETRY); + right_shift, this_cpu, bcp, smaster, try); + + if (completion_status == FLUSH_RETRY_PLUGGED) { + /* + * Our retries may be blocked by all destination swack + * resources being consumed, and a timeout pending. In + * that case hardware immediately returns the ERROR + * that looks like a destination timeout. + */ + udelay(TIMEOUT_DELAY); + bcp->plugged_tries++; + if (bcp->plugged_tries >= PLUGSB4RESET) { + bcp->plugged_tries = 0; + quiesce_local_uvhub(hmaster); + spin_lock(&hmaster->queue_lock); + uv_reset_with_ipi(&bau_desc->distribution, + this_cpu); + spin_unlock(&hmaster->queue_lock); + end_uvhub_quiesce(hmaster); + bcp->ipi_attempts++; + stat->s_resets_plug++; + } + } else if (completion_status == FLUSH_RETRY_TIMEOUT) { + hmaster->max_concurrent = 1; + bcp->timeout_tries++; + udelay(TIMEOUT_DELAY); + if (bcp->timeout_tries >= TIMEOUTSB4RESET) { + bcp->timeout_tries = 0; + quiesce_local_uvhub(hmaster); + spin_lock(&hmaster->queue_lock); + uv_reset_with_ipi(&bau_desc->distribution, + this_cpu); + spin_unlock(&hmaster->queue_lock); + end_uvhub_quiesce(hmaster); + bcp->ipi_attempts++; + stat->s_resets_timeout++; + } + } + if (bcp->ipi_attempts >= 3) { + bcp->ipi_attempts = 0; + completion_status = FLUSH_GIVEUP; + break; + } + cpu_relax(); + } while ((completion_status == FLUSH_RETRY_PLUGGED) || + (completion_status == FLUSH_RETRY_TIMEOUT)); time2 = get_cycles(); - __get_cpu_var(ptcstats).sflush += (time2 - time1); - if (tries > 1) - __get_cpu_var(ptcstats).retriesok++; - if (completion_status == FLUSH_GIVEUP) { + if ((completion_status == FLUSH_COMPLETE) && (bcp->conseccompletes > 5) + && (hmaster->max_concurrent < hmaster->max_concurrent_constant)) + hmaster->max_concurrent++; + + /* + * hold any cpu not timing out here; no other cpu currently held by + * the 'throttle' should enter the activation code + */ + while (hmaster->uvhub_quiesce) + cpu_relax(); + atomic_dec(&hmaster->active_descriptor_count); + + /* guard against cycles wrap */ + if (time2 > time1) + stat->s_time += (time2 - time1); + else + stat->s_requestor--; /* don't count this one */ + if (completion_status == FLUSH_COMPLETE && try > 1) + stat->s_retriesok++; + else if (completion_status == FLUSH_GIVEUP) { /* * Cause the caller to do an IPI-style TLB shootdown on - * the cpu's, all of which are still in the mask. + * the target cpu's, all of which are still in the mask. */ - __get_cpu_var(ptcstats).ptc_i++; + stat->s_giveup++; return flush_mask; } @@ -295,18 +666,17 @@ const struct cpumask *uv_flush_send_and_wait(int cpu, int this_pnode, * use the IPI method of shootdown on them. */ for_each_cpu(bit, flush_mask) { - pnode = uv_cpu_to_pnode(bit); - if (pnode == this_pnode) + uvhub = uv_cpu_to_blade_id(bit); + if (uvhub == this_uvhub) continue; cpumask_clear_cpu(bit, flush_mask); } if (!cpumask_empty(flush_mask)) return flush_mask; + return NULL; } -static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask); - /** * uv_flush_tlb_others - globally purge translation cache of a virtual * address or all TLB's @@ -323,8 +693,8 @@ static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask); * The caller has derived the cpumask from the mm_struct. This function * is called only if there are bits set in the mask. (e.g. flush_tlb_page()) * - * The cpumask is converted into a nodemask of the nodes containing - * the cpus. + * The cpumask is converted into a uvhubmask of the uvhubs containing + * those cpus. * * Note that this function should be called with preemption disabled. * @@ -336,52 +706,82 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, unsigned long va, unsigned int cpu) { - struct cpumask *flush_mask = __get_cpu_var(uv_flush_tlb_mask); - int i; - int bit; - int pnode; - int uv_cpu; - int this_pnode; + int remotes; + int tcpu; + int uvhub; int locals = 0; struct bau_desc *bau_desc; + struct cpumask *flush_mask; + struct ptc_stats *stat; + struct bau_control *bcp; - cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); + if (nobau) + return cpumask; - uv_cpu = uv_blade_processor_id(); - this_pnode = uv_hub_info->pnode; - bau_desc = __get_cpu_var(bau_control).descriptor_base; - bau_desc += UV_ITEMS_PER_DESCRIPTOR * uv_cpu; + bcp = &per_cpu(bau_control, cpu); + /* + * Each sending cpu has a per-cpu mask which it fills from the caller's + * cpu mask. Only remote cpus are converted to uvhubs and copied. + */ + flush_mask = (struct cpumask *)per_cpu(uv_flush_tlb_mask, cpu); + /* + * copy cpumask to flush_mask, removing current cpu + * (current cpu should already have been flushed by the caller and + * should never be returned if we return flush_mask) + */ + cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); + if (cpu_isset(cpu, *cpumask)) + locals++; /* current cpu was targeted */ - bau_nodes_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); + bau_desc = bcp->descriptor_base; + bau_desc += UV_ITEMS_PER_DESCRIPTOR * bcp->uvhub_cpu; - i = 0; - for_each_cpu(bit, flush_mask) { - pnode = uv_cpu_to_pnode(bit); - BUG_ON(pnode > (UV_DISTRIBUTION_SIZE - 1)); - if (pnode == this_pnode) { + bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); + remotes = 0; + for_each_cpu(tcpu, flush_mask) { + uvhub = uv_cpu_to_blade_id(tcpu); + if (uvhub == bcp->uvhub) { locals++; continue; } - bau_node_set(pnode - uv_partition_base_pnode, - &bau_desc->distribution); - i++; + bau_uvhub_set(uvhub, &bau_desc->distribution); + remotes++; } - if (i == 0) { + if (remotes == 0) { /* - * no off_node flushing; return status for local node + * No off_hub flushing; return status for local hub. + * Return the caller's mask if all were local (the current + * cpu may be in that mask). */ if (locals) - return flush_mask; + return cpumask; else return NULL; } - __get_cpu_var(ptcstats).requestor++; - __get_cpu_var(ptcstats).ntargeted += i; + stat = &per_cpu(ptcstats, cpu); + stat->s_requestor++; + stat->s_ntargcpu += remotes; + remotes = bau_uvhub_weight(&bau_desc->distribution); + stat->s_ntarguvhub += remotes; + if (remotes >= 16) + stat->s_ntarguvhub16++; + else if (remotes >= 8) + stat->s_ntarguvhub8++; + else if (remotes >= 4) + stat->s_ntarguvhub4++; + else if (remotes >= 2) + stat->s_ntarguvhub2++; + else + stat->s_ntarguvhub1++; bau_desc->payload.address = va; bau_desc->payload.sending_cpu = cpu; - return uv_flush_send_and_wait(uv_cpu, this_pnode, bau_desc, flush_mask); + /* + * uv_flush_send_and_wait returns null if all cpu's were messaged, or + * the adjusted flush_mask if any cpu's were not messaged. + */ + return uv_flush_send_and_wait(bau_desc, flush_mask, bcp); } /* @@ -390,87 +790,70 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, * * We received a broadcast assist message. * - * Interrupts may have been disabled; this interrupt could represent + * Interrupts are disabled; this interrupt could represent * the receipt of several messages. * - * All cores/threads on this node get this interrupt. - * The last one to see it does the s/w ack. + * All cores/threads on this hub get this interrupt. + * The last one to see it does the software ack. * (the resource will not be freed until noninterruptable cpus see this - * interrupt; hardware will timeout the s/w ack and reply ERROR) + * interrupt; hardware may timeout the s/w ack and reply ERROR) */ void uv_bau_message_interrupt(struct pt_regs *regs) { - struct bau_payload_queue_entry *va_queue_first; - struct bau_payload_queue_entry *va_queue_last; - struct bau_payload_queue_entry *msg; - struct pt_regs *old_regs = set_irq_regs(regs); - cycles_t time1; - cycles_t time2; - int msg_slot; - int sw_ack_slot; - int fw; int count = 0; - unsigned long local_pnode; - - ack_APIC_irq(); - exit_idle(); - irq_enter(); - - time1 = get_cycles(); - - local_pnode = uv_blade_to_pnode(uv_numa_blade_id()); - - va_queue_first = __get_cpu_var(bau_control).va_queue_first; - va_queue_last = __get_cpu_var(bau_control).va_queue_last; - - msg = __get_cpu_var(bau_control).bau_msg_head; + cycles_t time_start; + struct bau_payload_queue_entry *msg; + struct bau_control *bcp; + struct ptc_stats *stat; + struct msg_desc msgdesc; + + time_start = get_cycles(); + bcp = &per_cpu(bau_control, smp_processor_id()); + stat = &per_cpu(ptcstats, smp_processor_id()); + msgdesc.va_queue_first = bcp->va_queue_first; + msgdesc.va_queue_last = bcp->va_queue_last; + msg = bcp->bau_msg_head; while (msg->sw_ack_vector) { count++; - fw = msg->sw_ack_vector; - msg_slot = msg - va_queue_first; - sw_ack_slot = ffs(fw) - 1; - - uv_bau_process_message(msg, msg_slot, sw_ack_slot); - + msgdesc.msg_slot = msg - msgdesc.va_queue_first; + msgdesc.sw_ack_slot = ffs(msg->sw_ack_vector) - 1; + msgdesc.msg = msg; + uv_bau_process_message(&msgdesc, bcp); msg++; - if (msg > va_queue_last) - msg = va_queue_first; - __get_cpu_var(bau_control).bau_msg_head = msg; + if (msg > msgdesc.va_queue_last) + msg = msgdesc.va_queue_first; + bcp->bau_msg_head = msg; } + stat->d_time += (get_cycles() - time_start); if (!count) - __get_cpu_var(ptcstats).nomsg++; + stat->d_nomsg++; else if (count > 1) - __get_cpu_var(ptcstats).multmsg++; - - time2 = get_cycles(); - __get_cpu_var(ptcstats).dflush += (time2 - time1); - - irq_exit(); - set_irq_regs(old_regs); + stat->d_multmsg++; + ack_APIC_irq(); } /* * uv_enable_timeouts * - * Each target blade (i.e. blades that have cpu's) needs to have + * Each target uvhub (i.e. a uvhub that has no cpu's) needs to have * shootdown message timeouts enabled. The timeout does not cause * an interrupt, but causes an error message to be returned to * the sender. */ static void uv_enable_timeouts(void) { - int blade; - int nblades; + int uvhub; + int nuvhubs; int pnode; unsigned long mmr_image; - nblades = uv_num_possible_blades(); + nuvhubs = uv_num_possible_blades(); - for (blade = 0; blade < nblades; blade++) { - if (!uv_blade_nr_possible_cpus(blade)) + for (uvhub = 0; uvhub < nuvhubs; uvhub++) { + if (!uv_blade_nr_possible_cpus(uvhub)) continue; - pnode = uv_blade_to_pnode(blade); + pnode = uv_blade_to_pnode(uvhub); mmr_image = uv_read_global_mmr64(pnode, UVH_LB_BAU_MISC_CONTROL); /* @@ -523,9 +906,20 @@ static void uv_ptc_seq_stop(struct seq_file *file, void *data) { } +static inline unsigned long long +millisec_2_cycles(unsigned long millisec) +{ + unsigned long ns; + unsigned long long cyc; + + ns = millisec * 1000; + cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id())); + return cyc; +} + /* - * Display the statistics thru /proc - * data points to the cpu number + * Display the statistics thru /proc. + * 'data' points to the cpu number */ static int uv_ptc_seq_show(struct seq_file *file, void *data) { @@ -536,78 +930,155 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data) if (!cpu) { seq_printf(file, - "# cpu requestor requestee one all sretry dretry ptc_i "); + "# cpu sent stime numuvhubs numuvhubs16 numuvhubs8 "); seq_printf(file, - "sw_ack sflush dflush sok dnomsg dmult starget\n"); + "numuvhubs4 numuvhubs2 numuvhubs1 numcpus dto "); + seq_printf(file, + "retries rok resetp resett giveup sto bz throt "); + seq_printf(file, + "sw_ack recv rtime all "); + seq_printf(file, + "one mult none retry canc nocan reset rcan\n"); } if (cpu < num_possible_cpus() && cpu_online(cpu)) { stat = &per_cpu(ptcstats, cpu); - seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld ", - cpu, stat->requestor, - stat->requestee, stat->onetlb, stat->alltlb, - stat->s_retry, stat->d_retry, stat->ptc_i); - seq_printf(file, "%lx %ld %ld %ld %ld %ld %ld\n", + /* source side statistics */ + seq_printf(file, + "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", + cpu, stat->s_requestor, cycles_2_us(stat->s_time), + stat->s_ntarguvhub, stat->s_ntarguvhub16, + stat->s_ntarguvhub8, stat->s_ntarguvhub4, + stat->s_ntarguvhub2, stat->s_ntarguvhub1, + stat->s_ntargcpu, stat->s_dtimeout); + seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld ", + stat->s_retry_messages, stat->s_retriesok, + stat->s_resets_plug, stat->s_resets_timeout, + stat->s_giveup, stat->s_stimeout, + stat->s_busy, stat->s_throttles); + /* destination side statistics */ + seq_printf(file, + "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", uv_read_global_mmr64(uv_cpu_to_pnode(cpu), UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE), - stat->sflush, stat->dflush, - stat->retriesok, stat->nomsg, - stat->multmsg, stat->ntargeted); + stat->d_requestee, cycles_2_us(stat->d_time), + stat->d_alltlb, stat->d_onetlb, stat->d_multmsg, + stat->d_nomsg, stat->d_retries, stat->d_canceled, + stat->d_nocanceled, stat->d_resets, + stat->d_rcanceled); } return 0; } /* + * -1: resetf the statistics * 0: display meaning of the statistics - * >0: retry limit + * >0: maximum concurrent active descriptors per uvhub (throttle) */ static ssize_t uv_ptc_proc_write(struct file *file, const char __user *user, size_t count, loff_t *data) { - long newmode; + int cpu; + long input_arg; char optstr[64]; + struct ptc_stats *stat; + struct bau_control *bcp; if (count == 0 || count > sizeof(optstr)) return -EINVAL; if (copy_from_user(optstr, user, count)) return -EFAULT; optstr[count - 1] = '\0'; - if (strict_strtoul(optstr, 10, &newmode) < 0) { + if (strict_strtol(optstr, 10, &input_arg) < 0) { printk(KERN_DEBUG "%s is invalid\n", optstr); return -EINVAL; } - if (newmode == 0) { + if (input_arg == 0) { printk(KERN_DEBUG "# cpu: cpu number\n"); + printk(KERN_DEBUG "Sender statistics:\n"); + printk(KERN_DEBUG + "sent: number of shootdown messages sent\n"); + printk(KERN_DEBUG + "stime: time spent sending messages\n"); + printk(KERN_DEBUG + "numuvhubs: number of hubs targeted with shootdown\n"); + printk(KERN_DEBUG + "numuvhubs16: number times 16 or more hubs targeted\n"); + printk(KERN_DEBUG + "numuvhubs8: number times 8 or more hubs targeted\n"); + printk(KERN_DEBUG + "numuvhubs4: number times 4 or more hubs targeted\n"); + printk(KERN_DEBUG + "numuvhubs2: number times 2 or more hubs targeted\n"); + printk(KERN_DEBUG + "numuvhubs1: number times 1 hub targeted\n"); + printk(KERN_DEBUG + "numcpus: number of cpus targeted with shootdown\n"); + printk(KERN_DEBUG + "dto: number of destination timeouts\n"); + printk(KERN_DEBUG + "retries: destination timeout retries sent\n"); + printk(KERN_DEBUG + "rok: : destination timeouts successfully retried\n"); + printk(KERN_DEBUG + "resetp: ipi-style resource resets for plugs\n"); + printk(KERN_DEBUG + "resett: ipi-style resource resets for timeouts\n"); + printk(KERN_DEBUG + "giveup: fall-backs to ipi-style shootdowns\n"); + printk(KERN_DEBUG + "sto: number of source timeouts\n"); + printk(KERN_DEBUG + "bz: number of stay-busy's\n"); + printk(KERN_DEBUG + "throt: number times spun in throttle\n"); + printk(KERN_DEBUG "Destination side statistics:\n"); printk(KERN_DEBUG - "requestor: times this cpu was the flush requestor\n"); + "sw_ack: image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE\n"); printk(KERN_DEBUG - "requestee: times this cpu was requested to flush its TLBs\n"); + "recv: shootdown messages received\n"); printk(KERN_DEBUG - "one: times requested to flush a single address\n"); + "rtime: time spent processing messages\n"); printk(KERN_DEBUG - "all: times requested to flush all TLB's\n"); + "all: shootdown all-tlb messages\n"); printk(KERN_DEBUG - "sretry: number of retries of source-side timeouts\n"); + "one: shootdown one-tlb messages\n"); printk(KERN_DEBUG - "dretry: number of retries of destination-side timeouts\n"); + "mult: interrupts that found multiple messages\n"); printk(KERN_DEBUG - "ptc_i: times UV fell through to IPI-style flushes\n"); + "none: interrupts that found no messages\n"); printk(KERN_DEBUG - "sw_ack: image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE\n"); + "retry: number of retry messages processed\n"); printk(KERN_DEBUG - "sflush_us: cycles spent in uv_flush_tlb_others()\n"); + "canc: number messages canceled by retries\n"); printk(KERN_DEBUG - "dflush_us: cycles spent in handling flush requests\n"); - printk(KERN_DEBUG "sok: successes on retry\n"); - printk(KERN_DEBUG "dnomsg: interrupts with no message\n"); + "nocan: number retries that found nothing to cancel\n"); printk(KERN_DEBUG - "dmult: interrupts with multiple messages\n"); - printk(KERN_DEBUG "starget: nodes targeted\n"); + "reset: number of ipi-style reset requests processed\n"); + printk(KERN_DEBUG + "rcan: number messages canceled by reset requests\n"); + } else if (input_arg == -1) { + for_each_present_cpu(cpu) { + stat = &per_cpu(ptcstats, cpu); + memset(stat, 0, sizeof(struct ptc_stats)); + } } else { - uv_bau_retry_limit = newmode; - printk(KERN_DEBUG "timeout retry limit:%d\n", - uv_bau_retry_limit); + uv_bau_max_concurrent = input_arg; + bcp = &per_cpu(bau_control, smp_processor_id()); + if (uv_bau_max_concurrent < 1 || + uv_bau_max_concurrent > bcp->cpus_in_uvhub) { + printk(KERN_DEBUG + "Error: BAU max concurrent %d; %d is invalid\n", + bcp->max_concurrent, uv_bau_max_concurrent); + return -EINVAL; + } + printk(KERN_DEBUG "Set BAU max concurrent:%d\n", + uv_bau_max_concurrent); + for_each_present_cpu(cpu) { + bcp = &per_cpu(bau_control, cpu); + bcp->max_concurrent = uv_bau_max_concurrent; + } } return count; @@ -650,80 +1121,31 @@ static int __init uv_ptc_init(void) return 0; } -/* - * begin the initialization of the per-blade control structures - */ -static struct bau_control * __init uv_table_bases_init(int blade, int node) -{ - int i; - struct bau_msg_status *msp; - struct bau_control *bau_tabp; - - bau_tabp = - kmalloc_node(sizeof(struct bau_control), GFP_KERNEL, node); - BUG_ON(!bau_tabp); - - bau_tabp->msg_statuses = - kmalloc_node(sizeof(struct bau_msg_status) * - DEST_Q_SIZE, GFP_KERNEL, node); - BUG_ON(!bau_tabp->msg_statuses); - - for (i = 0, msp = bau_tabp->msg_statuses; i < DEST_Q_SIZE; i++, msp++) - bau_cpubits_clear(&msp->seen_by, (int) - uv_blade_nr_possible_cpus(blade)); - - uv_bau_table_bases[blade] = bau_tabp; - - return bau_tabp; -} - -/* - * finish the initialization of the per-blade control structures - */ -static void __init -uv_table_bases_finish(int blade, - struct bau_control *bau_tablesp, - struct bau_desc *adp) -{ - struct bau_control *bcp; - int cpu; - - for_each_present_cpu(cpu) { - if (blade != uv_cpu_to_blade_id(cpu)) - continue; - - bcp = (struct bau_control *)&per_cpu(bau_control, cpu); - bcp->bau_msg_head = bau_tablesp->va_queue_first; - bcp->va_queue_first = bau_tablesp->va_queue_first; - bcp->va_queue_last = bau_tablesp->va_queue_last; - bcp->msg_statuses = bau_tablesp->msg_statuses; - bcp->descriptor_base = adp; - } -} - /* * initialize the sending side's sending buffers */ -static struct bau_desc * __init +static void uv_activation_descriptor_init(int node, int pnode) { int i; + int cpu; unsigned long pa; unsigned long m; unsigned long n; - struct bau_desc *adp; - struct bau_desc *ad2; + struct bau_desc *bau_desc; + struct bau_desc *bd2; + struct bau_control *bcp; /* * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR) - * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per blade + * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per uvhub */ - adp = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)* + bau_desc = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)* UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node); - BUG_ON(!adp); + BUG_ON(!bau_desc); - pa = uv_gpa(adp); /* need the real nasid*/ - n = uv_gpa_to_pnode(pa); + pa = uv_gpa(bau_desc); /* need the real nasid*/ + n = pa >> uv_nshift; m = pa & uv_mmask; uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, @@ -732,96 +1154,188 @@ uv_activation_descriptor_init(int node, int pnode) /* * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each * cpu even though we only use the first one; one descriptor can - * describe a broadcast to 256 nodes. + * describe a broadcast to 256 uv hubs. */ - for (i = 0, ad2 = adp; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR); - i++, ad2++) { - memset(ad2, 0, sizeof(struct bau_desc)); - ad2->header.sw_ack_flag = 1; + for (i = 0, bd2 = bau_desc; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR); + i++, bd2++) { + memset(bd2, 0, sizeof(struct bau_desc)); + bd2->header.sw_ack_flag = 1; /* - * base_dest_nodeid is the first node in the partition, so - * the bit map will indicate partition-relative node numbers. - * note that base_dest_nodeid is actually a nasid. + * base_dest_nodeid is the nasid (pnode<<1) of the first uvhub + * in the partition. The bit map will indicate uvhub numbers, + * which are 0-N in a partition. Pnodes are unique system-wide. */ - ad2->header.base_dest_nodeid = uv_partition_base_pnode << 1; - ad2->header.dest_subnodeid = 0x10; /* the LB */ - ad2->header.command = UV_NET_ENDPOINT_INTD; - ad2->header.int_both = 1; + bd2->header.base_dest_nodeid = uv_partition_base_pnode << 1; + bd2->header.dest_subnodeid = 0x10; /* the LB */ + bd2->header.command = UV_NET_ENDPOINT_INTD; + bd2->header.int_both = 1; /* * all others need to be set to zero: * fairness chaining multilevel count replied_to */ } - return adp; + for_each_present_cpu(cpu) { + if (pnode != uv_blade_to_pnode(uv_cpu_to_blade_id(cpu))) + continue; + bcp = &per_cpu(bau_control, cpu); + bcp->descriptor_base = bau_desc; + } } /* * initialize the destination side's receiving buffers + * entered for each uvhub in the partition + * - node is first node (kernel memory notion) on the uvhub + * - pnode is the uvhub's physical identifier */ -static struct bau_payload_queue_entry * __init -uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp) +static void +uv_payload_queue_init(int node, int pnode) { - struct bau_payload_queue_entry *pqp; - unsigned long pa; int pn; + int cpu; char *cp; + unsigned long pa; + struct bau_payload_queue_entry *pqp; + struct bau_payload_queue_entry *pqp_malloc; + struct bau_control *bcp; pqp = (struct bau_payload_queue_entry *) kmalloc_node( (DEST_Q_SIZE + 1) * sizeof(struct bau_payload_queue_entry), GFP_KERNEL, node); BUG_ON(!pqp); + pqp_malloc = pqp; cp = (char *)pqp + 31; pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5); - bau_tablesp->va_queue_first = pqp; + + for_each_present_cpu(cpu) { + if (pnode != uv_cpu_to_pnode(cpu)) + continue; + /* for every cpu on this pnode: */ + bcp = &per_cpu(bau_control, cpu); + bcp->va_queue_first = pqp; + bcp->bau_msg_head = pqp; + bcp->va_queue_last = pqp + (DEST_Q_SIZE - 1); + } /* * need the pnode of where the memory was really allocated */ pa = uv_gpa(pqp); - pn = uv_gpa_to_pnode(pa); + pn = pa >> uv_nshift; uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) | uv_physnodeaddr(pqp)); uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, uv_physnodeaddr(pqp)); - bau_tablesp->va_queue_last = pqp + (DEST_Q_SIZE - 1); uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST, (unsigned long) - uv_physnodeaddr(bau_tablesp->va_queue_last)); + uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1))); + /* in effect, all msg_type's are set to MSG_NOOP */ memset(pqp, 0, sizeof(struct bau_payload_queue_entry) * DEST_Q_SIZE); - - return pqp; } /* - * Initialization of each UV blade's structures + * Initialization of each UV hub's structures */ -static int __init uv_init_blade(int blade) +static void __init uv_init_uvhub(int uvhub, int vector) { int node; int pnode; - unsigned long pa; unsigned long apicid; - struct bau_desc *adp; - struct bau_payload_queue_entry *pqp; - struct bau_control *bau_tablesp; - - node = blade_to_first_node(blade); - bau_tablesp = uv_table_bases_init(blade, node); - pnode = uv_blade_to_pnode(blade); - adp = uv_activation_descriptor_init(node, pnode); - pqp = uv_payload_queue_init(node, pnode, bau_tablesp); - uv_table_bases_finish(blade, bau_tablesp, adp); + + node = uvhub_to_first_node(uvhub); + pnode = uv_blade_to_pnode(uvhub); + uv_activation_descriptor_init(node, pnode); + uv_payload_queue_init(node, pnode); /* * the below initialization can't be in firmware because the * messaging IRQ will be determined by the OS */ - apicid = blade_to_first_apicid(blade); - pa = uv_read_global_mmr64(pnode, UVH_BAU_DATA_CONFIG); + apicid = uvhub_to_first_apicid(uvhub); uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, - ((apicid << 32) | UV_BAU_MESSAGE)); - return 0; + ((apicid << 32) | vector)); +} + +/* + * initialize the bau_control structure for each cpu + */ +static void uv_init_per_cpu(int nuvhubs) +{ + int i, j, k; + int cpu; + int pnode; + int uvhub; + short socket = 0; + struct bau_control *bcp; + struct uvhub_desc *bdp; + struct socket_desc *sdp; + struct bau_control *hmaster = NULL; + struct bau_control *smaster = NULL; + struct socket_desc { + short num_cpus; + short cpu_number[16]; + }; + struct uvhub_desc { + short num_sockets; + short num_cpus; + short uvhub; + short pnode; + struct socket_desc socket[2]; + }; + struct uvhub_desc *uvhub_descs; + + uvhub_descs = (struct uvhub_desc *) + kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); + memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); + for_each_present_cpu(cpu) { + bcp = &per_cpu(bau_control, cpu); + memset(bcp, 0, sizeof(struct bau_control)); + spin_lock_init(&bcp->masks_lock); + bcp->max_concurrent = uv_bau_max_concurrent; + pnode = uv_cpu_hub_info(cpu)->pnode; + uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; + bdp = &uvhub_descs[uvhub]; + bdp->num_cpus++; + bdp->uvhub = uvhub; + bdp->pnode = pnode; + /* time interval to catch a hardware stay-busy bug */ + bcp->timeout_interval = millisec_2_cycles(3); + /* kludge: assume uv_hub.h is constant */ + socket = (cpu_physical_id(cpu)>>5)&1; + if (socket >= bdp->num_sockets) + bdp->num_sockets = socket+1; + sdp = &bdp->socket[socket]; + sdp->cpu_number[sdp->num_cpus] = cpu; + sdp->num_cpus++; + } + socket = 0; + for_each_possible_blade(uvhub) { + bdp = &uvhub_descs[uvhub]; + for (i = 0; i < bdp->num_sockets; i++) { + sdp = &bdp->socket[i]; + for (j = 0; j < sdp->num_cpus; j++) { + cpu = sdp->cpu_number[j]; + bcp = &per_cpu(bau_control, cpu); + bcp->cpu = cpu; + if (j == 0) { + smaster = bcp; + if (i == 0) + hmaster = bcp; + } + bcp->cpus_in_uvhub = bdp->num_cpus; + bcp->cpus_in_socket = sdp->num_cpus; + bcp->socket_master = smaster; + bcp->uvhub_master = hmaster; + for (k = 0; k < DEST_Q_SIZE; k++) + bcp->socket_acknowledge_count[k] = 0; + bcp->uvhub_cpu = + uv_cpu_hub_info(cpu)->blade_processor_id; + } + socket++; + } + } + kfree(uvhub_descs); } /* @@ -829,38 +1343,54 @@ static int __init uv_init_blade(int blade) */ static int __init uv_bau_init(void) { - int blade; - int nblades; + int uvhub; + int pnode; + int nuvhubs; int cur_cpu; + int vector; + unsigned long mmr; if (!is_uv_system()) return 0; + if (nobau) + return 0; + for_each_possible_cpu(cur_cpu) zalloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu), GFP_KERNEL, cpu_to_node(cur_cpu)); - uv_bau_retry_limit = 1; + uv_bau_max_concurrent = MAX_BAU_CONCURRENT; + uv_nshift = uv_hub_info->m_val; uv_mmask = (1UL << uv_hub_info->m_val) - 1; - nblades = uv_num_possible_blades(); + nuvhubs = uv_num_possible_blades(); - uv_bau_table_bases = (struct bau_control **) - kmalloc(nblades * sizeof(struct bau_control *), GFP_KERNEL); - BUG_ON(!uv_bau_table_bases); + uv_init_per_cpu(nuvhubs); uv_partition_base_pnode = 0x7fffffff; - for (blade = 0; blade < nblades; blade++) - if (uv_blade_nr_possible_cpus(blade) && - (uv_blade_to_pnode(blade) < uv_partition_base_pnode)) - uv_partition_base_pnode = uv_blade_to_pnode(blade); - for (blade = 0; blade < nblades; blade++) - if (uv_blade_nr_possible_cpus(blade)) - uv_init_blade(blade); - - alloc_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1); + for (uvhub = 0; uvhub < nuvhubs; uvhub++) + if (uv_blade_nr_possible_cpus(uvhub) && + (uv_blade_to_pnode(uvhub) < uv_partition_base_pnode)) + uv_partition_base_pnode = uv_blade_to_pnode(uvhub); + + vector = UV_BAU_MESSAGE; + for_each_possible_blade(uvhub) + if (uv_blade_nr_possible_cpus(uvhub)) + uv_init_uvhub(uvhub, vector); + uv_enable_timeouts(); + alloc_intr_gate(vector, uv_bau_message_intr1); + + for_each_possible_blade(uvhub) { + pnode = uv_blade_to_pnode(uvhub); + /* INIT the bau */ + uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_ACTIVATION_CONTROL, + ((unsigned long)1 << 63)); + mmr = 1; /* should be 1 to broadcast to both sockets */ + uv_write_global_mmr64(pnode, UVH_BAU_DATA_BROADCAST, mmr); + } return 0; } -__initcall(uv_bau_init); -__initcall(uv_ptc_init); +core_initcall(uv_bau_init); +core_initcall(uv_ptc_init); -- cgit v1.2.3-59-g8ed1b From 8d318a50b3d72e3daf94131f91e1ab799a8d5ad4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 30 Mar 2010 15:33:42 +0200 Subject: DMAENGINE: Support for ST-Ericssons DMA40 block v3 This is a straightforward driver for the ST-Ericsson DMA40 DMA controller found in U8500, implemented akin to the existing COH 901 318 driver. Signed-off-by: Linus Walleij Acked-by: Srinidh Kasagar Cc: STEricsson_nomadik_linux@list.st.com Cc: Alessandro Rubini Signed-off-by: Andrew Morton Signed-off-by: Dan Williams --- arch/arm/plat-nomadik/include/plat/ste_dma40.h | 239 +++ drivers/dma/Kconfig | 7 + drivers/dma/Makefile | 1 + drivers/dma/ste_dma40.c | 2596 ++++++++++++++++++++++++ drivers/dma/ste_dma40_ll.c | 454 +++++ drivers/dma/ste_dma40_ll.h | 354 ++++ 6 files changed, 3651 insertions(+) create mode 100644 arch/arm/plat-nomadik/include/plat/ste_dma40.h create mode 100644 drivers/dma/ste_dma40.c create mode 100644 drivers/dma/ste_dma40_ll.c create mode 100644 drivers/dma/ste_dma40_ll.h (limited to 'arch') diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h new file mode 100644 index 000000000000..4d12ea4ca361 --- /dev/null +++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h @@ -0,0 +1,239 @@ +/* + * arch/arm/plat-nomadik/include/plat/ste_dma40.h + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + */ + + +#ifndef STE_DMA40_H +#define STE_DMA40_H + +#include +#include +#include +#include + +/* dev types for memcpy */ +#define STEDMA40_DEV_DST_MEMORY (-1) +#define STEDMA40_DEV_SRC_MEMORY (-1) + +/* + * Description of bitfields of channel_type variable is available in + * the info structure. + */ + +/* Priority */ +#define STEDMA40_INFO_PRIO_TYPE_POS 2 +#define STEDMA40_HIGH_PRIORITY_CHANNEL (0x1 << STEDMA40_INFO_PRIO_TYPE_POS) +#define STEDMA40_LOW_PRIORITY_CHANNEL (0x2 << STEDMA40_INFO_PRIO_TYPE_POS) + +/* Mode */ +#define STEDMA40_INFO_CH_MODE_TYPE_POS 6 +#define STEDMA40_CHANNEL_IN_PHY_MODE (0x1 << STEDMA40_INFO_CH_MODE_TYPE_POS) +#define STEDMA40_CHANNEL_IN_LOG_MODE (0x2 << STEDMA40_INFO_CH_MODE_TYPE_POS) +#define STEDMA40_CHANNEL_IN_OPER_MODE (0x3 << STEDMA40_INFO_CH_MODE_TYPE_POS) + +/* Mode options */ +#define STEDMA40_INFO_CH_MODE_OPT_POS 8 +#define STEDMA40_PCHAN_BASIC_MODE (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_PCHAN_MODULO_MODE (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_PCHAN_DOUBLE_DST_MODE (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_LCHAN_SRC_PHY_DST_LOG (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_LCHAN_SRC_LOG_DST_PHS (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_LCHAN_SRC_LOG_DST_LOG (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS) + +/* Interrupt */ +#define STEDMA40_INFO_TIM_POS 10 +#define STEDMA40_NO_TIM_FOR_LINK (0x0 << STEDMA40_INFO_TIM_POS) +#define STEDMA40_TIM_FOR_LINK (0x1 << STEDMA40_INFO_TIM_POS) + +/* End of channel_type configuration */ + +#define STEDMA40_ESIZE_8_BIT 0x0 +#define STEDMA40_ESIZE_16_BIT 0x1 +#define STEDMA40_ESIZE_32_BIT 0x2 +#define STEDMA40_ESIZE_64_BIT 0x3 + +/* The value 4 indicates that PEN-reg shall be set to 0 */ +#define STEDMA40_PSIZE_PHY_1 0x4 +#define STEDMA40_PSIZE_PHY_2 0x0 +#define STEDMA40_PSIZE_PHY_4 0x1 +#define STEDMA40_PSIZE_PHY_8 0x2 +#define STEDMA40_PSIZE_PHY_16 0x3 + +/* + * The number of elements differ in logical and + * physical mode + */ +#define STEDMA40_PSIZE_LOG_1 STEDMA40_PSIZE_PHY_2 +#define STEDMA40_PSIZE_LOG_4 STEDMA40_PSIZE_PHY_4 +#define STEDMA40_PSIZE_LOG_8 STEDMA40_PSIZE_PHY_8 +#define STEDMA40_PSIZE_LOG_16 STEDMA40_PSIZE_PHY_16 + +enum stedma40_flow_ctrl { + STEDMA40_NO_FLOW_CTRL, + STEDMA40_FLOW_CTRL, +}; + +enum stedma40_endianess { + STEDMA40_LITTLE_ENDIAN, + STEDMA40_BIG_ENDIAN +}; + +enum stedma40_periph_data_width { + STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT, + STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT, + STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT, + STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT +}; + +struct stedma40_half_channel_info { + enum stedma40_endianess endianess; + enum stedma40_periph_data_width data_width; + int psize; + enum stedma40_flow_ctrl flow_ctrl; +}; + +enum stedma40_xfer_dir { + STEDMA40_MEM_TO_MEM, + STEDMA40_MEM_TO_PERIPH, + STEDMA40_PERIPH_TO_MEM, + STEDMA40_PERIPH_TO_PERIPH +}; + + +/** + * struct stedma40_chan_cfg - Structure to be filled by client drivers. + * + * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH + * @channel_type: priority, mode, mode options and interrupt configuration. + * @src_dev_type: Src device type + * @dst_dev_type: Dst device type + * @src_info: Parameters for dst half channel + * @dst_info: Parameters for dst half channel + * @pre_transfer_data: Data to be passed on to the pre_transfer() function. + * @pre_transfer: Callback used if needed before preparation of transfer. + * Only called if device is set. size of bytes to transfer + * (in case of multiple element transfer size is size of the first element). + * + * + * This structure has to be filled by the client drivers. + * It is recommended to do all dma configurations for clients in the machine. + * + */ +struct stedma40_chan_cfg { + enum stedma40_xfer_dir dir; + unsigned int channel_type; + int src_dev_type; + int dst_dev_type; + struct stedma40_half_channel_info src_info; + struct stedma40_half_channel_info dst_info; + void *pre_transfer_data; + int (*pre_transfer) (struct dma_chan *chan, + void *data, + int size); +}; + +/** + * struct stedma40_platform_data - Configuration struct for the dma device. + * + * @dev_len: length of dev_tx and dev_rx + * @dev_tx: mapping between destination event line and io address + * @dev_rx: mapping between source event line and io address + * @memcpy: list of memcpy event lines + * @memcpy_len: length of memcpy + * @memcpy_conf_phy: default configuration of physical channel memcpy + * @memcpy_conf_log: default configuration of logical channel memcpy + * @llis_per_log: number of max linked list items per logical channel + * + */ +struct stedma40_platform_data { + u32 dev_len; + const dma_addr_t *dev_tx; + const dma_addr_t *dev_rx; + int *memcpy; + u32 memcpy_len; + struct stedma40_chan_cfg *memcpy_conf_phy; + struct stedma40_chan_cfg *memcpy_conf_log; + unsigned int llis_per_log; +}; + +/** + * setdma40_set_psize() - Used for changing the package size of an + * already configured dma channel. + * + * @chan: dmaengine handle + * @src_psize: new package side for src. (STEDMA40_PSIZE*) + * @src_psize: new package side for dst. (STEDMA40_PSIZE*) + * + * returns 0 on ok, otherwise negative error number. + */ +int stedma40_set_psize(struct dma_chan *chan, + int src_psize, + int dst_psize); + +/** + * stedma40_filter() - Provides stedma40_chan_cfg to the + * ste_dma40 dma driver via the dmaengine framework. + * does some checking of what's provided. + * + * Never directly called by client. It used by dmaengine. + * @chan: dmaengine handle. + * @data: Must be of type: struct stedma40_chan_cfg and is + * the configuration of the framework. + * + * + */ + +bool stedma40_filter(struct dma_chan *chan, void *data); + +/** + * stedma40_memcpy_sg() - extension of the dma framework, memcpy to/from + * scattergatter lists. + * + * @chan: dmaengine handle + * @sgl_dst: Destination scatter list + * @sgl_src: Source scatter list + * @sgl_len: The length of each scatterlist. Both lists must be of equal length + * and each element must match the corresponding element in the other scatter + * list. + * @flags: is actually enum dma_ctrl_flags. See dmaengine.h + */ + +struct dma_async_tx_descriptor *stedma40_memcpy_sg(struct dma_chan *chan, + struct scatterlist *sgl_dst, + struct scatterlist *sgl_src, + unsigned int sgl_len, + unsigned long flags); + +/** + * stedma40_slave_mem() - Transfers a raw data buffer to or from a slave + * (=device) + * + * @chan: dmaengine handle + * @addr: source or destination physicall address. + * @size: bytes to transfer + * @direction: direction of transfer + * @flags: is actually enum dma_ctrl_flags. See dmaengine.h + */ + +static inline struct +dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, + dma_addr_t addr, + unsigned int size, + enum dma_data_direction direction, + unsigned long flags) +{ + struct scatterlist sg; + sg_init_table(&sg, 1); + sg.dma_address = addr; + sg.length = size; + + return chan->device->device_prep_slave_sg(chan, &sg, 1, + direction, flags); +} + +#endif diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index a2fcb2ead892..1b8877922fb0 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -141,6 +141,13 @@ config COH901318 help Enable support for ST-Ericsson COH 901 318 DMA. +config STE_DMA40 + bool "ST-Ericsson DMA40 support" + depends on ARCH_U8500 + select DMA_ENGINE + help + Support for ST-Ericsson DMA40 controller + config AMCC_PPC440SPE_ADMA tristate "AMCC PPC440SPe ADMA support" depends on 440SPe || 440SP diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 40c627d8f73b..20881426c1ac 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_SH_DMAE) += shdma.o obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/ obj-$(CONFIG_TIMB_DMA) += timb_dma.o +obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c new file mode 100644 index 000000000000..e4295a27672b --- /dev/null +++ b/drivers/dma/ste_dma40.c @@ -0,0 +1,2596 @@ +/* + * driver/dma/ste_dma40.c + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "ste_dma40_ll.h" + +#define D40_NAME "dma40" + +#define D40_PHY_CHAN -1 + +/* For masking out/in 2 bit channel positions */ +#define D40_CHAN_POS(chan) (2 * (chan / 2)) +#define D40_CHAN_POS_MASK(chan) (0x3 << D40_CHAN_POS(chan)) + +/* Maximum iterations taken before giving up suspending a channel */ +#define D40_SUSPEND_MAX_IT 500 + +#define D40_ALLOC_FREE (1 << 31) +#define D40_ALLOC_PHY (1 << 30) +#define D40_ALLOC_LOG_FREE 0 + +/* The number of free d40_desc to keep in memory before starting + * to kfree() them */ +#define D40_DESC_CACHE_SIZE 50 + +/* Hardware designer of the block */ +#define D40_PERIPHID2_DESIGNER 0x8 + +/** + * enum 40_command - The different commands and/or statuses. + * + * @D40_DMA_STOP: DMA channel command STOP or status STOPPED, + * @D40_DMA_RUN: The DMA channel is RUNNING of the command RUN. + * @D40_DMA_SUSPEND_REQ: Request the DMA to SUSPEND as soon as possible. + * @D40_DMA_SUSPENDED: The DMA channel is SUSPENDED. + */ +enum d40_command { + D40_DMA_STOP = 0, + D40_DMA_RUN = 1, + D40_DMA_SUSPEND_REQ = 2, + D40_DMA_SUSPENDED = 3 +}; + +/** + * struct d40_lli_pool - Structure for keeping LLIs in memory + * + * @base: Pointer to memory area when the pre_alloc_lli's are not large + * enough, IE bigger than the most common case, 1 dst and 1 src. NULL if + * pre_alloc_lli is used. + * @size: The size in bytes of the memory at base or the size of pre_alloc_lli. + * @pre_alloc_lli: Pre allocated area for the most common case of transfers, + * one buffer to one buffer. + */ +struct d40_lli_pool { + void *base; + int size; + /* Space for dst and src, plus an extra for padding */ + u8 pre_alloc_lli[3 * sizeof(struct d40_phy_lli)]; +}; + +/** + * struct d40_desc - A descriptor is one DMA job. + * + * @lli_phy: LLI settings for physical channel. Both src and dst= + * points into the lli_pool, to base if lli_len > 1 or to pre_alloc_lli if + * lli_len equals one. + * @lli_log: Same as above but for logical channels. + * @lli_pool: The pool with two entries pre-allocated. + * @lli_len: Number of LLI's in lli_pool + * @lli_tcount: Number of LLIs processed in the transfer. When equals lli_len + * then this transfer job is done. + * @txd: DMA engine struct. Used for among other things for communication + * during a transfer. + * @node: List entry. + * @dir: The transfer direction of this job. + * @is_in_client_list: true if the client owns this descriptor. + * + * This descriptor is used for both logical and physical transfers. + */ + +struct d40_desc { + /* LLI physical */ + struct d40_phy_lli_bidir lli_phy; + /* LLI logical */ + struct d40_log_lli_bidir lli_log; + + struct d40_lli_pool lli_pool; + u32 lli_len; + u32 lli_tcount; + + struct dma_async_tx_descriptor txd; + struct list_head node; + + enum dma_data_direction dir; + bool is_in_client_list; +}; + +/** + * struct d40_lcla_pool - LCLA pool settings and data. + * + * @base: The virtual address of LCLA. + * @phy: Physical base address of LCLA. + * @base_size: size of lcla. + * @lock: Lock to protect the content in this struct. + * @alloc_map: Mapping between physical channel and LCLA entries. + * @num_blocks: The number of entries of alloc_map. Equals to the + * number of physical channels. + */ +struct d40_lcla_pool { + void *base; + dma_addr_t phy; + resource_size_t base_size; + spinlock_t lock; + u32 *alloc_map; + int num_blocks; +}; + +/** + * struct d40_phy_res - struct for handling eventlines mapped to physical + * channels. + * + * @lock: A lock protection this entity. + * @num: The physical channel number of this entity. + * @allocated_src: Bit mapped to show which src event line's are mapped to + * this physical channel. Can also be free or physically allocated. + * @allocated_dst: Same as for src but is dst. + * allocated_dst and allocated_src uses the D40_ALLOC* defines as well as + * event line number. Both allocated_src and allocated_dst can not be + * allocated to a physical channel, since the interrupt handler has then + * no way of figure out which one the interrupt belongs to. + */ +struct d40_phy_res { + spinlock_t lock; + int num; + u32 allocated_src; + u32 allocated_dst; +}; + +struct d40_base; + +/** + * struct d40_chan - Struct that describes a channel. + * + * @lock: A spinlock to protect this struct. + * @log_num: The logical number, if any of this channel. + * @completed: Starts with 1, after first interrupt it is set to dma engine's + * current cookie. + * @pending_tx: The number of pending transfers. Used between interrupt handler + * and tasklet. + * @busy: Set to true when transfer is ongoing on this channel. + * @phy_chan: Pointer to physical channel which this instance runs on. + * @chan: DMA engine handle. + * @tasklet: Tasklet that gets scheduled from interrupt context to complete a + * transfer and call client callback. + * @client: Cliented owned descriptor list. + * @active: Active descriptor. + * @queue: Queued jobs. + * @free: List of free descripts, ready to be reused. + * @free_len: Number of descriptors in the free list. + * @dma_cfg: The client configuration of this dma channel. + * @base: Pointer to the device instance struct. + * @src_def_cfg: Default cfg register setting for src. + * @dst_def_cfg: Default cfg register setting for dst. + * @log_def: Default logical channel settings. + * @lcla: Space for one dst src pair for logical channel transfers. + * @lcpa: Pointer to dst and src lcpa settings. + * + * This struct can either "be" a logical or a physical channel. + */ +struct d40_chan { + spinlock_t lock; + int log_num; + /* ID of the most recent completed transfer */ + int completed; + int pending_tx; + bool busy; + struct d40_phy_res *phy_chan; + struct dma_chan chan; + struct tasklet_struct tasklet; + struct list_head client; + struct list_head active; + struct list_head queue; + struct list_head free; + int free_len; + struct stedma40_chan_cfg dma_cfg; + struct d40_base *base; + /* Default register configurations */ + u32 src_def_cfg; + u32 dst_def_cfg; + struct d40_def_lcsp log_def; + struct d40_lcla_elem lcla; + struct d40_log_lli_full *lcpa; +}; + +/** + * struct d40_base - The big global struct, one for each probe'd instance. + * + * @interrupt_lock: Lock used to make sure one interrupt is handle a time. + * @execmd_lock: Lock for execute command usage since several channels share + * the same physical register. + * @dev: The device structure. + * @virtbase: The virtual base address of the DMA's register. + * @clk: Pointer to the DMA clock structure. + * @phy_start: Physical memory start of the DMA registers. + * @phy_size: Size of the DMA register map. + * @irq: The IRQ number. + * @num_phy_chans: The number of physical channels. Read from HW. This + * is the number of available channels for this driver, not counting "Secure + * mode" allocated physical channels. + * @num_log_chans: The number of logical channels. Calculated from + * num_phy_chans. + * @dma_both: dma_device channels that can do both memcpy and slave transfers. + * @dma_slave: dma_device channels that can do only do slave transfers. + * @dma_memcpy: dma_device channels that can do only do memcpy transfers. + * @phy_chans: Room for all possible physical channels in system. + * @log_chans: Room for all possible logical channels in system. + * @lookup_log_chans: Used to map interrupt number to logical channel. Points + * to log_chans entries. + * @lookup_phy_chans: Used to map interrupt number to physical channel. Points + * to phy_chans entries. + * @plat_data: Pointer to provided platform_data which is the driver + * configuration. + * @phy_res: Vector containing all physical channels. + * @lcla_pool: lcla pool settings and data. + * @lcpa_base: The virtual mapped address of LCPA. + * @phy_lcpa: The physical address of the LCPA. + * @lcpa_size: The size of the LCPA area. + */ +struct d40_base { + spinlock_t interrupt_lock; + spinlock_t execmd_lock; + struct device *dev; + void __iomem *virtbase; + struct clk *clk; + phys_addr_t phy_start; + resource_size_t phy_size; + int irq; + int num_phy_chans; + int num_log_chans; + struct dma_device dma_both; + struct dma_device dma_slave; + struct dma_device dma_memcpy; + struct d40_chan *phy_chans; + struct d40_chan *log_chans; + struct d40_chan **lookup_log_chans; + struct d40_chan **lookup_phy_chans; + struct stedma40_platform_data *plat_data; + /* Physical half channels */ + struct d40_phy_res *phy_res; + struct d40_lcla_pool lcla_pool; + void *lcpa_base; + dma_addr_t phy_lcpa; + resource_size_t lcpa_size; +}; + +/** + * struct d40_interrupt_lookup - lookup table for interrupt handler + * + * @src: Interrupt mask register. + * @clr: Interrupt clear register. + * @is_error: true if this is an error interrupt. + * @offset: start delta in the lookup_log_chans in d40_base. If equals to + * D40_PHY_CHAN, the lookup_phy_chans shall be used instead. + */ +struct d40_interrupt_lookup { + u32 src; + u32 clr; + bool is_error; + int offset; +}; + +/** + * struct d40_reg_val - simple lookup struct + * + * @reg: The register. + * @val: The value that belongs to the register in reg. + */ +struct d40_reg_val { + unsigned int reg; + unsigned int val; +}; + +static int d40_pool_lli_alloc(struct d40_desc *d40d, + int lli_len, bool is_log) +{ + u32 align; + void *base; + + if (is_log) + align = sizeof(struct d40_log_lli); + else + align = sizeof(struct d40_phy_lli); + + if (lli_len == 1) { + base = d40d->lli_pool.pre_alloc_lli; + d40d->lli_pool.size = sizeof(d40d->lli_pool.pre_alloc_lli); + d40d->lli_pool.base = NULL; + } else { + d40d->lli_pool.size = ALIGN(lli_len * 2 * align, align); + + base = kmalloc(d40d->lli_pool.size + align, GFP_NOWAIT); + d40d->lli_pool.base = base; + + if (d40d->lli_pool.base == NULL) + return -ENOMEM; + } + + if (is_log) { + d40d->lli_log.src = PTR_ALIGN((struct d40_log_lli *) base, + align); + d40d->lli_log.dst = PTR_ALIGN(d40d->lli_log.src + lli_len, + align); + } else { + d40d->lli_phy.src = PTR_ALIGN((struct d40_phy_lli *)base, + align); + d40d->lli_phy.dst = PTR_ALIGN(d40d->lli_phy.src + lli_len, + align); + + d40d->lli_phy.src_addr = virt_to_phys(d40d->lli_phy.src); + d40d->lli_phy.dst_addr = virt_to_phys(d40d->lli_phy.dst); + } + + return 0; +} + +static void d40_pool_lli_free(struct d40_desc *d40d) +{ + kfree(d40d->lli_pool.base); + d40d->lli_pool.base = NULL; + d40d->lli_pool.size = 0; + d40d->lli_log.src = NULL; + d40d->lli_log.dst = NULL; + d40d->lli_phy.src = NULL; + d40d->lli_phy.dst = NULL; + d40d->lli_phy.src_addr = 0; + d40d->lli_phy.dst_addr = 0; +} + +static dma_cookie_t d40_assign_cookie(struct d40_chan *d40c, + struct d40_desc *desc) +{ + dma_cookie_t cookie = d40c->chan.cookie; + + if (++cookie < 0) + cookie = 1; + + d40c->chan.cookie = cookie; + desc->txd.cookie = cookie; + + return cookie; +} + +static void d40_desc_reset(struct d40_desc *d40d) +{ + d40d->lli_tcount = 0; +} + +static void d40_desc_remove(struct d40_desc *d40d) +{ + list_del(&d40d->node); +} + +static struct d40_desc *d40_desc_get(struct d40_chan *d40c) +{ + struct d40_desc *desc; + struct d40_desc *d; + struct d40_desc *_d; + + if (!list_empty(&d40c->client)) { + list_for_each_entry_safe(d, _d, &d40c->client, node) + if (async_tx_test_ack(&d->txd)) { + d40_pool_lli_free(d); + d40_desc_remove(d); + desc = d; + goto out; + } + } + + if (list_empty(&d40c->free)) { + /* Alloc new desc because we're out of used ones */ + desc = kzalloc(sizeof(struct d40_desc), GFP_NOWAIT); + if (desc == NULL) + goto out; + INIT_LIST_HEAD(&desc->node); + } else { + /* Reuse an old desc. */ + desc = list_first_entry(&d40c->free, + struct d40_desc, + node); + list_del(&desc->node); + d40c->free_len--; + } +out: + return desc; +} + +static void d40_desc_free(struct d40_chan *d40c, struct d40_desc *d40d) +{ + if (d40c->free_len < D40_DESC_CACHE_SIZE) { + list_add_tail(&d40d->node, &d40c->free); + d40c->free_len++; + } else + kfree(d40d); +} + +static void d40_desc_submit(struct d40_chan *d40c, struct d40_desc *desc) +{ + list_add_tail(&desc->node, &d40c->active); +} + +static struct d40_desc *d40_first_active_get(struct d40_chan *d40c) +{ + struct d40_desc *d; + + if (list_empty(&d40c->active)) + return NULL; + + d = list_first_entry(&d40c->active, + struct d40_desc, + node); + return d; +} + +static void d40_desc_queue(struct d40_chan *d40c, struct d40_desc *desc) +{ + list_add_tail(&desc->node, &d40c->queue); +} + +static struct d40_desc *d40_first_queued(struct d40_chan *d40c) +{ + struct d40_desc *d; + + if (list_empty(&d40c->queue)) + return NULL; + + d = list_first_entry(&d40c->queue, + struct d40_desc, + node); + return d; +} + +/* Support functions for logical channels */ + +static int d40_lcla_id_get(struct d40_chan *d40c, + struct d40_lcla_pool *pool) +{ + int src_id = 0; + int dst_id = 0; + struct d40_log_lli *lcla_lidx_base = + pool->base + d40c->phy_chan->num * 1024; + int i; + int lli_per_log = d40c->base->plat_data->llis_per_log; + + if (d40c->lcla.src_id >= 0 && d40c->lcla.dst_id >= 0) + return 0; + + if (pool->num_blocks > 32) + return -EINVAL; + + spin_lock(&pool->lock); + + for (i = 0; i < pool->num_blocks; i++) { + if (!(pool->alloc_map[d40c->phy_chan->num] & (0x1 << i))) { + pool->alloc_map[d40c->phy_chan->num] |= (0x1 << i); + break; + } + } + src_id = i; + if (src_id >= pool->num_blocks) + goto err; + + for (; i < pool->num_blocks; i++) { + if (!(pool->alloc_map[d40c->phy_chan->num] & (0x1 << i))) { + pool->alloc_map[d40c->phy_chan->num] |= (0x1 << i); + break; + } + } + + dst_id = i; + if (dst_id == src_id) + goto err; + + d40c->lcla.src_id = src_id; + d40c->lcla.dst_id = dst_id; + d40c->lcla.dst = lcla_lidx_base + dst_id * lli_per_log + 1; + d40c->lcla.src = lcla_lidx_base + src_id * lli_per_log + 1; + + + spin_unlock(&pool->lock); + return 0; +err: + spin_unlock(&pool->lock); + return -EINVAL; +} + +static void d40_lcla_id_put(struct d40_chan *d40c, + struct d40_lcla_pool *pool, + int id) +{ + if (id < 0) + return; + + d40c->lcla.src_id = -1; + d40c->lcla.dst_id = -1; + + spin_lock(&pool->lock); + pool->alloc_map[d40c->phy_chan->num] &= (~(0x1 << id)); + spin_unlock(&pool->lock); +} + +static int d40_channel_execute_command(struct d40_chan *d40c, + enum d40_command command) +{ + int status, i; + void __iomem *active_reg; + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&d40c->base->execmd_lock, flags); + + if (d40c->phy_chan->num % 2 == 0) + active_reg = d40c->base->virtbase + D40_DREG_ACTIVE; + else + active_reg = d40c->base->virtbase + D40_DREG_ACTIVO; + + if (command == D40_DMA_SUSPEND_REQ) { + status = (readl(active_reg) & + D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> + D40_CHAN_POS(d40c->phy_chan->num); + + if (status == D40_DMA_SUSPENDED || status == D40_DMA_STOP) + goto done; + } + + writel(command << D40_CHAN_POS(d40c->phy_chan->num), active_reg); + + if (command == D40_DMA_SUSPEND_REQ) { + + for (i = 0 ; i < D40_SUSPEND_MAX_IT; i++) { + status = (readl(active_reg) & + D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> + D40_CHAN_POS(d40c->phy_chan->num); + + cpu_relax(); + /* + * Reduce the number of bus accesses while + * waiting for the DMA to suspend. + */ + udelay(3); + + if (status == D40_DMA_STOP || + status == D40_DMA_SUSPENDED) + break; + } + + if (i == D40_SUSPEND_MAX_IT) { + dev_err(&d40c->chan.dev->device, + "[%s]: unable to suspend the chl %d (log: %d) status %x\n", + __func__, d40c->phy_chan->num, d40c->log_num, + status); + dump_stack(); + ret = -EBUSY; + } + + } +done: + spin_unlock_irqrestore(&d40c->base->execmd_lock, flags); + return ret; +} + +static void d40_term_all(struct d40_chan *d40c) +{ + struct d40_desc *d40d; + struct d40_desc *d; + struct d40_desc *_d; + + /* Release active descriptors */ + while ((d40d = d40_first_active_get(d40c))) { + d40_desc_remove(d40d); + + /* Return desc to free-list */ + d40_desc_free(d40c, d40d); + } + + /* Release queued descriptors waiting for transfer */ + while ((d40d = d40_first_queued(d40c))) { + d40_desc_remove(d40d); + + /* Return desc to free-list */ + d40_desc_free(d40c, d40d); + } + + /* Release client owned descriptors */ + if (!list_empty(&d40c->client)) + list_for_each_entry_safe(d, _d, &d40c->client, node) { + d40_pool_lli_free(d); + d40_desc_remove(d); + /* Return desc to free-list */ + d40_desc_free(d40c, d40d); + } + + d40_lcla_id_put(d40c, &d40c->base->lcla_pool, + d40c->lcla.src_id); + d40_lcla_id_put(d40c, &d40c->base->lcla_pool, + d40c->lcla.dst_id); + + d40c->pending_tx = 0; + d40c->busy = false; +} + +static void d40_config_set_event(struct d40_chan *d40c, bool do_enable) +{ + u32 val; + unsigned long flags; + + if (do_enable) + val = D40_ACTIVATE_EVENTLINE; + else + val = D40_DEACTIVATE_EVENTLINE; + + spin_lock_irqsave(&d40c->phy_chan->lock, flags); + + /* Enable event line connected to device (or memcpy) */ + if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || + (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) { + u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); + + writel((val << D40_EVENTLINE_POS(event)) | + ~D40_EVENTLINE_MASK(event), + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SSLNK); + } + if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) { + u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); + + writel((val << D40_EVENTLINE_POS(event)) | + ~D40_EVENTLINE_MASK(event), + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDLNK); + } + + spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); +} + +static bool d40_chan_has_events(struct d40_chan *d40c) +{ + u32 val = 0; + + /* If SSLNK or SDLNK is zero all events are disabled */ + if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || + (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) + val = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SSLNK); + + if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) + val = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDLNK); + return (bool) val; +} + +static void d40_config_enable_lidx(struct d40_chan *d40c) +{ + /* Set LIDX for lcla */ + writel((d40c->phy_chan->num << D40_SREG_ELEM_LOG_LIDX_POS) & + D40_SREG_ELEM_LOG_LIDX_MASK, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + D40_CHAN_REG_SDELT); + + writel((d40c->phy_chan->num << D40_SREG_ELEM_LOG_LIDX_POS) & + D40_SREG_ELEM_LOG_LIDX_MASK, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + D40_CHAN_REG_SSELT); +} + +static int d40_config_write(struct d40_chan *d40c) +{ + u32 addr_base; + u32 var; + int res; + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res) + return res; + + /* Odd addresses are even addresses + 4 */ + addr_base = (d40c->phy_chan->num % 2) * 4; + /* Setup channel mode to logical or physical */ + var = ((u32)(d40c->log_num != D40_PHY_CHAN) + 1) << + D40_CHAN_POS(d40c->phy_chan->num); + writel(var, d40c->base->virtbase + D40_DREG_PRMSE + addr_base); + + /* Setup operational mode option register */ + var = ((d40c->dma_cfg.channel_type >> STEDMA40_INFO_CH_MODE_OPT_POS) & + 0x3) << D40_CHAN_POS(d40c->phy_chan->num); + + writel(var, d40c->base->virtbase + D40_DREG_PRMOE + addr_base); + + if (d40c->log_num != D40_PHY_CHAN) { + /* Set default config for CFG reg */ + writel(d40c->src_def_cfg, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SSCFG); + writel(d40c->dst_def_cfg, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDCFG); + + d40_config_enable_lidx(d40c); + } + return res; +} + +static void d40_desc_load(struct d40_chan *d40c, struct d40_desc *d40d) +{ + + if (d40d->lli_phy.dst && d40d->lli_phy.src) { + d40_phy_lli_write(d40c->base->virtbase, + d40c->phy_chan->num, + d40d->lli_phy.dst, + d40d->lli_phy.src); + d40d->lli_tcount = d40d->lli_len; + } else if (d40d->lli_log.dst && d40d->lli_log.src) { + u32 lli_len; + struct d40_log_lli *src = d40d->lli_log.src; + struct d40_log_lli *dst = d40d->lli_log.dst; + + src += d40d->lli_tcount; + dst += d40d->lli_tcount; + + if (d40d->lli_len <= d40c->base->plat_data->llis_per_log) + lli_len = d40d->lli_len; + else + lli_len = d40c->base->plat_data->llis_per_log; + d40d->lli_tcount += lli_len; + d40_log_lli_write(d40c->lcpa, d40c->lcla.src, + d40c->lcla.dst, + dst, src, + d40c->base->plat_data->llis_per_log); + } +} + +static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct d40_chan *d40c = container_of(tx->chan, + struct d40_chan, + chan); + struct d40_desc *d40d = container_of(tx, struct d40_desc, txd); + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + tx->cookie = d40_assign_cookie(d40c, d40d); + + d40_desc_queue(d40c, d40d); + + spin_unlock_irqrestore(&d40c->lock, flags); + + return tx->cookie; +} + +static int d40_start(struct d40_chan *d40c) +{ + int err; + + if (d40c->log_num != D40_PHY_CHAN) { + err = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (err) + return err; + d40_config_set_event(d40c, true); + } + + err = d40_channel_execute_command(d40c, D40_DMA_RUN); + + return err; +} + +static struct d40_desc *d40_queue_start(struct d40_chan *d40c) +{ + struct d40_desc *d40d; + int err; + + /* Start queued jobs, if any */ + d40d = d40_first_queued(d40c); + + if (d40d != NULL) { + d40c->busy = true; + + /* Remove from queue */ + d40_desc_remove(d40d); + + /* Add to active queue */ + d40_desc_submit(d40c, d40d); + + /* Initiate DMA job */ + d40_desc_load(d40c, d40d); + + /* Start dma job */ + err = d40_start(d40c); + + if (err) + return NULL; + } + + return d40d; +} + +/* called from interrupt context */ +static void dma_tc_handle(struct d40_chan *d40c) +{ + struct d40_desc *d40d; + + if (!d40c->phy_chan) + return; + + /* Get first active entry from list */ + d40d = d40_first_active_get(d40c); + + if (d40d == NULL) + return; + + if (d40d->lli_tcount < d40d->lli_len) { + + d40_desc_load(d40c, d40d); + /* Start dma job */ + (void) d40_start(d40c); + return; + } + + if (d40_queue_start(d40c) == NULL) + d40c->busy = false; + + d40c->pending_tx++; + tasklet_schedule(&d40c->tasklet); + +} + +static void dma_tasklet(unsigned long data) +{ + struct d40_chan *d40c = (struct d40_chan *) data; + struct d40_desc *d40d_fin; + unsigned long flags; + dma_async_tx_callback callback; + void *callback_param; + + spin_lock_irqsave(&d40c->lock, flags); + + /* Get first active entry from list */ + d40d_fin = d40_first_active_get(d40c); + + if (d40d_fin == NULL) + goto err; + + d40c->completed = d40d_fin->txd.cookie; + + /* + * If terminating a channel pending_tx is set to zero. + * This prevents any finished active jobs to return to the client. + */ + if (d40c->pending_tx == 0) { + spin_unlock_irqrestore(&d40c->lock, flags); + return; + } + + /* Callback to client */ + callback = d40d_fin->txd.callback; + callback_param = d40d_fin->txd.callback_param; + + if (async_tx_test_ack(&d40d_fin->txd)) { + d40_pool_lli_free(d40d_fin); + d40_desc_remove(d40d_fin); + /* Return desc to free-list */ + d40_desc_free(d40c, d40d_fin); + } else { + d40_desc_reset(d40d_fin); + if (!d40d_fin->is_in_client_list) { + d40_desc_remove(d40d_fin); + list_add_tail(&d40d_fin->node, &d40c->client); + d40d_fin->is_in_client_list = true; + } + } + + d40c->pending_tx--; + + if (d40c->pending_tx) + tasklet_schedule(&d40c->tasklet); + + spin_unlock_irqrestore(&d40c->lock, flags); + + if (callback) + callback(callback_param); + + return; + + err: + /* Rescue manouver if receiving double interrupts */ + if (d40c->pending_tx > 0) + d40c->pending_tx--; + spin_unlock_irqrestore(&d40c->lock, flags); +} + +static irqreturn_t d40_handle_interrupt(int irq, void *data) +{ + static const struct d40_interrupt_lookup il[] = { + {D40_DREG_LCTIS0, D40_DREG_LCICR0, false, 0}, + {D40_DREG_LCTIS1, D40_DREG_LCICR1, false, 32}, + {D40_DREG_LCTIS2, D40_DREG_LCICR2, false, 64}, + {D40_DREG_LCTIS3, D40_DREG_LCICR3, false, 96}, + {D40_DREG_LCEIS0, D40_DREG_LCICR0, true, 0}, + {D40_DREG_LCEIS1, D40_DREG_LCICR1, true, 32}, + {D40_DREG_LCEIS2, D40_DREG_LCICR2, true, 64}, + {D40_DREG_LCEIS3, D40_DREG_LCICR3, true, 96}, + {D40_DREG_PCTIS, D40_DREG_PCICR, false, D40_PHY_CHAN}, + {D40_DREG_PCEIS, D40_DREG_PCICR, true, D40_PHY_CHAN}, + }; + + int i; + u32 regs[ARRAY_SIZE(il)]; + u32 tmp; + u32 idx; + u32 row; + long chan = -1; + struct d40_chan *d40c; + unsigned long flags; + struct d40_base *base = data; + + spin_lock_irqsave(&base->interrupt_lock, flags); + + /* Read interrupt status of both logical and physical channels */ + for (i = 0; i < ARRAY_SIZE(il); i++) + regs[i] = readl(base->virtbase + il[i].src); + + for (;;) { + + chan = find_next_bit((unsigned long *)regs, + BITS_PER_LONG * ARRAY_SIZE(il), chan + 1); + + /* No more set bits found? */ + if (chan == BITS_PER_LONG * ARRAY_SIZE(il)) + break; + + row = chan / BITS_PER_LONG; + idx = chan & (BITS_PER_LONG - 1); + + /* ACK interrupt */ + tmp = readl(base->virtbase + il[row].clr); + tmp |= 1 << idx; + writel(tmp, base->virtbase + il[row].clr); + + if (il[row].offset == D40_PHY_CHAN) + d40c = base->lookup_phy_chans[idx]; + else + d40c = base->lookup_log_chans[il[row].offset + idx]; + spin_lock(&d40c->lock); + + if (!il[row].is_error) + dma_tc_handle(d40c); + else + dev_err(base->dev, "[%s] IRQ chan: %ld offset %d idx %d\n", + __func__, chan, il[row].offset, idx); + + spin_unlock(&d40c->lock); + } + + spin_unlock_irqrestore(&base->interrupt_lock, flags); + + return IRQ_HANDLED; +} + + +static int d40_validate_conf(struct d40_chan *d40c, + struct stedma40_chan_cfg *conf) +{ + int res = 0; + u32 dst_event_group = D40_TYPE_TO_GROUP(conf->dst_dev_type); + u32 src_event_group = D40_TYPE_TO_GROUP(conf->src_dev_type); + bool is_log = (conf->channel_type & STEDMA40_CHANNEL_IN_OPER_MODE) + == STEDMA40_CHANNEL_IN_LOG_MODE; + + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH && + dst_event_group == STEDMA40_DEV_DST_MEMORY) { + dev_err(&d40c->chan.dev->device, "[%s] Invalid dst\n", + __func__); + res = -EINVAL; + } + + if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM && + src_event_group == STEDMA40_DEV_SRC_MEMORY) { + dev_err(&d40c->chan.dev->device, "[%s] Invalid src\n", + __func__); + res = -EINVAL; + } + + if (src_event_group == STEDMA40_DEV_SRC_MEMORY && + dst_event_group == STEDMA40_DEV_DST_MEMORY && is_log) { + dev_err(&d40c->chan.dev->device, + "[%s] No event line\n", __func__); + res = -EINVAL; + } + + if (conf->dir == STEDMA40_PERIPH_TO_PERIPH && + (src_event_group != dst_event_group)) { + dev_err(&d40c->chan.dev->device, + "[%s] Invalid event group\n", __func__); + res = -EINVAL; + } + + if (conf->dir == STEDMA40_PERIPH_TO_PERIPH) { + /* + * DMAC HW supports it. Will be added to this driver, + * in case any dma client requires it. + */ + dev_err(&d40c->chan.dev->device, + "[%s] periph to periph not supported\n", + __func__); + res = -EINVAL; + } + + return res; +} + +static bool d40_alloc_mask_set(struct d40_phy_res *phy, bool is_src, + int log_event_line) +{ + unsigned long flags; + spin_lock_irqsave(&phy->lock, flags); + if (!log_event_line) { + /* Physical interrupts are masked per physical full channel */ + if (phy->allocated_src == D40_ALLOC_FREE && + phy->allocated_dst == D40_ALLOC_FREE) { + phy->allocated_dst = D40_ALLOC_PHY; + phy->allocated_src = D40_ALLOC_PHY; + goto found; + } else + goto not_found; + } + + /* Logical channel */ + if (is_src) { + if (phy->allocated_src == D40_ALLOC_PHY) + goto not_found; + + if (phy->allocated_src == D40_ALLOC_FREE) + phy->allocated_src = D40_ALLOC_LOG_FREE; + + if (!(phy->allocated_src & (1 << log_event_line))) { + phy->allocated_src |= 1 << log_event_line; + goto found; + } else + goto not_found; + } else { + if (phy->allocated_dst == D40_ALLOC_PHY) + goto not_found; + + if (phy->allocated_dst == D40_ALLOC_FREE) + phy->allocated_dst = D40_ALLOC_LOG_FREE; + + if (!(phy->allocated_dst & (1 << log_event_line))) { + phy->allocated_dst |= 1 << log_event_line; + goto found; + } else + goto not_found; + } + +not_found: + spin_unlock_irqrestore(&phy->lock, flags); + return false; +found: + spin_unlock_irqrestore(&phy->lock, flags); + return true; +} + +static bool d40_alloc_mask_free(struct d40_phy_res *phy, bool is_src, + int log_event_line) +{ + unsigned long flags; + bool is_free = false; + + spin_lock_irqsave(&phy->lock, flags); + if (!log_event_line) { + /* Physical interrupts are masked per physical full channel */ + phy->allocated_dst = D40_ALLOC_FREE; + phy->allocated_src = D40_ALLOC_FREE; + is_free = true; + goto out; + } + + /* Logical channel */ + if (is_src) { + phy->allocated_src &= ~(1 << log_event_line); + if (phy->allocated_src == D40_ALLOC_LOG_FREE) + phy->allocated_src = D40_ALLOC_FREE; + } else { + phy->allocated_dst &= ~(1 << log_event_line); + if (phy->allocated_dst == D40_ALLOC_LOG_FREE) + phy->allocated_dst = D40_ALLOC_FREE; + } + + is_free = ((phy->allocated_src | phy->allocated_dst) == + D40_ALLOC_FREE); + +out: + spin_unlock_irqrestore(&phy->lock, flags); + + return is_free; +} + +static int d40_allocate_channel(struct d40_chan *d40c) +{ + int dev_type; + int event_group; + int event_line; + struct d40_phy_res *phys; + int i; + int j; + int log_num; + bool is_src; + bool is_log = (d40c->dma_cfg.channel_type & STEDMA40_CHANNEL_IN_OPER_MODE) + == STEDMA40_CHANNEL_IN_LOG_MODE; + + + phys = d40c->base->phy_res; + + if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { + dev_type = d40c->dma_cfg.src_dev_type; + log_num = 2 * dev_type; + is_src = true; + } else if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || + d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + /* dst event lines are used for logical memcpy */ + dev_type = d40c->dma_cfg.dst_dev_type; + log_num = 2 * dev_type + 1; + is_src = false; + } else + return -EINVAL; + + event_group = D40_TYPE_TO_GROUP(dev_type); + event_line = D40_TYPE_TO_EVENT(dev_type); + + if (!is_log) { + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + /* Find physical half channel */ + for (i = 0; i < d40c->base->num_phy_chans; i++) { + + if (d40_alloc_mask_set(&phys[i], is_src, 0)) + goto found_phy; + } + } else + for (j = 0; j < d40c->base->num_phy_chans; j += 8) { + int phy_num = j + event_group * 2; + for (i = phy_num; i < phy_num + 2; i++) { + if (d40_alloc_mask_set(&phys[i], + is_src, 0)) + goto found_phy; + } + } + return -EINVAL; +found_phy: + d40c->phy_chan = &phys[i]; + d40c->log_num = D40_PHY_CHAN; + goto out; + } + if (dev_type == -1) + return -EINVAL; + + /* Find logical channel */ + for (j = 0; j < d40c->base->num_phy_chans; j += 8) { + int phy_num = j + event_group * 2; + /* + * Spread logical channels across all available physical rather + * than pack every logical channel at the first available phy + * channels. + */ + if (is_src) { + for (i = phy_num; i < phy_num + 2; i++) { + if (d40_alloc_mask_set(&phys[i], is_src, + event_line)) + goto found_log; + } + } else { + for (i = phy_num + 1; i >= phy_num; i--) { + if (d40_alloc_mask_set(&phys[i], is_src, + event_line)) + goto found_log; + } + } + } + return -EINVAL; + +found_log: + d40c->phy_chan = &phys[i]; + d40c->log_num = log_num; +out: + + if (is_log) + d40c->base->lookup_log_chans[d40c->log_num] = d40c; + else + d40c->base->lookup_phy_chans[d40c->phy_chan->num] = d40c; + + return 0; + +} + +static int d40_config_chan(struct d40_chan *d40c, + struct stedma40_chan_cfg *info) +{ + + /* Fill in basic CFG register values */ + d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg, + &d40c->dst_def_cfg, d40c->log_num != D40_PHY_CHAN); + + if (d40c->log_num != D40_PHY_CHAN) { + d40_log_cfg(&d40c->dma_cfg, + &d40c->log_def.lcsp1, &d40c->log_def.lcsp3); + + if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) + d40c->lcpa = d40c->base->lcpa_base + + d40c->dma_cfg.src_dev_type * 32; + else + d40c->lcpa = d40c->base->lcpa_base + + d40c->dma_cfg.dst_dev_type * 32 + 16; + } + + /* Write channel configuration to the DMA */ + return d40_config_write(d40c); +} + +static int d40_config_memcpy(struct d40_chan *d40c) +{ + dma_cap_mask_t cap = d40c->chan.device->cap_mask; + + if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) { + d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_log; + d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY; + d40c->dma_cfg.dst_dev_type = d40c->base->plat_data-> + memcpy[d40c->chan.chan_id]; + + } else if (dma_has_cap(DMA_MEMCPY, cap) && + dma_has_cap(DMA_SLAVE, cap)) { + d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_phy; + } else { + dev_err(&d40c->chan.dev->device, "[%s] No memcpy\n", + __func__); + return -EINVAL; + } + + return 0; +} + + +static int d40_free_dma(struct d40_chan *d40c) +{ + + int res = 0; + u32 event, dir; + struct d40_phy_res *phy = d40c->phy_chan; + bool is_src; + + /* Terminate all queued and active transfers */ + d40_term_all(d40c); + + if (phy == NULL) { + dev_err(&d40c->chan.dev->device, "[%s] phy == null\n", + __func__); + return -EINVAL; + } + + if (phy->allocated_src == D40_ALLOC_FREE && + phy->allocated_dst == D40_ALLOC_FREE) { + dev_err(&d40c->chan.dev->device, "[%s] channel already free\n", + __func__); + return -EINVAL; + } + + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res) { + dev_err(&d40c->chan.dev->device, "[%s] suspend\n", + __func__); + return res; + } + + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || + d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); + dir = D40_CHAN_REG_SDLNK; + is_src = false; + } else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { + event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); + dir = D40_CHAN_REG_SSLNK; + is_src = true; + } else { + dev_err(&d40c->chan.dev->device, + "[%s] Unknown direction\n", __func__); + return -EINVAL; + } + + if (d40c->log_num != D40_PHY_CHAN) { + /* + * Release logical channel, deactivate the event line during + * the time physical res is suspended. + */ + writel((D40_DEACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event)) & + D40_EVENTLINE_MASK(event), + d40c->base->virtbase + D40_DREG_PCBASE + + phy->num * D40_DREG_PCDELTA + dir); + + d40c->base->lookup_log_chans[d40c->log_num] = NULL; + + /* + * Check if there are more logical allocation + * on this phy channel. + */ + if (!d40_alloc_mask_free(phy, is_src, event)) { + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) { + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + if (res) { + dev_err(&d40c->chan.dev->device, + "[%s] Executing RUN command\n", + __func__); + return res; + } + } + return 0; + } + } else + d40_alloc_mask_free(phy, is_src, 0); + + /* Release physical channel */ + res = d40_channel_execute_command(d40c, D40_DMA_STOP); + if (res) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to stop channel\n", __func__); + return res; + } + d40c->phy_chan = NULL; + /* Invalidate channel type */ + d40c->dma_cfg.channel_type = 0; + d40c->base->lookup_phy_chans[phy->num] = NULL; + + return 0; + + +} + +static int d40_pause(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int res; + + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res == 0) { + if (d40c->log_num != D40_PHY_CHAN) { + d40_config_set_event(d40c, false); + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + } + } + + spin_unlock_irqrestore(&d40c->lock, flags); + return res; +} + +static bool d40_tx_is_linked(struct d40_chan *d40c) +{ + bool is_link; + + if (d40c->log_num != D40_PHY_CHAN) + is_link = readl(&d40c->lcpa->lcsp3) & D40_MEM_LCSP3_DLOS_MASK; + else + is_link = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDLNK) & + D40_SREG_LNK_PHYS_LNK_MASK; + return is_link; +} + +static u32 d40_residue(struct d40_chan *d40c) +{ + u32 num_elt; + + if (d40c->log_num != D40_PHY_CHAN) + num_elt = (readl(&d40c->lcpa->lcsp2) & D40_MEM_LCSP2_ECNT_MASK) + >> D40_MEM_LCSP2_ECNT_POS; + else + num_elt = (readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDELT) & + D40_SREG_ELEM_PHY_ECNT_MASK) >> D40_SREG_ELEM_PHY_ECNT_POS; + return num_elt * (1 << d40c->dma_cfg.dst_info.data_width); +} + +static int d40_resume(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int res = 0; + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + if (d40c->log_num != D40_PHY_CHAN) { + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res) + goto out; + + /* If bytes left to transfer or linked tx resume job */ + if (d40_residue(d40c) || d40_tx_is_linked(d40c)) { + d40_config_set_event(d40c, true); + res = d40_channel_execute_command(d40c, D40_DMA_RUN); + } + } else if (d40_residue(d40c) || d40_tx_is_linked(d40c)) + res = d40_channel_execute_command(d40c, D40_DMA_RUN); + +out: + spin_unlock_irqrestore(&d40c->lock, flags); + return res; +} + +static u32 stedma40_residue(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + u32 bytes_left; + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + bytes_left = d40_residue(d40c); + spin_unlock_irqrestore(&d40c->lock, flags); + + return bytes_left; +} + +/* Public DMA functions in addition to the DMA engine framework */ + +int stedma40_set_psize(struct dma_chan *chan, + int src_psize, + int dst_psize) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + if (d40c->log_num != D40_PHY_CHAN) { + d40c->log_def.lcsp1 &= ~D40_MEM_LCSP1_SCFG_PSIZE_MASK; + d40c->log_def.lcsp3 &= ~D40_MEM_LCSP1_SCFG_PSIZE_MASK; + d40c->log_def.lcsp1 |= src_psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; + d40c->log_def.lcsp3 |= dst_psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; + goto out; + } + + if (src_psize == STEDMA40_PSIZE_PHY_1) + d40c->src_def_cfg &= ~(1 << D40_SREG_CFG_PHY_PEN_POS); + else { + d40c->src_def_cfg |= 1 << D40_SREG_CFG_PHY_PEN_POS; + d40c->src_def_cfg &= ~(STEDMA40_PSIZE_PHY_16 << + D40_SREG_CFG_PSIZE_POS); + d40c->src_def_cfg |= src_psize << D40_SREG_CFG_PSIZE_POS; + } + + if (dst_psize == STEDMA40_PSIZE_PHY_1) + d40c->dst_def_cfg &= ~(1 << D40_SREG_CFG_PHY_PEN_POS); + else { + d40c->dst_def_cfg |= 1 << D40_SREG_CFG_PHY_PEN_POS; + d40c->dst_def_cfg &= ~(STEDMA40_PSIZE_PHY_16 << + D40_SREG_CFG_PSIZE_POS); + d40c->dst_def_cfg |= dst_psize << D40_SREG_CFG_PSIZE_POS; + } +out: + spin_unlock_irqrestore(&d40c->lock, flags); + return 0; +} +EXPORT_SYMBOL(stedma40_set_psize); + +struct dma_async_tx_descriptor *stedma40_memcpy_sg(struct dma_chan *chan, + struct scatterlist *sgl_dst, + struct scatterlist *sgl_src, + unsigned int sgl_len, + unsigned long flags) +{ + int res; + struct d40_desc *d40d; + struct d40_chan *d40c = container_of(chan, struct d40_chan, + chan); + unsigned long flg; + int lli_max = d40c->base->plat_data->llis_per_log; + + + spin_lock_irqsave(&d40c->lock, flg); + d40d = d40_desc_get(d40c); + + if (d40d == NULL) + goto err; + + memset(d40d, 0, sizeof(struct d40_desc)); + d40d->lli_len = sgl_len; + + d40d->txd.flags = flags; + + if (d40c->log_num != D40_PHY_CHAN) { + if (sgl_len > 1) + /* + * Check if there is space available in lcla. If not, + * split list into 1-length and run only in lcpa + * space. + */ + if (d40_lcla_id_get(d40c, + &d40c->base->lcla_pool) != 0) + lli_max = 1; + + if (d40_pool_lli_alloc(d40d, sgl_len, true) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + + (void) d40_log_sg_to_lli(d40c->lcla.src_id, + sgl_src, + sgl_len, + d40d->lli_log.src, + d40c->log_def.lcsp1, + d40c->dma_cfg.src_info.data_width, + flags & DMA_PREP_INTERRUPT, lli_max, + d40c->base->plat_data->llis_per_log); + + (void) d40_log_sg_to_lli(d40c->lcla.dst_id, + sgl_dst, + sgl_len, + d40d->lli_log.dst, + d40c->log_def.lcsp3, + d40c->dma_cfg.dst_info.data_width, + flags & DMA_PREP_INTERRUPT, lli_max, + d40c->base->plat_data->llis_per_log); + + + } else { + if (d40_pool_lli_alloc(d40d, sgl_len, false) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + + res = d40_phy_sg_to_lli(sgl_src, + sgl_len, + 0, + d40d->lli_phy.src, + d40d->lli_phy.src_addr, + d40c->src_def_cfg, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.src_info.psize, + true); + + if (res < 0) + goto err; + + res = d40_phy_sg_to_lli(sgl_dst, + sgl_len, + 0, + d40d->lli_phy.dst, + d40d->lli_phy.dst_addr, + d40c->dst_def_cfg, + d40c->dma_cfg.dst_info.data_width, + d40c->dma_cfg.dst_info.psize, + true); + + if (res < 0) + goto err; + + (void) dma_map_single(d40c->base->dev, d40d->lli_phy.src, + d40d->lli_pool.size, DMA_TO_DEVICE); + } + + dma_async_tx_descriptor_init(&d40d->txd, chan); + + d40d->txd.tx_submit = d40_tx_submit; + + spin_unlock_irqrestore(&d40c->lock, flg); + + return &d40d->txd; +err: + spin_unlock_irqrestore(&d40c->lock, flg); + return NULL; +} +EXPORT_SYMBOL(stedma40_memcpy_sg); + +bool stedma40_filter(struct dma_chan *chan, void *data) +{ + struct stedma40_chan_cfg *info = data; + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int err; + + if (data) { + err = d40_validate_conf(d40c, info); + if (!err) + d40c->dma_cfg = *info; + } else + err = d40_config_memcpy(d40c); + + return err == 0; +} +EXPORT_SYMBOL(stedma40_filter); + +/* DMA ENGINE functions */ +static int d40_alloc_chan_resources(struct dma_chan *chan) +{ + int err; + unsigned long flags; + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + + spin_lock_irqsave(&d40c->lock, flags); + + d40c->completed = chan->cookie = 1; + + /* + * If no dma configuration is set (channel_type == 0) + * use default configuration + */ + if (d40c->dma_cfg.channel_type == 0) { + err = d40_config_memcpy(d40c); + if (err) + goto err_alloc; + } + + err = d40_allocate_channel(d40c); + if (err) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to allocate channel\n", __func__); + goto err_alloc; + } + + err = d40_config_chan(d40c, &d40c->dma_cfg); + if (err) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to configure channel\n", + __func__); + goto err_config; + } + + spin_unlock_irqrestore(&d40c->lock, flags); + return 0; + + err_config: + (void) d40_free_dma(d40c); + err_alloc: + spin_unlock_irqrestore(&d40c->lock, flags); + dev_err(&d40c->chan.dev->device, + "[%s] Channel allocation failed\n", __func__); + return -EINVAL; +} + +static void d40_free_chan_resources(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int err; + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + err = d40_free_dma(d40c); + + if (err) + dev_err(&d40c->chan.dev->device, + "[%s] Failed to free channel\n", __func__); + spin_unlock_irqrestore(&d40c->lock, flags); +} + +static struct dma_async_tx_descriptor *d40_prep_memcpy(struct dma_chan *chan, + dma_addr_t dst, + dma_addr_t src, + size_t size, + unsigned long flags) +{ + struct d40_desc *d40d; + struct d40_chan *d40c = container_of(chan, struct d40_chan, + chan); + unsigned long flg; + int err = 0; + + spin_lock_irqsave(&d40c->lock, flg); + d40d = d40_desc_get(d40c); + + if (d40d == NULL) { + dev_err(&d40c->chan.dev->device, + "[%s] Descriptor is NULL\n", __func__); + goto err; + } + + memset(d40d, 0, sizeof(struct d40_desc)); + + d40d->txd.flags = flags; + + dma_async_tx_descriptor_init(&d40d->txd, chan); + + d40d->txd.tx_submit = d40_tx_submit; + + if (d40c->log_num != D40_PHY_CHAN) { + + if (d40_pool_lli_alloc(d40d, 1, true) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + d40d->lli_len = 1; + + d40_log_fill_lli(d40d->lli_log.src, + src, + size, + 0, + d40c->log_def.lcsp1, + d40c->dma_cfg.src_info.data_width, + true, true); + + d40_log_fill_lli(d40d->lli_log.dst, + dst, + size, + 0, + d40c->log_def.lcsp3, + d40c->dma_cfg.dst_info.data_width, + true, true); + + } else { + + if (d40_pool_lli_alloc(d40d, 1, false) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + + err = d40_phy_fill_lli(d40d->lli_phy.src, + src, + size, + d40c->dma_cfg.src_info.psize, + 0, + d40c->src_def_cfg, + true, + d40c->dma_cfg.src_info.data_width, + false); + if (err) + goto err_fill_lli; + + err = d40_phy_fill_lli(d40d->lli_phy.dst, + dst, + size, + d40c->dma_cfg.dst_info.psize, + 0, + d40c->dst_def_cfg, + true, + d40c->dma_cfg.dst_info.data_width, + false); + + if (err) + goto err_fill_lli; + + (void) dma_map_single(d40c->base->dev, d40d->lli_phy.src, + d40d->lli_pool.size, DMA_TO_DEVICE); + } + + spin_unlock_irqrestore(&d40c->lock, flg); + return &d40d->txd; + +err_fill_lli: + dev_err(&d40c->chan.dev->device, + "[%s] Failed filling in PHY LLI\n", __func__); + d40_pool_lli_free(d40d); +err: + spin_unlock_irqrestore(&d40c->lock, flg); + return NULL; +} + +static int d40_prep_slave_sg_log(struct d40_desc *d40d, + struct d40_chan *d40c, + struct scatterlist *sgl, + unsigned int sg_len, + enum dma_data_direction direction, + unsigned long flags) +{ + dma_addr_t dev_addr = 0; + int total_size; + int lli_max = d40c->base->plat_data->llis_per_log; + + if (d40_pool_lli_alloc(d40d, sg_len, true) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + return -ENOMEM; + } + + d40d->lli_len = sg_len; + d40d->lli_tcount = 0; + + if (sg_len > 1) + /* + * Check if there is space available in lcla. + * If not, split list into 1-length and run only + * in lcpa space. + */ + if (d40_lcla_id_get(d40c, &d40c->base->lcla_pool) != 0) + lli_max = 1; + + if (direction == DMA_FROM_DEVICE) { + dev_addr = d40c->base->plat_data->dev_rx[d40c->dma_cfg.src_dev_type]; + total_size = d40_log_sg_to_dev(&d40c->lcla, + sgl, sg_len, + &d40d->lli_log, + &d40c->log_def, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.dst_info.data_width, + direction, + flags & DMA_PREP_INTERRUPT, + dev_addr, lli_max, + d40c->base->plat_data->llis_per_log); + } else if (direction == DMA_TO_DEVICE) { + dev_addr = d40c->base->plat_data->dev_tx[d40c->dma_cfg.dst_dev_type]; + total_size = d40_log_sg_to_dev(&d40c->lcla, + sgl, sg_len, + &d40d->lli_log, + &d40c->log_def, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.dst_info.data_width, + direction, + flags & DMA_PREP_INTERRUPT, + dev_addr, lli_max, + d40c->base->plat_data->llis_per_log); + } else + return -EINVAL; + if (total_size < 0) + return -EINVAL; + + return 0; +} + +static int d40_prep_slave_sg_phy(struct d40_desc *d40d, + struct d40_chan *d40c, + struct scatterlist *sgl, + unsigned int sgl_len, + enum dma_data_direction direction, + unsigned long flags) +{ + dma_addr_t src_dev_addr; + dma_addr_t dst_dev_addr; + int res; + + if (d40_pool_lli_alloc(d40d, sgl_len, false) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + return -ENOMEM; + } + + d40d->lli_len = sgl_len; + d40d->lli_tcount = 0; + + if (direction == DMA_FROM_DEVICE) { + dst_dev_addr = 0; + src_dev_addr = d40c->base->plat_data->dev_rx[d40c->dma_cfg.src_dev_type]; + } else if (direction == DMA_TO_DEVICE) { + dst_dev_addr = d40c->base->plat_data->dev_tx[d40c->dma_cfg.dst_dev_type]; + src_dev_addr = 0; + } else + return -EINVAL; + + res = d40_phy_sg_to_lli(sgl, + sgl_len, + src_dev_addr, + d40d->lli_phy.src, + d40d->lli_phy.src_addr, + d40c->src_def_cfg, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.src_info.psize, + true); + if (res < 0) + return res; + + res = d40_phy_sg_to_lli(sgl, + sgl_len, + dst_dev_addr, + d40d->lli_phy.dst, + d40d->lli_phy.dst_addr, + d40c->dst_def_cfg, + d40c->dma_cfg.dst_info.data_width, + d40c->dma_cfg.dst_info.psize, + true); + if (res < 0) + return res; + + (void) dma_map_single(d40c->base->dev, d40d->lli_phy.src, + d40d->lli_pool.size, DMA_TO_DEVICE); + return 0; +} + +static struct dma_async_tx_descriptor *d40_prep_slave_sg(struct dma_chan *chan, + struct scatterlist *sgl, + unsigned int sg_len, + enum dma_data_direction direction, + unsigned long flags) +{ + struct d40_desc *d40d; + struct d40_chan *d40c = container_of(chan, struct d40_chan, + chan); + unsigned long flg; + int err; + + if (d40c->dma_cfg.pre_transfer) + d40c->dma_cfg.pre_transfer(chan, + d40c->dma_cfg.pre_transfer_data, + sg_dma_len(sgl)); + + spin_lock_irqsave(&d40c->lock, flg); + d40d = d40_desc_get(d40c); + spin_unlock_irqrestore(&d40c->lock, flg); + + if (d40d == NULL) + return NULL; + + memset(d40d, 0, sizeof(struct d40_desc)); + + if (d40c->log_num != D40_PHY_CHAN) + err = d40_prep_slave_sg_log(d40d, d40c, sgl, sg_len, + direction, flags); + else + err = d40_prep_slave_sg_phy(d40d, d40c, sgl, sg_len, + direction, flags); + if (err) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to prepare %s slave sg job: %d\n", + __func__, + d40c->log_num != D40_PHY_CHAN ? "log" : "phy", err); + return NULL; + } + + d40d->txd.flags = flags; + + dma_async_tx_descriptor_init(&d40d->txd, chan); + + d40d->txd.tx_submit = d40_tx_submit; + + return &d40d->txd; +} + +static enum dma_status d40_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate) +{ + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + dma_cookie_t last_used; + dma_cookie_t last_complete; + int ret; + + last_complete = d40c->completed; + last_used = chan->cookie; + + ret = dma_async_is_complete(cookie, last_complete, last_used); + + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = stedma40_residue(chan); + } + + return ret; +} + +static void d40_issue_pending(struct dma_chan *chan) +{ + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + /* Busy means that pending jobs are already being processed */ + if (!d40c->busy) + (void) d40_queue_start(d40c); + + spin_unlock_irqrestore(&d40c->lock, flags); +} + +static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +{ + unsigned long flags; + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + + switch (cmd) { + case DMA_TERMINATE_ALL: + spin_lock_irqsave(&d40c->lock, flags); + d40_term_all(d40c); + spin_unlock_irqrestore(&d40c->lock, flags); + return 0; + case DMA_PAUSE: + return d40_pause(chan); + case DMA_RESUME: + return d40_resume(chan); + } + + /* Other commands are unimplemented */ + return -ENXIO; +} + +/* Initialization functions */ + +static void __init d40_chan_init(struct d40_base *base, struct dma_device *dma, + struct d40_chan *chans, int offset, + int num_chans) +{ + int i = 0; + struct d40_chan *d40c; + + INIT_LIST_HEAD(&dma->channels); + + for (i = offset; i < offset + num_chans; i++) { + d40c = &chans[i]; + d40c->base = base; + d40c->chan.device = dma; + + /* Invalidate lcla element */ + d40c->lcla.src_id = -1; + d40c->lcla.dst_id = -1; + + spin_lock_init(&d40c->lock); + + d40c->log_num = D40_PHY_CHAN; + + INIT_LIST_HEAD(&d40c->free); + INIT_LIST_HEAD(&d40c->active); + INIT_LIST_HEAD(&d40c->queue); + INIT_LIST_HEAD(&d40c->client); + + d40c->free_len = 0; + + tasklet_init(&d40c->tasklet, dma_tasklet, + (unsigned long) d40c); + + list_add_tail(&d40c->chan.device_node, + &dma->channels); + } +} + +static int __init d40_dmaengine_init(struct d40_base *base, + int num_reserved_chans) +{ + int err ; + + d40_chan_init(base, &base->dma_slave, base->log_chans, + 0, base->num_log_chans); + + dma_cap_zero(base->dma_slave.cap_mask); + dma_cap_set(DMA_SLAVE, base->dma_slave.cap_mask); + + base->dma_slave.device_alloc_chan_resources = d40_alloc_chan_resources; + base->dma_slave.device_free_chan_resources = d40_free_chan_resources; + base->dma_slave.device_prep_dma_memcpy = d40_prep_memcpy; + base->dma_slave.device_prep_slave_sg = d40_prep_slave_sg; + base->dma_slave.device_tx_status = d40_tx_status; + base->dma_slave.device_issue_pending = d40_issue_pending; + base->dma_slave.device_control = d40_control; + base->dma_slave.dev = base->dev; + + err = dma_async_device_register(&base->dma_slave); + + if (err) { + dev_err(base->dev, + "[%s] Failed to register slave channels\n", + __func__); + goto failure1; + } + + d40_chan_init(base, &base->dma_memcpy, base->log_chans, + base->num_log_chans, base->plat_data->memcpy_len); + + dma_cap_zero(base->dma_memcpy.cap_mask); + dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); + + base->dma_memcpy.device_alloc_chan_resources = d40_alloc_chan_resources; + base->dma_memcpy.device_free_chan_resources = d40_free_chan_resources; + base->dma_memcpy.device_prep_dma_memcpy = d40_prep_memcpy; + base->dma_memcpy.device_prep_slave_sg = d40_prep_slave_sg; + base->dma_memcpy.device_tx_status = d40_tx_status; + base->dma_memcpy.device_issue_pending = d40_issue_pending; + base->dma_memcpy.device_control = d40_control; + base->dma_memcpy.dev = base->dev; + /* + * This controller can only access address at even + * 32bit boundaries, i.e. 2^2 + */ + base->dma_memcpy.copy_align = 2; + + err = dma_async_device_register(&base->dma_memcpy); + + if (err) { + dev_err(base->dev, + "[%s] Failed to regsiter memcpy only channels\n", + __func__); + goto failure2; + } + + d40_chan_init(base, &base->dma_both, base->phy_chans, + 0, num_reserved_chans); + + dma_cap_zero(base->dma_both.cap_mask); + dma_cap_set(DMA_SLAVE, base->dma_both.cap_mask); + dma_cap_set(DMA_MEMCPY, base->dma_both.cap_mask); + + base->dma_both.device_alloc_chan_resources = d40_alloc_chan_resources; + base->dma_both.device_free_chan_resources = d40_free_chan_resources; + base->dma_both.device_prep_dma_memcpy = d40_prep_memcpy; + base->dma_both.device_prep_slave_sg = d40_prep_slave_sg; + base->dma_both.device_tx_status = d40_tx_status; + base->dma_both.device_issue_pending = d40_issue_pending; + base->dma_both.device_control = d40_control; + base->dma_both.dev = base->dev; + base->dma_both.copy_align = 2; + err = dma_async_device_register(&base->dma_both); + + if (err) { + dev_err(base->dev, + "[%s] Failed to register logical and physical capable channels\n", + __func__); + goto failure3; + } + return 0; +failure3: + dma_async_device_unregister(&base->dma_memcpy); +failure2: + dma_async_device_unregister(&base->dma_slave); +failure1: + return err; +} + +/* Initialization functions. */ + +static int __init d40_phy_res_init(struct d40_base *base) +{ + int i; + int num_phy_chans_avail = 0; + u32 val[2]; + int odd_even_bit = -2; + + val[0] = readl(base->virtbase + D40_DREG_PRSME); + val[1] = readl(base->virtbase + D40_DREG_PRSMO); + + for (i = 0; i < base->num_phy_chans; i++) { + base->phy_res[i].num = i; + odd_even_bit += 2 * ((i % 2) == 0); + if (((val[i % 2] >> odd_even_bit) & 3) == 1) { + /* Mark security only channels as occupied */ + base->phy_res[i].allocated_src = D40_ALLOC_PHY; + base->phy_res[i].allocated_dst = D40_ALLOC_PHY; + } else { + base->phy_res[i].allocated_src = D40_ALLOC_FREE; + base->phy_res[i].allocated_dst = D40_ALLOC_FREE; + num_phy_chans_avail++; + } + spin_lock_init(&base->phy_res[i].lock); + } + dev_info(base->dev, "%d of %d physical DMA channels available\n", + num_phy_chans_avail, base->num_phy_chans); + + /* Verify settings extended vs standard */ + val[0] = readl(base->virtbase + D40_DREG_PRTYP); + + for (i = 0; i < base->num_phy_chans; i++) { + + if (base->phy_res[i].allocated_src == D40_ALLOC_FREE && + (val[0] & 0x3) != 1) + dev_info(base->dev, + "[%s] INFO: channel %d is misconfigured (%d)\n", + __func__, i, val[0] & 0x3); + + val[0] = val[0] >> 2; + } + + return num_phy_chans_avail; +} + +static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) +{ + static const struct d40_reg_val dma_id_regs[] = { + /* Peripheral Id */ + { .reg = D40_DREG_PERIPHID0, .val = 0x0040}, + { .reg = D40_DREG_PERIPHID1, .val = 0x0000}, + /* + * D40_DREG_PERIPHID2 Depends on HW revision: + * MOP500/HREF ED has 0x0008, + * ? has 0x0018, + * HREF V1 has 0x0028 + */ + { .reg = D40_DREG_PERIPHID3, .val = 0x0000}, + + /* PCell Id */ + { .reg = D40_DREG_CELLID0, .val = 0x000d}, + { .reg = D40_DREG_CELLID1, .val = 0x00f0}, + { .reg = D40_DREG_CELLID2, .val = 0x0005}, + { .reg = D40_DREG_CELLID3, .val = 0x00b1} + }; + struct stedma40_platform_data *plat_data; + struct clk *clk = NULL; + void __iomem *virtbase = NULL; + struct resource *res = NULL; + struct d40_base *base = NULL; + int num_log_chans = 0; + int num_phy_chans; + int i; + + clk = clk_get(&pdev->dev, NULL); + + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "[%s] No matching clock found\n", + __func__); + goto failure; + } + + clk_enable(clk); + + /* Get IO for DMAC base address */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base"); + if (!res) + goto failure; + + if (request_mem_region(res->start, resource_size(res), + D40_NAME " I/O base") == NULL) + goto failure; + + virtbase = ioremap(res->start, resource_size(res)); + if (!virtbase) + goto failure; + + /* HW version check */ + for (i = 0; i < ARRAY_SIZE(dma_id_regs); i++) { + if (dma_id_regs[i].val != + readl(virtbase + dma_id_regs[i].reg)) { + dev_err(&pdev->dev, + "[%s] Unknown hardware! Expected 0x%x at 0x%x but got 0x%x\n", + __func__, + dma_id_regs[i].val, + dma_id_regs[i].reg, + readl(virtbase + dma_id_regs[i].reg)); + goto failure; + } + } + + i = readl(virtbase + D40_DREG_PERIPHID2); + + if ((i & 0xf) != D40_PERIPHID2_DESIGNER) { + dev_err(&pdev->dev, + "[%s] Unknown designer! Got %x wanted %x\n", + __func__, i & 0xf, D40_PERIPHID2_DESIGNER); + goto failure; + } + + /* The number of physical channels on this HW */ + num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; + + dev_info(&pdev->dev, "hardware revision: %d @ 0x%x\n", + (i >> 4) & 0xf, res->start); + + plat_data = pdev->dev.platform_data; + + /* Count the number of logical channels in use */ + for (i = 0; i < plat_data->dev_len; i++) + if (plat_data->dev_rx[i] != 0) + num_log_chans++; + + for (i = 0; i < plat_data->dev_len; i++) + if (plat_data->dev_tx[i] != 0) + num_log_chans++; + + base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + + (num_phy_chans + num_log_chans + plat_data->memcpy_len) * + sizeof(struct d40_chan), GFP_KERNEL); + + if (base == NULL) { + dev_err(&pdev->dev, "[%s] Out of memory\n", __func__); + goto failure; + } + + base->clk = clk; + base->num_phy_chans = num_phy_chans; + base->num_log_chans = num_log_chans; + base->phy_start = res->start; + base->phy_size = resource_size(res); + base->virtbase = virtbase; + base->plat_data = plat_data; + base->dev = &pdev->dev; + base->phy_chans = ((void *)base) + ALIGN(sizeof(struct d40_base), 4); + base->log_chans = &base->phy_chans[num_phy_chans]; + + base->phy_res = kzalloc(num_phy_chans * sizeof(struct d40_phy_res), + GFP_KERNEL); + if (!base->phy_res) + goto failure; + + base->lookup_phy_chans = kzalloc(num_phy_chans * + sizeof(struct d40_chan *), + GFP_KERNEL); + if (!base->lookup_phy_chans) + goto failure; + + if (num_log_chans + plat_data->memcpy_len) { + /* + * The max number of logical channels are event lines for all + * src devices and dst devices + */ + base->lookup_log_chans = kzalloc(plat_data->dev_len * 2 * + sizeof(struct d40_chan *), + GFP_KERNEL); + if (!base->lookup_log_chans) + goto failure; + } + base->lcla_pool.alloc_map = kzalloc(num_phy_chans * sizeof(u32), + GFP_KERNEL); + if (!base->lcla_pool.alloc_map) + goto failure; + + return base; + +failure: + if (clk) { + clk_disable(clk); + clk_put(clk); + } + if (virtbase) + iounmap(virtbase); + if (res) + release_mem_region(res->start, + resource_size(res)); + if (virtbase) + iounmap(virtbase); + + if (base) { + kfree(base->lcla_pool.alloc_map); + kfree(base->lookup_log_chans); + kfree(base->lookup_phy_chans); + kfree(base->phy_res); + kfree(base); + } + + return NULL; +} + +static void __init d40_hw_init(struct d40_base *base) +{ + + static const struct d40_reg_val dma_init_reg[] = { + /* Clock every part of the DMA block from start */ + { .reg = D40_DREG_GCC, .val = 0x0000ff01}, + + /* Interrupts on all logical channels */ + { .reg = D40_DREG_LCMIS0, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCMIS1, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCMIS2, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCMIS3, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR0, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR1, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR2, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR3, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS0, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS1, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS2, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS3, .val = 0xFFFFFFFF} + }; + int i; + u32 prmseo[2] = {0, 0}; + u32 activeo[2] = {0xFFFFFFFF, 0xFFFFFFFF}; + u32 pcmis = 0; + u32 pcicr = 0; + + for (i = 0; i < ARRAY_SIZE(dma_init_reg); i++) + writel(dma_init_reg[i].val, + base->virtbase + dma_init_reg[i].reg); + + /* Configure all our dma channels to default settings */ + for (i = 0; i < base->num_phy_chans; i++) { + + activeo[i % 2] = activeo[i % 2] << 2; + + if (base->phy_res[base->num_phy_chans - i - 1].allocated_src + == D40_ALLOC_PHY) { + activeo[i % 2] |= 3; + continue; + } + + /* Enable interrupt # */ + pcmis = (pcmis << 1) | 1; + + /* Clear interrupt # */ + pcicr = (pcicr << 1) | 1; + + /* Set channel to physical mode */ + prmseo[i % 2] = prmseo[i % 2] << 2; + prmseo[i % 2] |= 1; + + } + + writel(prmseo[1], base->virtbase + D40_DREG_PRMSE); + writel(prmseo[0], base->virtbase + D40_DREG_PRMSO); + writel(activeo[1], base->virtbase + D40_DREG_ACTIVE); + writel(activeo[0], base->virtbase + D40_DREG_ACTIVO); + + /* Write which interrupt to enable */ + writel(pcmis, base->virtbase + D40_DREG_PCMIS); + + /* Write which interrupt to clear */ + writel(pcicr, base->virtbase + D40_DREG_PCICR); + +} + +static int __init d40_probe(struct platform_device *pdev) +{ + int err; + int ret = -ENOENT; + struct d40_base *base; + struct resource *res = NULL; + int num_reserved_chans; + u32 val; + + base = d40_hw_detect_init(pdev); + + if (!base) + goto failure; + + num_reserved_chans = d40_phy_res_init(base); + + platform_set_drvdata(pdev, base); + + spin_lock_init(&base->interrupt_lock); + spin_lock_init(&base->execmd_lock); + + /* Get IO for logical channel parameter address */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lcpa"); + if (!res) { + ret = -ENOENT; + dev_err(&pdev->dev, + "[%s] No \"lcpa\" memory resource\n", + __func__); + goto failure; + } + base->lcpa_size = resource_size(res); + base->phy_lcpa = res->start; + + if (request_mem_region(res->start, resource_size(res), + D40_NAME " I/O lcpa") == NULL) { + ret = -EBUSY; + dev_err(&pdev->dev, + "[%s] Failed to request LCPA region 0x%x-0x%x\n", + __func__, res->start, res->end); + goto failure; + } + + /* We make use of ESRAM memory for this. */ + val = readl(base->virtbase + D40_DREG_LCPA); + if (res->start != val && val != 0) { + dev_warn(&pdev->dev, + "[%s] Mismatch LCPA dma 0x%x, def 0x%x\n", + __func__, val, res->start); + } else + writel(res->start, base->virtbase + D40_DREG_LCPA); + + base->lcpa_base = ioremap(res->start, resource_size(res)); + if (!base->lcpa_base) { + ret = -ENOMEM; + dev_err(&pdev->dev, + "[%s] Failed to ioremap LCPA region\n", + __func__); + goto failure; + } + /* Get IO for logical channel link address */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lcla"); + if (!res) { + ret = -ENOENT; + dev_err(&pdev->dev, + "[%s] No \"lcla\" resource defined\n", + __func__); + goto failure; + } + + base->lcla_pool.base_size = resource_size(res); + base->lcla_pool.phy = res->start; + + if (request_mem_region(res->start, resource_size(res), + D40_NAME " I/O lcla") == NULL) { + ret = -EBUSY; + dev_err(&pdev->dev, + "[%s] Failed to request LCLA region 0x%x-0x%x\n", + __func__, res->start, res->end); + goto failure; + } + val = readl(base->virtbase + D40_DREG_LCLA); + if (res->start != val && val != 0) { + dev_warn(&pdev->dev, + "[%s] Mismatch LCLA dma 0x%x, def 0x%x\n", + __func__, val, res->start); + } else + writel(res->start, base->virtbase + D40_DREG_LCLA); + + base->lcla_pool.base = ioremap(res->start, resource_size(res)); + if (!base->lcla_pool.base) { + ret = -ENOMEM; + dev_err(&pdev->dev, + "[%s] Failed to ioremap LCLA 0x%x-0x%x\n", + __func__, res->start, res->end); + goto failure; + } + + spin_lock_init(&base->lcla_pool.lock); + + base->lcla_pool.num_blocks = base->num_phy_chans; + + base->irq = platform_get_irq(pdev, 0); + + ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base); + + if (ret) { + dev_err(&pdev->dev, "[%s] No IRQ defined\n", __func__); + goto failure; + } + + err = d40_dmaengine_init(base, num_reserved_chans); + if (err) + goto failure; + + d40_hw_init(base); + + dev_info(base->dev, "initialized\n"); + return 0; + +failure: + if (base) { + if (base->virtbase) + iounmap(base->virtbase); + if (base->lcla_pool.phy) + release_mem_region(base->lcla_pool.phy, + base->lcla_pool.base_size); + if (base->phy_lcpa) + release_mem_region(base->phy_lcpa, + base->lcpa_size); + if (base->phy_start) + release_mem_region(base->phy_start, + base->phy_size); + if (base->clk) { + clk_disable(base->clk); + clk_put(base->clk); + } + + kfree(base->lcla_pool.alloc_map); + kfree(base->lookup_log_chans); + kfree(base->lookup_phy_chans); + kfree(base->phy_res); + kfree(base); + } + + dev_err(&pdev->dev, "[%s] probe failed\n", __func__); + return ret; +} + +static struct platform_driver d40_driver = { + .driver = { + .owner = THIS_MODULE, + .name = D40_NAME, + }, +}; + +int __init stedma40_init(void) +{ + return platform_driver_probe(&d40_driver, d40_probe); +} +arch_initcall(stedma40_init); diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c new file mode 100644 index 000000000000..561fdd8a80c1 --- /dev/null +++ b/drivers/dma/ste_dma40_ll.c @@ -0,0 +1,454 @@ +/* + * driver/dma/ste_dma40_ll.c + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + */ + +#include +#include + +#include "ste_dma40_ll.h" + +/* Sets up proper LCSP1 and LCSP3 register for a logical channel */ +void d40_log_cfg(struct stedma40_chan_cfg *cfg, + u32 *lcsp1, u32 *lcsp3) +{ + u32 l3 = 0; /* dst */ + u32 l1 = 0; /* src */ + + /* src is mem? -> increase address pos */ + if (cfg->dir == STEDMA40_MEM_TO_PERIPH || + cfg->dir == STEDMA40_MEM_TO_MEM) + l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS; + + /* dst is mem? -> increase address pos */ + if (cfg->dir == STEDMA40_PERIPH_TO_MEM || + cfg->dir == STEDMA40_MEM_TO_MEM) + l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS; + + /* src is hw? -> master port 1 */ + if (cfg->dir == STEDMA40_PERIPH_TO_MEM || + cfg->dir == STEDMA40_PERIPH_TO_PERIPH) + l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS; + + /* dst is hw? -> master port 1 */ + if (cfg->dir == STEDMA40_MEM_TO_PERIPH || + cfg->dir == STEDMA40_PERIPH_TO_PERIPH) + l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS; + + l3 |= 1 << D40_MEM_LCSP3_DCFG_TIM_POS; + l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS; + l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; + l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS; + l3 |= 1 << D40_MEM_LCSP3_DTCP_POS; + + l1 |= 1 << D40_MEM_LCSP1_SCFG_EIM_POS; + l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; + l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS; + l1 |= 1 << D40_MEM_LCSP1_STCP_POS; + + *lcsp1 = l1; + *lcsp3 = l3; + +} + +/* Sets up SRC and DST CFG register for both logical and physical channels */ +void d40_phy_cfg(struct stedma40_chan_cfg *cfg, + u32 *src_cfg, u32 *dst_cfg, bool is_log) +{ + u32 src = 0; + u32 dst = 0; + + if (!is_log) { + /* Physical channel */ + if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || + (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + /* Set master port to 1 */ + src |= 1 << D40_SREG_CFG_MST_POS; + src |= D40_TYPE_TO_EVENT(cfg->src_dev_type); + + if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) + src |= 1 << D40_SREG_CFG_PHY_TM_POS; + else + src |= 3 << D40_SREG_CFG_PHY_TM_POS; + } + if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || + (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + /* Set master port to 1 */ + dst |= 1 << D40_SREG_CFG_MST_POS; + dst |= D40_TYPE_TO_EVENT(cfg->dst_dev_type); + + if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) + dst |= 1 << D40_SREG_CFG_PHY_TM_POS; + else + dst |= 3 << D40_SREG_CFG_PHY_TM_POS; + } + /* Interrupt on end of transfer for destination */ + dst |= 1 << D40_SREG_CFG_TIM_POS; + + /* Generate interrupt on error */ + src |= 1 << D40_SREG_CFG_EIM_POS; + dst |= 1 << D40_SREG_CFG_EIM_POS; + + /* PSIZE */ + if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { + src |= 1 << D40_SREG_CFG_PHY_PEN_POS; + src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; + } + if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { + dst |= 1 << D40_SREG_CFG_PHY_PEN_POS; + dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; + } + + /* Element size */ + src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; + dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; + + } else { + /* Logical channel */ + dst |= 1 << D40_SREG_CFG_LOG_GIM_POS; + src |= 1 << D40_SREG_CFG_LOG_GIM_POS; + } + + if (cfg->channel_type & STEDMA40_HIGH_PRIORITY_CHANNEL) { + src |= 1 << D40_SREG_CFG_PRI_POS; + dst |= 1 << D40_SREG_CFG_PRI_POS; + } + + src |= cfg->src_info.endianess << D40_SREG_CFG_LBE_POS; + dst |= cfg->dst_info.endianess << D40_SREG_CFG_LBE_POS; + + *src_cfg = src; + *dst_cfg = dst; +} + +int d40_phy_fill_lli(struct d40_phy_lli *lli, + dma_addr_t data, + u32 data_size, + int psize, + dma_addr_t next_lli, + u32 reg_cfg, + bool term_int, + u32 data_width, + bool is_device) +{ + int num_elems; + + if (psize == STEDMA40_PSIZE_PHY_1) + num_elems = 1; + else + num_elems = 2 << psize; + + /* + * Size is 16bit. data_width is 8, 16, 32 or 64 bit + * Block large than 64 KiB must be split. + */ + if (data_size > (0xffff << data_width)) + return -EINVAL; + + /* Must be aligned */ + if (!IS_ALIGNED(data, 0x1 << data_width)) + return -EINVAL; + + /* Transfer size can't be smaller than (num_elms * elem_size) */ + if (data_size < num_elems * (0x1 << data_width)) + return -EINVAL; + + /* The number of elements. IE now many chunks */ + lli->reg_elt = (data_size >> data_width) << D40_SREG_ELEM_PHY_ECNT_POS; + + /* + * Distance to next element sized entry. + * Usually the size of the element unless you want gaps. + */ + if (!is_device) + lli->reg_elt |= (0x1 << data_width) << + D40_SREG_ELEM_PHY_EIDX_POS; + + /* Where the data is */ + lli->reg_ptr = data; + lli->reg_cfg = reg_cfg; + + /* If this scatter list entry is the last one, no next link */ + if (next_lli == 0) + lli->reg_lnk = 0x1 << D40_SREG_LNK_PHY_TCP_POS; + else + lli->reg_lnk = next_lli; + + /* Set/clear interrupt generation on this link item.*/ + if (term_int) + lli->reg_cfg |= 0x1 << D40_SREG_CFG_TIM_POS; + else + lli->reg_cfg &= ~(0x1 << D40_SREG_CFG_TIM_POS); + + /* Post link */ + lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS; + + return 0; +} + +int d40_phy_sg_to_lli(struct scatterlist *sg, + int sg_len, + dma_addr_t target, + struct d40_phy_lli *lli, + dma_addr_t lli_phys, + u32 reg_cfg, + u32 data_width, + int psize, + bool term_int) +{ + int total_size = 0; + int i; + struct scatterlist *current_sg = sg; + dma_addr_t next_lli_phys; + dma_addr_t dst; + int err = 0; + + for_each_sg(sg, current_sg, sg_len, i) { + + total_size += sg_dma_len(current_sg); + + /* If this scatter list entry is the last one, no next link */ + if (sg_len - 1 == i) + next_lli_phys = 0; + else + next_lli_phys = ALIGN(lli_phys + (i + 1) * + sizeof(struct d40_phy_lli), + D40_LLI_ALIGN); + + if (target) + dst = target; + else + dst = sg_phys(current_sg); + + err = d40_phy_fill_lli(&lli[i], + dst, + sg_dma_len(current_sg), + psize, + next_lli_phys, + reg_cfg, + !next_lli_phys, + data_width, + target == dst); + if (err) + goto err; + } + + return total_size; + err: + return err; +} + + +void d40_phy_lli_write(void __iomem *virtbase, + u32 phy_chan_num, + struct d40_phy_lli *lli_dst, + struct d40_phy_lli *lli_src) +{ + + writel(lli_src->reg_cfg, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSCFG); + writel(lli_src->reg_elt, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSELT); + writel(lli_src->reg_ptr, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSPTR); + writel(lli_src->reg_lnk, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSLNK); + + writel(lli_dst->reg_cfg, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDCFG); + writel(lli_dst->reg_elt, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDELT); + writel(lli_dst->reg_ptr, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDPTR); + writel(lli_dst->reg_lnk, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDLNK); + +} + +/* DMA logical lli operations */ + +void d40_log_fill_lli(struct d40_log_lli *lli, + dma_addr_t data, u32 data_size, + u32 lli_next_off, u32 reg_cfg, + u32 data_width, + bool term_int, bool addr_inc) +{ + lli->lcsp13 = reg_cfg; + + /* The number of elements to transfer */ + lli->lcsp02 = ((data_size >> data_width) << + D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK; + /* 16 LSBs address of the current element */ + lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK; + /* 16 MSBs address of the current element */ + lli->lcsp13 |= data & D40_MEM_LCSP1_SPTR_MASK; + + if (addr_inc) + lli->lcsp13 |= D40_MEM_LCSP1_SCFG_INCR_MASK; + + lli->lcsp13 |= D40_MEM_LCSP3_DTCP_MASK; + /* If this scatter list entry is the last one, no next link */ + lli->lcsp13 |= (lli_next_off << D40_MEM_LCSP1_SLOS_POS) & + D40_MEM_LCSP1_SLOS_MASK; + + if (term_int) + lli->lcsp13 |= D40_MEM_LCSP1_SCFG_TIM_MASK; + else + lli->lcsp13 &= ~D40_MEM_LCSP1_SCFG_TIM_MASK; +} + +int d40_log_sg_to_dev(struct d40_lcla_elem *lcla, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli_bidir *lli, + struct d40_def_lcsp *lcsp, + u32 src_data_width, + u32 dst_data_width, + enum dma_data_direction direction, + bool term_int, dma_addr_t dev_addr, int max_len, + int llis_per_log) +{ + int total_size = 0; + struct scatterlist *current_sg = sg; + int i; + u32 next_lli_off_dst; + u32 next_lli_off_src; + + next_lli_off_src = 0; + next_lli_off_dst = 0; + + for_each_sg(sg, current_sg, sg_len, i) { + total_size += sg_dma_len(current_sg); + + /* + * If this scatter list entry is the last one or + * max length, terminate link. + */ + if (sg_len - 1 == i || ((i+1) % max_len == 0)) { + next_lli_off_src = 0; + next_lli_off_dst = 0; + } else { + if (next_lli_off_dst == 0 && + next_lli_off_src == 0) { + /* The first lli will be at next_lli_off */ + next_lli_off_dst = (lcla->dst_id * + llis_per_log + 1); + next_lli_off_src = (lcla->src_id * + llis_per_log + 1); + } else { + next_lli_off_dst++; + next_lli_off_src++; + } + } + + if (direction == DMA_TO_DEVICE) { + d40_log_fill_lli(&lli->src[i], + sg_phys(current_sg), + sg_dma_len(current_sg), + next_lli_off_src, + lcsp->lcsp1, src_data_width, + term_int && !next_lli_off_src, + true); + d40_log_fill_lli(&lli->dst[i], + dev_addr, + sg_dma_len(current_sg), + next_lli_off_dst, + lcsp->lcsp3, dst_data_width, + /* No next == terminal interrupt */ + term_int && !next_lli_off_dst, + false); + } else { + d40_log_fill_lli(&lli->dst[i], + sg_phys(current_sg), + sg_dma_len(current_sg), + next_lli_off_dst, + lcsp->lcsp3, dst_data_width, + /* No next == terminal interrupt */ + term_int && !next_lli_off_dst, + true); + d40_log_fill_lli(&lli->src[i], + dev_addr, + sg_dma_len(current_sg), + next_lli_off_src, + lcsp->lcsp1, src_data_width, + term_int && !next_lli_off_src, + false); + } + } + return total_size; +} + +int d40_log_sg_to_lli(int lcla_id, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli *lli_sg, + u32 lcsp13, /* src or dst*/ + u32 data_width, + bool term_int, int max_len, int llis_per_log) +{ + int total_size = 0; + struct scatterlist *current_sg = sg; + int i; + u32 next_lli_off = 0; + + for_each_sg(sg, current_sg, sg_len, i) { + total_size += sg_dma_len(current_sg); + + /* + * If this scatter list entry is the last one or + * max length, terminate link. + */ + if (sg_len - 1 == i || ((i+1) % max_len == 0)) + next_lli_off = 0; + else { + if (next_lli_off == 0) + /* The first lli will be at next_lli_off */ + next_lli_off = lcla_id * llis_per_log + 1; + else + next_lli_off++; + } + + d40_log_fill_lli(&lli_sg[i], + sg_phys(current_sg), + sg_dma_len(current_sg), + next_lli_off, + lcsp13, data_width, + term_int && !next_lli_off, + true); + } + return total_size; +} + +void d40_log_lli_write(struct d40_log_lli_full *lcpa, + struct d40_log_lli *lcla_src, + struct d40_log_lli *lcla_dst, + struct d40_log_lli *lli_dst, + struct d40_log_lli *lli_src, + int llis_per_log) +{ + u32 slos = 0; + u32 dlos = 0; + int i; + + lcpa->lcsp0 = lli_src->lcsp02; + lcpa->lcsp1 = lli_src->lcsp13; + lcpa->lcsp2 = lli_dst->lcsp02; + lcpa->lcsp3 = lli_dst->lcsp13; + + slos = lli_src->lcsp13 & D40_MEM_LCSP1_SLOS_MASK; + dlos = lli_dst->lcsp13 & D40_MEM_LCSP3_DLOS_MASK; + + for (i = 0; (i < llis_per_log) && slos && dlos; i++) { + writel(lli_src[i+1].lcsp02, &lcla_src[i].lcsp02); + writel(lli_src[i+1].lcsp13, &lcla_src[i].lcsp13); + writel(lli_dst[i+1].lcsp02, &lcla_dst[i].lcsp02); + writel(lli_dst[i+1].lcsp13, &lcla_dst[i].lcsp13); + + slos = lli_src[i+1].lcsp13 & D40_MEM_LCSP1_SLOS_MASK; + dlos = lli_dst[i+1].lcsp13 & D40_MEM_LCSP3_DLOS_MASK; + } +} diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h new file mode 100644 index 000000000000..2029280cb332 --- /dev/null +++ b/drivers/dma/ste_dma40_ll.h @@ -0,0 +1,354 @@ +/* + * driver/dma/ste_dma40_ll.h + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + */ +#ifndef STE_DMA40_LL_H +#define STE_DMA40_LL_H + +#define D40_DREG_PCBASE 0x400 +#define D40_DREG_PCDELTA (8 * 4) +#define D40_LLI_ALIGN 16 /* LLI alignment must be 16 bytes. */ + +#define D40_TYPE_TO_GROUP(type) (type / 16) +#define D40_TYPE_TO_EVENT(type) (type % 16) + +/* Most bits of the CFG register are the same in log as in phy mode */ +#define D40_SREG_CFG_MST_POS 15 +#define D40_SREG_CFG_TIM_POS 14 +#define D40_SREG_CFG_EIM_POS 13 +#define D40_SREG_CFG_LOG_INCR_POS 12 +#define D40_SREG_CFG_PHY_PEN_POS 12 +#define D40_SREG_CFG_PSIZE_POS 10 +#define D40_SREG_CFG_ESIZE_POS 8 +#define D40_SREG_CFG_PRI_POS 7 +#define D40_SREG_CFG_LBE_POS 6 +#define D40_SREG_CFG_LOG_GIM_POS 5 +#define D40_SREG_CFG_LOG_MFU_POS 4 +#define D40_SREG_CFG_PHY_TM_POS 4 +#define D40_SREG_CFG_PHY_EVTL_POS 0 + + +/* Standard channel parameters - basic mode (element register) */ +#define D40_SREG_ELEM_PHY_ECNT_POS 16 +#define D40_SREG_ELEM_PHY_EIDX_POS 0 + +#define D40_SREG_ELEM_PHY_ECNT_MASK (0xFFFF << D40_SREG_ELEM_PHY_ECNT_POS) + +/* Standard channel parameters - basic mode (Link register) */ +#define D40_SREG_LNK_PHY_TCP_POS 0 +#define D40_SREG_LNK_PHY_LMP_POS 1 +#define D40_SREG_LNK_PHY_PRE_POS 2 +/* + * Source destination link address. Contains the + * 29-bit byte word aligned address of the reload area. + */ +#define D40_SREG_LNK_PHYS_LNK_MASK 0xFFFFFFF8UL + +/* Standard basic channel logical mode */ + +/* Element register */ +#define D40_SREG_ELEM_LOG_ECNT_POS 16 +#define D40_SREG_ELEM_LOG_LIDX_POS 8 +#define D40_SREG_ELEM_LOG_LOS_POS 1 +#define D40_SREG_ELEM_LOG_TCP_POS 0 + +#define D40_SREG_ELEM_LOG_LIDX_MASK (0xFF << D40_SREG_ELEM_LOG_LIDX_POS) + +/* Link register */ +#define D40_DEACTIVATE_EVENTLINE 0x0 +#define D40_ACTIVATE_EVENTLINE 0x1 +#define D40_EVENTLINE_POS(i) (2 * i) +#define D40_EVENTLINE_MASK(i) (0x3 << D40_EVENTLINE_POS(i)) + +/* Standard basic channel logical params in memory */ + +/* LCSP0 */ +#define D40_MEM_LCSP0_ECNT_POS 16 +#define D40_MEM_LCSP0_SPTR_POS 0 + +#define D40_MEM_LCSP0_ECNT_MASK (0xFFFF << D40_MEM_LCSP0_ECNT_POS) +#define D40_MEM_LCSP0_SPTR_MASK (0xFFFF << D40_MEM_LCSP0_SPTR_POS) + +/* LCSP1 */ +#define D40_MEM_LCSP1_SPTR_POS 16 +#define D40_MEM_LCSP1_SCFG_MST_POS 15 +#define D40_MEM_LCSP1_SCFG_TIM_POS 14 +#define D40_MEM_LCSP1_SCFG_EIM_POS 13 +#define D40_MEM_LCSP1_SCFG_INCR_POS 12 +#define D40_MEM_LCSP1_SCFG_PSIZE_POS 10 +#define D40_MEM_LCSP1_SCFG_ESIZE_POS 8 +#define D40_MEM_LCSP1_SLOS_POS 1 +#define D40_MEM_LCSP1_STCP_POS 0 + +#define D40_MEM_LCSP1_SPTR_MASK (0xFFFF << D40_MEM_LCSP1_SPTR_POS) +#define D40_MEM_LCSP1_SCFG_TIM_MASK (0x1 << D40_MEM_LCSP1_SCFG_TIM_POS) +#define D40_MEM_LCSP1_SCFG_INCR_MASK (0x1 << D40_MEM_LCSP1_SCFG_INCR_POS) +#define D40_MEM_LCSP1_SCFG_PSIZE_MASK (0x3 << D40_MEM_LCSP1_SCFG_PSIZE_POS) +#define D40_MEM_LCSP1_SLOS_MASK (0x7F << D40_MEM_LCSP1_SLOS_POS) +#define D40_MEM_LCSP1_STCP_MASK (0x1 << D40_MEM_LCSP1_STCP_POS) + +/* LCSP2 */ +#define D40_MEM_LCSP2_ECNT_POS 16 + +#define D40_MEM_LCSP2_ECNT_MASK (0xFFFF << D40_MEM_LCSP2_ECNT_POS) + +/* LCSP3 */ +#define D40_MEM_LCSP3_DCFG_MST_POS 15 +#define D40_MEM_LCSP3_DCFG_TIM_POS 14 +#define D40_MEM_LCSP3_DCFG_EIM_POS 13 +#define D40_MEM_LCSP3_DCFG_INCR_POS 12 +#define D40_MEM_LCSP3_DCFG_PSIZE_POS 10 +#define D40_MEM_LCSP3_DCFG_ESIZE_POS 8 +#define D40_MEM_LCSP3_DLOS_POS 1 +#define D40_MEM_LCSP3_DTCP_POS 0 + +#define D40_MEM_LCSP3_DLOS_MASK (0x7F << D40_MEM_LCSP3_DLOS_POS) +#define D40_MEM_LCSP3_DTCP_MASK (0x1 << D40_MEM_LCSP3_DTCP_POS) + + +/* Standard channel parameter register offsets */ +#define D40_CHAN_REG_SSCFG 0x00 +#define D40_CHAN_REG_SSELT 0x04 +#define D40_CHAN_REG_SSPTR 0x08 +#define D40_CHAN_REG_SSLNK 0x0C +#define D40_CHAN_REG_SDCFG 0x10 +#define D40_CHAN_REG_SDELT 0x14 +#define D40_CHAN_REG_SDPTR 0x18 +#define D40_CHAN_REG_SDLNK 0x1C + +/* DMA Register Offsets */ +#define D40_DREG_GCC 0x000 +#define D40_DREG_PRTYP 0x004 +#define D40_DREG_PRSME 0x008 +#define D40_DREG_PRSMO 0x00C +#define D40_DREG_PRMSE 0x010 +#define D40_DREG_PRMSO 0x014 +#define D40_DREG_PRMOE 0x018 +#define D40_DREG_PRMOO 0x01C +#define D40_DREG_LCPA 0x020 +#define D40_DREG_LCLA 0x024 +#define D40_DREG_ACTIVE 0x050 +#define D40_DREG_ACTIVO 0x054 +#define D40_DREG_FSEB1 0x058 +#define D40_DREG_FSEB2 0x05C +#define D40_DREG_PCMIS 0x060 +#define D40_DREG_PCICR 0x064 +#define D40_DREG_PCTIS 0x068 +#define D40_DREG_PCEIS 0x06C +#define D40_DREG_LCMIS0 0x080 +#define D40_DREG_LCMIS1 0x084 +#define D40_DREG_LCMIS2 0x088 +#define D40_DREG_LCMIS3 0x08C +#define D40_DREG_LCICR0 0x090 +#define D40_DREG_LCICR1 0x094 +#define D40_DREG_LCICR2 0x098 +#define D40_DREG_LCICR3 0x09C +#define D40_DREG_LCTIS0 0x0A0 +#define D40_DREG_LCTIS1 0x0A4 +#define D40_DREG_LCTIS2 0x0A8 +#define D40_DREG_LCTIS3 0x0AC +#define D40_DREG_LCEIS0 0x0B0 +#define D40_DREG_LCEIS1 0x0B4 +#define D40_DREG_LCEIS2 0x0B8 +#define D40_DREG_LCEIS3 0x0BC +#define D40_DREG_STFU 0xFC8 +#define D40_DREG_ICFG 0xFCC +#define D40_DREG_PERIPHID0 0xFE0 +#define D40_DREG_PERIPHID1 0xFE4 +#define D40_DREG_PERIPHID2 0xFE8 +#define D40_DREG_PERIPHID3 0xFEC +#define D40_DREG_CELLID0 0xFF0 +#define D40_DREG_CELLID1 0xFF4 +#define D40_DREG_CELLID2 0xFF8 +#define D40_DREG_CELLID3 0xFFC + +/* LLI related structures */ + +/** + * struct d40_phy_lli - The basic configration register for each physical + * channel. + * + * @reg_cfg: The configuration register. + * @reg_elt: The element register. + * @reg_ptr: The pointer register. + * @reg_lnk: The link register. + * + * These registers are set up for both physical and logical transfers + * Note that the bit in each register means differently in logical and + * physical(standard) mode. + * + * This struct must be 16 bytes aligned, and only contain physical registers + * since it will be directly accessed by the DMA. + */ +struct d40_phy_lli { + u32 reg_cfg; + u32 reg_elt; + u32 reg_ptr; + u32 reg_lnk; +}; + +/** + * struct d40_phy_lli_bidir - struct for a transfer. + * + * @src: Register settings for src channel. + * @dst: Register settings for dst channel. + * @dst_addr: Physical destination address. + * @src_addr: Physical source address. + * + * All DMA transfers have a source and a destination. + */ + +struct d40_phy_lli_bidir { + struct d40_phy_lli *src; + struct d40_phy_lli *dst; + dma_addr_t dst_addr; + dma_addr_t src_addr; +}; + + +/** + * struct d40_log_lli - logical lli configuration + * + * @lcsp02: Either maps to register lcsp0 if src or lcsp2 if dst. + * @lcsp13: Either maps to register lcsp1 if src or lcsp3 if dst. + * + * This struct must be 8 bytes aligned since it will be accessed directy by + * the DMA. Never add any none hw mapped registers to this struct. + */ + +struct d40_log_lli { + u32 lcsp02; + u32 lcsp13; +}; + +/** + * struct d40_log_lli_bidir - For both src and dst + * + * @src: pointer to src lli configuration. + * @dst: pointer to dst lli configuration. + * + * You always have a src and a dst when doing DMA transfers. + */ + +struct d40_log_lli_bidir { + struct d40_log_lli *src; + struct d40_log_lli *dst; +}; + +/** + * struct d40_log_lli_full - LCPA layout + * + * @lcsp0: Logical Channel Standard Param 0 - Src. + * @lcsp1: Logical Channel Standard Param 1 - Src. + * @lcsp2: Logical Channel Standard Param 2 - Dst. + * @lcsp3: Logical Channel Standard Param 3 - Dst. + * + * This struct maps to LCPA physical memory layout. Must map to + * the hw. + */ +struct d40_log_lli_full { + u32 lcsp0; + u32 lcsp1; + u32 lcsp2; + u32 lcsp3; +}; + +/** + * struct d40_def_lcsp - Default LCSP1 and LCSP3 settings + * + * @lcsp3: The default configuration for dst. + * @lcsp1: The default configuration for src. + */ +struct d40_def_lcsp { + u32 lcsp3; + u32 lcsp1; +}; + +/** + * struct d40_lcla_elem - Info for one LCA element. + * + * @src_id: logical channel src id + * @dst_id: logical channel dst id + * @src: LCPA formated src parameters + * @dst: LCPA formated dst parameters + * + */ +struct d40_lcla_elem { + int src_id; + int dst_id; + struct d40_log_lli *src; + struct d40_log_lli *dst; +}; + +/* Physical channels */ + +void d40_phy_cfg(struct stedma40_chan_cfg *cfg, + u32 *src_cfg, u32 *dst_cfg, bool is_log); + +void d40_log_cfg(struct stedma40_chan_cfg *cfg, + u32 *lcsp1, u32 *lcsp2); + +int d40_phy_sg_to_lli(struct scatterlist *sg, + int sg_len, + dma_addr_t target, + struct d40_phy_lli *lli, + dma_addr_t lli_phys, + u32 reg_cfg, + u32 data_width, + int psize, + bool term_int); + +int d40_phy_fill_lli(struct d40_phy_lli *lli, + dma_addr_t data, + u32 data_size, + int psize, + dma_addr_t next_lli, + u32 reg_cfg, + bool term_int, + u32 data_width, + bool is_device); + +void d40_phy_lli_write(void __iomem *virtbase, + u32 phy_chan_num, + struct d40_phy_lli *lli_dst, + struct d40_phy_lli *lli_src); + +/* Logical channels */ + +void d40_log_fill_lli(struct d40_log_lli *lli, + dma_addr_t data, u32 data_size, + u32 lli_next_off, u32 reg_cfg, + u32 data_width, + bool term_int, bool addr_inc); + +int d40_log_sg_to_dev(struct d40_lcla_elem *lcla, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli_bidir *lli, + struct d40_def_lcsp *lcsp, + u32 src_data_width, + u32 dst_data_width, + enum dma_data_direction direction, + bool term_int, dma_addr_t dev_addr, int max_len, + int llis_per_log); + +void d40_log_lli_write(struct d40_log_lli_full *lcpa, + struct d40_log_lli *lcla_src, + struct d40_log_lli *lcla_dst, + struct d40_log_lli *lli_dst, + struct d40_log_lli *lli_src, + int llis_per_log); + +int d40_log_sg_to_lli(int lcla_id, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli *lli_sg, + u32 lcsp13, /* src or dst*/ + u32 data_width, + bool term_int, int max_len, int llis_per_log); + +#endif /* STE_DMA40_LLI_H */ -- cgit v1.2.3-59-g8ed1b From fecf066c2d2fbc7e6a7e7e3a5af772a165bdd7b0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 15 Apr 2010 11:59:28 +0900 Subject: sh: Disable IRQ balancing for timer and IPI IRQs. Make sure that the timer IRQs and IPIs aren't enabled for IRQ balancing. IPIs are disabled as a result of being percpu while the timers simply disable balancing outright. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/smp-shx3.c | 4 ++-- drivers/clocksource/sh_cmt.c | 3 ++- drivers/clocksource/sh_mtu2.c | 3 ++- drivers/clocksource/sh_tmu.c | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c index 11bf4c1e25c0..c98b4574c44e 100644 --- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c @@ -72,8 +72,8 @@ void __init plat_prepare_cpus(unsigned int max_cpus) BUILD_BUG_ON(SMP_MSG_NR >= 8); for (i = 0; i < SMP_MSG_NR; i++) - request_irq(104 + i, ipi_interrupt_handler, IRQF_DISABLED, - "IPI", (void *)(long)i); + request_irq(104 + i, ipi_interrupt_handler, + IRQF_DISABLED | IRQF_PERCPU, "IPI", (void *)(long)i); } void plat_start_cpu(unsigned int cpu, unsigned long entry_point) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index c5f66171a713..45be4dcb9514 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -605,7 +605,8 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) p->irqaction.name = dev_name(&p->pdev->dev); p->irqaction.handler = sh_cmt_interrupt; p->irqaction.dev_id = p; - p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL; + p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \ + IRQF_IRQPOLL | IRQF_NOBALANCING; /* get hold of clock */ p->clk = clk_get(&p->pdev->dev, "cmt_fck"); diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index b11882e0f1bd..644ecbbed256 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -280,7 +280,8 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev) p->irqaction.handler = sh_mtu2_interrupt; p->irqaction.dev_id = p; p->irqaction.irq = irq; - p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL; + p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \ + IRQF_IRQPOLL | IRQF_NOBALANCING; /* get hold of clock */ p->clk = clk_get(&p->pdev->dev, "mtu2_fck"); diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 6b62283c1aba..44c39a363768 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -384,7 +384,8 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) p->irqaction.handler = sh_tmu_interrupt; p->irqaction.dev_id = p; p->irqaction.irq = irq; - p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL; + p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \ + IRQF_IRQPOLL | IRQF_NOBALANCING; /* get hold of clock */ p->clk = clk_get(&p->pdev->dev, "tmu_fck"); -- cgit v1.2.3-59-g8ed1b From dc825b17904a06bbd2f79d720b23156e4c01a22f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 15 Apr 2010 13:13:52 +0900 Subject: sh: intc: IRQ auto-distribution support. This implements support for hardware-managed IRQ balancing as implemented by SH-X3 cores (presently only hooked up for SH7786, but can probably be carried over to other SH-X3 cores, too). CPUs need to specify their distribution register along with the mask definitions, as these follow the same format. Peripheral IRQs that don't opt out of balancing will be automatically distributed at the whim of the hardware block, while each CPU needs to verify whether it is handling the IRQ or not, especially before clearing the mask. Signed-off-by: Paul Mundt --- arch/sh/include/asm/irq.h | 16 +++ arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 36 +++++- arch/sh/kernel/irq.c | 49 ++++---- drivers/sh/Kconfig | 11 ++ drivers/sh/intc.c | 200 ++++++++++++++++++++++++--------- include/linux/sh_intc.h | 11 +- 6 files changed, 244 insertions(+), 79 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/irq.h b/arch/sh/include/asm/irq.h index df8e1500527c..99c593b3a827 100644 --- a/arch/sh/include/asm/irq.h +++ b/arch/sh/include/asm/irq.h @@ -11,6 +11,14 @@ #define NR_IRQS 256 #define NR_IRQS_LEGACY 8 /* Legacy external IRQ0-7 */ +/* + * This is a special IRQ number for indicating that no IRQ has been + * triggered and to simply ignore the IRQ dispatch. This is a special + * case that can happen with IRQ auto-distribution when multiple CPUs + * are woken up and signalled in parallel. + */ +#define NO_IRQ_IGNORE ((unsigned int)-1) + /* * Convert back and forth between INTEVT and IRQ values. */ @@ -53,6 +61,14 @@ extern void irq_ctx_exit(int cpu); # define irq_ctx_exit(cpu) do { } while (0) #endif +#ifdef CONFIG_INTC_BALANCING +extern unsigned int irq_lookup(unsigned int irq); +extern void irq_finish(unsigned int irq); +#else +#define irq_lookup(irq) (irq) +#define irq_finish(irq) do { } while (0) +#endif + #include #ifdef CONFIG_CPU_SH5 #include diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 235edf8065df..d7336036d04d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -573,7 +573,6 @@ static struct platform_device *sh7786_devices[] __initdata = { &usb_ohci_device, }; - /* * Please call this function if your platform board * use external clock for USB @@ -581,6 +580,7 @@ static struct platform_device *sh7786_devices[] __initdata = { #define USBCTL0 0xffe70858 #define CLOCK_MODE_MASK 0xffffff7f #define EXT_CLOCK_MODE 0x00000080 + void __init sh7786_usb_use_exclock(void) { u32 val = __raw_readl(USBCTL0) & CLOCK_MODE_MASK; @@ -598,6 +598,7 @@ void __init sh7786_usb_use_exclock(void) #define PLL_ENB 0x00000002 #define PHY_RST 0x00000004 #define ACT_PLL_STATUS 0xc0000000 + static void __init sh7786_usb_setup(void) { int i = 1000000; @@ -753,9 +754,19 @@ static struct intc_vect vectors[] __initdata = { #define INTMSK2 0xfe410068 #define INTMSKCLR2 0xfe41006c +#define INTDISTCR0 0xfe4100b0 +#define INTDISTCR1 0xfe4100b4 +#define INTACK 0xfe4100b8 +#define INTACKCLR 0xfe4100bc +#define INT2DISTCR0 0xfe410900 +#define INT2DISTCR1 0xfe410904 +#define INT2DISTCR2 0xfe410908 +#define INT2DISTCR3 0xfe41090c + static struct intc_mask_reg mask_registers[] __initdata = { { CnINTMSK0, CnINTMSKCLR0, 32, - { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 }, + INTC_SMP_BALANCING(INTDISTCR0) }, { INTMSK2, INTMSKCLR2, 32, { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH, IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH, @@ -767,7 +778,8 @@ static struct intc_mask_reg mask_registers[] __initdata = { IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } }, { CnINT2MSKR0, CnINT2MSKCR0 , 32, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WDT } }, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WDT }, + INTC_SMP_BALANCING(INT2DISTCR0) }, { CnINT2MSKR1, CnINT2MSKCR1, 32, { TMU0_0, TMU0_1, TMU0_2, TMU0_3, TMU1_0, TMU1_1, TMU1_2, 0, DMAC0_0, DMAC0_1, DMAC0_2, DMAC0_3, DMAC0_4, DMAC0_5, DMAC0_6, @@ -776,14 +788,14 @@ static struct intc_mask_reg mask_registers[] __initdata = { HPB_0, HPB_1, HPB_2, SCIF0_0, SCIF0_1, SCIF0_2, SCIF0_3, SCIF1, - TMU2, TMU3, 0, } }, + TMU2, TMU3, 0, }, INTC_SMP_BALANCING(INT2DISTCR1) }, { CnINT2MSKR2, CnINT2MSKCR2, 32, { 0, 0, SCIF2, SCIF3, SCIF4, SCIF5, Eth_0, Eth_1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PCIeC0_0, PCIeC0_1, PCIeC0_2, PCIeC1_0, PCIeC1_1, PCIeC1_2, - USB, 0, 0 } }, + USB, 0, 0 }, INTC_SMP_BALANCING(INT2DISTCR2) }, { CnINT2MSKR3, CnINT2MSKCR3, 32, { 0, 0, 0, 0, 0, 0, I2C0, I2C1, @@ -792,7 +804,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { HAC0, HAC1, FLCTL, 0, HSPI, GPIO0, GPIO1, Thermal, - 0, 0, 0, 0, 0, 0, 0, 0 } }, + 0, 0, 0, 0, 0, 0, 0, 0 }, INTC_SMP_BALANCING(INT2DISTCR3) }, }; static struct intc_prio_reg prio_registers[] __initdata = { @@ -910,6 +922,18 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567, #define INTC_INTMSKCLR2 INTMSKCLR2 #define INTC_USERIMASK 0xfe411000 +#ifdef CONFIG_INTC_BALANCING +unsigned int irq_lookup(unsigned int irq) +{ + return __raw_readl(INTACK) & 1 ? irq : NO_IRQ_IGNORE; +} + +void irq_finish(unsigned int irq) +{ + __raw_writel(irq2evt(irq), INTACKCLR); +} +#endif + void __init plat_irq_setup(void) { /* disable IRQ3-0 + IRQ7-4 */ diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index d2d41d046657..f6a9319c28e2 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -113,19 +113,14 @@ union irq_ctx { static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly; static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; -#endif -asmlinkage __irq_entry int do_IRQ(unsigned int irq, struct pt_regs *regs) +static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; +static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; + +static inline void handle_one_irq(unsigned int irq) { - struct pt_regs *old_regs = set_irq_regs(regs); -#ifdef CONFIG_IRQSTACKS union irq_ctx *curctx, *irqctx; -#endif - - irq_enter(); - irq = irq_demux(irq); -#ifdef CONFIG_IRQSTACKS curctx = (union irq_ctx *)current_thread_info(); irqctx = hardirq_ctx[smp_processor_id()]; @@ -164,20 +159,9 @@ asmlinkage __irq_entry int do_IRQ(unsigned int irq, struct pt_regs *regs) "r5", "r6", "r7", "r8", "t", "pr" ); } else -#endif generic_handle_irq(irq); - - irq_exit(); - - set_irq_regs(old_regs); - return 1; } -#ifdef CONFIG_IRQSTACKS -static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; - -static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; - /* * allocate per-cpu stacks for hardirq and for softirq processing */ @@ -257,8 +241,33 @@ asmlinkage void do_softirq(void) local_irq_restore(flags); } +#else +static inline void handle_one_irq(unsigned int irq) +{ + generic_handle_irq(irq); +} #endif +asmlinkage __irq_entry int do_IRQ(unsigned int irq, struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + + irq_enter(); + + irq = irq_demux(irq_lookup(irq)); + + if (irq != NO_IRQ_IGNORE) { + handle_one_irq(irq); + irq_finish(irq); + } + + irq_exit(); + + set_irq_regs(old_regs); + + return IRQ_HANDLED; +} + void __init init_IRQ(void) { plat_irq_setup(); diff --git a/drivers/sh/Kconfig b/drivers/sh/Kconfig index 22c3cdaf22fe..a54de0b9b3df 100644 --- a/drivers/sh/Kconfig +++ b/drivers/sh/Kconfig @@ -11,3 +11,14 @@ config INTC_USERIMASK drivers that are using special priority levels. If in doubt, say N. + +config INTC_BALANCING + bool "Hardware IRQ balancing support" + depends on SMP && SUPERH && CPU_SUBTYPE_SH7786 + help + This enables support for IRQ auto-distribution mode on SH-X3 + SMP parts. All of the balancing and CPU wakeup decisions are + taken care of automatically by hardware for distributed + vectors. + + If in doubt, say N. diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index 77d10acf1884..dcb4c833820b 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -98,6 +98,9 @@ static DEFINE_SPINLOCK(vector_lock); static unsigned int intc_prio_level[NR_IRQS]; /* for now */ static unsigned int default_prio_level = 2; /* 2 - 16 */ static unsigned long ack_handle[NR_IRQS]; +#ifdef CONFIG_INTC_BALANCING +static unsigned long dist_handle[NR_IRQS]; +#endif static inline struct intc_desc_int *get_intc_desc(unsigned int irq) { @@ -105,6 +108,47 @@ static inline struct intc_desc_int *get_intc_desc(unsigned int irq) return container_of(chip, struct intc_desc_int, chip); } +static unsigned long intc_phys_to_virt(struct intc_desc_int *d, + unsigned long address) +{ + struct intc_window *window; + int k; + + /* scan through physical windows and convert address */ + for (k = 0; k < d->nr_windows; k++) { + window = d->window + k; + + if (address < window->phys) + continue; + + if (address >= (window->phys + window->size)) + continue; + + address -= window->phys; + address += (unsigned long)window->virt; + + return address; + } + + /* no windows defined, register must be 1:1 mapped virt:phys */ + return address; +} + +static unsigned int intc_get_reg(struct intc_desc_int *d, unsigned long address) +{ + unsigned int k; + + address = intc_phys_to_virt(d, address); + + for (k = 0; k < d->nr_reg; k++) { + if (d->reg[k] == address) + return k; + } + + BUG(); + return 0; +} + static inline unsigned int set_field(unsigned int value, unsigned int field_value, unsigned int handle) @@ -238,6 +282,85 @@ static void (*intc_disable_fns[])(unsigned long addr, [MODE_PCLR_REG] = intc_mode_field, }; +#ifdef CONFIG_INTC_BALANCING +static inline void intc_balancing_enable(unsigned int irq) +{ + struct intc_desc_int *d = get_intc_desc(irq); + unsigned long handle = dist_handle[irq]; + unsigned long addr; + + if (irq_balancing_disabled(irq) || !handle) + return; + + addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); + intc_reg_fns[_INTC_FN(handle)](addr, handle, 1); +} + +static inline void intc_balancing_disable(unsigned int irq) +{ + struct intc_desc_int *d = get_intc_desc(irq); + unsigned long handle = dist_handle[irq]; + unsigned long addr; + + if (irq_balancing_disabled(irq) || !handle) + return; + + addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); + intc_reg_fns[_INTC_FN(handle)](addr, handle, 0); +} + +static unsigned int intc_dist_data(struct intc_desc *desc, + struct intc_desc_int *d, + intc_enum enum_id) +{ + struct intc_mask_reg *mr = desc->hw.mask_regs; + unsigned int i, j, fn, mode; + unsigned long reg_e, reg_d; + + for (i = 0; mr && enum_id && i < desc->hw.nr_mask_regs; i++) { + mr = desc->hw.mask_regs + i; + + /* + * Skip this entry if there's no auto-distribution + * register associated with it. + */ + if (!mr->dist_reg) + continue; + + for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { + if (mr->enum_ids[j] != enum_id) + continue; + + fn = REG_FN_MODIFY_BASE; + mode = MODE_ENABLE_REG; + reg_e = mr->dist_reg; + reg_d = mr->dist_reg; + + fn += (mr->reg_width >> 3) - 1; + return _INTC_MK(fn, mode, + intc_get_reg(d, reg_e), + intc_get_reg(d, reg_d), + 1, + (mr->reg_width - 1) - j); + } + } + + /* + * It's possible we've gotten here with no distribution options + * available for the IRQ in question, so we just skip over those. + */ + return 0; +} +#else +static inline void intc_balancing_enable(unsigned int irq) +{ +} + +static inline void intc_balancing_disable(unsigned int irq) +{ +} +#endif + static inline void _intc_enable(unsigned int irq, unsigned long handle) { struct intc_desc_int *d = get_intc_desc(irq); @@ -253,6 +376,8 @@ static inline void _intc_enable(unsigned int irq, unsigned long handle) intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\ [_INTC_FN(handle)], irq); } + + intc_balancing_enable(irq); } static void intc_enable(unsigned int irq) @@ -263,10 +388,12 @@ static void intc_enable(unsigned int irq) static void intc_disable(unsigned int irq) { struct intc_desc_int *d = get_intc_desc(irq); - unsigned long handle = (unsigned long) get_irq_chip_data(irq); + unsigned long handle = (unsigned long)get_irq_chip_data(irq); unsigned long addr; unsigned int cpu; + intc_balancing_disable(irq); + for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { #ifdef CONFIG_SMP if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity)) @@ -345,8 +472,7 @@ static void intc_mask_ack(unsigned int irq) intc_disable(irq); - /* read register and write zero only to the assocaited bit */ - + /* read register and write zero only to the associated bit */ if (handle) { addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); switch (_INTC_FN(handle)) { @@ -375,7 +501,8 @@ static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, { int i; - /* this doesn't scale well, but... + /* + * this doesn't scale well, but... * * this function should only be used for cerain uncommon * operations such as intc_set_priority() and intc_set_sense() @@ -386,7 +513,6 @@ static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, * memory footprint down is to make sure the array is sorted * and then perform a bisect to lookup the irq. */ - for (i = 0; i < nr_hp; i++) { if ((hp + i)->irq != irq) continue; @@ -417,7 +543,6 @@ int intc_set_priority(unsigned int irq, unsigned int prio) * primary masking method is using intc_prio_level[irq] * priority level will be set during next enable() */ - if (_INTC_FN(ihp->handle) != REG_FN_ERR) _intc_enable(irq, ihp->handle); } @@ -456,48 +581,6 @@ static int intc_set_sense(unsigned int irq, unsigned int type) return 0; } -static unsigned long intc_phys_to_virt(struct intc_desc_int *d, - unsigned long address) -{ - struct intc_window *window; - int k; - - /* scan through physical windows and convert address */ - for (k = 0; k < d->nr_windows; k++) { - window = d->window + k; - - if (address < window->phys) - continue; - - if (address >= (window->phys + window->size)) - continue; - - address -= window->phys; - address += (unsigned long)window->virt; - - return address; - } - - /* no windows defined, register must be 1:1 mapped virt:phys */ - return address; -} - -static unsigned int __init intc_get_reg(struct intc_desc_int *d, - unsigned long address) -{ - unsigned int k; - - address = intc_phys_to_virt(d, address); - - for (k = 0; k < d->nr_reg; k++) { - if (d->reg[k] == address) - return k; - } - - BUG(); - return 0; -} - static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id) { @@ -755,13 +838,14 @@ static void __init intc_register_irq(struct intc_desc *desc, */ set_bit(irq, intc_irq_map); - /* Prefer single interrupt source bitmap over other combinations: + /* + * Prefer single interrupt source bitmap over other combinations: + * * 1. bitmap, single interrupt source * 2. priority, single interrupt source * 3. bitmap, multiple interrupt sources (groups) * 4. priority, multiple interrupt sources (groups) */ - data[0] = intc_mask_data(desc, d, enum_id, 0); data[1] = intc_prio_data(desc, d, enum_id, 0); @@ -786,7 +870,8 @@ static void __init intc_register_irq(struct intc_desc *desc, handle_level_irq, "level"); set_irq_chip_data(irq, (void *)data[primary]); - /* set priority level + /* + * set priority level * - this needs to be at least 2 for 5-bit priorities on 7780 */ intc_prio_level[irq] = default_prio_level; @@ -806,7 +891,6 @@ static void __init intc_register_irq(struct intc_desc *desc, * only secondary priority should access registers, so * set _INTC_FN(h) = REG_FN_ERR for intc_set_priority() */ - hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0); hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0); } @@ -827,6 +911,11 @@ static void __init intc_register_irq(struct intc_desc *desc, if (desc->hw.ack_regs) ack_handle[irq] = intc_ack_data(desc, d, enum_id); +#ifdef CONFIG_INTC_BALANCING + if (desc->hw.mask_regs) + dist_handle[irq] = intc_dist_data(desc, d, enum_id); +#endif + #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */ #endif @@ -892,6 +981,10 @@ int __init register_intc_controller(struct intc_desc *desc) } d->nr_reg = hw->mask_regs ? hw->nr_mask_regs * 2 : 0; +#ifdef CONFIG_INTC_BALANCING + if (d->nr_reg) + d->nr_reg += hw->nr_mask_regs; +#endif d->nr_reg += hw->prio_regs ? hw->nr_prio_regs * 2 : 0; d->nr_reg += hw->sense_regs ? hw->nr_sense_regs : 0; d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0; @@ -912,6 +1005,9 @@ int __init register_intc_controller(struct intc_desc *desc) smp = IS_SMP(hw->mask_regs[i]); k += save_reg(d, k, hw->mask_regs[i].set_reg, smp); k += save_reg(d, k, hw->mask_regs[i].clr_reg, smp); +#ifdef CONFIG_INTC_BALANCING + k += save_reg(d, k, hw->mask_regs[i].dist_reg, 0); +#endif } } diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h index f0e8cca199c7..0d6cd38e673d 100644 --- a/include/linux/sh_intc.h +++ b/include/linux/sh_intc.h @@ -23,6 +23,9 @@ struct intc_group { struct intc_mask_reg { unsigned long set_reg, clr_reg, reg_width; intc_enum enum_ids[32]; +#ifdef CONFIG_INTC_BALANCING + unsigned long dist_reg; +#endif #ifdef CONFIG_SMP unsigned long smp; #endif @@ -41,8 +44,14 @@ struct intc_sense_reg { intc_enum enum_ids[16]; }; +#ifdef CONFIG_INTC_BALANCING +#define INTC_SMP_BALANCING(reg) .dist_reg = (reg) +#else +#define INTC_SMP_BALANCING(reg) +#endif + #ifdef CONFIG_SMP -#define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8) +#define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8) #else #define INTC_SMP(stride, nr) #endif -- cgit v1.2.3-59-g8ed1b From a289cc7c70da784a2d370b91885cab4f966dcb0f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 16 Apr 2010 17:51:42 -0700 Subject: x86, UV: uv_irq.c: Fix all sparse warnings Fix all sparse warnings in building uv_irq.c. arch/x86/kernel/uv_irq.c:46:17: warning: symbol 'uv_irq_chip' was not declared. Should it be static? arch/x86/kernel/uv_irq.c:143:50: error: no identifier for function argument arch/x86/kernel/uv_irq.c:162:13: error: typename in expression arch/x86/kernel/uv_irq.c:162:13: error: undefined identifier 'restrict' arch/x86/kernel/uv_irq.c:250:44: error: no identifier for function argument arch/x86/kernel/uv_irq.c:260:17: error: typename in expression arch/x86/kernel/uv_irq.c:260:17: error: undefined identifier 'restrict' arch/x86/kernel/uv_irq.c:233:50: warning: incorrect type in argument 3 (different signedness) arch/x86/kernel/uv_irq.c:233:50: expected int *pnode arch/x86/kernel/uv_irq.c:233:50: got unsigned int * arch/x86/include/asm/uv/uv_hub.h:318:44: warning: incorrect type in argument 2 (different address spaces) arch/x86/include/asm/uv/uv_hub.h:318:44: expected void volatile [noderef] *addr arch/x86/include/asm/uv/uv_hub.h:318:44: got unsigned long * Signed-off-by: Randy Dunlap Cc: Dimitri Sivanich Cc: Russ Anderson Cc: Robin Holt Cc: Mike Travis Cc: Cliff Wickman Cc: Jack Steiner LKML-Reference: <20100416175142.f4b59683.randy.dunlap@oracle.com> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/uv/uv_hub.h | 2 +- arch/x86/kernel/uv_irq.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index 14cc74ba5d23..bf6b88ef8eeb 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h @@ -307,7 +307,7 @@ static inline unsigned long uv_read_global_mmr32(int pnode, unsigned long offset * Access Global MMR space using the MMR space located at the top of physical * memory. */ -static inline unsigned long *uv_global_mmr64_address(int pnode, unsigned long offset) +static inline volatile void __iomem *uv_global_mmr64_address(int pnode, unsigned long offset) { return __va(UV_GLOBAL_MMR64_BASE | UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset); diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c index ece73d8e3240..1a9f55a33489 100644 --- a/arch/x86/kernel/uv_irq.c +++ b/arch/x86/kernel/uv_irq.c @@ -43,7 +43,7 @@ static void uv_ack_apic(unsigned int irq) ack_APIC_irq(); } -struct irq_chip uv_irq_chip = { +static struct irq_chip uv_irq_chip = { .name = "UV-CORE", .startup = uv_noop_ret, .shutdown = uv_noop, @@ -140,7 +140,7 @@ int uv_irq_2_mmr_info(int irq, unsigned long *offset, int *pnode) */ static int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, - unsigned long mmr_offset, int restrict) + unsigned long mmr_offset, int limit) { const struct cpumask *eligible_cpu = cpumask_of(cpu); struct irq_desc *desc = irq_to_desc(irq); @@ -159,7 +159,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, if (err != 0) return err; - if (restrict == UV_AFFINITY_CPU) + if (limit == UV_AFFINITY_CPU) desc->status |= IRQ_NO_BALANCING; else desc->status |= IRQ_MOVE_PCNTXT; @@ -213,7 +213,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask) unsigned long mmr_value; struct uv_IO_APIC_route_entry *entry; unsigned long mmr_offset; - unsigned mmr_pnode; + int mmr_pnode; if (set_desc_affinity(desc, mask, &dest)) return -1; @@ -247,7 +247,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask) * interrupt is raised. */ int uv_setup_irq(char *irq_name, int cpu, int mmr_blade, - unsigned long mmr_offset, int restrict) + unsigned long mmr_offset, int limit) { int irq, ret; @@ -257,7 +257,7 @@ int uv_setup_irq(char *irq_name, int cpu, int mmr_blade, return -EBUSY; ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset, - restrict); + limit); if (ret == irq) uv_set_irq_2_mmr_info(irq, mmr_offset, mmr_blade); else -- cgit v1.2.3-59-g8ed1b From d9c944463d8f3f7cafaaba8f3e44df62ce817484 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 19 Apr 2010 16:27:47 +0900 Subject: sh: mach-sdk7786: pm_power_off support. This wires up power-off support for the SDK7786 board. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-sdk7786/setup.c | 14 ++++++++++++++ arch/sh/include/mach-sdk7786/mach/fpga.h | 9 +++++++++ 2 files changed, 23 insertions(+) (limited to 'arch') diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index f094ea2ee783..0c057a93fe29 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c @@ -165,6 +165,19 @@ static void sdk7786_restart(char *cmd) fpga_write_reg(0xa5a5, SRSTR); } +static void sdk7786_power_off(void) +{ + fpga_write_reg(fpga_read_reg(PWRCR) | PWRCR_PDWNREQ, PWRCR); + + /* + * It can take up to 20us for the R8C to do its job, back off and + * wait a bit until we've been shut off. Even though newer FPGA + * versions don't set the ACK bit, the latency issue remains. + */ + while ((fpga_read_reg(PWRCR) & PWRCR_PDWNACK) == 0) + cpu_sleep(); +} + /* Initialize the board */ static void __init sdk7786_setup(char **cmdline_p) { @@ -175,6 +188,7 @@ static void __init sdk7786_setup(char **cmdline_p) pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf); machine_ops.restart = sdk7786_restart; + pm_power_off = sdk7786_power_off; } /* diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h index 2120d67dec70..416b621d94d1 100644 --- a/arch/sh/include/mach-sdk7786/mach/fpga.h +++ b/arch/sh/include/mach-sdk7786/mach/fpga.h @@ -42,6 +42,15 @@ #define SCBR_I2CCEN BIT(1) /* CPU I2C master enable */ #define PWRCR 0x1a0 +#define PWRCR_SCISEL0 BIT(0) +#define PWRCR_SCISEL1 BIT(1) +#define PWRCR_SCIEN BIT(2) /* Serial port enable */ +#define PWRCR_PDWNACK BIT(5) /* Power down acknowledge */ +#define PWRCR_PDWNREQ BIT(7) /* Power down request */ +#define PWRCR_INT2 BIT(11) /* INT2 connection to power manager */ +#define PWRCR_BUPINIT BIT(13) /* DDR backup initialize */ +#define PWRCR_BKPRST BIT(15) /* Backup power reset */ + #define SPCBR 0x1b0 #define SPICR 0x1c0 #define SPIDR 0x1d0 -- cgit v1.2.3-59-g8ed1b From 3cf6fa1e334a3a4af702f92229690195018b747f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 19 Apr 2010 17:27:17 +0900 Subject: sh: Enable SH-X3 hardware synonym avoidance handling. This enables support for the hardware synonym avoidance handling on SH-X3 CPUs for the case where dcache aliases are possible. icache handling is retained, but we flip on broadcasting of the block invalidations due to the lack of coherency otherwise on SMP. Signed-off-by: Paul Mundt --- arch/sh/mm/Makefile | 1 + arch/sh/mm/cache-shx3.c | 35 +++++++++++++++++++++++++++++++++++ arch/sh/mm/cache.c | 7 +++++++ 3 files changed, 43 insertions(+) create mode 100644 arch/sh/mm/cache-shx3.c (limited to 'arch') diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index c73018a9972c..53f7c684afb2 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -10,6 +10,7 @@ cacheops-$(CONFIG_CPU_SH3) := cache-sh3.o cacheops-$(CONFIG_CPU_SH4) := cache-sh4.o flush-sh4.o cacheops-$(CONFIG_CPU_SH5) := cache-sh5.o flush-sh4.o cacheops-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o +cacheops-$(CONFIG_CPU_SHX3) += cache-shx3.o obj-y += $(cacheops-y) diff --git a/arch/sh/mm/cache-shx3.c b/arch/sh/mm/cache-shx3.c new file mode 100644 index 000000000000..65936c4fef03 --- /dev/null +++ b/arch/sh/mm/cache-shx3.c @@ -0,0 +1,35 @@ +/* + * arch/sh/mm/cache-shx3.c - SH-X3 optimized cache ops + * + * Copyright (C) 2010 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +#define CCR_CACHE_SNM 0x40000 /* Hardware-assisted synonym avoidance */ +#define CCR_CACHE_IBE 0x1000000 /* ICBI broadcast */ + +void __init shx3_cache_init(void) +{ + unsigned int ccr; + + ccr = __raw_readl(CCR); + + if (boot_cpu_data.dcache.n_aliases) + ccr |= CCR_CACHE_SNM; + +#ifdef CONFIG_SMP + /* + * Broadcast I-cache block invalidations by default. + */ + ccr |= CCR_CACHE_IBE; +#endif + + writel_uncached(ccr, CCR); +} diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index 0f4095d7ac8b..ba401d137bb9 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -334,6 +334,13 @@ void __init cpu_cache_init(void) extern void __weak sh4_cache_init(void); sh4_cache_init(); + + if ((boot_cpu_data.type == CPU_SH7786) || + (boot_cpu_data.type == CPU_SHX3)) { + extern void __weak shx3_cache_init(void); + + shx3_cache_init(); + } } if (boot_cpu_data.family == CPU_FAMILY_SH5) { -- cgit v1.2.3-59-g8ed1b From 39447b386c846bbf1c56f6403c5282837486200f Mon Sep 17 00:00:00 2001 From: "Zhang, Yanmin" Date: Mon, 19 Apr 2010 13:32:41 +0800 Subject: perf: Enhance perf to allow for guest statistic collection from host Below patch introduces perf_guest_info_callbacks and related register/unregister functions. Add more PERF_RECORD_MISC_XXX bits meaning guest kernel and guest user space. Signed-off-by: Zhang Yanmin Signed-off-by: Avi Kivity --- arch/x86/include/asm/perf_event.h | 15 ++++----------- arch/x86/kernel/cpu/perf_event.c | 31 +++++++++++++++++++++++++++++++ include/linux/perf_event.h | 21 ++++++++++++++++++++- kernel/perf_event.c | 23 ++++++++++++++++++++++- 4 files changed, 77 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index f6d43dbfd8e7..254883d0c7e0 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -135,17 +135,10 @@ extern void perf_events_lapic_init(void); */ #define PERF_EFLAGS_EXACT (1UL << 3) -#define perf_misc_flags(regs) \ -({ int misc = 0; \ - if (user_mode(regs)) \ - misc |= PERF_RECORD_MISC_USER; \ - else \ - misc |= PERF_RECORD_MISC_KERNEL; \ - if (regs->flags & PERF_EFLAGS_EXACT) \ - misc |= PERF_RECORD_MISC_EXACT; \ - misc; }) - -#define perf_instruction_pointer(regs) ((regs)->ip) +struct pt_regs; +extern unsigned long perf_instruction_pointer(struct pt_regs *regs); +extern unsigned long perf_misc_flags(struct pt_regs *regs); +#define perf_misc_flags(regs) perf_misc_flags(regs) #else static inline void init_hw_perf_events(void) { } diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 626154a9f535..2ea78abf69d9 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1720,6 +1720,11 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) { struct perf_callchain_entry *entry; + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + /* TODO: We don't support guest os callchain now */ + return NULL; + } + if (in_nmi()) entry = &__get_cpu_var(pmc_nmi_entry); else @@ -1743,3 +1748,29 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski regs->cs = __KERNEL_CS; local_save_flags(regs->flags); } + +unsigned long perf_instruction_pointer(struct pt_regs *regs) +{ + unsigned long ip; + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) + ip = perf_guest_cbs->get_guest_ip(); + else + ip = instruction_pointer(regs); + return ip; +} + +unsigned long perf_misc_flags(struct pt_regs *regs) +{ + int misc = 0; + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + misc |= perf_guest_cbs->is_user_mode() ? + PERF_RECORD_MISC_GUEST_USER : + PERF_RECORD_MISC_GUEST_KERNEL; + } else + misc |= user_mode(regs) ? PERF_RECORD_MISC_USER : + PERF_RECORD_MISC_KERNEL; + if (regs->flags & PERF_EFLAGS_EXACT) + misc |= PERF_RECORD_MISC_EXACT; + + return misc; +} diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index bf896d0b2e9c..24de5f181a41 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -288,11 +288,13 @@ struct perf_event_mmap_page { __u64 data_tail; /* user-space written tail */ }; -#define PERF_RECORD_MISC_CPUMODE_MASK (3 << 0) +#define PERF_RECORD_MISC_CPUMODE_MASK (7 << 0) #define PERF_RECORD_MISC_CPUMODE_UNKNOWN (0 << 0) #define PERF_RECORD_MISC_KERNEL (1 << 0) #define PERF_RECORD_MISC_USER (2 << 0) #define PERF_RECORD_MISC_HYPERVISOR (3 << 0) +#define PERF_RECORD_MISC_GUEST_KERNEL (4 << 0) +#define PERF_RECORD_MISC_GUEST_USER (5 << 0) #define PERF_RECORD_MISC_EXACT (1 << 14) /* @@ -446,6 +448,12 @@ enum perf_callchain_context { # include #endif +struct perf_guest_info_callbacks { + int (*is_in_guest) (void); + int (*is_user_mode) (void); + unsigned long (*get_guest_ip) (void); +}; + #ifdef CONFIG_HAVE_HW_BREAKPOINT #include #endif @@ -932,6 +940,12 @@ static inline void perf_event_mmap(struct vm_area_struct *vma) __perf_event_mmap(vma); } +extern struct perf_guest_info_callbacks *perf_guest_cbs; +extern int perf_register_guest_info_callbacks( + struct perf_guest_info_callbacks *); +extern int perf_unregister_guest_info_callbacks( + struct perf_guest_info_callbacks *); + extern void perf_event_comm(struct task_struct *tsk); extern void perf_event_fork(struct task_struct *tsk); @@ -1001,6 +1015,11 @@ perf_sw_event(u32 event_id, u64 nr, int nmi, static inline void perf_bp_event(struct perf_event *event, void *data) { } +static inline int perf_register_guest_info_callbacks +(struct perf_guest_info_callbacks *) {return 0; } +static inline int perf_unregister_guest_info_callbacks +(struct perf_guest_info_callbacks *) {return 0; } + static inline void perf_event_mmap(struct vm_area_struct *vma) { } static inline void perf_event_comm(struct task_struct *tsk) { } static inline void perf_event_fork(struct task_struct *tsk) { } diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 07b7a435bf03..9dbe8cdaf145 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -2797,6 +2797,27 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski } +/* + * We assume there is only KVM supporting the callbacks. + * Later on, we might change it to a list if there is + * another virtualization implementation supporting the callbacks. + */ +struct perf_guest_info_callbacks *perf_guest_cbs; + +int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs) +{ + perf_guest_cbs = cbs; + return 0; +} +EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks); + +int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *cbs) +{ + perf_guest_cbs = NULL; + return 0; +} +EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks); + /* * Output */ @@ -3749,7 +3770,7 @@ void __perf_event_mmap(struct vm_area_struct *vma) .event_id = { .header = { .type = PERF_RECORD_MMAP, - .misc = 0, + .misc = PERF_RECORD_MISC_USER, /* .size */ }, /* .pid */ -- cgit v1.2.3-59-g8ed1b From ff9d07a0e7ce756a183e7c2e483aec452ee6b574 Mon Sep 17 00:00:00 2001 From: "Zhang, Yanmin" Date: Mon, 19 Apr 2010 13:32:45 +0800 Subject: KVM: Implement perf callbacks for guest sampling Below patch implements the perf_guest_info_callbacks on kvm. Signed-off-by: Zhang Yanmin Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 5 ++++- arch/x86/kvm/x86.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.h | 3 +++ 3 files changed, 53 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 686492ed3079..82be6dac3d25 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3654,8 +3654,11 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) /* We need to handle NMIs before interrupts are enabled */ if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR && - (exit_intr_info & INTR_INFO_VALID_MASK)) + (exit_intr_info & INTR_INFO_VALID_MASK)) { + kvm_before_handle_nmi(&vmx->vcpu); asm("int $2"); + kvm_after_handle_nmi(&vmx->vcpu); + } idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 24cd0ee896e9..c3a33b2bb169 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #undef TRACE_INCLUDE_FILE #define CREATE_TRACE_POINTS @@ -3765,6 +3766,47 @@ static void kvm_timer_init(void) } } +static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu); + +static int kvm_is_in_guest(void) +{ + return percpu_read(current_vcpu) != NULL; +} + +static int kvm_is_user_mode(void) +{ + int user_mode = 3; + if (percpu_read(current_vcpu)) + user_mode = kvm_x86_ops->get_cpl(percpu_read(current_vcpu)); + return user_mode != 0; +} + +static unsigned long kvm_get_guest_ip(void) +{ + unsigned long ip = 0; + if (percpu_read(current_vcpu)) + ip = kvm_rip_read(percpu_read(current_vcpu)); + return ip; +} + +static struct perf_guest_info_callbacks kvm_guest_cbs = { + .is_in_guest = kvm_is_in_guest, + .is_user_mode = kvm_is_user_mode, + .get_guest_ip = kvm_get_guest_ip, +}; + +void kvm_before_handle_nmi(struct kvm_vcpu *vcpu) +{ + percpu_write(current_vcpu, vcpu); +} +EXPORT_SYMBOL_GPL(kvm_before_handle_nmi); + +void kvm_after_handle_nmi(struct kvm_vcpu *vcpu) +{ + percpu_write(current_vcpu, NULL); +} +EXPORT_SYMBOL_GPL(kvm_after_handle_nmi); + int kvm_arch_init(void *opaque) { int r; @@ -3801,6 +3843,8 @@ int kvm_arch_init(void *opaque) kvm_timer_init(); + perf_register_guest_info_callbacks(&kvm_guest_cbs); + return 0; out: @@ -3809,6 +3853,8 @@ out: void kvm_arch_exit(void) { + perf_unregister_guest_info_callbacks(&kvm_guest_cbs); + if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 2d101639bd8d..b7a404722d2b 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -65,4 +65,7 @@ static inline int is_paging(struct kvm_vcpu *vcpu) return kvm_read_cr0_bits(vcpu, X86_CR0_PG); } +void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); +void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); + #endif -- cgit v1.2.3-59-g8ed1b From 1d5cc550ede76825ab401941fb1165f2056e2c46 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 20 Apr 2010 14:34:15 +0900 Subject: sh: dwarf unwinder needs linux/module.h. Previously the struct module definition was pulled in from other headers, but we want the reference to be explicit. Fixes up randconfig build issues. Signed-off-by: Paul Mundt --- arch/sh/kernel/dwarf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 94739ee7aa74..8c09f62cebd1 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From dcf46b9443ad48a227a61713adea001228925adf Mon Sep 17 00:00:00 2001 From: "Zhang, Yanmin" Date: Tue, 20 Apr 2010 10:13:58 +0800 Subject: perf & kvm: Clean up some of the guest profiling callback API details Fix some build bug and programming style issues: - use valid C - fix up various style details Signed-off-by: Zhang Yanmin Cc: Avi Kivity Cc: Peter Zijlstra Cc: Sheng Yang Cc: Marcelo Tosatti Cc: oerg Roedel Cc: Jes Sorensen Cc: Gleb Natapov Cc: Zachary Amsden Cc: zhiteng.huang@intel.com Cc: tim.c.chen@intel.com Cc: Arnaldo Carvalho de Melo LKML-Reference: <1271729638.2078.624.camel@ymzhang.sh.intel.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 20 ++++++++++++++------ arch/x86/kvm/x86.c | 4 ++++ include/linux/perf_event.h | 10 ++++------ 3 files changed, 22 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 2ea78abf69d9..7de70613e6c3 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1752,23 +1752,31 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski unsigned long perf_instruction_pointer(struct pt_regs *regs) { unsigned long ip; + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) ip = perf_guest_cbs->get_guest_ip(); else ip = instruction_pointer(regs); + return ip; } unsigned long perf_misc_flags(struct pt_regs *regs) { int misc = 0; + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { - misc |= perf_guest_cbs->is_user_mode() ? - PERF_RECORD_MISC_GUEST_USER : - PERF_RECORD_MISC_GUEST_KERNEL; - } else - misc |= user_mode(regs) ? PERF_RECORD_MISC_USER : - PERF_RECORD_MISC_KERNEL; + if (perf_guest_cbs->is_user_mode()) + misc |= PERF_RECORD_MISC_GUEST_USER; + else + misc |= PERF_RECORD_MISC_GUEST_KERNEL; + } else { + if (user_mode(regs)) + misc |= PERF_RECORD_MISC_USER; + else + misc |= PERF_RECORD_MISC_KERNEL; + } + if (regs->flags & PERF_EFLAGS_EXACT) misc |= PERF_RECORD_MISC_EXACT; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c3a33b2bb169..21b9b6aa3e88 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3776,16 +3776,20 @@ static int kvm_is_in_guest(void) static int kvm_is_user_mode(void) { int user_mode = 3; + if (percpu_read(current_vcpu)) user_mode = kvm_x86_ops->get_cpl(percpu_read(current_vcpu)); + return user_mode != 0; } static unsigned long kvm_get_guest_ip(void) { unsigned long ip = 0; + if (percpu_read(current_vcpu)) ip = kvm_rip_read(percpu_read(current_vcpu)); + return ip; } diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 24de5f181a41..ace31fbac513 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -941,10 +941,8 @@ static inline void perf_event_mmap(struct vm_area_struct *vma) } extern struct perf_guest_info_callbacks *perf_guest_cbs; -extern int perf_register_guest_info_callbacks( - struct perf_guest_info_callbacks *); -extern int perf_unregister_guest_info_callbacks( - struct perf_guest_info_callbacks *); +extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks); +extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks); extern void perf_event_comm(struct task_struct *tsk); extern void perf_event_fork(struct task_struct *tsk); @@ -1016,9 +1014,9 @@ static inline void perf_bp_event(struct perf_event *event, void *data) { } static inline int perf_register_guest_info_callbacks -(struct perf_guest_info_callbacks *) {return 0; } +(struct perf_guest_info_callbacks *callbacks) { return 0; } static inline int perf_unregister_guest_info_callbacks -(struct perf_guest_info_callbacks *) {return 0; } +(struct perf_guest_info_callbacks *callbacks) { return 0; } static inline void perf_event_mmap(struct vm_area_struct *vma) { } static inline void perf_event_comm(struct task_struct *tsk) { } -- cgit v1.2.3-59-g8ed1b From 88253e845996670f56635b054550fa45e1fec3d8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 20 Apr 2010 15:37:23 +0900 Subject: sh: Zero out aliases counter when using SH-X3 hardware assistance. This zeroes out the number of cache aliases in the cache info descriptors when hardware alias avoidance is enabled. This cuts down on the amount of flushing taken care of by common code, and also permits coherency control to be disabled for the single CPU and 4k page size case. Signed-off-by: Paul Mundt --- arch/sh/mm/cache-shx3.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/mm/cache-shx3.c b/arch/sh/mm/cache-shx3.c index 65936c4fef03..c0adbee97b5f 100644 --- a/arch/sh/mm/cache-shx3.c +++ b/arch/sh/mm/cache-shx3.c @@ -21,9 +21,18 @@ void __init shx3_cache_init(void) ccr = __raw_readl(CCR); - if (boot_cpu_data.dcache.n_aliases) + /* + * If we've got cache aliases, resolve them in hardware. + */ + if (boot_cpu_data.dcache.n_aliases || boot_cpu_data.icache.n_aliases) { ccr |= CCR_CACHE_SNM; + boot_cpu_data.icache.n_aliases = 0; + boot_cpu_data.dcache.n_aliases = 0; + + pr_info("Enabling hardware synonym avoidance\n"); + } + #ifdef CONFIG_SMP /* * Broadcast I-cache block invalidations by default. -- cgit v1.2.3-59-g8ed1b From 1896950b6138a2a82771780d4dbd5a5d940d4739 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 19 Apr 2010 23:53:04 +0200 Subject: UML: Remove unused variable from line driver Signed-off-by: Jan Kiszka Acked-by: WANG Cong Signed-off-by: Jiri Kosina --- arch/um/drivers/line.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 64cda95f59ca..74874ed08373 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -18,7 +18,6 @@ static irqreturn_t line_interrupt(int irq, void *data) { struct chan *chan = data; struct line *line = chan->line; - struct tty_struct *tty; if (line) chan_interrupt(&line->chan_list, &line->task, line->tty, irq); -- cgit v1.2.3-59-g8ed1b From 5156d0118bb66f0a296b8059afb061c7ae4fda9d Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 19 Apr 2010 23:53:08 +0200 Subject: UML: Clean up asm/system.h Remove duplicates and unused prototypes. Signed-off-by: Jan Kiszka Acked-by: WANG Cong Signed-off-by: Jiri Kosina --- arch/um/include/asm/system.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/um/include/asm/system.h b/arch/um/include/asm/system.h index 753346e2cdfd..93af1cf0907d 100644 --- a/arch/um/include/asm/system.h +++ b/arch/um/include/asm/system.h @@ -3,11 +3,8 @@ #include "sysdep/system.h" -extern void *switch_to(void *prev, void *next, void *last); - extern int get_signals(void); extern int set_signals(int enable); -extern int get_signals(void); extern void block_signals(void); extern void unblock_signals(void); -- cgit v1.2.3-59-g8ed1b From 814f75ec5a94a4897fdfd605bf5ed4fa6f459c90 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 19 Apr 2010 23:53:05 +0200 Subject: UML: Drop private round_down definition Already defined in kernel.h. The official version assumes that 'n' is power of two - which it is in our case. Signed-off-by: Jan Kiszka Signed-off-by: Jiri Kosina --- arch/um/sys-x86_64/signal.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index 1a899a7ed7a6..07797d10b3dc 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -165,8 +165,6 @@ struct rt_sigframe struct _fpstate fpstate; }; -#define round_down(m, n) (((m) / (n)) * (n)) - int setup_signal_stack_si(unsigned long stack_top, int sig, struct k_sigaction *ka, struct pt_regs * regs, siginfo_t *info, sigset_t *set) -- cgit v1.2.3-59-g8ed1b From 40f0a5d0a16e68a68ab3d230f1ddd96c81cf5340 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 19 Apr 2010 11:51:16 -0700 Subject: Fix comment typo in percpu.h Fix a typo in arch/x86/include/asm/percpu.h Signed-off-by: Justin P. Mattock Signed-off-by: Jiri Kosina --- arch/x86/include/asm/percpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 66a272dfd8b8..9899afa0283e 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -105,7 +105,7 @@ do { \ /* * Generate a percpu add to memory instruction and optimize code - * if a one is added or subtracted. + * if one is added or subtracted. */ #define percpu_add_op(var, val) \ do { \ -- cgit v1.2.3-59-g8ed1b From aa2110cb1a7510f9b834adfb39b05d4843a35d35 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 8 Apr 2010 14:34:27 +0800 Subject: ACPI: add boot option acpi=copy_dsdt to fix corrupt DSDT Some BIOS on Toshiba machines corrupt the DSDT, so add a new boot option acpi=copy_dsdt to workaround it. Add warning message to ask users to use this option if corrupt DSDT detected. Also build a DMI blacklist to check it and automatically copy DSDT. https://bugzilla.kernel.org/show_bug.cgi?id=14679 Signed-off-by: Lin Ming Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 1 + arch/x86/kernel/acpi/boot.c | 4 ++++ drivers/acpi/acpica/tbutils.c | 4 ++++ drivers/acpi/bus.c | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e2202e93b148..93f113a1b326 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -151,6 +151,7 @@ and is between 256 and 4096 characters. It is defined in the file strict -- Be less tolerant of platforms that are not strictly ACPI specification compliant. rsdt -- prefer RSDT over (default) XSDT + copy_dsdt -- copy DSDT to memory See also Documentation/power/pm.txt, pci=noacpi diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index cd40aba6aa95..b9629384263c 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1576,6 +1576,10 @@ static int __init parse_acpi(char *arg) /* "acpi=noirq" disables ACPI interrupt routing */ else if (strcmp(arg, "noirq") == 0) { acpi_noirq_set(); + } + /* "acpi=copy_dsdt" copys DSDT */ + else if (strcmp(arg, "copy_dsdt") == 0) { + acpi_gbl_copy_dsdt_locally = 1; } else { /* Core will printk when we return error. */ return -EINVAL; diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 54a8712bae62..a9b105fc2e55 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -373,6 +373,10 @@ void acpi_tb_check_dsdt_header(void) acpi_tb_print_table_header(0, &acpi_gbl_original_dsdt_header); acpi_tb_print_table_header(0, acpi_gbl_DSDT); + ACPI_ERROR((AE_INFO, + "Please send DMI info to linux-acpi@vger.kernel.org\n" + "If system does not work as expected, please boot with acpi=copy_dsdt")); + /* Disable further error messages */ acpi_gbl_original_dsdt_header.length = acpi_gbl_DSDT->length; diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 37132dc2da03..49af19bb8c9b 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -69,6 +69,37 @@ static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = { }; +static int set_copy_dsdt(const struct dmi_system_id *id) +{ + printk(KERN_NOTICE "%s detected - " + "force copy of DSDT to local memory\n", id->ident); + acpi_gbl_copy_dsdt_locally = 1; + return 0; +} + +static struct dmi_system_id dsdt_dmi_table[] __initdata = { + /* + * Insyde BIOS on some TOSHIBA machines corrupt the DSDT. + * https://bugzilla.kernel.org/show_bug.cgi?id=14679 + */ + { + .callback = set_copy_dsdt, + .ident = "TOSHIBA Satellite A505", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A505"), + }, + }, + { + .callback = set_copy_dsdt, + .ident = "TOSHIBA Satellite L505D", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L505D"), + }, + } +}; + /* -------------------------------------------------------------------------- Device Management -------------------------------------------------------------------------- */ @@ -813,6 +844,12 @@ void __init acpi_early_init(void) acpi_gbl_permanent_mmap = 1; + /* + * If the machine falls into the DMI check table, + * DSDT will be copied to memory + */ + dmi_check_system(dsdt_dmi_table); + status = acpi_reallocate_root_table(); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX -- cgit v1.2.3-59-g8ed1b From 0df6e9402e9f6f77b2d431f35ba0f8906b9ca8f3 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 20 Apr 2010 17:47:24 +0200 Subject: UML: add kernel.h include to signal.c Commit 814f75ec5a94a48 ("UML: Drop private round_down definition") dropped the private round_down() macro and makes signal.c use the one from kernel.h instead. kernel.h is implicitly included through uaccess.h -> sched.h -> kernel.h but we'd rather make this dependency explicit. Signed-off-by: Jiri Kosina --- arch/um/sys-x86_64/signal.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index 07797d10b3dc..b6b65c7c7a7d 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 4cb3ca7cd7e2cae8d1daf5345ec99a1e8502cf3f Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 19 Apr 2010 23:53:06 +0200 Subject: UML: Fix compiler warning due to missing task_struct declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can't pull in linux/sched.h due to circular dependency, so just forward-declare the struct. This fixes the following warning: CC arch/um/sys-i386/elfcore.o In file included from /data/linux-2.6/include/linux/elf.h:8, from /data/linux-2.6/arch/um/sys-i386/elfcore.c:2: arch/um/sys-i386/asm/elf.h:78: warning: ‘struct task_struct’ declared inside parameter list arch/um/sys-i386/asm/elf.h:78: warning: its scope is only this definition or declaration, which is probably not what you want I guess not many people build against i386 hosts anymore, so this remained widely unnoticed. Signed-off-by: Jan Kiszka Signed-off-by: Jiri Kosina --- arch/um/sys-i386/asm/elf.h | 2 ++ arch/um/sys-x86_64/asm/elf.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/um/sys-i386/asm/elf.h b/arch/um/sys-i386/asm/elf.h index e64cd41d7bab..a979a22a8d9f 100644 --- a/arch/um/sys-i386/asm/elf.h +++ b/arch/um/sys-i386/asm/elf.h @@ -75,6 +75,8 @@ typedef struct user_i387_struct elf_fpregset_t; pr_reg[16] = PT_REGS_SS(regs); \ } while (0); +struct task_struct; + extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); #define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu) diff --git a/arch/um/sys-x86_64/asm/elf.h b/arch/um/sys-x86_64/asm/elf.h index 49655c83efd2..d760967f33a7 100644 --- a/arch/um/sys-x86_64/asm/elf.h +++ b/arch/um/sys-x86_64/asm/elf.h @@ -95,6 +95,8 @@ typedef struct user_i387_struct elf_fpregset_t; (pr_reg)[25] = 0; \ (pr_reg)[26] = 0; +struct task_struct; + extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); #define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu) -- cgit v1.2.3-59-g8ed1b From 3bd16668872b5ad0afb22f15ef6c800a8faf7532 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 21 Apr 2010 11:38:04 +0900 Subject: sh: hw-breakpoints: Kill off stub unthrottle callback. This follows the x86 change and kills off the unthrottle stub. As the x86 change killed off the generic callback it isn't used anymore anyways. Signed-off-by: Paul Mundt --- arch/sh/include/asm/hw_breakpoint.h | 1 - arch/sh/kernel/hw_breakpoint.c | 5 ----- 2 files changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h index 965dd780d51b..1c388c1de381 100644 --- a/arch/sh/include/asm/hw_breakpoint.h +++ b/arch/sh/include/asm/hw_breakpoint.h @@ -56,7 +56,6 @@ extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, int arch_install_hw_breakpoint(struct perf_event *bp); void arch_uninstall_hw_breakpoint(struct perf_event *bp); void hw_breakpoint_pmu_read(struct perf_event *bp); -void hw_breakpoint_pmu_unthrottle(struct perf_event *bp); extern void arch_fill_perf_breakpoint(struct perf_event *bp); extern int register_sh_ubc(struct sh_ubc *); diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c index 675eea7785d9..5499857067b4 100644 --- a/arch/sh/kernel/hw_breakpoint.c +++ b/arch/sh/kernel/hw_breakpoint.c @@ -425,11 +425,6 @@ void hw_breakpoint_pmu_read(struct perf_event *bp) /* TODO */ } -void hw_breakpoint_pmu_unthrottle(struct perf_event *bp) -{ - /* TODO */ -} - int register_sh_ubc(struct sh_ubc *ubc) { /* Bail if it's already assigned */ -- cgit v1.2.3-59-g8ed1b From a9079ca0cb15feda15e7a380092e02d5cd834148 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 21 Apr 2010 12:01:06 +0900 Subject: sh: Tidy CPU probing and fixup section annotations. This does a detect_cpu_and_cache_system() -> cpu_probe() rename, tidies up the unused return value, and stuffs it under __cpuinit in preparation for CPU hotplug. Signed-off-by: Paul Mundt --- arch/sh/include/asm/cache.h | 4 ---- arch/sh/include/asm/processor.h | 2 ++ arch/sh/kernel/cpu/init.c | 4 ++-- arch/sh/kernel/cpu/sh2/probe.c | 5 +---- arch/sh/kernel/cpu/sh2a/probe.c | 4 +--- arch/sh/kernel/cpu/sh3/probe.c | 4 +--- arch/sh/kernel/cpu/sh4/probe.c | 4 +--- arch/sh/kernel/cpu/sh5/probe.c | 4 +--- 8 files changed, 9 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h index 02df18ea9608..e461d67f03c3 100644 --- a/arch/sh/include/asm/cache.h +++ b/arch/sh/include/asm/cache.h @@ -38,14 +38,10 @@ struct cache_info { * 2. those in the physical page number. */ unsigned int alias_mask; - unsigned int n_aliases; /* Number of aliases */ unsigned long flags; }; - -int __init detect_cpu_and_cache_system(void); - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* __ASM_SH_CACHE_H */ diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 9605e062840f..c2be22505fee 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -102,6 +102,8 @@ struct task_struct; extern struct pt_regs fake_swapper_regs; +extern void cpu_probe(void); + /* arch/sh/kernel/process.c */ extern unsigned int xstate_size; extern void free_thread_xstate(struct task_struct *); diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index c736422344eb..ffaa00a2216b 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -293,14 +293,14 @@ static inline void __init dsp_init(void) { } * subtype and initial configuration will all be done. * * Each processor family is still responsible for doing its own probing - * and cache configuration in detect_cpu_and_cache_system(). + * and cache configuration in cpu_probe(). */ asmlinkage void __init sh_cpu_init(void) { current_thread_info()->cpu = hard_smp_processor_id(); /* First, probe the CPU */ - detect_cpu_and_cache_system(); + cpu_probe(); if (current_cpu_data.type == CPU_SH_NONE) panic("Unknown CPU"); diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 1db6d8883888..bab8e75958ae 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -13,7 +13,7 @@ #include #include -int __init detect_cpu_and_cache_system(void) +void __cpuinit cpu_probe(void) { #if defined(CONFIG_CPU_SUBTYPE_SH7619) boot_cpu_data.type = CPU_SH7619; @@ -30,7 +30,4 @@ int __init detect_cpu_and_cache_system(void) boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED; boot_cpu_data.icache = boot_cpu_data.dcache; boot_cpu_data.family = CPU_FAMILY_SH2; - - return 0; } - diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c index 6825d6507164..48e97a2a0c8d 100644 --- a/arch/sh/kernel/cpu/sh2a/probe.c +++ b/arch/sh/kernel/cpu/sh2a/probe.c @@ -13,7 +13,7 @@ #include #include -int __init detect_cpu_and_cache_system(void) +void __cpuinit cpu_probe(void) { boot_cpu_data.family = CPU_FAMILY_SH2A; @@ -51,6 +51,4 @@ int __init detect_cpu_and_cache_system(void) * on the cache info. */ boot_cpu_data.icache = boot_cpu_data.dcache; - - return 0; } diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index 295ec4c99e98..bf23c322e164 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -16,7 +16,7 @@ #include #include -int detect_cpu_and_cache_system(void) +void __cpuinit cpu_probe(void) { unsigned long addr0, addr1, data0, data1, data2, data3; @@ -108,6 +108,4 @@ int detect_cpu_and_cache_system(void) boot_cpu_data.icache = boot_cpu_data.dcache; boot_cpu_data.family = CPU_FAMILY_SH3; - - return 0; } diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 822977a06d84..d180f16281ed 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -15,7 +15,7 @@ #include #include -int __init detect_cpu_and_cache_system(void) +void __cpuinit cpu_probe(void) { unsigned long pvr, prr, cvr; unsigned long size; @@ -251,6 +251,4 @@ int __init detect_cpu_and_cache_system(void) boot_cpu_data.scache.linesz); } } - - return 0; } diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c index 521d05b3f7ba..9e882409e4e9 100644 --- a/arch/sh/kernel/cpu/sh5/probe.c +++ b/arch/sh/kernel/cpu/sh5/probe.c @@ -17,7 +17,7 @@ #include #include -int __init detect_cpu_and_cache_system(void) +void __cpuinit cpu_probe(void) { unsigned long long cir; @@ -72,6 +72,4 @@ int __init detect_cpu_and_cache_system(void) /* Setup some I/D TLB defaults */ sh64_tlb_init(); - - return 0; } -- cgit v1.2.3-59-g8ed1b From 4a6feab0ee5240c4bd5378d9f8a46b85718c68a7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 21 Apr 2010 12:20:42 +0900 Subject: sh: __cpuinit annotate the CPU init path. All of the regular CPU init path needs to be __cpuinit annotated for CPU hotplug. Signed-off-by: Paul Mundt --- arch/sh/include/asm/processor.h | 1 + arch/sh/include/asm/processor_32.h | 2 -- arch/sh/kernel/cpu/init.c | 20 ++++++++++---------- arch/sh/kernel/head_32.S | 2 +- arch/sh/kernel/process.c | 2 +- 5 files changed, 13 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index c2be22505fee..26b3f026eec9 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -102,6 +102,7 @@ struct task_struct; extern struct pt_regs fake_swapper_regs; +extern void cpu_init(void); extern void cpu_probe(void); /* arch/sh/kernel/process.c */ diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 572b4eb09493..61a445d2d02a 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -27,8 +27,6 @@ #define CCN_CVR 0xff000040 #define CCN_PRR 0xff000044 -asmlinkage void __init sh_cpu_init(void); - /* * User space process size: 2GB. * diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index ffaa00a2216b..97661061ff20 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -43,9 +43,9 @@ * peripherals (nofpu, nodsp, and so forth). */ #define onchip_setup(x) \ -static int x##_disabled __initdata = !cpu_has_##x; \ +static int x##_disabled __cpuinitdata = !cpu_has_##x; \ \ -static int __init x##_setup(char *opts) \ +static int __cpuinit x##_setup(char *opts) \ { \ x##_disabled = 1; \ return 1; \ @@ -59,7 +59,7 @@ onchip_setup(dsp); #define CPUOPM 0xff2f0000 #define CPUOPM_RABD (1 << 5) -static void __init speculative_execution_init(void) +static void __cpuinit speculative_execution_init(void) { /* Clear RABD */ __raw_writel(__raw_readl(CPUOPM) & ~CPUOPM_RABD, CPUOPM); @@ -78,7 +78,7 @@ static void __init speculative_execution_init(void) #define EXPMASK_BRDSSLP (1 << 1) #define EXPMASK_MMCAW (1 << 4) -static void __init expmask_init(void) +static void __cpuinit expmask_init(void) { unsigned long expmask = __raw_readl(EXPMASK); @@ -217,7 +217,7 @@ static void detect_cache_shape(void) l2_cache_shape = -1; /* No S-cache */ } -static void __init fpu_init(void) +static void __cpuinit fpu_init(void) { /* Disable the FPU */ if (fpu_disabled && (current_cpu_data.flags & CPU_HAS_FPU)) { @@ -230,7 +230,7 @@ static void __init fpu_init(void) } #ifdef CONFIG_SH_DSP -static void __init release_dsp(void) +static void __cpuinit release_dsp(void) { unsigned long sr; @@ -244,7 +244,7 @@ static void __init release_dsp(void) ); } -static void __init dsp_init(void) +static void __cpuinit dsp_init(void) { unsigned long sr; @@ -276,11 +276,11 @@ static void __init dsp_init(void) release_dsp(); } #else -static inline void __init dsp_init(void) { } +static inline void __cpuinit dsp_init(void) { } #endif /* CONFIG_SH_DSP */ /** - * sh_cpu_init + * cpu_init * * This is our initial entry point for each CPU, and is invoked on the * boot CPU prior to calling start_kernel(). For SMP, a combination of @@ -295,7 +295,7 @@ static inline void __init dsp_init(void) { } * Each processor family is still responsible for doing its own probing * and cache configuration in cpu_probe(). */ -asmlinkage void __init sh_cpu_init(void) +asmlinkage void __cpuinit cpu_init(void) { current_thread_info()->cpu = hard_smp_processor_id(); diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index fe0b743881b0..8c1fc9a9fab2 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -335,7 +335,7 @@ ENTRY(stack_start) 3: .long __bss_start 4: .long _end 5: .long start_kernel -6: .long sh_cpu_init +6: .long cpu_init 7: .long init_thread_union #ifdef CONFIG_PMB diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 81add9b9ea6e..4d49c8643777 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -89,7 +89,7 @@ void arch_task_cache_init(void) # define HAVE_SOFTFP 0 #endif -void init_thread_xstate(void) +void __cpuinit init_thread_xstate(void) { if (boot_cpu_data.flags & CPU_HAS_FPU) xstate_size = sizeof(struct sh_fpu_hard_struct); -- cgit v1.2.3-59-g8ed1b From 3366e3585fbf0d40ce6f2382b544851cf4df1654 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 30 Mar 2010 12:38:01 +0900 Subject: sh: Move platform smp ops in to their own structure. This cribs the MIPS plat_smp_ops approach for wrapping up the platform ops. This will allow for mixing and matching different ops on the same platform in the future. Signed-off-by: Paul Mundt --- arch/sh/boards/board-urquell.c | 3 +++ arch/sh/boards/mach-sdk7786/setup.c | 3 +++ arch/sh/boards/mach-x3proto/setup.c | 7 +++++++ arch/sh/include/asm/smp-ops.h | 39 +++++++++++++++++++++++++++++++++++++ arch/sh/include/asm/smp.h | 18 ++++++++++------- arch/sh/kernel/cpu/sh4a/smp-shx3.c | 20 +++++++++++++------ arch/sh/kernel/localtimer.c | 2 +- arch/sh/kernel/setup.c | 2 -- arch/sh/kernel/smp.c | 24 ++++++++++++++++------- 9 files changed, 95 insertions(+), 23 deletions(-) create mode 100644 arch/sh/include/asm/smp-ops.h (limited to 'arch') diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c index a9bd6e3ee10b..d81c609decc7 100644 --- a/arch/sh/boards/board-urquell.c +++ b/arch/sh/boards/board-urquell.c @@ -24,6 +24,7 @@ #include #include #include +#include /* * bit 1234 5678 @@ -203,6 +204,8 @@ static void __init urquell_setup(char **cmdline_p) printk(KERN_INFO "Renesas Technology Corp. Urquell support.\n"); pm_power_off = urquell_power_off; + + register_smp_ops(&shx3_smp_ops); } /* diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index 0c057a93fe29..2ec1ea5cf8ef 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c @@ -21,6 +21,7 @@ #include #include #include +#include static struct resource heartbeat_resource = { .start = 0x07fff8b0, @@ -189,6 +190,8 @@ static void __init sdk7786_setup(char **cmdline_p) machine_ops.restart = sdk7786_restart; pm_power_off = sdk7786_power_off; + + register_smp_ops(&shx3_smp_ops); } /* diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c index e284592fd42a..102bf56befb4 100644 --- a/arch/sh/boards/mach-x3proto/setup.c +++ b/arch/sh/boards/mach-x3proto/setup.c @@ -19,6 +19,7 @@ #include #include #include +#include static struct resource heartbeat_resources[] = { [0] = { @@ -152,7 +153,13 @@ static void __init x3proto_init_irq(void) __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000); } +static void __init x3proto_setup(char **cmdline_p) +{ + register_smp_ops(&shx3_smp_ops); +} + static struct sh_machine_vector mv_x3proto __initmv = { .mv_name = "x3proto", + .mv_setup = x3proto_setup, .mv_init_irq = x3proto_init_irq, }; diff --git a/arch/sh/include/asm/smp-ops.h b/arch/sh/include/asm/smp-ops.h new file mode 100644 index 000000000000..0581b2a4c8ce --- /dev/null +++ b/arch/sh/include/asm/smp-ops.h @@ -0,0 +1,39 @@ +#ifndef __ASM_SH_SMP_OPS_H +#define __ASM_SH_SMP_OPS_H + +struct plat_smp_ops { + void (*smp_setup)(void); + unsigned int (*smp_processor_id)(void); + void (*prepare_cpus)(unsigned int max_cpus); + void (*start_cpu)(unsigned int cpu, unsigned long entry_point); + void (*send_ipi)(unsigned int cpu, unsigned int message); +}; + +extern struct plat_smp_ops shx3_smp_ops; + +#ifdef CONFIG_SMP + +static inline void plat_smp_setup(void) +{ + extern struct plat_smp_ops *mp_ops; /* private */ + + BUG_ON(!mp_ops); + mp_ops->smp_setup(); +} + +extern void register_smp_ops(struct plat_smp_ops *ops); + +#else + +static inline void plat_smp_setup(void) +{ + /* UP, nothing to do ... */ +} + +static inline void register_smp_ops(struct plat_smp_ops *ops) +{ +} + +#endif /* CONFIG_SMP */ + +#endif /* __ASM_SH_SMP_OPS_H */ diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h index 53ef26ced75f..7f13d46ec8d7 100644 --- a/arch/sh/include/asm/smp.h +++ b/arch/sh/include/asm/smp.h @@ -3,6 +3,7 @@ #include #include +#include #ifdef CONFIG_SMP @@ -11,7 +12,6 @@ #include #define raw_smp_processor_id() (current_thread_info()->cpu) -#define hard_smp_processor_id() plat_smp_processor_id() /* Map from cpu id to sequential logical cpu number. */ extern int __cpu_number_map[NR_CPUS]; @@ -36,15 +36,19 @@ void smp_timer_broadcast(const struct cpumask *mask); void local_timer_interrupt(void); void local_timer_setup(unsigned int cpu); -void plat_smp_setup(void); -void plat_prepare_cpus(unsigned int max_cpus); -int plat_smp_processor_id(void); -void plat_start_cpu(unsigned int cpu, unsigned long entry_point); -void plat_send_ipi(unsigned int cpu, unsigned int message); - void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); +static inline int hard_smp_processor_id(void) +{ + extern struct plat_smp_ops *mp_ops; /* private */ + + if (!mp_ops) + return 0; /* boot CPU */ + + return mp_ops->smp_processor_id(); +} + #else #define hard_smp_processor_id() (0) diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c index c98b4574c44e..5c5d50ccbfcd 100644 --- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c @@ -1,7 +1,7 @@ /* * SH-X3 SMP * - * Copyright (C) 2007 - 2008 Paul Mundt + * Copyright (C) 2007 - 2010 Paul Mundt * Copyright (C) 2007 Magnus Damm * * This file is subject to the terms and conditions of the GNU General Public @@ -37,7 +37,7 @@ static irqreturn_t ipi_interrupt_handler(int irq, void *arg) return IRQ_HANDLED; } -void __init plat_smp_setup(void) +static void shx3_smp_setup(void) { unsigned int cpu = 0; int i, num; @@ -63,7 +63,7 @@ void __init plat_smp_setup(void) printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); } -void __init plat_prepare_cpus(unsigned int max_cpus) +static void shx3_prepare_cpus(unsigned int max_cpus) { int i; @@ -76,7 +76,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus) IRQF_DISABLED | IRQF_PERCPU, "IPI", (void *)(long)i); } -void plat_start_cpu(unsigned int cpu, unsigned long entry_point) +static void shx3_start_cpu(unsigned int cpu, unsigned long entry_point) { if (__in_29bit_mode()) __raw_writel(entry_point, RESET_REG(cpu)); @@ -93,12 +93,12 @@ void plat_start_cpu(unsigned int cpu, unsigned long entry_point) __raw_writel(STBCR_RESET | STBCR_LTSLP, STBCR_REG(cpu)); } -int plat_smp_processor_id(void) +static unsigned int shx3_smp_processor_id(void) { return __raw_readl(0xff000048); /* CPIDR */ } -void plat_send_ipi(unsigned int cpu, unsigned int message) +static void shx3_send_ipi(unsigned int cpu, unsigned int message) { unsigned long addr = 0xfe410070 + (cpu * 4); @@ -106,3 +106,11 @@ void plat_send_ipi(unsigned int cpu, unsigned int message) __raw_writel(1 << (message << 2), addr); /* C0INTICI..CnINTICI */ } + +struct plat_smp_ops shx3_smp_ops = { + .smp_setup = shx3_smp_setup, + .prepare_cpus = shx3_prepare_cpus, + .start_cpu = shx3_start_cpu, + .smp_processor_id = shx3_smp_processor_id, + .send_ipi = shx3_send_ipi, +}; diff --git a/arch/sh/kernel/localtimer.c b/arch/sh/kernel/localtimer.c index 0b04e7d4a9b9..865a2f1029b1 100644 --- a/arch/sh/kernel/localtimer.c +++ b/arch/sh/kernel/localtimer.c @@ -44,7 +44,7 @@ static void dummy_timer_set_mode(enum clock_event_mode mode, { } -void __cpuinit local_timer_setup(unsigned int cpu) +void local_timer_setup(unsigned int cpu) { struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 8870d6ba64bf..29155384d5a8 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -459,9 +459,7 @@ void __init setup_arch(char **cmdline_p) if (likely(sh_mv.mv_setup)) sh_mv.mv_setup(cmdline_p); -#ifdef CONFIG_SMP plat_smp_setup(); -#endif } /* processor boot mode configuration */ diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 002cc612deef..2f348fda0159 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -3,7 +3,7 @@ * * SMP support for the SuperH processors. * - * Copyright (C) 2002 - 2008 Paul Mundt + * Copyright (C) 2002 - 2010 Paul Mundt * Copyright (C) 2006 - 2007 Akio Idehara * * This file is subject to the terms and conditions of the GNU General Public @@ -31,6 +31,16 @@ int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ +struct plat_smp_ops *mp_ops = NULL; + +void __cpuinit register_smp_ops(struct plat_smp_ops *ops) +{ + if (mp_ops) + printk(KERN_WARNING "Overriding previously set SMP ops\n"); + + mp_ops = ops; +} + static inline void __init smp_store_cpu_info(unsigned int cpu) { struct sh_cpuinfo *c = cpu_data + cpu; @@ -46,7 +56,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) init_new_context(current, &init_mm); current_thread_info()->cpu = cpu; - plat_prepare_cpus(max_cpus); + mp_ops->prepare_cpus(max_cpus); #ifndef CONFIG_HOTPLUG_CPU init_cpu_present(&cpu_possible_map); @@ -127,7 +137,7 @@ int __cpuinit __cpu_up(unsigned int cpu) (unsigned long)&stack_start + sizeof(stack_start)); wmb(); - plat_start_cpu(cpu, (unsigned long)_stext); + mp_ops->start_cpu(cpu, (unsigned long)_stext); timeout = jiffies + HZ; while (time_before(jiffies, timeout)) { @@ -159,7 +169,7 @@ void __init smp_cpus_done(unsigned int max_cpus) void smp_send_reschedule(int cpu) { - plat_send_ipi(cpu, SMP_MSG_RESCHEDULE); + mp_ops->send_ipi(cpu, SMP_MSG_RESCHEDULE); } void smp_send_stop(void) @@ -172,12 +182,12 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask) int cpu; for_each_cpu(cpu, mask) - plat_send_ipi(cpu, SMP_MSG_FUNCTION); + mp_ops->send_ipi(cpu, SMP_MSG_FUNCTION); } void arch_send_call_function_single_ipi(int cpu) { - plat_send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE); + mp_ops->send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE); } void smp_timer_broadcast(const struct cpumask *mask) @@ -185,7 +195,7 @@ void smp_timer_broadcast(const struct cpumask *mask) int cpu; for_each_cpu(cpu, mask) - plat_send_ipi(cpu, SMP_MSG_TIMER); + mp_ops->send_ipi(cpu, SMP_MSG_TIMER); } static void ipi_timer(void) -- cgit v1.2.3-59-g8ed1b From 87e8f0e3e6d0b720a2462ebc5667eaa462752f74 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 21 Apr 2010 02:31:50 -0700 Subject: sparc64: Show stack backtrace from show_regs() just like other platforms. Signed-off-by: David S. Miller --- arch/sparc/kernel/process_64.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index a5cf3864b31f..dbe81a368b45 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -202,6 +202,7 @@ void show_regs(struct pt_regs *regs) regs->u_regs[15]); printk("RPC: <%pS>\n", (void *) regs->u_regs[15]); show_regwindow(regs); + show_stack(current, (unsigned long *) regs->u_regs[UREG_FP]); } struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; -- cgit v1.2.3-59-g8ed1b From 667f0cee3e0321151aa7a1a5222afe67ca4be0ea Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 21 Apr 2010 03:08:11 -0700 Subject: sparc64: Fix stack dumping and tracing when function graph is enabled. Like x86, when the function graph tracer is enabled, emit the ftrace stub as well as the program counter it will be transformed back into. We duplicate a lot of similar stack walking logic in 3 or 4 spots, so eventually we should consolidate things like x86 does. Thanks to Frederic Weisbecker for pointing this out. Signed-off-by: David S. Miller --- arch/sparc/kernel/perf_event.c | 14 ++++++++++++++ arch/sparc/kernel/stacktrace.c | 23 ++++++++++++++++++++++- arch/sparc/kernel/traps_64.c | 14 ++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index e2771939341d..34ce49f80eac 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -1276,6 +1277,9 @@ static void perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) { unsigned long ksp, fp; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + int graph = 0; +#endif callchain_store(entry, PERF_CONTEXT_KERNEL); callchain_store(entry, regs->tpc); @@ -1303,6 +1307,16 @@ static void perf_callchain_kernel(struct pt_regs *regs, fp = (unsigned long)sf->fp + STACK_BIAS; } callchain_store(entry, pc); +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + if ((pc + 8UL) == (unsigned long) &return_to_handler) { + int index = current->curr_ret_stack; + if (current->ret_stack && index >= graph) { + pc = current->ret_stack[index - graph].ret; + callchain_store(entry, pc); + graph++; + } + } +#endif } while (entry->nr < PERF_MAX_STACK_DEPTH); } diff --git a/arch/sparc/kernel/stacktrace.c b/arch/sparc/kernel/stacktrace.c index acb12f673757..3e0815349630 100644 --- a/arch/sparc/kernel/stacktrace.c +++ b/arch/sparc/kernel/stacktrace.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -12,6 +13,10 @@ static void __save_stack_trace(struct thread_info *tp, bool skip_sched) { unsigned long ksp, fp; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + struct task_struct *t; + int graph = 0; +#endif if (tp == current_thread_info()) { stack_trace_flush(); @@ -21,6 +26,9 @@ static void __save_stack_trace(struct thread_info *tp, } fp = ksp + STACK_BIAS; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + t = tp->task; +#endif do { struct sparc_stackf *sf; struct pt_regs *regs; @@ -44,8 +52,21 @@ static void __save_stack_trace(struct thread_info *tp, if (trace->skip > 0) trace->skip--; - else if (!skip_sched || !in_sched_functions(pc)) + else if (!skip_sched || !in_sched_functions(pc)) { trace->entries[trace->nr_entries++] = pc; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + if ((pc + 8UL) == (unsigned long) &return_to_handler) { + int index = t->curr_ret_stack; + if (t->ret_stack && index >= graph) { + pc = t->ret_stack[index - graph].ret; + if (trace->nr_entries < + trace->max_entries) + trace->entries[trace->nr_entries++] = pc; + graph++; + } + } +#endif + } } while (trace->nr_entries < trace->max_entries); } diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 9da57f032983..42ad2ba85010 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -2154,6 +2155,9 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) unsigned long fp, thread_base, ksp; struct thread_info *tp; int count = 0; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + int graph = 0; +#endif ksp = (unsigned long) _ksp; if (!tsk) @@ -2193,6 +2197,16 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) } printk(" [%016lx] %pS\n", pc, (void *) pc); +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + if ((pc + 8UL) == (unsigned long) &return_to_handler) { + int index = tsk->curr_ret_stack; + if (tsk->ret_stack && index >= graph) { + pc = tsk->ret_stack[index - graph].ret; + printk(" [%016lx] %pS\n", pc, (void *) pc); + graph++; + } + } +#endif } while (++count < 16); } -- cgit v1.2.3-59-g8ed1b From 52882173cfed4fabcc1496755000bf022d681e52 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 19 Apr 2010 13:20:49 +0100 Subject: ARM: 6058/1: Add support for PCI domains This patch adds support for PCI domains on ARM platforms. Also, protect asm/mach/pci.h from multiple inclustions, otherwise build fails because of pci_domain_nr() and pci_proc_domain() redefinitions. Signed-off-by: Anton Vorontsov Signed-off-by: Russell King --- arch/arm/Kconfig | 4 ++++ arch/arm/include/asm/mach/pci.h | 11 +++++++++++ arch/arm/include/asm/pci.h | 15 +++++++++++++++ arch/arm/kernel/bios32.c | 3 +++ 4 files changed, 33 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5c8128c76996..88f9334110cf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1074,6 +1074,10 @@ config PCI your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or VESA. If you have PCI, say Y, otherwise N. +config PCI_DOMAINS + bool + depends on PCI + config PCI_SYSCALL def_bool PCI diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index a38bdc7afa34..52f0da1e97df 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h @@ -8,10 +8,16 @@ * published by the Free Software Foundation. */ +#ifndef __ASM_MACH_PCI_H +#define __ASM_MACH_PCI_H + struct pci_sys_data; struct pci_bus; struct hw_pci { +#ifdef CONFIG_PCI_DOMAINS + int domain; +#endif struct list_head buses; int nr_controllers; int (*setup)(int nr, struct pci_sys_data *); @@ -26,6 +32,9 @@ struct hw_pci { * Per-controller structure */ struct pci_sys_data { +#ifdef CONFIG_PCI_DOMAINS + int domain; +#endif struct list_head node; int busnr; /* primary bus number */ u64 mem_offset; /* bus->cpu memory mapping offset */ @@ -70,3 +79,5 @@ extern int pci_v3_setup(int nr, struct pci_sys_data *); extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *); extern void pci_v3_preinit(void); extern void pci_v3_postinit(void); + +#endif /* __ASM_MACH_PCI_H */ diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index 47980118d0a5..92e2a833693d 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -4,8 +4,23 @@ #ifdef __KERNEL__ #include +#include /* for pci_sys_data */ #include /* for PCIBIOS_MIN_* */ +#ifdef CONFIG_PCI_DOMAINS +static inline int pci_domain_nr(struct pci_bus *bus) +{ + struct pci_sys_data *root = bus->sysdata; + + return root->domain; +} + +static inline int pci_proc_domain(struct pci_bus *bus) +{ + return pci_domain_nr(bus); +} +#endif /* CONFIG_PCI_DOMAINS */ + #ifdef CONFIG_PCI_HOST_ITE8152 /* ITE bridge requires setting latency timer to avoid early bus access termination by PIC bus mater devices diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index bd397e0b663e..c6273a3bfc25 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -527,6 +527,9 @@ static void __init pcibios_init_hw(struct hw_pci *hw) if (!sys) panic("PCI: unable to allocate sys data!"); +#ifdef CONFIG_PCI_DOMAINS + sys->domain = hw->domain; +#endif sys->hw = hw; sys->busnr = busnr; sys->swizzle = hw->swizzle; -- cgit v1.2.3-59-g8ed1b From b1ab1b4d9ab9812c77843abec79030292ef0a544 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 22 Apr 2010 16:06:58 +0200 Subject: x86, cacheinfo: Unify AMD L3 cache index disable checking All F10h CPUs starting with model 8 resp. 9, stepping 1, support L3 cache index disable. Concentrate the family, model, stepping checking at one place and enable the feature implicitly on upcoming Fam10h models. Signed-off-by: Borislav Petkov LKML-Reference: <1271945222-5283-2-git-send-email-bp@amd64.org> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/intel_cacheinfo.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index b3eeb66c0a51..acfb08383908 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -328,18 +328,22 @@ static unsigned int __cpuinit amd_calc_l3_indices(void) static void __cpuinit amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) { - if (index < 3) + if (boot_cpu_data.x86 != 0x10) return; - if (boot_cpu_data.x86 == 0x11) + if (index < 3) return; /* see errata #382 and #388 */ - if ((boot_cpu_data.x86 == 0x10) && - ((boot_cpu_data.x86_model < 0x8) || - (boot_cpu_data.x86_mask < 0x1))) + if (boot_cpu_data.x86_model < 0x8) return; + if ((boot_cpu_data.x86_model == 0x8 || + boot_cpu_data.x86_model == 0x9) + && + boot_cpu_data.x86_mask < 0x1) + return; + this_leaf->can_disable = true; this_leaf->l3_indices = amd_calc_l3_indices(); } @@ -443,8 +447,7 @@ __cpuinit cpuid4_cache_lookup_regs(int index, if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { amd_cpuid4(index, &eax, &ebx, &ecx); - if (boot_cpu_data.x86 >= 0x10) - amd_check_l3_disable(index, this_leaf); + amd_check_l3_disable(index, this_leaf); } else { cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); } -- cgit v1.2.3-59-g8ed1b From f2b20e41407fccfcfacf927ff91ec888832a37af Mon Sep 17 00:00:00 2001 From: Frank Arnold Date: Thu, 22 Apr 2010 16:06:59 +0200 Subject: x86, cacheinfo: Turn off L3 cache index disable feature in virtualized environments When running a quest kernel on xen we get: BUG: unable to handle kernel NULL pointer dereference at 0000000000000038 IP: [] cpuid4_cache_lookup_regs+0x2ca/0x3df PGD 0 Oops: 0000 [#1] SMP last sysfs file: CPU 0 Modules linked in: Pid: 0, comm: swapper Tainted: G W 2.6.34-rc3 #1 /HVM domU RIP: 0010:[] [] cpuid4_cache_lookup_regs+0x 2ca/0x3df RSP: 0018:ffff880002203e08 EFLAGS: 00010046 RAX: 0000000000000000 RBX: 0000000000000003 RCX: 0000000000000060 RDX: 0000000000000000 RSI: 0000000000000040 RDI: 0000000000000000 RBP: ffff880002203ed8 R08: 00000000000017c0 R09: ffff880002203e38 R10: ffff8800023d5d40 R11: ffffffff81a01e28 R12: ffff880187e6f5c0 R13: ffff880002203e34 R14: ffff880002203e58 R15: ffff880002203e68 FS: 0000000000000000(0000) GS:ffff880002200000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000038 CR3: 0000000001a3c000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process swapper (pid: 0, threadinfo ffffffff81a00000, task ffffffff81a44020) Stack: ffffffff810d7ecb ffff880002203e20 ffffffff81059140 ffff880002203e30 <0> ffffffff810d7ec9 0000000002203e40 000000000050d140 ffff880002203e70 <0> 0000000002008140 0000000000000086 ffff880040020140 ffffffff81068b8b Call Trace: [] ? sync_supers_timer_fn+0x0/0x1c [] ? mod_timer+0x23/0x25 [] ? arm_supers_timer+0x34/0x36 [] ? hrtimer_get_next_event+0xa7/0xc3 [] ? get_next_timer_interrupt+0x19a/0x20d [] get_cpu_leaves+0x5c/0x232 [] ? sched_clock_local+0x1c/0x82 [] ? sched_clock_tick+0x75/0x7a [] generic_smp_call_function_single_interrupt+0xae/0xd0 [] smp_call_function_single_interrupt+0x18/0x27 [] call_function_single_interrupt+0x13/0x20 [] ? notifier_call_chain+0x14/0x63 [] ? native_safe_halt+0xc/0xd [] ? default_idle+0x36/0x53 [] cpu_idle+0xaa/0xe4 [] rest_init+0x7e/0x80 [] start_kernel+0x40e/0x419 [] x86_64_start_reservations+0xb3/0xb7 [] x86_64_start_kernel+0xf8/0x107 Code: 14 d5 40 ff ae 81 8b 14 02 31 c0 3b 15 47 1c 8b 00 7d 0e 48 8b 05 36 1c 8b 00 48 63 d2 48 8b 04 d0 c7 85 5c ff ff ff 00 00 00 00 <8b> 70 38 48 8d 8d 5c ff ff ff 48 8b 78 10 ba c4 01 00 00 e8 eb RIP [] cpuid4_cache_lookup_regs+0x2ca/0x3df RSP CR2: 0000000000000038 ---[ end trace a7919e7f17c0a726 ]--- The L3 cache index disable feature of AMD CPUs has to be disabled if the kernel is running as guest on top of a hypervisor because northbridge devices are not available to the guest. Currently, this fixes a boot crash on top of Xen. In the future this will become an issue on KVM as well. Check if northbridge devices are present and do not enable the feature if there are none. Signed-off-by: Frank Arnold LKML-Reference: <1271945222-5283-3-git-send-email-bp@amd64.org> Acked-by: Borislav Petkov Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/intel_cacheinfo.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index acfb08383908..5ab14c86c6ec 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -344,6 +344,10 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) boot_cpu_data.x86_mask < 0x1) return; + /* not in virtualized environments */ + if (num_k8_northbridges == 0) + return; + this_leaf->can_disable = true; this_leaf->l3_indices = amd_calc_l3_indices(); } -- cgit v1.2.3-59-g8ed1b From 9350f982e4fe539e83a2d4a13e9b53ad8253c4a8 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 22 Apr 2010 16:07:00 +0200 Subject: x86, cacheinfo: Reorganize AMD L3 cache structure Add a struct representing L3 cache attributes (subcache sizes and indices count) and move the respective members out of _cpuid4_info. Also, stash the struct pci_dev ptr into the struct simplifying the code even more. There should be no functionality change resulting from this patch except slightly slimming the _cpuid4_info per-cpu vars. Signed-off-by: Borislav Petkov LKML-Reference: <1271945222-5283-4-git-send-email-bp@amd64.org> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/intel_cacheinfo.c | 53 +++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 5ab14c86c6ec..ff663ca63fdc 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -148,13 +148,19 @@ union _cpuid4_leaf_ecx { u32 full; }; +struct amd_l3_cache { + struct pci_dev *dev; + bool can_disable; + unsigned indices; + u8 subcaches[4]; +}; + struct _cpuid4_info { union _cpuid4_leaf_eax eax; union _cpuid4_leaf_ebx ebx; union _cpuid4_leaf_ecx ecx; unsigned long size; - bool can_disable; - unsigned int l3_indices; + struct amd_l3_cache *l3; DECLARE_BITMAP(shared_cpu_map, NR_CPUS); }; @@ -164,8 +170,7 @@ struct _cpuid4_info_regs { union _cpuid4_leaf_ebx ebx; union _cpuid4_leaf_ecx ecx; unsigned long size; - bool can_disable; - unsigned int l3_indices; + struct amd_l3_cache *l3; }; unsigned short num_cache_leaves; @@ -302,7 +307,7 @@ struct _cache_attr { }; #ifdef CONFIG_CPU_SUP_AMD -static unsigned int __cpuinit amd_calc_l3_indices(void) +static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3) { /* * We're called over smp_call_function_single() and therefore @@ -317,12 +322,14 @@ static unsigned int __cpuinit amd_calc_l3_indices(void) pci_read_config_dword(dev, 0x1C4, &val); /* calculate subcache sizes */ - sc0 = !(val & BIT(0)); - sc1 = !(val & BIT(4)); - sc2 = !(val & BIT(8)) + !(val & BIT(9)); - sc3 = !(val & BIT(12)) + !(val & BIT(13)); + l3->subcaches[0] = sc0 = !(val & BIT(0)); + l3->subcaches[1] = sc1 = !(val & BIT(4)); + l3->subcaches[2] = sc2 = !(val & BIT(8)) + !(val & BIT(9)); + l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13)); + + l3->indices = (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1; - return (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1; + l3->dev = dev; } static void __cpuinit @@ -348,19 +355,23 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) if (num_k8_northbridges == 0) return; - this_leaf->can_disable = true; - this_leaf->l3_indices = amd_calc_l3_indices(); + this_leaf->l3 = kzalloc(sizeof(struct amd_l3_cache), GFP_ATOMIC); + if (!this_leaf->l3) { + printk(KERN_WARNING "Error allocating L3 struct\n"); + return; + } + + this_leaf->l3->can_disable = true; + amd_calc_l3_indices(this_leaf->l3); } static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, unsigned int index) { - int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); - int node = amd_get_nb_id(cpu); - struct pci_dev *dev = node_to_k8_nb_misc(node); + struct pci_dev *dev = this_leaf->l3->dev; unsigned int reg = 0; - if (!this_leaf->can_disable) + if (!this_leaf->l3 || !this_leaf->l3->can_disable) return -EINVAL; if (!dev) @@ -382,15 +393,14 @@ SHOW_CACHE_DISABLE(1) static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf, size_t count, unsigned int index) { + struct pci_dev *dev = this_leaf->l3->dev; int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); - int node = amd_get_nb_id(cpu); - struct pci_dev *dev = node_to_k8_nb_misc(node); unsigned long val = 0; #define SUBCACHE_MASK (3UL << 20) #define SUBCACHE_INDEX 0xfff - if (!this_leaf->can_disable) + if (!this_leaf->l3 || !this_leaf->l3->can_disable) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) @@ -404,7 +414,7 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, /* do not allow writes outside of allowed bits */ if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) || - ((val & SUBCACHE_INDEX) > this_leaf->l3_indices)) + ((val & SUBCACHE_INDEX) > this_leaf->l3->indices)) return -EINVAL; val |= BIT(30); @@ -708,6 +718,7 @@ static void __cpuinit free_cache_attributes(unsigned int cpu) for (i = 0; i < num_cache_leaves; i++) cache_remove_shared_cpu_map(cpu, i); + kfree(per_cpu(ici_cpuid4_info, cpu)->l3); kfree(per_cpu(ici_cpuid4_info, cpu)); per_cpu(ici_cpuid4_info, cpu) = NULL; } @@ -992,7 +1003,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) this_leaf = CPUID4_INFO_IDX(cpu, i); - if (this_leaf->can_disable) + if (this_leaf->l3 && this_leaf->l3->can_disable) ktype_cache.default_attrs = default_l3_attrs; else ktype_cache.default_attrs = default_attrs; -- cgit v1.2.3-59-g8ed1b From ba06edb63f5ef2913aad37070eaec3c9d8ac73b8 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 22 Apr 2010 16:07:01 +0200 Subject: x86, cacheinfo: Make L3 cache info per node Currently, we're allocating L3 cache info and calculating indices for each online cpu which is clearly superfluous. Instead, we need to do this per-node as is each L3 cache. No functional change, only per-cpu memory savings. -v2: Allocate L3 cache descriptors array dynamically. Signed-off-by: Borislav Petkov LKML-Reference: <1271945222-5283-5-git-send-email-bp@amd64.org> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/intel_cacheinfo.c | 59 ++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index ff663ca63fdc..1346e9c23fc4 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -307,19 +307,18 @@ struct _cache_attr { }; #ifdef CONFIG_CPU_SUP_AMD + +/* + * L3 cache descriptors + */ +static struct amd_l3_cache **__cpuinitdata l3_caches; + static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3) { - /* - * We're called over smp_call_function_single() and therefore - * are on the correct cpu. - */ - int cpu = smp_processor_id(); - int node = cpu_to_node(cpu); - struct pci_dev *dev = node_to_k8_nb_misc(node); unsigned int sc0, sc1, sc2, sc3; u32 val = 0; - pci_read_config_dword(dev, 0x1C4, &val); + pci_read_config_dword(l3->dev, 0x1C4, &val); /* calculate subcache sizes */ l3->subcaches[0] = sc0 = !(val & BIT(0)); @@ -328,13 +327,31 @@ static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3) l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13)); l3->indices = (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1; +} + +static struct amd_l3_cache * __cpuinit amd_init_l3_cache(int node) +{ + struct amd_l3_cache *l3; + struct pci_dev *dev = node_to_k8_nb_misc(node); + + l3 = kzalloc(sizeof(struct amd_l3_cache), GFP_ATOMIC); + if (!l3) { + printk(KERN_WARNING "Error allocating L3 struct\n"); + return NULL; + } l3->dev = dev; + + amd_calc_l3_indices(l3); + + return l3; } static void __cpuinit amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) { + int node; + if (boot_cpu_data.x86 != 0x10) return; @@ -355,14 +372,28 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) if (num_k8_northbridges == 0) return; - this_leaf->l3 = kzalloc(sizeof(struct amd_l3_cache), GFP_ATOMIC); - if (!this_leaf->l3) { - printk(KERN_WARNING "Error allocating L3 struct\n"); - return; + /* + * Strictly speaking, the amount in @size below is leaked since it is + * never freed but this is done only on shutdown so it doesn't matter. + */ + if (!l3_caches) { + int size = num_k8_northbridges * sizeof(struct amd_l3_cache *); + + l3_caches = kzalloc(size, GFP_ATOMIC); + if (!l3_caches) + return; } - this_leaf->l3->can_disable = true; - amd_calc_l3_indices(this_leaf->l3); + node = amd_get_nb_id(smp_processor_id()); + + if (!l3_caches[node]) { + l3_caches[node] = amd_init_l3_cache(node); + l3_caches[node]->can_disable = true; + } + + WARN_ON(!l3_caches[node]); + + this_leaf->l3 = l3_caches[node]; } static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, -- cgit v1.2.3-59-g8ed1b From 59d3b388741cf1a5eb7ad27fd4e9ed72643164ae Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 22 Apr 2010 16:07:02 +0200 Subject: x86, cacheinfo: Disable index in all four subcaches When disabling an L3 cache index, make sure we disable that index in all four subcaches of the L3. Clarify nomenclature while at it, wrt to disable slots versus disable index and rename accordingly. Signed-off-by: Borislav Petkov LKML-Reference: <1271945222-5283-6-git-send-email-bp@amd64.org> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/intel_cacheinfo.c | 60 +++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 1346e9c23fc4..33eae2062cf5 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -397,7 +397,7 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) } static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, - unsigned int index) + unsigned int slot) { struct pci_dev *dev = this_leaf->l3->dev; unsigned int reg = 0; @@ -408,21 +408,53 @@ static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, if (!dev) return -EINVAL; - pci_read_config_dword(dev, 0x1BC + index * 4, ®); + pci_read_config_dword(dev, 0x1BC + slot * 4, ®); return sprintf(buf, "0x%08x\n", reg); } -#define SHOW_CACHE_DISABLE(index) \ +#define SHOW_CACHE_DISABLE(slot) \ static ssize_t \ -show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \ +show_cache_disable_##slot(struct _cpuid4_info *this_leaf, char *buf) \ { \ - return show_cache_disable(this_leaf, buf, index); \ + return show_cache_disable(this_leaf, buf, slot); \ } SHOW_CACHE_DISABLE(0) SHOW_CACHE_DISABLE(1) +static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu, + unsigned slot, unsigned long idx) +{ + int i; + + idx |= BIT(30); + + /* + * disable index in all 4 subcaches + */ + for (i = 0; i < 4; i++) { + u32 reg = idx | (i << 20); + + if (!l3->subcaches[i]) + continue; + + pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg); + + /* + * We need to WBINVD on a core on the node containing the L3 + * cache which indices we disable therefore a simple wbinvd() + * is not sufficient. + */ + wbinvd_on_cpu(cpu); + + reg |= BIT(31); + pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg); + } +} + + static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, - const char *buf, size_t count, unsigned int index) + const char *buf, size_t count, + unsigned int slot) { struct pci_dev *dev = this_leaf->l3->dev; int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); @@ -448,23 +480,17 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, ((val & SUBCACHE_INDEX) > this_leaf->l3->indices)) return -EINVAL; - val |= BIT(30); - pci_write_config_dword(dev, 0x1BC + index * 4, val); - /* - * We need to WBINVD on a core on the node containing the L3 cache which - * indices we disable therefore a simple wbinvd() is not sufficient. - */ - wbinvd_on_cpu(cpu); - pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31)); + amd_l3_disable_index(this_leaf->l3, cpu, slot, val); + return count; } -#define STORE_CACHE_DISABLE(index) \ +#define STORE_CACHE_DISABLE(slot) \ static ssize_t \ -store_cache_disable_##index(struct _cpuid4_info *this_leaf, \ +store_cache_disable_##slot(struct _cpuid4_info *this_leaf, \ const char *buf, size_t count) \ { \ - return store_cache_disable(this_leaf, buf, count, index); \ + return store_cache_disable(this_leaf, buf, count, slot); \ } STORE_CACHE_DISABLE(0) STORE_CACHE_DISABLE(1) -- cgit v1.2.3-59-g8ed1b From 1f9cc3cb6a27521edfe0a21abf97d2bb11c4d237 Mon Sep 17 00:00:00 2001 From: Robin Holt Date: Fri, 23 Apr 2010 10:36:22 -0500 Subject: x86, pat: Update the page flags for memtype atomically instead of using memtype_lock While testing an application using the xpmem (out of kernel) driver, we noticed a significant page fault rate reduction of x86_64 with respect to ia64. For one test running with 32 cpus, one thread per cpu, it took 01:08 for each of the threads to vm_insert_pfn 2GB worth of pages. For the same test running on 256 cpus, one thread per cpu, it took 14:48 to vm_insert_pfn 2 GB worth of pages. The slowdown was tracked to lookup_memtype which acquires the spinlock memtype_lock. This heavily contended lock was slowing down vm_insert_pfn(). With the cmpxchg on page->flags method, both the 32 cpu and 256 cpu cases take approx 00:01.3 seconds to complete. Signed-off-by: Robin Holt LKML-Reference: <20100423153627.751194346@gulag1.americas.sgi.com> Cc: Venkatesh Pallipadi Cc: Rafael Wysocki Reviewed-by: Suresh Siddha Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/cacheflush.h | 44 ++++++++++++++++++++++----------------- arch/x86/mm/pat.c | 8 ------- 2 files changed, 25 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h index 634c40a739a6..c70068d05f70 100644 --- a/arch/x86/include/asm/cacheflush.h +++ b/arch/x86/include/asm/cacheflush.h @@ -44,9 +44,6 @@ static inline void copy_from_user_page(struct vm_area_struct *vma, memcpy(dst, src, len); } -#define PG_WC PG_arch_1 -PAGEFLAG(WC, WC) - #ifdef CONFIG_X86_PAT /* * X86 PAT uses page flags WC and Uncached together to keep track of @@ -55,16 +52,24 @@ PAGEFLAG(WC, WC) * _PAGE_CACHE_UC_MINUS and fourth state where page's memory type has not * been changed from its default (value of -1 used to denote this). * Note we do not support _PAGE_CACHE_UC here. - * - * Caller must hold memtype_lock for atomicity. */ + +#define _PGMT_DEFAULT 0 +#define _PGMT_WC (1UL << PG_arch_1) +#define _PGMT_UC_MINUS (1UL << PG_uncached) +#define _PGMT_WB (1UL << PG_uncached | 1UL << PG_arch_1) +#define _PGMT_MASK (1UL << PG_uncached | 1UL << PG_arch_1) +#define _PGMT_CLEAR_MASK (~_PGMT_MASK) + static inline unsigned long get_page_memtype(struct page *pg) { - if (!PageUncached(pg) && !PageWC(pg)) + unsigned long pg_flags = pg->flags & _PGMT_MASK; + + if (pg_flags == _PGMT_DEFAULT) return -1; - else if (!PageUncached(pg) && PageWC(pg)) + else if (pg_flags == _PGMT_WC) return _PAGE_CACHE_WC; - else if (PageUncached(pg) && !PageWC(pg)) + else if (pg_flags == _PGMT_UC_MINUS) return _PAGE_CACHE_UC_MINUS; else return _PAGE_CACHE_WB; @@ -72,25 +77,26 @@ static inline unsigned long get_page_memtype(struct page *pg) static inline void set_page_memtype(struct page *pg, unsigned long memtype) { + unsigned long memtype_flags = _PGMT_DEFAULT; + unsigned long old_flags; + unsigned long new_flags; + switch (memtype) { case _PAGE_CACHE_WC: - ClearPageUncached(pg); - SetPageWC(pg); + memtype_flags = _PGMT_WC; break; case _PAGE_CACHE_UC_MINUS: - SetPageUncached(pg); - ClearPageWC(pg); + memtype_flags = _PGMT_UC_MINUS; break; case _PAGE_CACHE_WB: - SetPageUncached(pg); - SetPageWC(pg); - break; - default: - case -1: - ClearPageUncached(pg); - ClearPageWC(pg); + memtype_flags = _PGMT_WB; break; } + + do { + old_flags = pg->flags; + new_flags = (old_flags & _PGMT_CLEAR_MASK) | memtype_flags; + } while (cmpxchg(&pg->flags, old_flags, new_flags) != old_flags); } #else static inline unsigned long get_page_memtype(struct page *pg) { return -1; } diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 951011166ef5..501fc60e5e4d 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -190,8 +190,6 @@ static int pat_pagerange_is_ram(unsigned long start, unsigned long end) * Here we do two pass: * - Find the memtype of all the pages in the range, look for any conflicts * - In case of no conflicts, set the new memtype for pages in the range - * - * Caller must hold memtype_lock for atomicity. */ static int reserve_ram_pages_type(u64 start, u64 end, unsigned long req_type, unsigned long *new_type) @@ -297,9 +295,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, is_range_ram = pat_pagerange_is_ram(start, end); if (is_range_ram == 1) { - spin_lock(&memtype_lock); err = reserve_ram_pages_type(start, end, req_type, new_type); - spin_unlock(&memtype_lock); return err; } else if (is_range_ram < 0) { @@ -351,9 +347,7 @@ int free_memtype(u64 start, u64 end) is_range_ram = pat_pagerange_is_ram(start, end); if (is_range_ram == 1) { - spin_lock(&memtype_lock); err = free_ram_pages_type(start, end); - spin_unlock(&memtype_lock); return err; } else if (is_range_ram < 0) { @@ -394,10 +388,8 @@ static unsigned long lookup_memtype(u64 paddr) if (pat_pagerange_is_ram(paddr, paddr + PAGE_SIZE)) { struct page *page; - spin_lock(&memtype_lock); page = pfn_to_page(paddr >> PAGE_SHIFT); rettype = get_page_memtype(page); - spin_unlock(&memtype_lock); /* * -1 from get_page_memtype() implies RAM page is in its * default state and not reserved, and hence of type WB -- cgit v1.2.3-59-g8ed1b From 89a27f4d0e042a2fa3391a76b652aec3e16ef200 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Tue, 16 Feb 2010 10:51:48 +0200 Subject: KVM: use desc_ptr struct instead of kvm private descriptor_table x86 arch defines desc_ptr for idt/gdt pointers, no need to define another structure in kvm code. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_host.h | 17 ++++++--------- arch/x86/kvm/svm.c | 28 ++++++++++++------------- arch/x86/kvm/vmx.c | 36 ++++++++++++++++---------------- arch/x86/kvm/x86.c | 46 ++++++++++++++++++++--------------------- 4 files changed, 61 insertions(+), 66 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 06d9e79ca37d..cf392dfb8000 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -461,11 +461,6 @@ struct kvm_vcpu_stat { u32 nmi_injections; }; -struct descriptor_table { - u16 limit; - unsigned long base; -} __attribute__((packed)); - struct kvm_x86_ops { int (*cpu_has_kvm_support)(void); /* __init */ int (*disabled_by_bios)(void); /* __init */ @@ -503,10 +498,10 @@ struct kvm_x86_ops { void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); void (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4); void (*set_efer)(struct kvm_vcpu *vcpu, u64 efer); - void (*get_idt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt); - void (*set_idt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt); - void (*get_gdt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt); - void (*set_gdt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt); + void (*get_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); + void (*set_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); + void (*get_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); + void (*set_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); int (*get_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long *dest); int (*set_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long value); void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); @@ -724,12 +719,12 @@ static inline void kvm_load_ldt(u16 sel) asm("lldt %0" : : "rm"(sel)); } -static inline void kvm_get_idt(struct descriptor_table *table) +static inline void kvm_get_idt(struct desc_ptr *table) { asm("sidt %0" : "=m"(*table)); } -static inline void kvm_get_gdt(struct descriptor_table *table) +static inline void kvm_get_gdt(struct desc_ptr *table) { asm("sgdt %0" : "=m"(*table)); } diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 2ba58206812a..77fa2e3053b5 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -319,7 +319,7 @@ static int svm_hardware_enable(void *garbage) struct svm_cpu_data *sd; uint64_t efer; - struct descriptor_table gdt_descr; + struct desc_ptr gdt_descr; struct desc_struct *gdt; int me = raw_smp_processor_id(); @@ -345,7 +345,7 @@ static int svm_hardware_enable(void *garbage) sd->next_asid = sd->max_asid + 1; kvm_get_gdt(&gdt_descr); - gdt = (struct desc_struct *)gdt_descr.base; + gdt = (struct desc_struct *)gdt_descr.address; sd->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); wrmsrl(MSR_EFER, efer | EFER_SVME); @@ -936,36 +936,36 @@ static int svm_get_cpl(struct kvm_vcpu *vcpu) return save->cpl; } -static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +static void svm_get_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) { struct vcpu_svm *svm = to_svm(vcpu); - dt->limit = svm->vmcb->save.idtr.limit; - dt->base = svm->vmcb->save.idtr.base; + dt->size = svm->vmcb->save.idtr.limit; + dt->address = svm->vmcb->save.idtr.base; } -static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +static void svm_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) { struct vcpu_svm *svm = to_svm(vcpu); - svm->vmcb->save.idtr.limit = dt->limit; - svm->vmcb->save.idtr.base = dt->base ; + svm->vmcb->save.idtr.limit = dt->size; + svm->vmcb->save.idtr.base = dt->address ; } -static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +static void svm_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) { struct vcpu_svm *svm = to_svm(vcpu); - dt->limit = svm->vmcb->save.gdtr.limit; - dt->base = svm->vmcb->save.gdtr.base; + dt->size = svm->vmcb->save.gdtr.limit; + dt->address = svm->vmcb->save.gdtr.base; } -static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +static void svm_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) { struct vcpu_svm *svm = to_svm(vcpu); - svm->vmcb->save.gdtr.limit = dt->limit; - svm->vmcb->save.gdtr.base = dt->base ; + svm->vmcb->save.gdtr.limit = dt->size; + svm->vmcb->save.gdtr.base = dt->address ; } static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index bc933cfb4e66..68f895b00450 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -600,11 +600,11 @@ static void reload_tss(void) /* * VT restores TR but not its size. Useless. */ - struct descriptor_table gdt; + struct desc_ptr gdt; struct desc_struct *descs; kvm_get_gdt(&gdt); - descs = (void *)gdt.base; + descs = (void *)gdt.address; descs[GDT_ENTRY_TSS].type = 9; /* available TSS */ load_TR_desc(); } @@ -758,7 +758,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) } if (vcpu->cpu != cpu) { - struct descriptor_table dt; + struct desc_ptr dt; unsigned long sysenter_esp; vcpu->cpu = cpu; @@ -768,7 +768,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) */ vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */ kvm_get_gdt(&dt); - vmcs_writel(HOST_GDTR_BASE, dt.base); /* 22.2.4 */ + vmcs_writel(HOST_GDTR_BASE, dt.address); /* 22.2.4 */ rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ @@ -1934,28 +1934,28 @@ static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) *l = (ar >> 13) & 1; } -static void vmx_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +static void vmx_get_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) { - dt->limit = vmcs_read32(GUEST_IDTR_LIMIT); - dt->base = vmcs_readl(GUEST_IDTR_BASE); + dt->size = vmcs_read32(GUEST_IDTR_LIMIT); + dt->address = vmcs_readl(GUEST_IDTR_BASE); } -static void vmx_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +static void vmx_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) { - vmcs_write32(GUEST_IDTR_LIMIT, dt->limit); - vmcs_writel(GUEST_IDTR_BASE, dt->base); + vmcs_write32(GUEST_IDTR_LIMIT, dt->size); + vmcs_writel(GUEST_IDTR_BASE, dt->address); } -static void vmx_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +static void vmx_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) { - dt->limit = vmcs_read32(GUEST_GDTR_LIMIT); - dt->base = vmcs_readl(GUEST_GDTR_BASE); + dt->size = vmcs_read32(GUEST_GDTR_LIMIT); + dt->address = vmcs_readl(GUEST_GDTR_BASE); } -static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) { - vmcs_write32(GUEST_GDTR_LIMIT, dt->limit); - vmcs_writel(GUEST_GDTR_BASE, dt->base); + vmcs_write32(GUEST_GDTR_LIMIT, dt->size); + vmcs_writel(GUEST_GDTR_BASE, dt->address); } static bool rmode_segment_valid(struct kvm_vcpu *vcpu, int seg) @@ -2334,7 +2334,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) u32 junk; u64 host_pat, tsc_this, tsc_base; unsigned long a; - struct descriptor_table dt; + struct desc_ptr dt; int i; unsigned long kvm_vmx_return; u32 exec_control; @@ -2416,7 +2416,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */ kvm_get_idt(&dt); - vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */ + vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */ asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return)); vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3c4ca98ad27f..274a8e39bca7 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -225,7 +225,7 @@ static void drop_user_return_notifiers(void *ignore) unsigned long segment_base(u16 selector) { - struct descriptor_table gdt; + struct desc_ptr gdt; struct desc_struct *d; unsigned long table_base; unsigned long v; @@ -234,7 +234,7 @@ unsigned long segment_base(u16 selector) return 0; kvm_get_gdt(&gdt); - table_base = gdt.base; + table_base = gdt.address; if (selector & 4) { /* from ldt */ u16 ldt_selector = kvm_read_ldt(); @@ -3949,14 +3949,14 @@ static u64 mk_cr_64(u64 curr_cr, u32 new_val) void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) { - struct descriptor_table dt = { limit, base }; + struct desc_ptr dt = { limit, base }; kvm_x86_ops->set_gdt(vcpu, &dt); } void realmode_lidt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) { - struct descriptor_table dt = { limit, base }; + struct desc_ptr dt = { limit, base }; kvm_x86_ops->set_idt(vcpu, &dt); } @@ -4581,7 +4581,7 @@ EXPORT_SYMBOL_GPL(kvm_get_cs_db_l_bits); int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) { - struct descriptor_table dt; + struct desc_ptr dt; vcpu_load(vcpu); @@ -4596,11 +4596,11 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, kvm_get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); kvm_x86_ops->get_idt(vcpu, &dt); - sregs->idt.limit = dt.limit; - sregs->idt.base = dt.base; + sregs->idt.limit = dt.size; + sregs->idt.base = dt.address; kvm_x86_ops->get_gdt(vcpu, &dt); - sregs->gdt.limit = dt.limit; - sregs->gdt.base = dt.base; + sregs->gdt.limit = dt.size; + sregs->gdt.base = dt.address; sregs->cr0 = kvm_read_cr0(vcpu); sregs->cr2 = vcpu->arch.cr2; @@ -4672,7 +4672,7 @@ static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector, static void get_segment_descriptor_dtable(struct kvm_vcpu *vcpu, u16 selector, - struct descriptor_table *dtable) + struct desc_ptr *dtable) { if (selector & 1 << 2) { struct kvm_segment kvm_seg; @@ -4680,10 +4680,10 @@ static void get_segment_descriptor_dtable(struct kvm_vcpu *vcpu, kvm_get_segment(vcpu, &kvm_seg, VCPU_SREG_LDTR); if (kvm_seg.unusable) - dtable->limit = 0; + dtable->size = 0; else - dtable->limit = kvm_seg.limit; - dtable->base = kvm_seg.base; + dtable->size = kvm_seg.limit; + dtable->address = kvm_seg.base; } else kvm_x86_ops->get_gdt(vcpu, dtable); @@ -4693,7 +4693,7 @@ static void get_segment_descriptor_dtable(struct kvm_vcpu *vcpu, static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, struct desc_struct *seg_desc) { - struct descriptor_table dtable; + struct desc_ptr dtable; u16 index = selector >> 3; int ret; u32 err; @@ -4701,7 +4701,7 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, get_segment_descriptor_dtable(vcpu, selector, &dtable); - if (dtable.limit < index * 8 + 7) { + if (dtable.size < index * 8 + 7) { kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); return X86EMUL_PROPAGATE_FAULT; } @@ -4718,14 +4718,14 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, struct desc_struct *seg_desc) { - struct descriptor_table dtable; + struct desc_ptr dtable; u16 index = selector >> 3; get_segment_descriptor_dtable(vcpu, selector, &dtable); - if (dtable.limit < index * 8 + 7) + if (dtable.size < index * 8 + 7) return 1; - return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu, NULL); + return kvm_write_guest_virt(dtable.address + index*8, seg_desc, sizeof(*seg_desc), vcpu, NULL); } static gpa_t get_tss_base_addr_write(struct kvm_vcpu *vcpu, @@ -5204,15 +5204,15 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, { int mmu_reset_needed = 0; int pending_vec, max_bits; - struct descriptor_table dt; + struct desc_ptr dt; vcpu_load(vcpu); - dt.limit = sregs->idt.limit; - dt.base = sregs->idt.base; + dt.size = sregs->idt.limit; + dt.address = sregs->idt.base; kvm_x86_ops->set_idt(vcpu, &dt); - dt.limit = sregs->gdt.limit; - dt.base = sregs->gdt.base; + dt.size = sregs->gdt.limit; + dt.address = sregs->gdt.base; kvm_x86_ops->set_gdt(vcpu, &dt); vcpu->arch.cr2 = sregs->cr2; -- cgit v1.2.3-59-g8ed1b From 1161624f15f584096a0df3dda70403cd1d00721e Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 11 Feb 2010 14:43:14 +0200 Subject: KVM: inject #UD in 64bit mode from instruction that are not valid there Some instruction are obsolete in a long mode. Inject #UD. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/kvm/emulate.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 4dade6ac0827..96d4bef06e14 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1015,11 +1015,6 @@ done_prefixes: } } - if (mode == X86EMUL_MODE_PROT64 && (c->d & No64)) { - kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction"); - return -1; - } - if (c->d & Group) { group = c->d & GroupMask; c->modrm = insn_fetch(u8, 1, c->eip); @@ -1828,6 +1823,11 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); saved_eip = c->eip; + if (ctxt->mode == X86EMUL_MODE_PROT64 && (c->d & No64)) { + kvm_queue_exception(ctxt->vcpu, UD_VECTOR); + goto done; + } + /* LOCK prefix is allowed only with some instructions */ if (c->lock_prefix && !(c->d & Lock)) { kvm_queue_exception(ctxt->vcpu, UD_VECTOR); -- cgit v1.2.3-59-g8ed1b From 3e2815e9fa6c06bcb8a9340e43008bbe48437d25 Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Fri, 12 Feb 2010 15:53:59 +0900 Subject: KVM: x86 emulator: X86EMUL macro replacements: from do_fetch_insn_byte() to x86_decode_insn() This patch just replaces the integer values used inside x86's decode functions to X86EMUL_*. By this patch, it becomes clearer that we are using X86EMUL_* value propagated from ops->read_std() in do_fetch_insn_byte(). Signed-off-by: Takuya Yoshikawa Signed-off-by: Avi Kivity --- arch/x86/kvm/emulate.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 96d4bef06e14..b8aed35ab5f9 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -647,20 +647,20 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, if (linear < fc->start || linear >= fc->end) { size = min(15UL, PAGE_SIZE - offset_in_page(linear)); rc = ops->fetch(linear, fc->data, size, ctxt->vcpu, NULL); - if (rc) + if (rc != X86EMUL_CONTINUE) return rc; fc->start = linear; fc->end = linear + size; } *dest = fc->data[linear - fc->start]; - return 0; + return X86EMUL_CONTINUE; } static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, unsigned long eip, void *dest, unsigned size) { - int rc = 0; + int rc; /* x86 instructions are limited to 15 bytes. */ if (eip + size - ctxt->decode.eip_orig > 15) @@ -668,10 +668,10 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, eip += ctxt->cs_base; while (size--) { rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++); - if (rc) + if (rc != X86EMUL_CONTINUE) return rc; } - return 0; + return X86EMUL_CONTINUE; } /* @@ -782,7 +782,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, struct decode_cache *c = &ctxt->decode; u8 sib; int index_reg = 0, base_reg = 0, scale; - int rc = 0; + int rc = X86EMUL_CONTINUE; if (c->rex_prefix) { c->modrm_reg = (c->rex_prefix & 4) << 1; /* REX.R */ @@ -895,7 +895,7 @@ static int decode_abs(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = &ctxt->decode; - int rc = 0; + int rc = X86EMUL_CONTINUE; switch (c->ad_bytes) { case 2: @@ -916,7 +916,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = &ctxt->decode; - int rc = 0; + int rc = X86EMUL_CONTINUE; int mode = ctxt->mode; int def_op_bytes, def_ad_bytes, group; @@ -1041,7 +1041,7 @@ done_prefixes: rc = decode_modrm(ctxt, ops); else if (c->d & MemAbs) rc = decode_abs(ctxt, ops); - if (rc) + if (rc != X86EMUL_CONTINUE) goto done; if (!c->has_seg_override) -- cgit v1.2.3-59-g8ed1b From 1b30eaa84609031c06e417eafd5b68f45e4266f7 Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Fri, 12 Feb 2010 15:57:56 +0900 Subject: KVM: x86 emulator: X86EMUL macro replacements: x86_emulate_insn() and its helpers This patch just replaces integer values used inside x86_emulate_insn() and its helper functions to X86EMUL_*. The purpose of this is to make it clear what will happen when the variable rc is compared to X86EMUL_* at the end of x86_emulate_insn(). Signed-off-by: Takuya Yoshikawa Signed-off-by: Avi Kivity --- arch/x86/kvm/emulate.c | 62 +++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index b8aed35ab5f9..ee1a2a2c12e9 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -702,7 +702,7 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, *address = 0; rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, ctxt->vcpu, NULL); - if (rc) + if (rc != X86EMUL_CONTINUE) return rc; rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, ctxt->vcpu, NULL); @@ -1301,7 +1301,7 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt, int rc; rc = emulate_pop(ctxt, ops, &selector, c->op_bytes); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) return rc; rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, seg); @@ -1327,7 +1327,7 @@ static int emulate_popa(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = &ctxt->decode; - int rc = 0; + int rc = X86EMUL_CONTINUE; int reg = VCPU_REGS_RDI; while (reg >= VCPU_REGS_RAX) { @@ -1338,7 +1338,7 @@ static int emulate_popa(struct x86_emulate_ctxt *ctxt, } rc = emulate_pop(ctxt, ops, &c->regs[reg], c->op_bytes); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) break; --reg; } @@ -1349,12 +1349,8 @@ static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = &ctxt->decode; - int rc; - rc = emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes); - if (rc != 0) - return rc; - return 0; + return emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes); } static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt) @@ -1390,7 +1386,7 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = &ctxt->decode; - int rc = 0; + int rc = X86EMUL_CONTINUE; switch (c->modrm_reg) { case 0 ... 1: /* test */ @@ -1437,7 +1433,7 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, emulate_push(ctxt); break; } - return 0; + return X86EMUL_CONTINUE; } static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, @@ -1468,7 +1464,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, return rc; ctxt->eflags |= EFLG_ZF; } - return 0; + return X86EMUL_CONTINUE; } static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, @@ -1479,12 +1475,12 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, unsigned long cs; rc = emulate_pop(ctxt, ops, &c->eip, c->op_bytes); - if (rc) + if (rc != X86EMUL_CONTINUE) return rc; if (c->op_bytes == 4) c->eip = (u32)c->eip; rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); - if (rc) + if (rc != X86EMUL_CONTINUE) return rc; rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, VCPU_SREG_CS); return rc; @@ -1539,7 +1535,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, default: break; } - return 0; + return X86EMUL_CONTINUE; } static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) @@ -1811,7 +1807,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) struct decode_cache *c = &ctxt->decode; unsigned int port; int io_dir_in; - int rc = 0; + int rc = X86EMUL_CONTINUE; ctxt->interruptibility = 0; @@ -1926,7 +1922,7 @@ special_insn: break; case 0x07: /* pop es */ rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; break; case 0x08 ... 0x0d: @@ -1945,7 +1941,7 @@ special_insn: break; case 0x17: /* pop ss */ rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; break; case 0x18 ... 0x1d: @@ -1957,7 +1953,7 @@ special_insn: break; case 0x1f: /* pop ds */ rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; break; case 0x20 ... 0x25: @@ -1988,7 +1984,7 @@ special_insn: case 0x58 ... 0x5f: /* pop reg */ pop_instruction: rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; break; case 0x60: /* pusha */ @@ -1996,7 +1992,7 @@ special_insn: break; case 0x61: /* popa */ rc = emulate_popa(ctxt, ops); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; break; case 0x63: /* movsxd */ @@ -2141,7 +2137,7 @@ special_insn: } case 0x8f: /* pop (sole member of Grp1a) */ rc = emulate_grp1a(ctxt, ops); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; break; case 0x90: /* nop / xchg r8,rax */ @@ -2277,7 +2273,7 @@ special_insn: break; case 0xcb: /* ret far */ rc = emulate_ret_far(ctxt, ops); - if (rc) + if (rc != X86EMUL_CONTINUE) goto done; break; case 0xd0 ... 0xd1: /* Grp2 */ @@ -2351,7 +2347,7 @@ special_insn: break; case 0xf6 ... 0xf7: /* Grp3 */ rc = emulate_grp3(ctxt, ops); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; break; case 0xf8: /* clc */ @@ -2385,14 +2381,14 @@ special_insn: break; case 0xfe ... 0xff: /* Grp4/Grp5 */ rc = emulate_grp45(ctxt, ops); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; break; } writeback: rc = writeback(ctxt, ops); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; /* Commit shadow register state. */ @@ -2418,7 +2414,7 @@ twobyte_insn: goto cannot_emulate; rc = kvm_fix_hypercall(ctxt->vcpu); - if (rc) + if (rc != X86EMUL_CONTINUE) goto done; /* Let the processor re-execute the fixed hypercall */ @@ -2429,7 +2425,7 @@ twobyte_insn: case 2: /* lgdt */ rc = read_descriptor(ctxt, ops, c->src.ptr, &size, &address, c->op_bytes); - if (rc) + if (rc != X86EMUL_CONTINUE) goto done; realmode_lgdt(ctxt->vcpu, size, address); /* Disable writeback. */ @@ -2440,7 +2436,7 @@ twobyte_insn: switch (c->modrm_rm) { case 1: rc = kvm_fix_hypercall(ctxt->vcpu); - if (rc) + if (rc != X86EMUL_CONTINUE) goto done; break; default: @@ -2450,7 +2446,7 @@ twobyte_insn: rc = read_descriptor(ctxt, ops, c->src.ptr, &size, &address, c->op_bytes); - if (rc) + if (rc != X86EMUL_CONTINUE) goto done; realmode_lidt(ctxt->vcpu, size, address); } @@ -2577,7 +2573,7 @@ twobyte_insn: break; case 0xa1: /* pop fs */ rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; break; case 0xa3: @@ -2596,7 +2592,7 @@ twobyte_insn: break; case 0xa9: /* pop gs */ rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; break; case 0xab: @@ -2669,7 +2665,7 @@ twobyte_insn: break; case 0xc7: /* Grp9 (cmpxchg8b) */ rc = emulate_grp9(ctxt, ops, memop); - if (rc != 0) + if (rc != X86EMUL_CONTINUE) goto done; c->dst.type = OP_NONE; break; -- cgit v1.2.3-59-g8ed1b From 0e4176a15f9af494ad098cb5a76bcfa17e14282b Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Fri, 12 Feb 2010 16:00:55 +0900 Subject: KVM: x86 emulator: Fix x86_emulate_insn() not to use the variable rc for non-X86EMUL values This patch makes non-X86EMUL_* family functions not to use the variable rc. Be sure that this changes nothing but makes the purpose of the variable rc clearer. Signed-off-by: Takuya Yoshikawa Signed-off-by: Avi Kivity --- arch/x86/kvm/emulate.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index ee1a2a2c12e9..35f7acd4a91f 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2498,9 +2498,9 @@ twobyte_insn: case 0x21: /* mov from dr to reg */ if (c->modrm_mod != 3) goto cannot_emulate; - rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]); - if (rc) + if (emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm])) goto cannot_emulate; + rc = X86EMUL_CONTINUE; c->dst.type = OP_NONE; /* no writeback */ break; case 0x22: /* mov reg, cr */ @@ -2513,18 +2513,16 @@ twobyte_insn: case 0x23: /* mov from reg to dr */ if (c->modrm_mod != 3) goto cannot_emulate; - rc = emulator_set_dr(ctxt, c->modrm_reg, - c->regs[c->modrm_rm]); - if (rc) + if (emulator_set_dr(ctxt, c->modrm_reg, c->regs[c->modrm_rm])) goto cannot_emulate; + rc = X86EMUL_CONTINUE; c->dst.type = OP_NONE; /* no writeback */ break; case 0x30: /* wrmsr */ msr_data = (u32)c->regs[VCPU_REGS_RAX] | ((u64)c->regs[VCPU_REGS_RDX] << 32); - rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data); - if (rc) { + if (kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data)) { kvm_inject_gp(ctxt->vcpu, 0); c->eip = kvm_rip_read(ctxt->vcpu); } @@ -2533,8 +2531,7 @@ twobyte_insn: break; case 0x32: /* rdmsr */ - rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data); - if (rc) { + if (kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data)) { kvm_inject_gp(ctxt->vcpu, 0); c->eip = kvm_rip_read(ctxt->vcpu); } else { -- cgit v1.2.3-59-g8ed1b From ad91f8ffbb18413e79f9f976a55b4e11d02e6a6d Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Fri, 12 Feb 2010 16:02:54 +0900 Subject: KVM: remove redundant prototype of load_pdptrs() This patch removes redundant prototype of load_pdptrs(). I found load_pdptrs() twice in kvm_host.h. Let's remove one. Signed-off-by: Takuya Yoshikawa Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_host.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index cf392dfb8000..d46e791de129 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -670,7 +670,6 @@ void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva); void kvm_enable_tdp(void); void kvm_disable_tdp(void); -int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); int complete_pio(struct kvm_vcpu *vcpu); bool kvm_check_iopl(struct kvm_vcpu *vcpu); -- cgit v1.2.3-59-g8ed1b From 7597f129d8b6799da7a264e6d6f7401668d3a36d Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 19 Feb 2010 16:23:00 +0100 Subject: KVM: SVM: Don't use kmap_atomic in nested_svm_map Use of kmap_atomic disables preemption but if we run in shadow-shadow mode the vmrun emulation executes kvm_set_cr3 which might sleep or fault. So use kmap instead for nested_svm_map. Cc: stable@kernel.org Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 77fa2e3053b5..f9da35b06ec7 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1423,7 +1423,7 @@ static inline int nested_svm_intr(struct vcpu_svm *svm) return 0; } -static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, enum km_type idx) +static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page) { struct page *page; @@ -1431,7 +1431,9 @@ static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, enum km_type idx) if (is_error_page(page)) goto error; - return kmap_atomic(page, idx); + *_page = page; + + return kmap(page); error: kvm_release_page_clean(page); @@ -1440,16 +1442,9 @@ error: return NULL; } -static void nested_svm_unmap(void *addr, enum km_type idx) +static void nested_svm_unmap(struct page *page) { - struct page *page; - - if (!addr) - return; - - page = kmap_atomic_to_page(addr); - - kunmap_atomic(addr, idx); + kunmap(page); kvm_release_page_dirty(page); } @@ -1457,6 +1452,7 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm) { u32 param = svm->vmcb->control.exit_info_1 & 1; u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; + struct page *page; bool ret = false; u32 t0, t1; u8 *msrpm; @@ -1464,7 +1460,7 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm) if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) return false; - msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0); + msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, &page); if (!msrpm) goto out; @@ -1492,7 +1488,7 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm) ret = msrpm[t1] & ((1 << param) << t0); out: - nested_svm_unmap(msrpm, KM_USER0); + nested_svm_unmap(page); return ret; } @@ -1615,6 +1611,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) struct vmcb *nested_vmcb; struct vmcb *hsave = svm->nested.hsave; struct vmcb *vmcb = svm->vmcb; + struct page *page; trace_kvm_nested_vmexit_inject(vmcb->control.exit_code, vmcb->control.exit_info_1, @@ -1622,7 +1619,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) vmcb->control.exit_int_info, vmcb->control.exit_int_info_err); - nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, KM_USER0); + nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, &page); if (!nested_vmcb) return 1; @@ -1712,7 +1709,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) /* Exit nested SVM mode */ svm->nested.vmcb = 0; - nested_svm_unmap(nested_vmcb, KM_USER0); + nested_svm_unmap(page); kvm_mmu_reset_context(&svm->vcpu); kvm_mmu_load(&svm->vcpu); @@ -1723,9 +1720,10 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) { u32 *nested_msrpm; + struct page *page; int i; - nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0); + nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, &page); if (!nested_msrpm) return false; @@ -1734,7 +1732,7 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm); - nested_svm_unmap(nested_msrpm, KM_USER0); + nested_svm_unmap(page); return true; } @@ -1744,8 +1742,9 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) struct vmcb *nested_vmcb; struct vmcb *hsave = svm->nested.hsave; struct vmcb *vmcb = svm->vmcb; + struct page *page; - nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0); + nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); if (!nested_vmcb) return false; @@ -1857,7 +1856,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) svm->vmcb->control.event_inj = nested_vmcb->control.event_inj; svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err; - nested_svm_unmap(nested_vmcb, KM_USER0); + nested_svm_unmap(page); enable_gif(svm); @@ -1883,6 +1882,7 @@ static void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb) static int vmload_interception(struct vcpu_svm *svm) { struct vmcb *nested_vmcb; + struct page *page; if (nested_svm_check_permissions(svm)) return 1; @@ -1890,12 +1890,12 @@ static int vmload_interception(struct vcpu_svm *svm) svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; skip_emulated_instruction(&svm->vcpu); - nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0); + nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); if (!nested_vmcb) return 1; nested_svm_vmloadsave(nested_vmcb, svm->vmcb); - nested_svm_unmap(nested_vmcb, KM_USER0); + nested_svm_unmap(page); return 1; } @@ -1903,6 +1903,7 @@ static int vmload_interception(struct vcpu_svm *svm) static int vmsave_interception(struct vcpu_svm *svm) { struct vmcb *nested_vmcb; + struct page *page; if (nested_svm_check_permissions(svm)) return 1; @@ -1910,12 +1911,12 @@ static int vmsave_interception(struct vcpu_svm *svm) svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; skip_emulated_instruction(&svm->vcpu); - nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0); + nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); if (!nested_vmcb) return 1; nested_svm_vmloadsave(svm->vmcb, nested_vmcb); - nested_svm_unmap(nested_vmcb, KM_USER0); + nested_svm_unmap(page); return 1; } -- cgit v1.2.3-59-g8ed1b From b8e88bc8ffba5fe53fb8d8a0a4be3bbcffeebe56 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 19 Feb 2010 16:23:02 +0100 Subject: KVM: SVM: Fix schedule-while-atomic on nested exception handling Move the actual vmexit routine out of code that runs with irqs and preemption disabled. Cc: stable@kernel.org Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index f9da35b06ec7..c27da0ad040c 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -129,6 +129,7 @@ static void svm_flush_tlb(struct kvm_vcpu *vcpu); static void svm_complete_interrupts(struct vcpu_svm *svm); static int nested_svm_exit_handled(struct vcpu_svm *svm); +static int nested_svm_intercept(struct vcpu_svm *svm); static int nested_svm_vmexit(struct vcpu_svm *svm); static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, bool has_error_code, u32 error_code); @@ -1384,6 +1385,8 @@ static int nested_svm_check_permissions(struct vcpu_svm *svm) static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, bool has_error_code, u32 error_code) { + int vmexit; + if (!is_nested(svm)) return 0; @@ -1392,7 +1395,11 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, svm->vmcb->control.exit_info_1 = error_code; svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2; - return nested_svm_exit_handled(svm); + vmexit = nested_svm_intercept(svm); + if (vmexit == NESTED_EXIT_DONE) + svm->nested.exit_required = true; + + return vmexit; } static inline int nested_svm_intr(struct vcpu_svm *svm) @@ -1521,7 +1528,7 @@ static int nested_svm_exit_special(struct vcpu_svm *svm) /* * If this function returns true, this #vmexit was already handled */ -static int nested_svm_exit_handled(struct vcpu_svm *svm) +static int nested_svm_intercept(struct vcpu_svm *svm) { u32 exit_code = svm->vmcb->control.exit_code; int vmexit = NESTED_EXIT_HOST; @@ -1567,9 +1574,17 @@ static int nested_svm_exit_handled(struct vcpu_svm *svm) } } - if (vmexit == NESTED_EXIT_DONE) { + return vmexit; +} + +static int nested_svm_exit_handled(struct vcpu_svm *svm) +{ + int vmexit; + + vmexit = nested_svm_intercept(svm); + + if (vmexit == NESTED_EXIT_DONE) nested_svm_vmexit(svm); - } return vmexit; } -- cgit v1.2.3-59-g8ed1b From cdbbdc1210223879450555fee04c29ebf116576b Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 19 Feb 2010 16:23:03 +0100 Subject: KVM: SVM: Sync all control registers on nested vmexit Currently the vmexit emulation does not sync control registers were the access is typically intercepted by the nested hypervisor. But we can not count on that intercepts to sync these registers too and make the code architecturally more correct. Cc: stable@kernel.org Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c27da0ad040c..02f8d491d15a 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1647,9 +1647,13 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) nested_vmcb->save.ds = vmcb->save.ds; nested_vmcb->save.gdtr = vmcb->save.gdtr; nested_vmcb->save.idtr = vmcb->save.idtr; + nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu); if (npt_enabled) nested_vmcb->save.cr3 = vmcb->save.cr3; + else + nested_vmcb->save.cr3 = svm->vcpu.arch.cr3; nested_vmcb->save.cr2 = vmcb->save.cr2; + nested_vmcb->save.cr4 = svm->vcpu.arch.cr4; nested_vmcb->save.rflags = vmcb->save.rflags; nested_vmcb->save.rip = vmcb->save.rip; nested_vmcb->save.rsp = vmcb->save.rsp; -- cgit v1.2.3-59-g8ed1b From 6c3bd3d7660c35a703073b81eccfd5a3b7c15295 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 19 Feb 2010 16:23:04 +0100 Subject: KVM: SVM: Annotate nested_svm_map with might_sleep() The nested_svm_map() function can sleep and must not be called from atomic context. So annotate that function. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 02f8d491d15a..4bc018333d76 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1434,6 +1434,8 @@ static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page) { struct page *page; + might_sleep(); + page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT); if (is_error_page(page)) goto error; -- cgit v1.2.3-59-g8ed1b From 4c7da8cb43c09e71a405b5aeaa58a1dbac3c39e9 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 19 Feb 2010 16:23:05 +0100 Subject: KVM: SVM: Fix nested msr intercept handling The nested_svm_exit_handled_msr() function maps only one page of the guests msr permission bitmap. This patch changes the code to use kvm_read_guest to fix the bug. Cc: stable@kernel.org Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 4bc018333d76..4459c477af9f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1461,19 +1461,13 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm) { u32 param = svm->vmcb->control.exit_info_1 & 1; u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; - struct page *page; bool ret = false; u32 t0, t1; - u8 *msrpm; + u8 val; if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) return false; - msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, &page); - - if (!msrpm) - goto out; - switch (msr) { case 0 ... 0x1fff: t0 = (msr * 2) % 8; @@ -1494,11 +1488,10 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm) goto out; } - ret = msrpm[t1] & ((1 << param) << t0); + if (!kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + t1, &val, 1)) + ret = val & ((1 << param) << t0); out: - nested_svm_unmap(page); - return ret; } -- cgit v1.2.3-59-g8ed1b From 88ab24adc7142506c8583ac36a34fa388300b750 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 19 Feb 2010 16:23:06 +0100 Subject: KVM: SVM: Don't sync nested cr8 to lapic and back This patch makes syncing of the guest tpr to the lapic conditional on !nested. Otherwise a nested guest using the TPR could freeze the guest. Another important change this patch introduces is that the cr8 intercept bits are no longer ORed at vmrun emulation if the guest sets VINTR_MASKING in its VMCB. The reason is that nested cr8 accesses need alway be handled by the nested hypervisor because they change the shadow version of the tpr. Cc: stable@kernel.org Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 4459c477af9f..481bd0ee5f7e 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1832,21 +1832,6 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) svm->vmcb->save.dr6 = nested_vmcb->save.dr6; svm->vmcb->save.cpl = nested_vmcb->save.cpl; - /* We don't want a nested guest to be more powerful than the guest, - so all intercepts are ORed */ - svm->vmcb->control.intercept_cr_read |= - nested_vmcb->control.intercept_cr_read; - svm->vmcb->control.intercept_cr_write |= - nested_vmcb->control.intercept_cr_write; - svm->vmcb->control.intercept_dr_read |= - nested_vmcb->control.intercept_dr_read; - svm->vmcb->control.intercept_dr_write |= - nested_vmcb->control.intercept_dr_write; - svm->vmcb->control.intercept_exceptions |= - nested_vmcb->control.intercept_exceptions; - - svm->vmcb->control.intercept |= nested_vmcb->control.intercept; - svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa; /* cache intercepts */ @@ -1864,6 +1849,28 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) else svm->vcpu.arch.hflags &= ~HF_VINTR_MASK; + if (svm->vcpu.arch.hflags & HF_VINTR_MASK) { + /* We only want the cr8 intercept bits of the guest */ + svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR8_MASK; + svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK; + } + + /* We don't want a nested guest to be more powerful than the guest, + so all intercepts are ORed */ + svm->vmcb->control.intercept_cr_read |= + nested_vmcb->control.intercept_cr_read; + svm->vmcb->control.intercept_cr_write |= + nested_vmcb->control.intercept_cr_write; + svm->vmcb->control.intercept_dr_read |= + nested_vmcb->control.intercept_dr_read; + svm->vmcb->control.intercept_dr_write |= + nested_vmcb->control.intercept_dr_write; + svm->vmcb->control.intercept_exceptions |= + nested_vmcb->control.intercept_exceptions; + + svm->vmcb->control.intercept |= nested_vmcb->control.intercept; + + svm->vmcb->control.lbr_ctl = nested_vmcb->control.lbr_ctl; svm->vmcb->control.int_vector = nested_vmcb->control.int_vector; svm->vmcb->control.int_state = nested_vmcb->control.int_state; svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset; @@ -2526,6 +2533,9 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) { struct vcpu_svm *svm = to_svm(vcpu); + if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK)) + return; + if (irr == -1) return; @@ -2629,6 +2639,9 @@ static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK)) + return; + if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR8_MASK)) { int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK; kvm_set_cr8(vcpu, cr8); @@ -2640,6 +2653,9 @@ static inline void sync_lapic_to_cr8(struct kvm_vcpu *vcpu) struct vcpu_svm *svm = to_svm(vcpu); u64 cr8; + if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK)) + return; + cr8 = kvm_get_cr8(vcpu); svm->vmcb->control.int_ctl &= ~V_TPR_MASK; svm->vmcb->control.int_ctl |= cr8 & V_TPR_MASK; -- cgit v1.2.3-59-g8ed1b From 06fc7772690dec2a0e3814633357babf8f63af41 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 19 Feb 2010 16:23:07 +0100 Subject: KVM: SVM: Activate nested state only when guest state is complete Certain functions called during the emulated world switch behave differently when the vcpu is running nested. This is not the expected behavior during a world switch emulation. This patch ensures that the nested state is activated only if the vcpu is completly in nested state. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 481bd0ee5f7e..8ace0b0da933 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1633,6 +1633,9 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) if (!nested_vmcb) return 1; + /* Exit nested SVM mode */ + svm->nested.vmcb = 0; + /* Give the current vmcb to the guest */ disable_gif(svm); @@ -1720,9 +1723,6 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) svm->vmcb->save.cpl = 0; svm->vmcb->control.exit_int_info = 0; - /* Exit nested SVM mode */ - svm->nested.vmcb = 0; - nested_svm_unmap(page); kvm_mmu_reset_context(&svm->vcpu); @@ -1757,14 +1757,14 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) struct vmcb *hsave = svm->nested.hsave; struct vmcb *vmcb = svm->vmcb; struct page *page; + u64 vmcb_gpa; + + vmcb_gpa = svm->vmcb->save.rax; nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); if (!nested_vmcb) return false; - /* nested_vmcb is our indicator if nested SVM is activated */ - svm->nested.vmcb = svm->vmcb->save.rax; - trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, svm->nested.vmcb, nested_vmcb->save.rip, nested_vmcb->control.int_ctl, @@ -1879,6 +1879,9 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) nested_svm_unmap(page); + /* nested_vmcb is our indicator if nested SVM is activated */ + svm->nested.vmcb = vmcb_gpa; + enable_gif(svm); return true; -- cgit v1.2.3-59-g8ed1b From 66a562f7e2576cde384ec813b481404d8f54f4c6 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 19 Feb 2010 16:23:08 +0100 Subject: KVM: SVM: Make lazy FPU switching work with nested svm The new lazy fpu switching code may disable cr0 intercepts when running nested. This is a bug because the nested hypervisor may still want to intercept cr0 which will break in this situation. This patch fixes this issue and makes lazy fpu switching working with nested svm. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 8ace0b0da933..a8ec53fe74f5 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -979,6 +979,7 @@ static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) static void update_cr0_intercept(struct vcpu_svm *svm) { + struct vmcb *vmcb = svm->vmcb; ulong gcr0 = svm->vcpu.arch.cr0; u64 *hcr0 = &svm->vmcb->save.cr0; @@ -990,11 +991,25 @@ static void update_cr0_intercept(struct vcpu_svm *svm) if (gcr0 == *hcr0 && svm->vcpu.fpu_active) { - svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK; - svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK; + vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK; + vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK; + if (is_nested(svm)) { + struct vmcb *hsave = svm->nested.hsave; + + hsave->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK; + hsave->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK; + vmcb->control.intercept_cr_read |= svm->nested.intercept_cr_read; + vmcb->control.intercept_cr_write |= svm->nested.intercept_cr_write; + } } else { svm->vmcb->control.intercept_cr_read |= INTERCEPT_CR0_MASK; svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR0_MASK; + if (is_nested(svm)) { + struct vmcb *hsave = svm->nested.hsave; + + hsave->control.intercept_cr_read |= INTERCEPT_CR0_MASK; + hsave->control.intercept_cr_write |= INTERCEPT_CR0_MASK; + } } } @@ -1269,7 +1284,22 @@ static int ud_interception(struct vcpu_svm *svm) static void svm_fpu_activate(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); - svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); + u32 excp; + + if (is_nested(svm)) { + u32 h_excp, n_excp; + + h_excp = svm->nested.hsave->control.intercept_exceptions; + n_excp = svm->nested.intercept_exceptions; + h_excp &= ~(1 << NM_VECTOR); + excp = h_excp | n_excp; + } else { + excp = svm->vmcb->control.intercept_exceptions; + excp &= ~(1 << NM_VECTOR); + } + + svm->vmcb->control.intercept_exceptions = excp; + svm->vcpu.fpu_active = 1; update_cr0_intercept(svm); } @@ -1513,6 +1543,9 @@ static int nested_svm_exit_special(struct vcpu_svm *svm) if (!npt_enabled) return NESTED_EXIT_HOST; break; + case SVM_EXIT_EXCP_BASE + NM_VECTOR: + nm_interception(svm); + break; default: break; } @@ -2980,8 +3013,10 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); - update_cr0_intercept(svm); svm->vmcb->control.intercept_exceptions |= 1 << NM_VECTOR; + if (is_nested(svm)) + svm->nested.hsave->control.intercept_exceptions |= 1 << NM_VECTOR; + update_cr0_intercept(svm); } static struct kvm_x86_ops svm_x86_ops = { -- cgit v1.2.3-59-g8ed1b From 052ce6211c4f7309988068fccdb7204c721871df Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 19 Feb 2010 16:23:09 +0100 Subject: KVM: SVM: Remove newlines from nested trace points The tracing infrastructure adds its own newlines. Remove them from the trace point printk format strings. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/trace.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 6ad30a29f044..12f8d2dee984 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -413,7 +413,7 @@ TRACE_EVENT(kvm_nested_vmrun, ), TP_printk("rip: 0x%016llx vmcb: 0x%016llx nrip: 0x%016llx int_ctl: 0x%08x " - "event_inj: 0x%08x npt: %s\n", + "event_inj: 0x%08x npt: %s", __entry->rip, __entry->vmcb, __entry->nested_rip, __entry->int_ctl, __entry->event_inj, __entry->npt ? "on" : "off") @@ -447,7 +447,7 @@ TRACE_EVENT(kvm_nested_vmexit, __entry->exit_int_info_err = exit_int_info_err; ), TP_printk("rip: 0x%016llx reason: %s ext_inf1: 0x%016llx " - "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x\n", + "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x", __entry->rip, ftrace_print_symbols_seq(p, __entry->exit_code, kvm_x86_ops->exit_reasons_str), @@ -482,7 +482,7 @@ TRACE_EVENT(kvm_nested_vmexit_inject, ), TP_printk("reason: %s ext_inf1: 0x%016llx " - "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x\n", + "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x", ftrace_print_symbols_seq(p, __entry->exit_code, kvm_x86_ops->exit_reasons_str), __entry->exit_info1, __entry->exit_info2, @@ -504,7 +504,7 @@ TRACE_EVENT(kvm_nested_intr_vmexit, __entry->rip = rip ), - TP_printk("rip: 0x%016llx\n", __entry->rip) + TP_printk("rip: 0x%016llx", __entry->rip) ); /* @@ -526,7 +526,7 @@ TRACE_EVENT(kvm_invlpga, __entry->address = address; ), - TP_printk("rip: 0x%016llx asid: %d address: 0x%016llx\n", + TP_printk("rip: 0x%016llx asid: %d address: 0x%016llx", __entry->rip, __entry->asid, __entry->address) ); @@ -547,7 +547,7 @@ TRACE_EVENT(kvm_skinit, __entry->slb = slb; ), - TP_printk("rip: 0x%016llx slb: 0x%08x\n", + TP_printk("rip: 0x%016llx slb: 0x%08x", __entry->rip, __entry->slb) ); -- cgit v1.2.3-59-g8ed1b From 5aa9e2f43aedff25e735b4c44e0f0f6e5d1a40ae Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:27 +0100 Subject: KVM: PPC: Add QPR registers The Gekko has GPRs, SPRs and FPRs like normal PowerPC codes, but it also has QPRs which are basically single precision only FPU registers that get used when in paired single mode. The following patches depend on them being around, so let's add the definitions early. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_host.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 5e5bae7e152f..4b14dcd4874b 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -186,6 +186,11 @@ struct kvm_vcpu_arch { u64 vsr[32]; #endif +#ifdef CONFIG_PPC_BOOK3S + /* For Gekko paired singles */ + u32 qpr[32]; +#endif + ulong pc; ulong ctr; ulong lr; -- cgit v1.2.3-59-g8ed1b From c62e096dec032c82bae60545623c24743116f5dd Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:28 +0100 Subject: KVM: PPC: Make fpscr 64-bit Modern PowerPCs have a 64 bit wide FPSCR register. Let's accomodate for that and make it 64 bits in our vcpu struct too. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 4b14dcd4874b..fb87dcf418bf 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -175,7 +175,7 @@ struct kvm_vcpu_arch { ulong gpr[32]; u64 fpr[32]; - u32 fpscr; + u64 fpscr; #ifdef CONFIG_ALTIVEC vector128 vr[32]; -- cgit v1.2.3-59-g8ed1b From b104d06632d08957f384ff7403f609fb5dfb9cbd Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:29 +0100 Subject: KVM: PPC: Enable MMIO to do 64 bits, fprs and qprs Right now MMIO access can only happen for GPRs and is at most 32 bit wide. That's actually enough for almost all types of hardware out there. Unfortunately, the guest I was using used FPU writes to MMIO regions, so it ended up writing 64 bit MMIOs using FPRs and QPRs. So let's add code to handle those odd cases too. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm.h | 7 +++++++ arch/powerpc/include/asm/kvm_ppc.h | 2 +- arch/powerpc/kvm/powerpc.c | 24 ++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index 81f3b0b5601e..19bae31202ce 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -77,4 +77,11 @@ struct kvm_debug_exit_arch { struct kvm_guest_debug_arch { }; +#define KVM_REG_MASK 0x001f +#define KVM_REG_EXT_MASK 0xffe0 +#define KVM_REG_GPR 0x0000 +#define KVM_REG_FPR 0x0020 +#define KVM_REG_QPR 0x0040 +#define KVM_REG_FQPR 0x0060 + #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index e2642829e435..c011170f572b 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -49,7 +49,7 @@ extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, unsigned int rt, unsigned int bytes, int is_bigendian); extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, - u32 val, unsigned int bytes, int is_bigendian); + u64 val, unsigned int bytes, int is_bigendian); extern int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu); diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 297fcd2ff7d0..b7858b1e15ec 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -278,7 +278,7 @@ static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run) { - ulong gpr; + u64 gpr; if (run->mmio.len > sizeof(gpr)) { printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len); @@ -287,6 +287,7 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, if (vcpu->arch.mmio_is_bigendian) { switch (run->mmio.len) { + case 8: gpr = *(u64 *)run->mmio.data; break; case 4: gpr = *(u32 *)run->mmio.data; break; case 2: gpr = *(u16 *)run->mmio.data; break; case 1: gpr = *(u8 *)run->mmio.data; break; @@ -301,6 +302,24 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, } kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); + + switch (vcpu->arch.io_gpr & KVM_REG_EXT_MASK) { + case KVM_REG_GPR: + kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); + break; + case KVM_REG_FPR: + vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; + break; + case KVM_REG_QPR: + vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; + break; + case KVM_REG_FQPR: + vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; + vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; + break; + default: + BUG(); + } } int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, @@ -324,7 +343,7 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, } int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, - u32 val, unsigned int bytes, int is_bigendian) + u64 val, unsigned int bytes, int is_bigendian) { void *data = run->mmio.data; @@ -342,6 +361,7 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, /* Store the value at the lowest bytes in 'data'. */ if (is_bigendian) { switch (bytes) { + case 8: *(u64 *)data = val; break; case 4: *(u32 *)data = val; break; case 2: *(u16 *)data = val; break; case 1: *(u8 *)data = val; break; -- cgit v1.2.3-59-g8ed1b From 3587d5348ced089666c51411bd9d771fb0b072cf Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:30 +0100 Subject: KVM: PPC: Teach MMIO Signedness The guest I was trying to get to run uses the LHA and LHAU instructions. Those instructions basically do a load, but also sign extend the result. Since we need to fill our registers by hand when doing MMIO, we also need to sign extend manually. This patch implements sign extended MMIO and the LHA(U) instructions. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/include/asm/kvm_ppc.h | 3 +++ arch/powerpc/kvm/emulate.c | 14 ++++++++++++++ arch/powerpc/kvm/powerpc.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index fb87dcf418bf..119deb4750d9 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -270,6 +270,7 @@ struct kvm_vcpu_arch { u8 io_gpr; /* GPR used as IO source/target */ u8 mmio_is_bigendian; + u8 mmio_sign_extend; u8 dcr_needed; u8 dcr_is_write; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index c011170f572b..a288dd2fbb2c 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -48,6 +48,9 @@ extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu); extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, unsigned int rt, unsigned int bytes, int is_bigendian); +extern int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int rt, unsigned int bytes, + int is_bigendian); extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, u64 val, unsigned int bytes, int is_bigendian); diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index cb72a65f4ecc..11789dd33a13 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -62,6 +62,8 @@ #define OP_STBU 39 #define OP_LHZ 40 #define OP_LHZU 41 +#define OP_LHA 42 +#define OP_LHAU 43 #define OP_STH 44 #define OP_STHU 45 @@ -450,6 +452,18 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); break; + case OP_LHA: + rt = get_rt(inst); + emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); + break; + + case OP_LHAU: + ra = get_ra(inst); + rt = get_rt(inst); + emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); + kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); + break; + case OP_STH: rs = get_rs(inst); emulated = kvmppc_handle_store(run, vcpu, diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index b7858b1e15ec..1266ed02b471 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -301,6 +301,22 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, } } + if (vcpu->arch.mmio_sign_extend) { + switch (run->mmio.len) { +#ifdef CONFIG_PPC64 + case 4: + gpr = (s64)(s32)gpr; + break; +#endif + case 2: + gpr = (s64)(s16)gpr; + break; + case 1: + gpr = (s64)(s8)gpr; + break; + } + } + kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); switch (vcpu->arch.io_gpr & KVM_REG_EXT_MASK) { @@ -338,10 +354,23 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, vcpu->arch.mmio_is_bigendian = is_bigendian; vcpu->mmio_needed = 1; vcpu->mmio_is_write = 0; + vcpu->arch.mmio_sign_extend = 0; return EMULATE_DO_MMIO; } +/* Same as above, but sign extends */ +int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int rt, unsigned int bytes, int is_bigendian) +{ + int r; + + r = kvmppc_handle_load(run, vcpu, rt, bytes, is_bigendian); + vcpu->arch.mmio_sign_extend = 1; + + return r; +} + int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, u64 val, unsigned int bytes, int is_bigendian) { -- cgit v1.2.3-59-g8ed1b From 37f5bca64e206ed97e53f734d7de5b7c5ade3578 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:31 +0100 Subject: KVM: PPC: Add AGAIN type for emulation return Emulation of an instruction can have different outcomes. It can succeed, fail, require MMIO, do funky BookE stuff - or it can just realize something's odd and will be fixed the next time around. Exactly that is what EMULATE_AGAIN means. Using that flag we can now tell the caller that nothing happened, but we still want to go back to the guest and see what happens next time we come around. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_ppc.h | 1 + arch/powerpc/kvm/book3s.c | 3 +++ arch/powerpc/kvm/emulate.c | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index a288dd2fbb2c..07612189eb8b 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -37,6 +37,7 @@ enum emulation_result { EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */ EMULATE_DO_DCR, /* kvm_run filled with DCR request */ EMULATE_FAIL, /* can't emulate this instruction */ + EMULATE_AGAIN, /* something went wrong. go again */ }; extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 604af29b71ed..6416f227d345 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -789,6 +789,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, case EMULATE_DONE: r = RESUME_GUEST_NV; break; + case EMULATE_AGAIN: + r = RESUME_GUEST; + break; case EMULATE_FAIL: printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", __func__, vcpu->arch.pc, vcpu->arch.last_inst); diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index 11789dd33a13..2410ec2a756a 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -486,7 +486,9 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) if (emulated == EMULATE_FAIL) { emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance); - if (emulated == EMULATE_FAIL) { + if (emulated == EMULATE_AGAIN) { + advance = 0; + } else if (emulated == EMULATE_FAIL) { advance = 0; printk(KERN_ERR "Couldn't emulate instruction 0x%08x " "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst)); -- cgit v1.2.3-59-g8ed1b From 3c402a75ea66e7aafa212077d1f93f1b560d0bd0 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:32 +0100 Subject: KVM: PPC: Add hidden flag for paired singles The Gekko implements an extension called paired singles. When the guest wants to use that extension, we need to make sure we're not running the host FPU, because all FPU instructions need to get emulated to accomodate for additional operations that occur. This patch adds an hflag to track if we're in paired single mode or not. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_asm.h | 1 + arch/powerpc/kvm/book3s.c | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index aadf2dd6f84e..7238c048e5bb 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h @@ -88,6 +88,7 @@ #define BOOK3S_HFLAG_DCBZ32 0x1 #define BOOK3S_HFLAG_SLB 0x2 +#define BOOK3S_HFLAG_PAIRED_SINGLE 0x4 #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 6416f227d345..8cb9f5a67464 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -639,6 +639,10 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, u64 *thread_fpr = (u64*)t->fpr; int i; + /* When we have paired singles, we emulate in software */ + if (vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE) + return RESUME_GUEST; + if (!(vcpu->arch.msr & msr)) { kvmppc_book3s_queue_irqprio(vcpu, exit_nr); return RESUME_GUEST; -- cgit v1.2.3-59-g8ed1b From d6d549b20776c937cb4717b24ef05baec4768f99 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:33 +0100 Subject: KVM: PPC: Add Gekko SPRs The Gekko has some SPR values that differ from other PPC core values and also some additional ones. Let's add support for them in our mfspr/mtspr emulator. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 1 + arch/powerpc/include/asm/reg.h | 10 +++++ arch/powerpc/kvm/book3s_64_emulate.c | 70 +++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index db7db0a96967..d28ee839ed84 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -82,6 +82,7 @@ struct kvmppc_vcpu_book3s { struct kvmppc_bat ibat[8]; struct kvmppc_bat dbat[8]; u64 hid[6]; + u64 gqr[8]; int slb_nr; u64 sdr1; u64 dsisr; diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 5572e86223f4..8a69a39a10b1 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -293,10 +293,12 @@ #define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ #define HID1_PS (1<<16) /* 750FX PLL selection */ #define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */ +#define SPRN_HID2_GEKKO 0x398 /* Gekko HID2 Register */ #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ #define SPRN_IABR2 0x3FA /* 83xx */ #define SPRN_IBCR 0x135 /* 83xx Insn Breakpoint Control Reg */ #define SPRN_HID4 0x3F4 /* 970 HID4 */ +#define SPRN_HID4_GEKKO 0x3F3 /* Gekko HID4 */ #define SPRN_HID5 0x3F6 /* 970 HID5 */ #define SPRN_HID6 0x3F9 /* BE HID 6 */ #define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */ @@ -465,6 +467,14 @@ #define SPRN_VRSAVE 0x100 /* Vector Register Save Register */ #define SPRN_XER 0x001 /* Fixed Point Exception Register */ +#define SPRN_MMCR0_GEKKO 0x3B8 /* Gekko Monitor Mode Control Register 0 */ +#define SPRN_MMCR1_GEKKO 0x3BC /* Gekko Monitor Mode Control Register 1 */ +#define SPRN_PMC1_GEKKO 0x3B9 /* Gekko Performance Monitor Control 1 */ +#define SPRN_PMC2_GEKKO 0x3BA /* Gekko Performance Monitor Control 2 */ +#define SPRN_PMC3_GEKKO 0x3BD /* Gekko Performance Monitor Control 3 */ +#define SPRN_PMC4_GEKKO 0x3BE /* Gekko Performance Monitor Control 4 */ +#define SPRN_WPAR_GEKKO 0x399 /* Gekko Write Pipe Address Register */ + #define SPRN_SCOMC 0x114 /* SCOM Access Control */ #define SPRN_SCOMD 0x115 /* SCOM Access DATA */ diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index 2b0ee7e040c9..bb4a7c1f8f05 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c @@ -42,6 +42,15 @@ /* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */ #define OP_31_XOP_DCBZ 1010 +#define SPRN_GQR0 912 +#define SPRN_GQR1 913 +#define SPRN_GQR2 914 +#define SPRN_GQR3 915 +#define SPRN_GQR4 916 +#define SPRN_GQR5 917 +#define SPRN_GQR6 918 +#define SPRN_GQR7 919 + int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, unsigned int inst, int *advance) { @@ -268,7 +277,29 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) case SPRN_HID2: to_book3s(vcpu)->hid[2] = spr_val; break; + case SPRN_HID2_GEKKO: + to_book3s(vcpu)->hid[2] = spr_val; + /* HID2.PSE controls paired single on gekko */ + switch (vcpu->arch.pvr) { + case 0x00080200: /* lonestar 2.0 */ + case 0x00088202: /* lonestar 2.2 */ + case 0x70000100: /* gekko 1.0 */ + case 0x00080100: /* gekko 2.0 */ + case 0x00083203: /* gekko 2.3a */ + case 0x00083213: /* gekko 2.3b */ + case 0x00083204: /* gekko 2.4 */ + case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */ + if (spr_val & (1 << 29)) { /* HID2.PSE */ + vcpu->arch.hflags |= BOOK3S_HFLAG_PAIRED_SINGLE; + kvmppc_giveup_ext(vcpu, MSR_FP); + } else { + vcpu->arch.hflags &= ~BOOK3S_HFLAG_PAIRED_SINGLE; + } + break; + } + break; case SPRN_HID4: + case SPRN_HID4_GEKKO: to_book3s(vcpu)->hid[4] = spr_val; break; case SPRN_HID5: @@ -278,12 +309,30 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) (mfmsr() & MSR_HV)) vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; break; + case SPRN_GQR0: + case SPRN_GQR1: + case SPRN_GQR2: + case SPRN_GQR3: + case SPRN_GQR4: + case SPRN_GQR5: + case SPRN_GQR6: + case SPRN_GQR7: + to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val; + break; case SPRN_ICTC: case SPRN_THRM1: case SPRN_THRM2: case SPRN_THRM3: case SPRN_CTRLF: case SPRN_CTRLT: + case SPRN_L2CR: + case SPRN_MMCR0_GEKKO: + case SPRN_MMCR1_GEKKO: + case SPRN_PMC1_GEKKO: + case SPRN_PMC2_GEKKO: + case SPRN_PMC3_GEKKO: + case SPRN_PMC4_GEKKO: + case SPRN_WPAR_GEKKO: break; default: printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn); @@ -320,19 +369,40 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[1]); break; case SPRN_HID2: + case SPRN_HID2_GEKKO: kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[2]); break; case SPRN_HID4: + case SPRN_HID4_GEKKO: kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[4]); break; case SPRN_HID5: kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[5]); break; + case SPRN_GQR0: + case SPRN_GQR1: + case SPRN_GQR2: + case SPRN_GQR3: + case SPRN_GQR4: + case SPRN_GQR5: + case SPRN_GQR6: + case SPRN_GQR7: + kvmppc_set_gpr(vcpu, rt, + to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]); + break; case SPRN_THRM1: case SPRN_THRM2: case SPRN_THRM3: case SPRN_CTRLF: case SPRN_CTRLT: + case SPRN_L2CR: + case SPRN_MMCR0_GEKKO: + case SPRN_MMCR1_GEKKO: + case SPRN_PMC1_GEKKO: + case SPRN_PMC2_GEKKO: + case SPRN_PMC3_GEKKO: + case SPRN_PMC4_GEKKO: + case SPRN_WPAR_GEKKO: kvmppc_set_gpr(vcpu, rt, 0); break; default: -- cgit v1.2.3-59-g8ed1b From c8c0b6f2f7db22a340f1311602182a25a2378996 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:34 +0100 Subject: KVM: PPC: Combine extension interrupt handlers When we for example get an Altivec interrupt, but our guest doesn't support altivec, we need to inject a program interrupt, not an altivec interrupt. The same goes for paired singles. When an altivec interrupt arrives, we're pretty sure we need to emulate the instruction because it's a paired single operation. So let's make all the ext handlers aware that they need to jump to the program interrupt handler when an extension interrupt arrives that was not supposed to arrive for the guest CPU. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 55 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 8cb9f5a67464..b18415fc0188 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -37,6 +37,8 @@ /* #define DEBUG_EXT */ static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); +static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, + ulong msr); struct kvm_stats_debugfs_item debugfs_entries[] = { { "exits", VCPU_STAT(sum_exits) }, @@ -629,6 +631,30 @@ static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) kvmppc_recalc_shadow_msr(vcpu); } +static int kvmppc_check_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr) +{ + ulong srr0 = vcpu->arch.pc; + int ret; + + /* Need to do paired single emulation? */ + if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)) + return EMULATE_DONE; + + /* Read out the instruction */ + ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &vcpu->arch.last_inst, false); + if (ret == -ENOENT) { + vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 33, 33, 1); + vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 34, 36, 0); + vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 42, 47, 0); + kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE); + } else if(ret == EMULATE_DONE) { + /* Need to emulate */ + return EMULATE_FAIL; + } + + return EMULATE_AGAIN; +} + /* Handle external providers (FPU, Altivec, VSX) */ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, ulong msr) @@ -773,6 +799,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, enum emulation_result er; ulong flags; +program_interrupt: flags = vcpu->arch.shadow_srr1 & 0x1f0000ull; if (vcpu->arch.msr & MSR_PR) { @@ -816,14 +843,32 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, r = RESUME_GUEST; break; case BOOK3S_INTERRUPT_FP_UNAVAIL: - r = kvmppc_handle_ext(vcpu, exit_nr, MSR_FP); - break; case BOOK3S_INTERRUPT_ALTIVEC: - r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VEC); - break; case BOOK3S_INTERRUPT_VSX: - r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VSX); + { + int ext_msr = 0; + + switch (exit_nr) { + case BOOK3S_INTERRUPT_FP_UNAVAIL: ext_msr = MSR_FP; break; + case BOOK3S_INTERRUPT_ALTIVEC: ext_msr = MSR_VEC; break; + case BOOK3S_INTERRUPT_VSX: ext_msr = MSR_VSX; break; + } + + switch (kvmppc_check_ext(vcpu, exit_nr)) { + case EMULATE_DONE: + /* everything ok - let's enable the ext */ + r = kvmppc_handle_ext(vcpu, exit_nr, ext_msr); + break; + case EMULATE_FAIL: + /* we need to emulate this instruction */ + goto program_interrupt; + break; + default: + /* nothing to worry about - go again */ + break; + } break; + } case BOOK3S_INTERRUPT_MACHINE_CHECK: case BOOK3S_INTERRUPT_TRACE: kvmppc_book3s_queue_irqprio(vcpu, exit_nr); -- cgit v1.2.3-59-g8ed1b From d1bab74c51eb13cf860ea2f0cd1d4d4605deb292 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:35 +0100 Subject: KVM: PPC: Preload FPU when possible There are some situations when we're pretty sure the guest will use the FPU soon. So we can save the churn of going into the guest, finding out it does want to use the FPU and going out again. This patch adds preloading of the FPU when it's reasonable. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index b18415fc0188..55c38e598280 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -138,6 +138,10 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) kvmppc_mmu_flush_segments(vcpu); kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc); } + + /* Preload FPU if it's enabled */ + if (vcpu->arch.msr & MSR_FP) + kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP); } void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags) @@ -1196,6 +1200,10 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) /* XXX we get called with irq disabled - change that! */ local_irq_enable(); + /* Preload FPU if it's enabled */ + if (vcpu->arch.msr & MSR_FP) + kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP); + ret = __kvmppc_vcpu_entry(kvm_run, vcpu); local_irq_disable(); -- cgit v1.2.3-59-g8ed1b From e425a6de1a2b427747f5af17bd76630548944ff1 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:36 +0100 Subject: KVM: PPC: Fix typo in book3s_32 debug code There's a typo in the debug ifdef of the book3s_32 mmu emulation. While trying to debug something I stumbled across that and wanted to save anyone after me (or myself later) from having to debug that again. So let's fix the ifdef. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_32_mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index faf99f20d993..1483a9bdddae 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c @@ -37,7 +37,7 @@ #define dprintk(X...) do { } while(0) #endif -#ifdef DEBUG_PTE +#ifdef DEBUG_MMU_PTE #define dprintk_pte(X...) printk(KERN_INFO X) #else #define dprintk_pte(X...) do { } while(0) -- cgit v1.2.3-59-g8ed1b From 71db4089361b9424314c41fcf92f63ce26263fcc Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:37 +0100 Subject: KVM: PPC: Implement mtsr instruction emulation The Book3S_32 specifications allows for two instructions to modify segment registers: mtsrin and mtsr. Most normal operating systems use mtsrin, because it allows to define which segment it wants to change using a register. But since I was trying to run an embedded guest, it turned out to be using mtsr with hardcoded values. So let's also emulate mtsr. It's a valid instruction after all. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_emulate.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index bb4a7c1f8f05..e4e7ec318eb0 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c @@ -28,6 +28,7 @@ #define OP_31_XOP_MFMSR 83 #define OP_31_XOP_MTMSR 146 #define OP_31_XOP_MTMSRD 178 +#define OP_31_XOP_MTSR 210 #define OP_31_XOP_MTSRIN 242 #define OP_31_XOP_TLBIEL 274 #define OP_31_XOP_TLBIE 306 @@ -101,6 +102,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, } break; } + case OP_31_XOP_MTSR: + vcpu->arch.mmu.mtsrin(vcpu, + (inst >> 16) & 0xf, + kvmppc_get_gpr(vcpu, get_rs(inst))); + break; case OP_31_XOP_MTSRIN: vcpu->arch.mmu.mtsrin(vcpu, (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf, -- cgit v1.2.3-59-g8ed1b From 5467a97d0f0ac99d2db0281ce1762e85afe16da2 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:38 +0100 Subject: KVM: PPC: Make software load/store return eaddr The Book3S KVM implementation contains some helper functions to load and store data from and to virtual addresses. Unfortunately, this helper used to keep the physical address it so nicely found out for us to itself. So let's change that and make it return the physical address it resolved. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 4 ++-- arch/powerpc/kvm/book3s.c | 41 +++++++++++++++++++++-------------- arch/powerpc/kvm/book3s_64_emulate.c | 11 +++++----- 3 files changed, 33 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index d28ee839ed84..8463976ff9f1 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -115,8 +115,8 @@ extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte); extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr); extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu); extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data); -extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, bool data); -extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr); +extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); +extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper, u32 val); diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 55c38e598280..a9f45197a036 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -440,55 +440,64 @@ err: return kvmppc_bad_hva(); } -int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr) +int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, + bool data) { struct kvmppc_pte pte; - hva_t hva = eaddr; + hva_t hva = *eaddr; vcpu->stat.st++; - if (kvmppc_xlate(vcpu, eaddr, false, &pte)) - goto err; + if (kvmppc_xlate(vcpu, *eaddr, data, &pte)) + goto nopte; + + *eaddr = pte.raddr; hva = kvmppc_pte_to_hva(vcpu, &pte, false); if (kvm_is_error_hva(hva)) - goto err; + goto mmio; if (copy_to_user((void __user *)hva, ptr, size)) { printk(KERN_INFO "kvmppc_st at 0x%lx failed\n", hva); - goto err; + goto mmio; } - return 0; + return EMULATE_DONE; -err: +nopte: return -ENOENT; +mmio: + return EMULATE_DO_MMIO; } -int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, +int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data) { struct kvmppc_pte pte; - hva_t hva = eaddr; + hva_t hva = *eaddr; vcpu->stat.ld++; - if (kvmppc_xlate(vcpu, eaddr, data, &pte)) - goto err; + if (kvmppc_xlate(vcpu, *eaddr, data, &pte)) + goto nopte; + + *eaddr = pte.raddr; hva = kvmppc_pte_to_hva(vcpu, &pte, true); if (kvm_is_error_hva(hva)) - goto err; + goto mmio; if (copy_from_user(ptr, (void __user *)hva, size)) { printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva); - goto err; + goto mmio; } - return 0; + return EMULATE_DONE; -err: +nopte: return -ENOENT; +mmio: + return EMULATE_DO_MMIO; } static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index e4e7ec318eb0..a93aa4719178 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c @@ -169,7 +169,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, { ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst)); ulong ra = 0; - ulong addr; + ulong addr, vaddr; u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; if (get_ra(inst)) @@ -178,15 +178,16 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, addr = (ra + rb) & ~31ULL; if (!(vcpu->arch.msr & MSR_SF)) addr &= 0xffffffff; + vaddr = addr; - if (kvmppc_st(vcpu, addr, 32, zeros)) { - vcpu->arch.dear = addr; - vcpu->arch.fault_dear = addr; + if (kvmppc_st(vcpu, &addr, 32, zeros, true)) { + vcpu->arch.dear = vaddr; + vcpu->arch.fault_dear = vaddr; to_book3s(vcpu)->dsisr = DSISR_PROTFAULT | DSISR_ISSTORE; kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE); - kvmppc_mmu_pte_flush(vcpu, addr, ~0xFFFULL); + kvmppc_mmu_pte_flush(vcpu, vaddr, ~0xFFFULL); } break; -- cgit v1.2.3-59-g8ed1b From aba3bd7ffe13fad6c4483b49686ad454a4cb409b Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:39 +0100 Subject: KVM: PPC: Make ext giveup non-static We need to call the ext giveup handlers from code outside of book3s.c. So let's make it non-static. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 1 + arch/powerpc/kvm/book3s.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 8463976ff9f1..fd432100f6db 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -120,6 +120,7 @@ extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, b extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper, u32 val); +extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); extern u32 kvmppc_trampoline_lowmem; extern u32 kvmppc_trampoline_enter; diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index a9f45197a036..38f242a690f7 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -36,7 +36,6 @@ /* #define EXIT_DEBUG_SIMPLE */ /* #define DEBUG_EXT */ -static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, ulong msr); @@ -598,7 +597,7 @@ static inline int get_fpr_index(int i) } /* Give up external provider (FPU, Altivec, VSX) */ -static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) +void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) { struct thread_struct *t = ¤t->thread; u64 *vcpu_fpr = vcpu->arch.fpr; -- cgit v1.2.3-59-g8ed1b From 963cf3dc6342fe60bb78c615884537621abca0bc Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:40 +0100 Subject: KVM: PPC: Add helpers to call FPU instructions To emulate paired single instructions, we need to be able to call FPU operations from within the kernel. Since we don't want gcc to spill arbitrary FPU code everywhere, we tell it to use a soft fpu. Since we know we can really call the FPU in safe areas, let's also add some calls that we can later use to actually execute real world FPU operations on the host's FPU. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_fpu.h | 85 ++++++++++++ arch/powerpc/kernel/ppc_ksyms.c | 2 + arch/powerpc/kvm/Makefile | 1 + arch/powerpc/kvm/fpu.S | 273 +++++++++++++++++++++++++++++++++++++ 4 files changed, 361 insertions(+) create mode 100644 arch/powerpc/include/asm/kvm_fpu.h create mode 100644 arch/powerpc/kvm/fpu.S (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_fpu.h b/arch/powerpc/include/asm/kvm_fpu.h new file mode 100644 index 000000000000..94f05de9ad04 --- /dev/null +++ b/arch/powerpc/include/asm/kvm_fpu.h @@ -0,0 +1,85 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright Novell Inc. 2010 + * + * Authors: Alexander Graf + */ + +#ifndef __ASM_KVM_FPU_H__ +#define __ASM_KVM_FPU_H__ + +#include + +extern void fps_fres(struct thread_struct *t, u32 *dst, u32 *src1); +extern void fps_frsqrte(struct thread_struct *t, u32 *dst, u32 *src1); +extern void fps_fsqrts(struct thread_struct *t, u32 *dst, u32 *src1); + +extern void fps_fadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); +extern void fps_fdivs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); +extern void fps_fmuls(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); +extern void fps_fsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); + +extern void fps_fmadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, + u32 *src3); +extern void fps_fmsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, + u32 *src3); +extern void fps_fnmadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, + u32 *src3); +extern void fps_fnmsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, + u32 *src3); +extern void fps_fsel(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, + u32 *src3); + +#define FPD_ONE_IN(name) extern void fpd_ ## name(u64 *fpscr, u32 *cr, \ + u64 *dst, u64 *src1); +#define FPD_TWO_IN(name) extern void fpd_ ## name(u64 *fpscr, u32 *cr, \ + u64 *dst, u64 *src1, u64 *src2); +#define FPD_THREE_IN(name) extern void fpd_ ## name(u64 *fpscr, u32 *cr, \ + u64 *dst, u64 *src1, u64 *src2, u64 *src3); + +extern void fpd_fcmpu(u64 *fpscr, u32 *cr, u64 *src1, u64 *src2); +extern void fpd_fcmpo(u64 *fpscr, u32 *cr, u64 *src1, u64 *src2); + +FPD_ONE_IN(fsqrts) +FPD_ONE_IN(frsqrtes) +FPD_ONE_IN(fres) +FPD_ONE_IN(frsp) +FPD_ONE_IN(fctiw) +FPD_ONE_IN(fctiwz) +FPD_ONE_IN(fsqrt) +FPD_ONE_IN(fre) +FPD_ONE_IN(frsqrte) +FPD_ONE_IN(fneg) +FPD_ONE_IN(fabs) +FPD_TWO_IN(fadds) +FPD_TWO_IN(fsubs) +FPD_TWO_IN(fdivs) +FPD_TWO_IN(fmuls) +FPD_TWO_IN(fcpsgn) +FPD_TWO_IN(fdiv) +FPD_TWO_IN(fadd) +FPD_TWO_IN(fmul) +FPD_TWO_IN(fsub) +FPD_THREE_IN(fmsubs) +FPD_THREE_IN(fmadds) +FPD_THREE_IN(fnmsubs) +FPD_THREE_IN(fnmadds) +FPD_THREE_IN(fsel) +FPD_THREE_IN(fmsub) +FPD_THREE_IN(fmadd) +FPD_THREE_IN(fnmsub) +FPD_THREE_IN(fnmadd) + +#endif diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index ab3e392ac63c..58fdb3a784de 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -101,6 +101,8 @@ EXPORT_SYMBOL(pci_dram_offset); EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(kernel_thread); +EXPORT_SYMBOL_GPL(cvt_df); +EXPORT_SYMBOL_GPL(cvt_fd); EXPORT_SYMBOL(giveup_fpu); #ifdef CONFIG_ALTIVEC EXPORT_SYMBOL(giveup_altivec); diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 56484d652377..e575cfd015fe 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -40,6 +40,7 @@ kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs) kvm-book3s_64-objs := \ $(common-objs-y) \ + fpu.o \ book3s.o \ book3s_64_emulate.o \ book3s_64_interrupts.o \ diff --git a/arch/powerpc/kvm/fpu.S b/arch/powerpc/kvm/fpu.S new file mode 100644 index 000000000000..2b340a3eee90 --- /dev/null +++ b/arch/powerpc/kvm/fpu.S @@ -0,0 +1,273 @@ +/* + * FPU helper code to use FPU operations from inside the kernel + * + * Copyright (C) 2010 Alexander Graf (agraf@suse.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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Instructions operating on single parameters */ + +/* + * Single operation with one input operand + * + * R3 = (double*)&fpscr + * R4 = (short*)&result + * R5 = (short*)¶m1 + */ +#define FPS_ONE_IN(name) \ +_GLOBAL(fps_ ## name); \ + lfd 0,0(r3); /* load up fpscr value */ \ + MTFSF_L(0); \ + lfs 0,0(r5); \ + \ + name 0,0; \ + \ + stfs 0,0(r4); \ + mffs 0; \ + stfd 0,0(r3); /* save new fpscr value */ \ + blr + +/* + * Single operation with two input operands + * + * R3 = (double*)&fpscr + * R4 = (short*)&result + * R5 = (short*)¶m1 + * R6 = (short*)¶m2 + */ +#define FPS_TWO_IN(name) \ +_GLOBAL(fps_ ## name); \ + lfd 0,0(r3); /* load up fpscr value */ \ + MTFSF_L(0); \ + lfs 0,0(r5); \ + lfs 1,0(r6); \ + \ + name 0,0,1; \ + \ + stfs 0,0(r4); \ + mffs 0; \ + stfd 0,0(r3); /* save new fpscr value */ \ + blr + +/* + * Single operation with three input operands + * + * R3 = (double*)&fpscr + * R4 = (short*)&result + * R5 = (short*)¶m1 + * R6 = (short*)¶m2 + * R7 = (short*)¶m3 + */ +#define FPS_THREE_IN(name) \ +_GLOBAL(fps_ ## name); \ + lfd 0,0(r3); /* load up fpscr value */ \ + MTFSF_L(0); \ + lfs 0,0(r5); \ + lfs 1,0(r6); \ + lfs 2,0(r7); \ + \ + name 0,0,1,2; \ + \ + stfs 0,0(r4); \ + mffs 0; \ + stfd 0,0(r3); /* save new fpscr value */ \ + blr + +FPS_ONE_IN(fres) +FPS_ONE_IN(frsqrte) +FPS_ONE_IN(fsqrts) +FPS_TWO_IN(fadds) +FPS_TWO_IN(fdivs) +FPS_TWO_IN(fmuls) +FPS_TWO_IN(fsubs) +FPS_THREE_IN(fmadds) +FPS_THREE_IN(fmsubs) +FPS_THREE_IN(fnmadds) +FPS_THREE_IN(fnmsubs) +FPS_THREE_IN(fsel) + + +/* Instructions operating on double parameters */ + +/* + * Beginning of double instruction processing + * + * R3 = (double*)&fpscr + * R4 = (u32*)&cr + * R5 = (double*)&result + * R6 = (double*)¶m1 + * R7 = (double*)¶m2 [load_two] + * R8 = (double*)¶m3 [load_three] + * LR = instruction call function + */ +fpd_load_three: + lfd 2,0(r8) /* load param3 */ +fpd_load_two: + lfd 1,0(r7) /* load param2 */ +fpd_load_one: + lfd 0,0(r6) /* load param1 */ +fpd_load_none: + lfd 3,0(r3) /* load up fpscr value */ + MTFSF_L(3) + lwz r6, 0(r4) /* load cr */ + mtcr r6 + blr + +/* + * End of double instruction processing + * + * R3 = (double*)&fpscr + * R4 = (u32*)&cr + * R5 = (double*)&result + * LR = caller of instruction call function + */ +fpd_return: + mfcr r6 + stfd 0,0(r5) /* save result */ + mffs 0 + stfd 0,0(r3) /* save new fpscr value */ + stw r6,0(r4) /* save new cr value */ + blr + +/* + * Double operation with no input operand + * + * R3 = (double*)&fpscr + * R4 = (u32*)&cr + * R5 = (double*)&result + */ +#define FPD_NONE_IN(name) \ +_GLOBAL(fpd_ ## name); \ + mflr r12; \ + bl fpd_load_none; \ + mtlr r12; \ + \ + name. 0; /* call instruction */ \ + b fpd_return + +/* + * Double operation with one input operand + * + * R3 = (double*)&fpscr + * R4 = (u32*)&cr + * R5 = (double*)&result + * R6 = (double*)¶m1 + */ +#define FPD_ONE_IN(name) \ +_GLOBAL(fpd_ ## name); \ + mflr r12; \ + bl fpd_load_one; \ + mtlr r12; \ + \ + name. 0,0; /* call instruction */ \ + b fpd_return + +/* + * Double operation with two input operands + * + * R3 = (double*)&fpscr + * R4 = (u32*)&cr + * R5 = (double*)&result + * R6 = (double*)¶m1 + * R7 = (double*)¶m2 + * R8 = (double*)¶m3 + */ +#define FPD_TWO_IN(name) \ +_GLOBAL(fpd_ ## name); \ + mflr r12; \ + bl fpd_load_two; \ + mtlr r12; \ + \ + name. 0,0,1; /* call instruction */ \ + b fpd_return + +/* + * CR Double operation with two input operands + * + * R3 = (double*)&fpscr + * R4 = (u32*)&cr + * R5 = (double*)¶m1 + * R6 = (double*)¶m2 + * R7 = (double*)¶m3 + */ +#define FPD_TWO_IN_CR(name) \ +_GLOBAL(fpd_ ## name); \ + lfd 1,0(r6); /* load param2 */ \ + lfd 0,0(r5); /* load param1 */ \ + lfd 3,0(r3); /* load up fpscr value */ \ + MTFSF_L(3); \ + lwz r6, 0(r4); /* load cr */ \ + mtcr r6; \ + \ + name 0,0,1; /* call instruction */ \ + mfcr r6; \ + mffs 0; \ + stfd 0,0(r3); /* save new fpscr value */ \ + stw r6,0(r4); /* save new cr value */ \ + blr + +/* + * Double operation with three input operands + * + * R3 = (double*)&fpscr + * R4 = (u32*)&cr + * R5 = (double*)&result + * R6 = (double*)¶m1 + * R7 = (double*)¶m2 + * R8 = (double*)¶m3 + */ +#define FPD_THREE_IN(name) \ +_GLOBAL(fpd_ ## name); \ + mflr r12; \ + bl fpd_load_three; \ + mtlr r12; \ + \ + name. 0,0,1,2; /* call instruction */ \ + b fpd_return + +FPD_ONE_IN(fsqrts) +FPD_ONE_IN(frsqrtes) +FPD_ONE_IN(fres) +FPD_ONE_IN(frsp) +FPD_ONE_IN(fctiw) +FPD_ONE_IN(fctiwz) +FPD_ONE_IN(fsqrt) +FPD_ONE_IN(fre) +FPD_ONE_IN(frsqrte) +FPD_ONE_IN(fneg) +FPD_ONE_IN(fabs) +FPD_TWO_IN(fadds) +FPD_TWO_IN(fsubs) +FPD_TWO_IN(fdivs) +FPD_TWO_IN(fmuls) +FPD_TWO_IN_CR(fcmpu) +FPD_TWO_IN(fcpsgn) +FPD_TWO_IN(fdiv) +FPD_TWO_IN(fadd) +FPD_TWO_IN(fmul) +FPD_TWO_IN_CR(fcmpo) +FPD_TWO_IN(fsub) +FPD_THREE_IN(fmsubs) +FPD_THREE_IN(fmadds) +FPD_THREE_IN(fnmsubs) +FPD_THREE_IN(fnmadds) +FPD_THREE_IN(fsel) +FPD_THREE_IN(fmsub) +FPD_THREE_IN(fmadd) +FPD_THREE_IN(fnmsub) +FPD_THREE_IN(fnmadd) -- cgit v1.2.3-59-g8ed1b From dba2e123e7502870c965e4b445554bc8e56f78b2 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:41 +0100 Subject: KVM: PPC: Fix error in BAT assignment BATs didn't work. Well, they did, but only up to BAT3. As soon as we came to BAT4 the offset calculation was screwed up and we ended up overwriting BAT0-3. Fortunately, Linux hasn't been using BAT4+. It's still a good idea to write correct code though. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_emulate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index a93aa4719178..1d1b9524f0e4 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c @@ -233,13 +233,13 @@ static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val) bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2]; break; case SPRN_IBAT4U ... SPRN_IBAT7L: - bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT4U) / 2]; + bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)]; break; case SPRN_DBAT0U ... SPRN_DBAT3L: bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2]; break; case SPRN_DBAT4U ... SPRN_DBAT7L: - bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT4U) / 2]; + bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)]; break; default: BUG(); -- cgit v1.2.3-59-g8ed1b From 0564ee8a8611326f28bae2a0455182b458826762 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:42 +0100 Subject: KVM: PPC: Add helpers to modify ppc fields The PowerPC specification always lists bits from MSB to LSB. That is really confusing when you're trying to write C code, because it fits in pretty badly with the normal (1 << xx) schemes. So I came up with some nice wrappers that allow to get and set fields in a u64 with bit numbers exactly as given in the spec. That makes the code in KVM and the spec easier comparable. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_ppc.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 07612189eb8b..c7fcdd751f14 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -103,6 +103,39 @@ extern void kvmppc_booke_exit(void); extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu); +/* + * Cuts out inst bits with ordering according to spec. + * That means the leftmost bit is zero. All given bits are included. + */ +static inline u32 kvmppc_get_field(u64 inst, int msb, int lsb) +{ + u32 r; + u32 mask; + + BUG_ON(msb > lsb); + + mask = (1 << (lsb - msb + 1)) - 1; + r = (inst >> (63 - lsb)) & mask; + + return r; +} + +/* + * Replaces inst bits with ordering according to spec. + */ +static inline u32 kvmppc_set_field(u64 inst, int msb, int lsb, int value) +{ + u32 r; + u32 mask; + + BUG_ON(msb > lsb); + + mask = ((1 << (lsb - msb + 1)) - 1) << (63 - lsb); + r = (inst & ~mask) | ((value << (63 - lsb)) & mask); + + return r; +} + #ifdef CONFIG_PPC_BOOK3S /* We assume we're always acting on the current vcpu */ -- cgit v1.2.3-59-g8ed1b From e5c29e926cd29444d76657398801d49119851a56 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:43 +0100 Subject: KVM: PPC: Enable program interrupt to do MMIO When we get a program interrupt we usually don't expect it to perform an MMIO operation. But why not? When we emulate paired singles, we can end up loading or storing to an MMIO address - and the handling of those happens in the program interrupt handler. So let's teach the program interrupt handler how to deal with EMULATE_MMIO. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 38f242a690f7..0446c5a39ae2 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -841,6 +841,10 @@ program_interrupt: kvmppc_core_queue_program(vcpu, flags); r = RESUME_GUEST; break; + case EMULATE_DO_MMIO: + run->exit_reason = KVM_EXIT_MMIO; + r = RESUME_HOST_NV; + break; default: BUG(); } -- cgit v1.2.3-59-g8ed1b From 831317b605e7d7ce0bdadb3b0f50560fc13cecbf Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:44 +0100 Subject: KVM: PPC: Implement Paired Single emulation The one big thing about the Gekko is paired singles. Paired singles are an extension to the instruction set, that adds 32 single precision floating point registers (qprs), some SPRs to modify the behavior of paired singled operations and instructions to deal with qprs to the instruction set. Unfortunately, it also changes semantics of existing operations that affect single values in FPRs. In most cases they get mirrored to the coresponding QPR. Thanks to that we need to emulate all FPU operations and all the new paired single operations too. In order to achieve that, we use the just introduced FPU call helpers to call the real FPU whenever the guest wants to modify an FPR. Additionally we also fix up the QPR values along the way. That way we can execute paired single FPU operations without implementing a soft fpu. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 1 + arch/powerpc/kvm/Makefile | 1 + arch/powerpc/kvm/book3s_64_emulate.c | 3 + arch/powerpc/kvm/book3s_paired_singles.c | 1289 ++++++++++++++++++++++++++++++ 4 files changed, 1294 insertions(+) create mode 100644 arch/powerpc/kvm/book3s_paired_singles.c (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index fd432100f6db..e6ea974df44e 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -121,6 +121,7 @@ extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec) extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper, u32 val); extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); +extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu); extern u32 kvmppc_trampoline_lowmem; extern u32 kvmppc_trampoline_enter; diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index e575cfd015fe..eba721e39328 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -41,6 +41,7 @@ kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs) kvm-book3s_64-objs := \ $(common-objs-y) \ fpu.o \ + book3s_paired_singles.o \ book3s.o \ book3s_64_emulate.o \ book3s_64_interrupts.o \ diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index 1d1b9524f0e4..c9892140dd02 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c @@ -200,6 +200,9 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, emulated = EMULATE_FAIL; } + if (emulated == EMULATE_FAIL) + emulated = kvmppc_emulate_paired_single(run, vcpu); + return emulated; } diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c new file mode 100644 index 000000000000..7a27bac8c44a --- /dev/null +++ b/arch/powerpc/kvm/book3s_paired_singles.c @@ -0,0 +1,1289 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright Novell Inc 2010 + * + * Authors: Alexander Graf + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* #define DEBUG */ + +#ifdef DEBUG +#define dprintk printk +#else +#define dprintk(...) do { } while(0); +#endif + +#define OP_LFS 48 +#define OP_LFSU 49 +#define OP_LFD 50 +#define OP_LFDU 51 +#define OP_STFS 52 +#define OP_STFSU 53 +#define OP_STFD 54 +#define OP_STFDU 55 +#define OP_PSQ_L 56 +#define OP_PSQ_LU 57 +#define OP_PSQ_ST 60 +#define OP_PSQ_STU 61 + +#define OP_31_LFSX 535 +#define OP_31_LFSUX 567 +#define OP_31_LFDX 599 +#define OP_31_LFDUX 631 +#define OP_31_STFSX 663 +#define OP_31_STFSUX 695 +#define OP_31_STFX 727 +#define OP_31_STFUX 759 +#define OP_31_LWIZX 887 +#define OP_31_STFIWX 983 + +#define OP_59_FADDS 21 +#define OP_59_FSUBS 20 +#define OP_59_FSQRTS 22 +#define OP_59_FDIVS 18 +#define OP_59_FRES 24 +#define OP_59_FMULS 25 +#define OP_59_FRSQRTES 26 +#define OP_59_FMSUBS 28 +#define OP_59_FMADDS 29 +#define OP_59_FNMSUBS 30 +#define OP_59_FNMADDS 31 + +#define OP_63_FCMPU 0 +#define OP_63_FCPSGN 8 +#define OP_63_FRSP 12 +#define OP_63_FCTIW 14 +#define OP_63_FCTIWZ 15 +#define OP_63_FDIV 18 +#define OP_63_FADD 21 +#define OP_63_FSQRT 22 +#define OP_63_FSEL 23 +#define OP_63_FRE 24 +#define OP_63_FMUL 25 +#define OP_63_FRSQRTE 26 +#define OP_63_FMSUB 28 +#define OP_63_FMADD 29 +#define OP_63_FNMSUB 30 +#define OP_63_FNMADD 31 +#define OP_63_FCMPO 32 +#define OP_63_MTFSB1 38 // XXX +#define OP_63_FSUB 20 +#define OP_63_FNEG 40 +#define OP_63_MCRFS 64 +#define OP_63_MTFSB0 70 +#define OP_63_FMR 72 +#define OP_63_MTFSFI 134 +#define OP_63_FABS 264 +#define OP_63_MFFS 583 +#define OP_63_MTFSF 711 + +#define OP_4X_PS_CMPU0 0 +#define OP_4X_PSQ_LX 6 +#define OP_4XW_PSQ_STX 7 +#define OP_4A_PS_SUM0 10 +#define OP_4A_PS_SUM1 11 +#define OP_4A_PS_MULS0 12 +#define OP_4A_PS_MULS1 13 +#define OP_4A_PS_MADDS0 14 +#define OP_4A_PS_MADDS1 15 +#define OP_4A_PS_DIV 18 +#define OP_4A_PS_SUB 20 +#define OP_4A_PS_ADD 21 +#define OP_4A_PS_SEL 23 +#define OP_4A_PS_RES 24 +#define OP_4A_PS_MUL 25 +#define OP_4A_PS_RSQRTE 26 +#define OP_4A_PS_MSUB 28 +#define OP_4A_PS_MADD 29 +#define OP_4A_PS_NMSUB 30 +#define OP_4A_PS_NMADD 31 +#define OP_4X_PS_CMPO0 32 +#define OP_4X_PSQ_LUX 38 +#define OP_4XW_PSQ_STUX 39 +#define OP_4X_PS_NEG 40 +#define OP_4X_PS_CMPU1 64 +#define OP_4X_PS_MR 72 +#define OP_4X_PS_CMPO1 96 +#define OP_4X_PS_NABS 136 +#define OP_4X_PS_ABS 264 +#define OP_4X_PS_MERGE00 528 +#define OP_4X_PS_MERGE01 560 +#define OP_4X_PS_MERGE10 592 +#define OP_4X_PS_MERGE11 624 + +#define SCALAR_NONE 0 +#define SCALAR_HIGH (1 << 0) +#define SCALAR_LOW (1 << 1) +#define SCALAR_NO_PS0 (1 << 2) +#define SCALAR_NO_PS1 (1 << 3) + +#define GQR_ST_TYPE_MASK 0x00000007 +#define GQR_ST_TYPE_SHIFT 0 +#define GQR_ST_SCALE_MASK 0x00003f00 +#define GQR_ST_SCALE_SHIFT 8 +#define GQR_LD_TYPE_MASK 0x00070000 +#define GQR_LD_TYPE_SHIFT 16 +#define GQR_LD_SCALE_MASK 0x3f000000 +#define GQR_LD_SCALE_SHIFT 24 + +#define GQR_QUANTIZE_FLOAT 0 +#define GQR_QUANTIZE_U8 4 +#define GQR_QUANTIZE_U16 5 +#define GQR_QUANTIZE_S8 6 +#define GQR_QUANTIZE_S16 7 + +#define FPU_LS_SINGLE 0 +#define FPU_LS_DOUBLE 1 +#define FPU_LS_SINGLE_LOW 2 + +static inline void kvmppc_sync_qpr(struct kvm_vcpu *vcpu, int rt) +{ + struct thread_struct t; + + t.fpscr.val = vcpu->arch.fpscr; + cvt_df((double*)&vcpu->arch.fpr[rt], (float*)&vcpu->arch.qpr[rt], &t); +} + +static void kvmppc_inject_pf(struct kvm_vcpu *vcpu, ulong eaddr, bool is_store) +{ + u64 dsisr; + + vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 33, 36, 0); + vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 42, 47, 0); + vcpu->arch.dear = eaddr; + /* Page Fault */ + dsisr = kvmppc_set_field(0, 33, 33, 1); + if (is_store) + to_book3s(vcpu)->dsisr = kvmppc_set_field(dsisr, 38, 38, 1); + kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE); +} + +static int kvmppc_emulate_fpr_load(struct kvm_run *run, struct kvm_vcpu *vcpu, + int rs, ulong addr, int ls_type) +{ + int emulated = EMULATE_FAIL; + struct thread_struct t; + int r; + char tmp[8]; + int len = sizeof(u32); + + if (ls_type == FPU_LS_DOUBLE) + len = sizeof(u64); + + t.fpscr.val = vcpu->arch.fpscr; + + /* read from memory */ + r = kvmppc_ld(vcpu, &addr, len, tmp, true); + vcpu->arch.paddr_accessed = addr; + + if (r < 0) { + kvmppc_inject_pf(vcpu, addr, false); + goto done_load; + } else if (r == EMULATE_DO_MMIO) { + emulated = kvmppc_handle_load(run, vcpu, KVM_REG_FPR | rs, len, 1); + goto done_load; + } + + emulated = EMULATE_DONE; + + /* put in registers */ + switch (ls_type) { + case FPU_LS_SINGLE: + cvt_fd((float*)tmp, (double*)&vcpu->arch.fpr[rs], &t); + vcpu->arch.qpr[rs] = *((u32*)tmp); + break; + case FPU_LS_DOUBLE: + vcpu->arch.fpr[rs] = *((u64*)tmp); + break; + } + + dprintk(KERN_INFO "KVM: FPR_LD [0x%llx] at 0x%lx (%d)\n", *(u64*)tmp, + addr, len); + +done_load: + return emulated; +} + +static int kvmppc_emulate_fpr_store(struct kvm_run *run, struct kvm_vcpu *vcpu, + int rs, ulong addr, int ls_type) +{ + int emulated = EMULATE_FAIL; + struct thread_struct t; + int r; + char tmp[8]; + u64 val; + int len; + + t.fpscr.val = vcpu->arch.fpscr; + + switch (ls_type) { + case FPU_LS_SINGLE: + cvt_df((double*)&vcpu->arch.fpr[rs], (float*)tmp, &t); + val = *((u32*)tmp); + len = sizeof(u32); + break; + case FPU_LS_SINGLE_LOW: + *((u32*)tmp) = vcpu->arch.fpr[rs]; + val = vcpu->arch.fpr[rs] & 0xffffffff; + len = sizeof(u32); + break; + case FPU_LS_DOUBLE: + *((u64*)tmp) = vcpu->arch.fpr[rs]; + val = vcpu->arch.fpr[rs]; + len = sizeof(u64); + break; + default: + val = 0; + len = 0; + } + + r = kvmppc_st(vcpu, &addr, len, tmp, true); + vcpu->arch.paddr_accessed = addr; + if (r < 0) { + kvmppc_inject_pf(vcpu, addr, true); + } else if (r == EMULATE_DO_MMIO) { + emulated = kvmppc_handle_store(run, vcpu, val, len, 1); + } else { + emulated = EMULATE_DONE; + } + + dprintk(KERN_INFO "KVM: FPR_ST [0x%llx] at 0x%lx (%d)\n", + val, addr, len); + + return emulated; +} + +static int kvmppc_emulate_psq_load(struct kvm_run *run, struct kvm_vcpu *vcpu, + int rs, ulong addr, bool w, int i) +{ + int emulated = EMULATE_FAIL; + struct thread_struct t; + int r; + float one = 1.0; + u32 tmp[2]; + + t.fpscr.val = vcpu->arch.fpscr; + + /* read from memory */ + if (w) { + r = kvmppc_ld(vcpu, &addr, sizeof(u32), tmp, true); + memcpy(&tmp[1], &one, sizeof(u32)); + } else { + r = kvmppc_ld(vcpu, &addr, sizeof(u32) * 2, tmp, true); + } + vcpu->arch.paddr_accessed = addr; + if (r < 0) { + kvmppc_inject_pf(vcpu, addr, false); + goto done_load; + } else if ((r == EMULATE_DO_MMIO) && w) { + emulated = kvmppc_handle_load(run, vcpu, KVM_REG_FPR | rs, 4, 1); + vcpu->arch.qpr[rs] = tmp[1]; + goto done_load; + } else if (r == EMULATE_DO_MMIO) { + emulated = kvmppc_handle_load(run, vcpu, KVM_REG_FQPR | rs, 8, 1); + goto done_load; + } + + emulated = EMULATE_DONE; + + /* put in registers */ + cvt_fd((float*)&tmp[0], (double*)&vcpu->arch.fpr[rs], &t); + vcpu->arch.qpr[rs] = tmp[1]; + + dprintk(KERN_INFO "KVM: PSQ_LD [0x%x, 0x%x] at 0x%lx (%d)\n", tmp[0], + tmp[1], addr, w ? 4 : 8); + +done_load: + return emulated; +} + +static int kvmppc_emulate_psq_store(struct kvm_run *run, struct kvm_vcpu *vcpu, + int rs, ulong addr, bool w, int i) +{ + int emulated = EMULATE_FAIL; + struct thread_struct t; + int r; + u32 tmp[2]; + int len = w ? sizeof(u32) : sizeof(u64); + + t.fpscr.val = vcpu->arch.fpscr; + + cvt_df((double*)&vcpu->arch.fpr[rs], (float*)&tmp[0], &t); + tmp[1] = vcpu->arch.qpr[rs]; + + r = kvmppc_st(vcpu, &addr, len, tmp, true); + vcpu->arch.paddr_accessed = addr; + if (r < 0) { + kvmppc_inject_pf(vcpu, addr, true); + } else if ((r == EMULATE_DO_MMIO) && w) { + emulated = kvmppc_handle_store(run, vcpu, tmp[0], 4, 1); + } else if (r == EMULATE_DO_MMIO) { + u64 val = ((u64)tmp[0] << 32) | tmp[1]; + emulated = kvmppc_handle_store(run, vcpu, val, 8, 1); + } else { + emulated = EMULATE_DONE; + } + + dprintk(KERN_INFO "KVM: PSQ_ST [0x%x, 0x%x] at 0x%lx (%d)\n", + tmp[0], tmp[1], addr, len); + + return emulated; +} + +/* + * Cuts out inst bits with ordering according to spec. + * That means the leftmost bit is zero. All given bits are included. + */ +static inline u32 inst_get_field(u32 inst, int msb, int lsb) +{ + return kvmppc_get_field(inst, msb + 32, lsb + 32); +} + +/* + * Replaces inst bits with ordering according to spec. + */ +static inline u32 inst_set_field(u32 inst, int msb, int lsb, int value) +{ + return kvmppc_set_field(inst, msb + 32, lsb + 32, value); +} + +bool kvmppc_inst_is_paired_single(struct kvm_vcpu *vcpu, u32 inst) +{ + if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)) + return false; + + switch (get_op(inst)) { + case OP_PSQ_L: + case OP_PSQ_LU: + case OP_PSQ_ST: + case OP_PSQ_STU: + case OP_LFS: + case OP_LFSU: + case OP_LFD: + case OP_LFDU: + case OP_STFS: + case OP_STFSU: + case OP_STFD: + case OP_STFDU: + return true; + case 4: + /* X form */ + switch (inst_get_field(inst, 21, 30)) { + case OP_4X_PS_CMPU0: + case OP_4X_PSQ_LX: + case OP_4X_PS_CMPO0: + case OP_4X_PSQ_LUX: + case OP_4X_PS_NEG: + case OP_4X_PS_CMPU1: + case OP_4X_PS_MR: + case OP_4X_PS_CMPO1: + case OP_4X_PS_NABS: + case OP_4X_PS_ABS: + case OP_4X_PS_MERGE00: + case OP_4X_PS_MERGE01: + case OP_4X_PS_MERGE10: + case OP_4X_PS_MERGE11: + return true; + } + /* XW form */ + switch (inst_get_field(inst, 25, 30)) { + case OP_4XW_PSQ_STX: + case OP_4XW_PSQ_STUX: + return true; + } + /* A form */ + switch (inst_get_field(inst, 26, 30)) { + case OP_4A_PS_SUM1: + case OP_4A_PS_SUM0: + case OP_4A_PS_MULS0: + case OP_4A_PS_MULS1: + case OP_4A_PS_MADDS0: + case OP_4A_PS_MADDS1: + case OP_4A_PS_DIV: + case OP_4A_PS_SUB: + case OP_4A_PS_ADD: + case OP_4A_PS_SEL: + case OP_4A_PS_RES: + case OP_4A_PS_MUL: + case OP_4A_PS_RSQRTE: + case OP_4A_PS_MSUB: + case OP_4A_PS_MADD: + case OP_4A_PS_NMSUB: + case OP_4A_PS_NMADD: + return true; + } + break; + case 59: + switch (inst_get_field(inst, 21, 30)) { + case OP_59_FADDS: + case OP_59_FSUBS: + case OP_59_FDIVS: + case OP_59_FRES: + case OP_59_FRSQRTES: + return true; + } + switch (inst_get_field(inst, 26, 30)) { + case OP_59_FMULS: + case OP_59_FMSUBS: + case OP_59_FMADDS: + case OP_59_FNMSUBS: + case OP_59_FNMADDS: + return true; + } + break; + case 63: + switch (inst_get_field(inst, 21, 30)) { + case OP_63_MTFSB0: + case OP_63_MTFSB1: + case OP_63_MTFSF: + case OP_63_MTFSFI: + case OP_63_MCRFS: + case OP_63_MFFS: + case OP_63_FCMPU: + case OP_63_FCMPO: + case OP_63_FNEG: + case OP_63_FMR: + case OP_63_FABS: + case OP_63_FRSP: + case OP_63_FDIV: + case OP_63_FADD: + case OP_63_FSUB: + case OP_63_FCTIW: + case OP_63_FCTIWZ: + case OP_63_FRSQRTE: + case OP_63_FCPSGN: + return true; + } + switch (inst_get_field(inst, 26, 30)) { + case OP_63_FMUL: + case OP_63_FSEL: + case OP_63_FMSUB: + case OP_63_FMADD: + case OP_63_FNMSUB: + case OP_63_FNMADD: + return true; + } + break; + case 31: + switch (inst_get_field(inst, 21, 30)) { + case OP_31_LFSX: + case OP_31_LFSUX: + case OP_31_LFDX: + case OP_31_LFDUX: + case OP_31_STFSX: + case OP_31_STFSUX: + case OP_31_STFX: + case OP_31_STFUX: + case OP_31_STFIWX: + return true; + } + break; + } + + return false; +} + +static int get_d_signext(u32 inst) +{ + int d = inst & 0x8ff; + + if (d & 0x800) + return -(d & 0x7ff); + + return (d & 0x7ff); +} + +static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc, + int reg_out, int reg_in1, int reg_in2, + int reg_in3, int scalar, + void (*func)(struct thread_struct *t, + u32 *dst, u32 *src1, + u32 *src2, u32 *src3)) +{ + u32 *qpr = vcpu->arch.qpr; + u64 *fpr = vcpu->arch.fpr; + u32 ps0_out; + u32 ps0_in1, ps0_in2, ps0_in3; + u32 ps1_in1, ps1_in2, ps1_in3; + struct thread_struct t; + t.fpscr.val = vcpu->arch.fpscr; + + /* RC */ + WARN_ON(rc); + + /* PS0 */ + cvt_df((double*)&fpr[reg_in1], (float*)&ps0_in1, &t); + cvt_df((double*)&fpr[reg_in2], (float*)&ps0_in2, &t); + cvt_df((double*)&fpr[reg_in3], (float*)&ps0_in3, &t); + + if (scalar & SCALAR_LOW) + ps0_in2 = qpr[reg_in2]; + + func(&t, &ps0_out, &ps0_in1, &ps0_in2, &ps0_in3); + + dprintk(KERN_INFO "PS3 ps0 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n", + ps0_in1, ps0_in2, ps0_in3, ps0_out); + + if (!(scalar & SCALAR_NO_PS0)) + cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t); + + /* PS1 */ + ps1_in1 = qpr[reg_in1]; + ps1_in2 = qpr[reg_in2]; + ps1_in3 = qpr[reg_in3]; + + if (scalar & SCALAR_HIGH) + ps1_in2 = ps0_in2; + + if (!(scalar & SCALAR_NO_PS1)) + func(&t, &qpr[reg_out], &ps1_in1, &ps1_in2, &ps1_in3); + + dprintk(KERN_INFO "PS3 ps1 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n", + ps1_in1, ps1_in2, ps1_in3, qpr[reg_out]); + + return EMULATE_DONE; +} + +static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc, + int reg_out, int reg_in1, int reg_in2, + int scalar, + void (*func)(struct thread_struct *t, + u32 *dst, u32 *src1, + u32 *src2)) +{ + u32 *qpr = vcpu->arch.qpr; + u64 *fpr = vcpu->arch.fpr; + u32 ps0_out; + u32 ps0_in1, ps0_in2; + u32 ps1_out; + u32 ps1_in1, ps1_in2; + struct thread_struct t; + t.fpscr.val = vcpu->arch.fpscr; + + /* RC */ + WARN_ON(rc); + + /* PS0 */ + cvt_df((double*)&fpr[reg_in1], (float*)&ps0_in1, &t); + + if (scalar & SCALAR_LOW) + ps0_in2 = qpr[reg_in2]; + else + cvt_df((double*)&fpr[reg_in2], (float*)&ps0_in2, &t); + + func(&t, &ps0_out, &ps0_in1, &ps0_in2); + + if (!(scalar & SCALAR_NO_PS0)) { + dprintk(KERN_INFO "PS2 ps0 -> f(0x%x, 0x%x) = 0x%x\n", + ps0_in1, ps0_in2, ps0_out); + + cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t); + } + + /* PS1 */ + ps1_in1 = qpr[reg_in1]; + ps1_in2 = qpr[reg_in2]; + + if (scalar & SCALAR_HIGH) + ps1_in2 = ps0_in2; + + func(&t, &ps1_out, &ps1_in1, &ps1_in2); + + if (!(scalar & SCALAR_NO_PS1)) { + qpr[reg_out] = ps1_out; + + dprintk(KERN_INFO "PS2 ps1 -> f(0x%x, 0x%x) = 0x%x\n", + ps1_in1, ps1_in2, qpr[reg_out]); + } + + return EMULATE_DONE; +} + +static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc, + int reg_out, int reg_in, + void (*func)(struct thread_struct *t, + u32 *dst, u32 *src1)) +{ + u32 *qpr = vcpu->arch.qpr; + u64 *fpr = vcpu->arch.fpr; + u32 ps0_out, ps0_in; + u32 ps1_in; + struct thread_struct t; + t.fpscr.val = vcpu->arch.fpscr; + + /* RC */ + WARN_ON(rc); + + /* PS0 */ + cvt_df((double*)&fpr[reg_in], (float*)&ps0_in, &t); + func(&t, &ps0_out, &ps0_in); + + dprintk(KERN_INFO "PS1 ps0 -> f(0x%x) = 0x%x\n", + ps0_in, ps0_out); + + cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t); + + /* PS1 */ + ps1_in = qpr[reg_in]; + func(&t, &qpr[reg_out], &ps1_in); + + dprintk(KERN_INFO "PS1 ps1 -> f(0x%x) = 0x%x\n", + ps1_in, qpr[reg_out]); + + return EMULATE_DONE; +} + +int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) +{ + u32 inst = vcpu->arch.last_inst; + enum emulation_result emulated = EMULATE_DONE; + + int ax_rd = inst_get_field(inst, 6, 10); + int ax_ra = inst_get_field(inst, 11, 15); + int ax_rb = inst_get_field(inst, 16, 20); + int ax_rc = inst_get_field(inst, 21, 25); + short full_d = inst_get_field(inst, 16, 31); + + u64 *fpr_d = &vcpu->arch.fpr[ax_rd]; + u64 *fpr_a = &vcpu->arch.fpr[ax_ra]; + u64 *fpr_b = &vcpu->arch.fpr[ax_rb]; + u64 *fpr_c = &vcpu->arch.fpr[ax_rc]; + + bool rcomp = (inst & 1) ? true : false; + u32 cr = kvmppc_get_cr(vcpu); + struct thread_struct t; +#ifdef DEBUG + int i; +#endif + + t.fpscr.val = vcpu->arch.fpscr; + + if (!kvmppc_inst_is_paired_single(vcpu, inst)) + return EMULATE_FAIL; + + if (!(vcpu->arch.msr & MSR_FP)) { + kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL); + return EMULATE_AGAIN; + } + + kvmppc_giveup_ext(vcpu, MSR_FP); + preempt_disable(); + enable_kernel_fp(); + /* Do we need to clear FE0 / FE1 here? Don't think so. */ + +#ifdef DEBUG + for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) { + u32 f; + cvt_df((double*)&vcpu->arch.fpr[i], (float*)&f, &t); + dprintk(KERN_INFO "FPR[%d] = 0x%x / 0x%llx QPR[%d] = 0x%x\n", + i, f, vcpu->arch.fpr[i], i, vcpu->arch.qpr[i]); + } +#endif + + switch (get_op(inst)) { + case OP_PSQ_L: + { + ulong addr = ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0; + bool w = inst_get_field(inst, 16, 16) ? true : false; + int i = inst_get_field(inst, 17, 19); + + addr += get_d_signext(inst); + emulated = kvmppc_emulate_psq_load(run, vcpu, ax_rd, addr, w, i); + break; + } + case OP_PSQ_LU: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra); + bool w = inst_get_field(inst, 16, 16) ? true : false; + int i = inst_get_field(inst, 17, 19); + + addr += get_d_signext(inst); + emulated = kvmppc_emulate_psq_load(run, vcpu, ax_rd, addr, w, i); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case OP_PSQ_ST: + { + ulong addr = ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0; + bool w = inst_get_field(inst, 16, 16) ? true : false; + int i = inst_get_field(inst, 17, 19); + + addr += get_d_signext(inst); + emulated = kvmppc_emulate_psq_store(run, vcpu, ax_rd, addr, w, i); + break; + } + case OP_PSQ_STU: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra); + bool w = inst_get_field(inst, 16, 16) ? true : false; + int i = inst_get_field(inst, 17, 19); + + addr += get_d_signext(inst); + emulated = kvmppc_emulate_psq_store(run, vcpu, ax_rd, addr, w, i); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case 4: + /* X form */ + switch (inst_get_field(inst, 21, 30)) { + case OP_4X_PS_CMPU0: + /* XXX */ + emulated = EMULATE_FAIL; + break; + case OP_4X_PSQ_LX: + { + ulong addr = ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0; + bool w = inst_get_field(inst, 21, 21) ? true : false; + int i = inst_get_field(inst, 22, 24); + + addr += kvmppc_get_gpr(vcpu, ax_rb); + emulated = kvmppc_emulate_psq_load(run, vcpu, ax_rd, addr, w, i); + break; + } + case OP_4X_PS_CMPO0: + /* XXX */ + emulated = EMULATE_FAIL; + break; + case OP_4X_PSQ_LUX: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra); + bool w = inst_get_field(inst, 21, 21) ? true : false; + int i = inst_get_field(inst, 22, 24); + + addr += kvmppc_get_gpr(vcpu, ax_rb); + emulated = kvmppc_emulate_psq_load(run, vcpu, ax_rd, addr, w, i); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case OP_4X_PS_NEG: + vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_rb]; + vcpu->arch.fpr[ax_rd] ^= 0x8000000000000000ULL; + vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; + vcpu->arch.qpr[ax_rd] ^= 0x80000000; + break; + case OP_4X_PS_CMPU1: + /* XXX */ + emulated = EMULATE_FAIL; + break; + case OP_4X_PS_MR: + WARN_ON(rcomp); + vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_rb]; + vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; + break; + case OP_4X_PS_CMPO1: + /* XXX */ + emulated = EMULATE_FAIL; + break; + case OP_4X_PS_NABS: + WARN_ON(rcomp); + vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_rb]; + vcpu->arch.fpr[ax_rd] |= 0x8000000000000000ULL; + vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; + vcpu->arch.qpr[ax_rd] |= 0x80000000; + break; + case OP_4X_PS_ABS: + WARN_ON(rcomp); + vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_rb]; + vcpu->arch.fpr[ax_rd] &= ~0x8000000000000000ULL; + vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; + vcpu->arch.qpr[ax_rd] &= ~0x80000000; + break; + case OP_4X_PS_MERGE00: + WARN_ON(rcomp); + vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_ra]; + /* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */ + cvt_df((double*)&vcpu->arch.fpr[ax_rb], + (float*)&vcpu->arch.qpr[ax_rd], &t); + break; + case OP_4X_PS_MERGE01: + WARN_ON(rcomp); + vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_ra]; + vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; + break; + case OP_4X_PS_MERGE10: + WARN_ON(rcomp); + /* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */ + cvt_fd((float*)&vcpu->arch.qpr[ax_ra], + (double*)&vcpu->arch.fpr[ax_rd], &t); + /* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */ + cvt_df((double*)&vcpu->arch.fpr[ax_rb], + (float*)&vcpu->arch.qpr[ax_rd], &t); + break; + case OP_4X_PS_MERGE11: + WARN_ON(rcomp); + /* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */ + cvt_fd((float*)&vcpu->arch.qpr[ax_ra], + (double*)&vcpu->arch.fpr[ax_rd], &t); + vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; + break; + } + /* XW form */ + switch (inst_get_field(inst, 25, 30)) { + case OP_4XW_PSQ_STX: + { + ulong addr = ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0; + bool w = inst_get_field(inst, 21, 21) ? true : false; + int i = inst_get_field(inst, 22, 24); + + addr += kvmppc_get_gpr(vcpu, ax_rb); + emulated = kvmppc_emulate_psq_store(run, vcpu, ax_rd, addr, w, i); + break; + } + case OP_4XW_PSQ_STUX: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra); + bool w = inst_get_field(inst, 21, 21) ? true : false; + int i = inst_get_field(inst, 22, 24); + + addr += kvmppc_get_gpr(vcpu, ax_rb); + emulated = kvmppc_emulate_psq_store(run, vcpu, ax_rd, addr, w, i); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + } + /* A form */ + switch (inst_get_field(inst, 26, 30)) { + case OP_4A_PS_SUM1: + emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, + ax_rb, ax_ra, SCALAR_NO_PS0 | SCALAR_HIGH, fps_fadds); + vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_rc]; + break; + case OP_4A_PS_SUM0: + emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rb, SCALAR_NO_PS1 | SCALAR_LOW, fps_fadds); + vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rc]; + break; + case OP_4A_PS_MULS0: + emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rc, SCALAR_HIGH, fps_fmuls); + break; + case OP_4A_PS_MULS1: + emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rc, SCALAR_LOW, fps_fmuls); + break; + case OP_4A_PS_MADDS0: + emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rc, ax_rb, SCALAR_HIGH, fps_fmadds); + break; + case OP_4A_PS_MADDS1: + emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rc, ax_rb, SCALAR_LOW, fps_fmadds); + break; + case OP_4A_PS_DIV: + emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rb, SCALAR_NONE, fps_fdivs); + break; + case OP_4A_PS_SUB: + emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rb, SCALAR_NONE, fps_fsubs); + break; + case OP_4A_PS_ADD: + emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rb, SCALAR_NONE, fps_fadds); + break; + case OP_4A_PS_SEL: + emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rc, ax_rb, SCALAR_NONE, fps_fsel); + break; + case OP_4A_PS_RES: + emulated = kvmppc_ps_one_in(vcpu, rcomp, ax_rd, + ax_rb, fps_fres); + break; + case OP_4A_PS_MUL: + emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rc, SCALAR_NONE, fps_fmuls); + break; + case OP_4A_PS_RSQRTE: + emulated = kvmppc_ps_one_in(vcpu, rcomp, ax_rd, + ax_rb, fps_frsqrte); + break; + case OP_4A_PS_MSUB: + emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rc, ax_rb, SCALAR_NONE, fps_fmsubs); + break; + case OP_4A_PS_MADD: + emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rc, ax_rb, SCALAR_NONE, fps_fmadds); + break; + case OP_4A_PS_NMSUB: + emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rc, ax_rb, SCALAR_NONE, fps_fnmsubs); + break; + case OP_4A_PS_NMADD: + emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, + ax_ra, ax_rc, ax_rb, SCALAR_NONE, fps_fnmadds); + break; + } + break; + + /* Real FPU operations */ + + case OP_LFS: + { + ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + full_d; + + emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, addr, + FPU_LS_SINGLE); + break; + } + case OP_LFSU: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + full_d; + + emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, addr, + FPU_LS_SINGLE); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case OP_LFD: + { + ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + full_d; + + emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, addr, + FPU_LS_DOUBLE); + break; + } + case OP_LFDU: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + full_d; + + emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, addr, + FPU_LS_DOUBLE); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case OP_STFS: + { + ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + full_d; + + emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, addr, + FPU_LS_SINGLE); + break; + } + case OP_STFSU: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + full_d; + + emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, addr, + FPU_LS_SINGLE); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case OP_STFD: + { + ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + full_d; + + emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, addr, + FPU_LS_DOUBLE); + break; + } + case OP_STFDU: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + full_d; + + emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, addr, + FPU_LS_DOUBLE); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case 31: + switch (inst_get_field(inst, 21, 30)) { + case OP_31_LFSX: + { + ulong addr = ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0; + + addr += kvmppc_get_gpr(vcpu, ax_rb); + emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, + addr, FPU_LS_SINGLE); + break; + } + case OP_31_LFSUX: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + + kvmppc_get_gpr(vcpu, ax_rb); + + emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, + addr, FPU_LS_SINGLE); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case OP_31_LFDX: + { + ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + + kvmppc_get_gpr(vcpu, ax_rb); + + emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, + addr, FPU_LS_DOUBLE); + break; + } + case OP_31_LFDUX: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + + kvmppc_get_gpr(vcpu, ax_rb); + + emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, + addr, FPU_LS_DOUBLE); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case OP_31_STFSX: + { + ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + + kvmppc_get_gpr(vcpu, ax_rb); + + emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, + addr, FPU_LS_SINGLE); + break; + } + case OP_31_STFSUX: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + + kvmppc_get_gpr(vcpu, ax_rb); + + emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, + addr, FPU_LS_SINGLE); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case OP_31_STFX: + { + ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + + kvmppc_get_gpr(vcpu, ax_rb); + + emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, + addr, FPU_LS_DOUBLE); + break; + } + case OP_31_STFUX: + { + ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + + kvmppc_get_gpr(vcpu, ax_rb); + + emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, + addr, FPU_LS_DOUBLE); + + if (emulated == EMULATE_DONE) + kvmppc_set_gpr(vcpu, ax_ra, addr); + break; + } + case OP_31_STFIWX: + { + ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + + kvmppc_get_gpr(vcpu, ax_rb); + + emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, + addr, + FPU_LS_SINGLE_LOW); + break; + } + break; + } + break; + case 59: + switch (inst_get_field(inst, 21, 30)) { + case OP_59_FADDS: + fpd_fadds(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + case OP_59_FSUBS: + fpd_fsubs(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + case OP_59_FDIVS: + fpd_fdivs(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + case OP_59_FRES: + fpd_fres(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + case OP_59_FRSQRTES: + fpd_frsqrtes(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + } + switch (inst_get_field(inst, 26, 30)) { + case OP_59_FMULS: + fpd_fmuls(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + case OP_59_FMSUBS: + fpd_fmsubs(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + case OP_59_FMADDS: + fpd_fmadds(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + case OP_59_FNMSUBS: + fpd_fnmsubs(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + case OP_59_FNMADDS: + fpd_fnmadds(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + } + break; + case 63: + switch (inst_get_field(inst, 21, 30)) { + case OP_63_MTFSB0: + case OP_63_MTFSB1: + case OP_63_MCRFS: + case OP_63_MTFSFI: + /* XXX need to implement */ + break; + case OP_63_MFFS: + /* XXX missing CR */ + *fpr_d = vcpu->arch.fpscr; + break; + case OP_63_MTFSF: + /* XXX missing fm bits */ + /* XXX missing CR */ + vcpu->arch.fpscr = *fpr_b; + break; + case OP_63_FCMPU: + { + u32 tmp_cr; + u32 cr0_mask = 0xf0000000; + u32 cr_shift = inst_get_field(inst, 6, 8) * 4; + + fpd_fcmpu(&vcpu->arch.fpscr, &tmp_cr, fpr_a, fpr_b); + cr &= ~(cr0_mask >> cr_shift); + cr |= (cr & cr0_mask) >> cr_shift; + break; + } + case OP_63_FCMPO: + { + u32 tmp_cr; + u32 cr0_mask = 0xf0000000; + u32 cr_shift = inst_get_field(inst, 6, 8) * 4; + + fpd_fcmpo(&vcpu->arch.fpscr, &tmp_cr, fpr_a, fpr_b); + cr &= ~(cr0_mask >> cr_shift); + cr |= (cr & cr0_mask) >> cr_shift; + break; + } + case OP_63_FNEG: + fpd_fneg(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); + break; + case OP_63_FMR: + *fpr_d = *fpr_b; + break; + case OP_63_FABS: + fpd_fabs(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); + break; + case OP_63_FCPSGN: + fpd_fcpsgn(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); + break; + case OP_63_FDIV: + fpd_fdiv(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); + break; + case OP_63_FADD: + fpd_fadd(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); + break; + case OP_63_FSUB: + fpd_fsub(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); + break; + case OP_63_FCTIW: + fpd_fctiw(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); + break; + case OP_63_FCTIWZ: + fpd_fctiwz(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); + break; + case OP_63_FRSP: + fpd_frsp(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); + kvmppc_sync_qpr(vcpu, ax_rd); + break; + case OP_63_FRSQRTE: + { + double one = 1.0f; + + /* fD = sqrt(fB) */ + fpd_fsqrt(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); + /* fD = 1.0f / fD */ + fpd_fdiv(&vcpu->arch.fpscr, &cr, fpr_d, (u64*)&one, fpr_d); + break; + } + } + switch (inst_get_field(inst, 26, 30)) { + case OP_63_FMUL: + fpd_fmul(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c); + break; + case OP_63_FSEL: + fpd_fsel(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); + break; + case OP_63_FMSUB: + fpd_fmsub(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); + break; + case OP_63_FMADD: + fpd_fmadd(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); + break; + case OP_63_FNMSUB: + fpd_fnmsub(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); + break; + case OP_63_FNMADD: + fpd_fnmadd(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); + break; + } + break; + } + +#ifdef DEBUG + for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) { + u32 f; + cvt_df((double*)&vcpu->arch.fpr[i], (float*)&f, &t); + dprintk(KERN_INFO "FPR[%d] = 0x%x\n", i, f); + } +#endif + + if (rcomp) + kvmppc_set_cr(vcpu, cr); + + preempt_enable(); + + return emulated; +} -- cgit v1.2.3-59-g8ed1b From c10207fe86b1761c3ad135eb922fdb41bbde3025 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:45 +0100 Subject: KVM: PPC: Add capability for paired singles We need to tell userspace that we can emulate paired single instructions. So let's add a capability export. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/powerpc.c | 1 + include/linux/kvm.h | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 1266ed02b471..ad2b6275acb7 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -148,6 +148,7 @@ int kvm_dev_ioctl_check_extension(long ext) switch (ext) { case KVM_CAP_PPC_SEGSTATE: + case KVM_CAP_PPC_PAIRED_SINGLES: r = 1; break; case KVM_CAP_COALESCED_MMIO: diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 60df9c84ecae..360f85e8c435 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -501,6 +501,7 @@ struct kvm_ioeventfd { #define KVM_CAP_HYPERV_VAPIC 45 #define KVM_CAP_HYPERV_SPIN 46 #define KVM_CAP_PCI_SEGMENT 47 +#define KVM_CAP_PPC_PAIRED_SINGLES 48 #define KVM_CAP_X86_ROBUST_SINGLESTEP 51 #ifdef KVM_CAP_IRQ_ROUTING -- cgit v1.2.3-59-g8ed1b From 20a340abd3f7a1ca4d11502ec71d52b4f414326e Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:46 +0100 Subject: KVM: PPC: Enable use of secondary htab bucket We had code to make use of the secondary htab buckets, but kept that disabled because it was unstable when I put it in. I checked again if that's still the case and apparently it was only exposing some instability that was there anyways before. I haven't seen any badness related to usage of secondary htab entries so far. This should speed up guest memory allocations by quite a bit, because we now have more space to put PTEs in. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_mmu_host.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index f2899b297ffd..25bd4ede722c 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -257,16 +257,9 @@ map_again: if (ret < 0) { /* If we couldn't map a primary PTE, try a secondary */ -#ifdef USE_SECONDARY hash = ~hash; + vflags ^= HPTE_V_SECONDARY; attempt++; - if (attempt % 2) - vflags = HPTE_V_SECONDARY; - else - vflags = 0; -#else - attempt = 2; -#endif goto map_again; } else { int hpte_id = kvmppc_mmu_hpte_cache_next(vcpu); -- cgit v1.2.3-59-g8ed1b From 964b6411af10fbddc827fdd3887c49f7f5d2bfd3 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:47 +0100 Subject: KVM: PPC: Simplify kvmppc_load_up_(FPU|VMX|VSX) We don't need as complex code. I had some thinkos while writing it, figuring I needed to support PPC32 paths on PPC64 which would have required DR=0, but everything just runs fine with DR=1. So let's make the functions simple C call wrappers that reserve some space on the stack for the respective functions to clobber. Fixes out-of-RMA-access (and thus guest FPU loading) on the PS3. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_rmhandlers.S | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_rmhandlers.S b/arch/powerpc/kvm/book3s_64_rmhandlers.S index c83c60ad96c5..bd08535fcdc8 100644 --- a/arch/powerpc/kvm/book3s_64_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_64_rmhandlers.S @@ -164,24 +164,15 @@ _GLOBAL(kvmppc_rmcall) #define define_load_up(what) \ \ _GLOBAL(kvmppc_load_up_ ## what); \ - subi r1, r1, INT_FRAME_SIZE; \ + stdu r1, -INT_FRAME_SIZE(r1); \ mflr r3; \ std r3, _LINK(r1); \ - mfmsr r4; \ - std r31, GPR3(r1); \ - mr r31, r4; \ - li r5, MSR_DR; \ - oris r5, r5, MSR_EE@h; \ - andc r4, r4, r5; \ - mtmsr r4; \ \ bl .load_up_ ## what; \ \ - mtmsr r31; \ ld r3, _LINK(r1); \ - ld r31, GPR3(r1); \ - addi r1, r1, INT_FRAME_SIZE; \ mtlr r3; \ + addi r1, r1, INT_FRAME_SIZE; \ blr define_load_up(fpu) -- cgit v1.2.3-59-g8ed1b From 032c3407310c7612db55ab7e1335a21dc2b4690d Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 12:24:33 +0100 Subject: KVM: PPC: Allocate vcpu struct using vmalloc We used to use get_free_pages to allocate our vcpu struct. Unfortunately that call failed on me several times after my machine had a big enough uptime, as memory became too fragmented by then. Fortunately, we don't need it to be page aligned any more! We can just vmalloc it and everything's great. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 0446c5a39ae2..6758ec80f902 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -1112,8 +1112,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) struct kvm_vcpu *vcpu; int err; - vcpu_book3s = (struct kvmppc_vcpu_book3s *)__get_free_pages( GFP_KERNEL | __GFP_ZERO, - get_order(sizeof(struct kvmppc_vcpu_book3s))); + vcpu_book3s = vmalloc(sizeof(struct kvmppc_vcpu_book3s)); if (!vcpu_book3s) { err = -ENOMEM; goto out; @@ -1151,7 +1150,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) return vcpu; free_vcpu: - free_pages((long)vcpu_book3s, get_order(sizeof(struct kvmppc_vcpu_book3s))); + vfree(vcpu_book3s); out: return ERR_PTR(err); } @@ -1162,7 +1161,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) __destroy_context(vcpu_book3s->context_id); kvm_vcpu_uninit(vcpu); - free_pages((long)vcpu_book3s, get_order(sizeof(struct kvmppc_vcpu_book3s))); + vfree(vcpu_book3s); } extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); -- cgit v1.2.3-59-g8ed1b From 112592da0dc2460c95e8a89d0c5657c6a30286aa Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Sun, 21 Feb 2010 15:00:47 +0200 Subject: KVM: drop unneeded kvm_run check in emulate_instruction() vcpu->run is initialized on vcpu creation and can never be NULL here. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 274a8e39bca7..1d27a57026ab 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3443,7 +3443,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, if (vcpu->arch.pio.string) return EMULATE_DO_MMIO; - if ((r || vcpu->mmio_is_write) && run) { + if (r || vcpu->mmio_is_write) { run->exit_reason = KVM_EXIT_MMIO; run->mmio.phys_addr = vcpu->mmio_phys_addr; memcpy(run->mmio.data, vcpu->mmio_data, 8); -- cgit v1.2.3-59-g8ed1b From 8fe546547cf6857a9d984bfe2f2194910f3fc5d0 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 19 Feb 2010 16:23:01 +0100 Subject: KVM: SVM: Fix wrong interrupt injection in enable_irq_windows The nested_svm_intr() function does not execute the vmexit anymore. Therefore we may still be in the nested state after that function ran. This patch changes the nested_svm_intr() function to return wether the irq window could be enabled. Cc: stable@kernel.org Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index a8ec53fe74f5..294bbca34173 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1432,16 +1432,17 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, return vmexit; } -static inline int nested_svm_intr(struct vcpu_svm *svm) +/* This function returns true if it is save to enable the irq window */ +static inline bool nested_svm_intr(struct vcpu_svm *svm) { if (!is_nested(svm)) - return 0; + return true; if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) - return 0; + return true; if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) - return 0; + return false; svm->vmcb->control.exit_code = SVM_EXIT_INTR; @@ -1454,10 +1455,10 @@ static inline int nested_svm_intr(struct vcpu_svm *svm) */ svm->nested.exit_required = true; trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip); - return 1; + return false; } - return 0; + return true; } static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page) @@ -2629,13 +2630,11 @@ static void enable_irq_window(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); - nested_svm_intr(svm); - /* In case GIF=0 we can't rely on the CPU to tell us when * GIF becomes 1, because that's a separate STGI/VMRUN intercept. * The next time we get that intercept, this function will be * called again though and we'll get the vintr intercept. */ - if (gif_set(svm)) { + if (gif_set(svm) && nested_svm_intr(svm)) { svm_set_vintr(svm); svm_inject_irq(svm, 0x0); } -- cgit v1.2.3-59-g8ed1b From 03b82a30ea8b26199901b219848d706dbd70c609 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 15 Feb 2010 10:45:41 +0100 Subject: KVM: x86: Do not return soft events in vcpu_events To avoid that user space migrates a pending software exception or interrupt, mask them out on KVM_GET_VCPU_EVENTS. Without this, user space would try to reinject them, and we would have to reconstruct the proper instruction length for VMX event injection. Now the pending event will be reinjected via executing the triggering instruction again. Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 1d27a57026ab..2b1c9f2fb8dd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2100,14 +2100,17 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, { vcpu_load(vcpu); - events->exception.injected = vcpu->arch.exception.pending; + events->exception.injected = + vcpu->arch.exception.pending && + !kvm_exception_is_soft(vcpu->arch.exception.nr); events->exception.nr = vcpu->arch.exception.nr; events->exception.has_error_code = vcpu->arch.exception.has_error_code; events->exception.error_code = vcpu->arch.exception.error_code; - events->interrupt.injected = vcpu->arch.interrupt.pending; + events->interrupt.injected = + vcpu->arch.interrupt.pending && !vcpu->arch.interrupt.soft; events->interrupt.nr = vcpu->arch.interrupt.nr; - events->interrupt.soft = vcpu->arch.interrupt.soft; + events->interrupt.soft = 0; events->nmi.injected = vcpu->arch.nmi_injected; events->nmi.pending = vcpu->arch.nmi_pending; -- cgit v1.2.3-59-g8ed1b From 48005f64d0ea965d454e38b5181af4aba9bdef5b Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Fri, 19 Feb 2010 19:38:07 +0100 Subject: KVM: x86: Save&restore interrupt shadow mask The interrupt shadow created by STI or MOV-SS-like operations is part of the VCPU state and must be preserved across migration. Transfer it in the spare padding field of kvm_vcpu_events.interrupt. As a side effect we now have to make vmx_set_interrupt_shadow robust against both shadow types being set. Give MOV SS a higher priority and skip STI in that case to avoid that VMX throws a fault on next entry. Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity --- Documentation/kvm/api.txt | 11 ++++++++++- arch/x86/include/asm/kvm.h | 7 ++++++- arch/x86/include/asm/kvm_emulate.h | 3 --- arch/x86/kvm/emulate.c | 4 ++-- arch/x86/kvm/svm.c | 2 +- arch/x86/kvm/vmx.c | 8 ++++---- arch/x86/kvm/x86.c | 12 ++++++++++-- include/linux/kvm.h | 1 + 8 files changed, 34 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index beb444a95013..9e5de5a1c4ef 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt @@ -656,6 +656,7 @@ struct kvm_clock_data { 4.29 KVM_GET_VCPU_EVENTS Capability: KVM_CAP_VCPU_EVENTS +Extended by: KVM_CAP_INTR_SHADOW Architectures: x86 Type: vm ioctl Parameters: struct kvm_vcpu_event (out) @@ -676,7 +677,7 @@ struct kvm_vcpu_events { __u8 injected; __u8 nr; __u8 soft; - __u8 pad; + __u8 shadow; } interrupt; struct { __u8 injected; @@ -688,9 +689,13 @@ struct kvm_vcpu_events { __u32 flags; }; +KVM_VCPUEVENT_VALID_SHADOW may be set in the flags field to signal that +interrupt.shadow contains a valid state. Otherwise, this field is undefined. + 4.30 KVM_SET_VCPU_EVENTS Capability: KVM_CAP_VCPU_EVENTS +Extended by: KVM_CAP_INTR_SHADOW Architectures: x86 Type: vm ioctl Parameters: struct kvm_vcpu_event (in) @@ -709,6 +714,10 @@ current in-kernel state. The bits are: KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector +If KVM_CAP_INTR_SHADOW is available, KVM_VCPUEVENT_VALID_SHADOW can be set in +the flags field to signal that interrupt.shadow contains a valid state and +shall be written into the VCPU. + 5. The kvm_run structure diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index f46b79f6c16c..fb6117063ea3 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h @@ -257,6 +257,11 @@ struct kvm_reinject_control { /* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */ #define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001 #define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002 +#define KVM_VCPUEVENT_VALID_SHADOW 0x00000004 + +/* Interrupt shadow states */ +#define KVM_X86_SHADOW_INT_MOV_SS 0x01 +#define KVM_X86_SHADOW_INT_STI 0x02 /* for KVM_GET/SET_VCPU_EVENTS */ struct kvm_vcpu_events { @@ -271,7 +276,7 @@ struct kvm_vcpu_events { __u8 injected; __u8 nr; __u8 soft; - __u8 pad; + __u8 shadow; } interrupt; struct { __u8 injected; diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 7a6f54fa13ba..2666d7ac3229 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -153,9 +153,6 @@ struct decode_cache { struct fetch_cache fetch; }; -#define X86_SHADOW_INT_MOV_SS 1 -#define X86_SHADOW_INT_STI 2 - struct x86_emulate_ctxt { /* Register state before/after emulation. */ struct kvm_vcpu *vcpu; diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 35f7acd4a91f..c9f604b0819c 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2128,7 +2128,7 @@ special_insn: } if (c->modrm_reg == VCPU_SREG_SS) - toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS); + toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_MOV_SS); rc = kvm_load_segment_descriptor(ctxt->vcpu, sel, c->modrm_reg); @@ -2366,7 +2366,7 @@ special_insn: if (emulator_bad_iopl(ctxt)) kvm_inject_gp(ctxt->vcpu, 0); else { - toggle_interruptibility(ctxt, X86_SHADOW_INT_STI); + toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_STI); ctxt->eflags |= X86_EFLAGS_IF; c->dst.type = OP_NONE; /* Disable writeback. */ } diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 294bbca34173..bd8f52f0823f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -265,7 +265,7 @@ static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) u32 ret = 0; if (svm->vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) - ret |= X86_SHADOW_INT_STI | X86_SHADOW_INT_MOV_SS; + ret |= KVM_X86_SHADOW_INT_STI | KVM_X86_SHADOW_INT_MOV_SS; return ret & mask; } diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 68f895b00450..61f03980adae 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -846,9 +846,9 @@ static u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) int ret = 0; if (interruptibility & GUEST_INTR_STATE_STI) - ret |= X86_SHADOW_INT_STI; + ret |= KVM_X86_SHADOW_INT_STI; if (interruptibility & GUEST_INTR_STATE_MOV_SS) - ret |= X86_SHADOW_INT_MOV_SS; + ret |= KVM_X86_SHADOW_INT_MOV_SS; return ret & mask; } @@ -860,9 +860,9 @@ static void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) interruptibility &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS); - if (mask & X86_SHADOW_INT_MOV_SS) + if (mask & KVM_X86_SHADOW_INT_MOV_SS) interruptibility |= GUEST_INTR_STATE_MOV_SS; - if (mask & X86_SHADOW_INT_STI) + else if (mask & KVM_X86_SHADOW_INT_STI) interruptibility |= GUEST_INTR_STATE_STI; if ((interruptibility != interruptibility_old)) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 2b1c9f2fb8dd..84ffd95ee198 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2111,6 +2111,9 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, vcpu->arch.interrupt.pending && !vcpu->arch.interrupt.soft; events->interrupt.nr = vcpu->arch.interrupt.nr; events->interrupt.soft = 0; + events->interrupt.shadow = + kvm_x86_ops->get_interrupt_shadow(vcpu, + KVM_X86_SHADOW_INT_MOV_SS | KVM_X86_SHADOW_INT_STI); events->nmi.injected = vcpu->arch.nmi_injected; events->nmi.pending = vcpu->arch.nmi_pending; @@ -2119,7 +2122,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, events->sipi_vector = vcpu->arch.sipi_vector; events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING - | KVM_VCPUEVENT_VALID_SIPI_VECTOR); + | KVM_VCPUEVENT_VALID_SIPI_VECTOR + | KVM_VCPUEVENT_VALID_SHADOW); vcpu_put(vcpu); } @@ -2128,7 +2132,8 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, struct kvm_vcpu_events *events) { if (events->flags & ~(KVM_VCPUEVENT_VALID_NMI_PENDING - | KVM_VCPUEVENT_VALID_SIPI_VECTOR)) + | KVM_VCPUEVENT_VALID_SIPI_VECTOR + | KVM_VCPUEVENT_VALID_SHADOW)) return -EINVAL; vcpu_load(vcpu); @@ -2143,6 +2148,9 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, vcpu->arch.interrupt.soft = events->interrupt.soft; if (vcpu->arch.interrupt.pending && irqchip_in_kernel(vcpu->kvm)) kvm_pic_clear_isr_ack(vcpu->kvm); + if (events->flags & KVM_VCPUEVENT_VALID_SHADOW) + kvm_x86_ops->set_interrupt_shadow(vcpu, + events->interrupt.shadow); vcpu->arch.nmi_injected = events->nmi.injected; if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING) diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 360f85e8c435..48516a2a0b84 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -502,6 +502,7 @@ struct kvm_ioeventfd { #define KVM_CAP_HYPERV_SPIN 46 #define KVM_CAP_PCI_SEGMENT 47 #define KVM_CAP_PPC_PAIRED_SINGLES 48 +#define KVM_CAP_INTR_SHADOW 49 #define KVM_CAP_X86_ROBUST_SINGLESTEP 51 #ifdef KVM_CAP_IRQ_ROUTING -- cgit v1.2.3-59-g8ed1b From a1efbe77c1fd7c34a97a76a61520bf23fb3663f6 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 15 Feb 2010 10:45:43 +0100 Subject: KVM: x86: Add support for saving&restoring debug registers So far user space was not able to save and restore debug registers for migration or after reset. Plug this hole. Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity --- Documentation/kvm/api.txt | 31 ++++++++++++++++++++++++++ arch/x86/include/asm/kvm.h | 10 +++++++++ arch/x86/kvm/x86.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/kvm.h | 6 ++++++ 4 files changed, 101 insertions(+) (limited to 'arch') diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index 9e5de5a1c4ef..d170cb435545 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt @@ -718,6 +718,37 @@ If KVM_CAP_INTR_SHADOW is available, KVM_VCPUEVENT_VALID_SHADOW can be set in the flags field to signal that interrupt.shadow contains a valid state and shall be written into the VCPU. +4.32 KVM_GET_DEBUGREGS + +Capability: KVM_CAP_DEBUGREGS +Architectures: x86 +Type: vm ioctl +Parameters: struct kvm_debugregs (out) +Returns: 0 on success, -1 on error + +Reads debug registers from the vcpu. + +struct kvm_debugregs { + __u64 db[4]; + __u64 dr6; + __u64 dr7; + __u64 flags; + __u64 reserved[9]; +}; + +4.33 KVM_SET_DEBUGREGS + +Capability: KVM_CAP_DEBUGREGS +Architectures: x86 +Type: vm ioctl +Parameters: struct kvm_debugregs (in) +Returns: 0 on success, -1 on error + +Writes debug registers into the vcpu. + +See KVM_GET_DEBUGREGS for the data structure. The flags field is unused +yet and must be cleared on entry. + 5. The kvm_run structure diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index fb6117063ea3..ff90055c7f0b 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h @@ -21,6 +21,7 @@ #define __KVM_HAVE_PIT_STATE2 #define __KVM_HAVE_XEN_HVM #define __KVM_HAVE_VCPU_EVENTS +#define __KVM_HAVE_DEBUGREGS /* Architectural interrupt line count. */ #define KVM_NR_INTERRUPTS 256 @@ -289,4 +290,13 @@ struct kvm_vcpu_events { __u32 reserved[10]; }; +/* for KVM_GET/SET_DEBUGREGS */ +struct kvm_debugregs { + __u64 db[4]; + __u64 dr6; + __u64 dr7; + __u64 flags; + __u64 reserved[9]; +}; + #endif /* _ASM_X86_KVM_H */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 84ffd95ee198..efeeabd84ecd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1548,6 +1548,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_HYPERV_VAPIC: case KVM_CAP_HYPERV_SPIN: case KVM_CAP_PCI_SEGMENT: + case KVM_CAP_DEBUGREGS: case KVM_CAP_X86_ROBUST_SINGLESTEP: r = 1; break; @@ -2165,6 +2166,36 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, return 0; } +static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, + struct kvm_debugregs *dbgregs) +{ + vcpu_load(vcpu); + + memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db)); + dbgregs->dr6 = vcpu->arch.dr6; + dbgregs->dr7 = vcpu->arch.dr7; + dbgregs->flags = 0; + + vcpu_put(vcpu); +} + +static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, + struct kvm_debugregs *dbgregs) +{ + if (dbgregs->flags) + return -EINVAL; + + vcpu_load(vcpu); + + memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); + vcpu->arch.dr6 = dbgregs->dr6; + vcpu->arch.dr7 = dbgregs->dr7; + + vcpu_put(vcpu); + + return 0; +} + long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -2343,6 +2374,29 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = kvm_vcpu_ioctl_x86_set_vcpu_events(vcpu, &events); break; } + case KVM_GET_DEBUGREGS: { + struct kvm_debugregs dbgregs; + + kvm_vcpu_ioctl_x86_get_debugregs(vcpu, &dbgregs); + + r = -EFAULT; + if (copy_to_user(argp, &dbgregs, + sizeof(struct kvm_debugregs))) + break; + r = 0; + break; + } + case KVM_SET_DEBUGREGS: { + struct kvm_debugregs dbgregs; + + r = -EFAULT; + if (copy_from_user(&dbgregs, argp, + sizeof(struct kvm_debugregs))) + break; + + r = kvm_vcpu_ioctl_x86_set_debugregs(vcpu, &dbgregs); + break; + } default: r = -EINVAL; } diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 48516a2a0b84..ce2876717a8b 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -503,6 +503,9 @@ struct kvm_ioeventfd { #define KVM_CAP_PCI_SEGMENT 47 #define KVM_CAP_PPC_PAIRED_SINGLES 48 #define KVM_CAP_INTR_SHADOW 49 +#ifdef __KVM_HAVE_DEBUGREGS +#define KVM_CAP_DEBUGREGS 50 +#endif #define KVM_CAP_X86_ROBUST_SINGLESTEP 51 #ifdef KVM_CAP_IRQ_ROUTING @@ -690,6 +693,9 @@ struct kvm_clock_data { /* Available with KVM_CAP_VCPU_EVENTS */ #define KVM_GET_VCPU_EVENTS _IOR(KVMIO, 0x9f, struct kvm_vcpu_events) #define KVM_SET_VCPU_EVENTS _IOW(KVMIO, 0xa0, struct kvm_vcpu_events) +/* Available with KVM_CAP_DEBUGREGS */ +#define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) +#define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) -- cgit v1.2.3-59-g8ed1b From 7e821d3920c130d413c4c7454b0ece59445490db Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Mon, 22 Feb 2010 16:52:08 +0100 Subject: KVM: PPC: Memset vcpu to zeros While converting the kzalloc we used to allocate our vcpu struct to vmalloc, I forgot to memset the contents to zeros. That broke quite a lot. This patch memsets it to zero again. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 6758ec80f902..8cab902771a2 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -1117,6 +1117,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) err = -ENOMEM; goto out; } + memset(vcpu_book3s, 0, sizeof(struct kvmppc_vcpu_book3s)); vcpu = &vcpu_book3s->vcpu; err = kvm_vcpu_init(vcpu, kvm, id); -- cgit v1.2.3-59-g8ed1b From a595405df9efb89710cd555d29df0e4902f90613 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Mon, 22 Feb 2010 16:52:14 +0100 Subject: KVM: PPC: Destory timer on vcpu destruction When we destory a vcpu, we should also make sure to kill all pending timers that could still be up. When not doing this, hrtimers might dereference null pointers trying to call our code. This patch fixes spontanious kernel panics seen after closing VMs. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/powerpc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index ad2b6275acb7..ace31ca05245 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -200,6 +200,10 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) { + /* Make sure we're not using the vcpu anymore */ + hrtimer_cancel(&vcpu->arch.dec_timer); + tasklet_kill(&vcpu->arch.tasklet); + kvmppc_remove_vcpu_debugfs(vcpu); kvmppc_core_vcpu_free(vcpu); } -- cgit v1.2.3-59-g8ed1b From 50a085bdd48af08cc7e3178ba0d7c1d5d8191698 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 24 Feb 2010 10:41:58 +0100 Subject: KVM: x86: Kick VCPU outside PIC lock again This restores the deferred VCPU kicking before 956f97cf. We need this over -rt as wake_up* requires non-atomic context in this configuration. Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity --- arch/x86/kvm/i8259.c | 53 +++++++++++++++++++++++++++++++++++++--------------- arch/x86/kvm/irq.h | 1 + 2 files changed, 39 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index a790fa128a9f..93825ff3338f 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c @@ -33,6 +33,29 @@ #include #include "trace.h" +static void pic_lock(struct kvm_pic *s) + __acquires(&s->lock) +{ + raw_spin_lock(&s->lock); +} + +static void pic_unlock(struct kvm_pic *s) + __releases(&s->lock) +{ + bool wakeup = s->wakeup_needed; + struct kvm_vcpu *vcpu; + + s->wakeup_needed = false; + + raw_spin_unlock(&s->lock); + + if (wakeup) { + vcpu = s->kvm->bsp_vcpu; + if (vcpu) + kvm_vcpu_kick(vcpu); + } +} + static void pic_clear_isr(struct kvm_kpic_state *s, int irq) { s->isr &= ~(1 << irq); @@ -45,19 +68,19 @@ static void pic_clear_isr(struct kvm_kpic_state *s, int irq) * Other interrupt may be delivered to PIC while lock is dropped but * it should be safe since PIC state is already updated at this stage. */ - raw_spin_unlock(&s->pics_state->lock); + pic_unlock(s->pics_state); kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq); - raw_spin_lock(&s->pics_state->lock); + pic_lock(s->pics_state); } void kvm_pic_clear_isr_ack(struct kvm *kvm) { struct kvm_pic *s = pic_irqchip(kvm); - raw_spin_lock(&s->lock); + pic_lock(s); s->pics[0].isr_ack = 0xff; s->pics[1].isr_ack = 0xff; - raw_spin_unlock(&s->lock); + pic_unlock(s); } /* @@ -158,9 +181,9 @@ static void pic_update_irq(struct kvm_pic *s) void kvm_pic_update_irq(struct kvm_pic *s) { - raw_spin_lock(&s->lock); + pic_lock(s); pic_update_irq(s); - raw_spin_unlock(&s->lock); + pic_unlock(s); } int kvm_pic_set_irq(void *opaque, int irq, int level) @@ -168,14 +191,14 @@ int kvm_pic_set_irq(void *opaque, int irq, int level) struct kvm_pic *s = opaque; int ret = -1; - raw_spin_lock(&s->lock); + pic_lock(s); if (irq >= 0 && irq < PIC_NUM_PINS) { ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); pic_update_irq(s); trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr, s->pics[irq >> 3].imr, ret == 0); } - raw_spin_unlock(&s->lock); + pic_unlock(s); return ret; } @@ -205,7 +228,7 @@ int kvm_pic_read_irq(struct kvm *kvm) int irq, irq2, intno; struct kvm_pic *s = pic_irqchip(kvm); - raw_spin_lock(&s->lock); + pic_lock(s); irq = pic_get_irq(&s->pics[0]); if (irq >= 0) { pic_intack(&s->pics[0], irq); @@ -230,7 +253,7 @@ int kvm_pic_read_irq(struct kvm *kvm) intno = s->pics[0].irq_base + irq; } pic_update_irq(s); - raw_spin_unlock(&s->lock); + pic_unlock(s); return intno; } @@ -444,7 +467,7 @@ static int picdev_write(struct kvm_io_device *this, printk(KERN_ERR "PIC: non byte write\n"); return 0; } - raw_spin_lock(&s->lock); + pic_lock(s); switch (addr) { case 0x20: case 0x21: @@ -457,7 +480,7 @@ static int picdev_write(struct kvm_io_device *this, elcr_ioport_write(&s->pics[addr & 1], addr, data); break; } - raw_spin_unlock(&s->lock); + pic_unlock(s); return 0; } @@ -474,7 +497,7 @@ static int picdev_read(struct kvm_io_device *this, printk(KERN_ERR "PIC: non byte read\n"); return 0; } - raw_spin_lock(&s->lock); + pic_lock(s); switch (addr) { case 0x20: case 0x21: @@ -488,7 +511,7 @@ static int picdev_read(struct kvm_io_device *this, break; } *(unsigned char *)val = data; - raw_spin_unlock(&s->lock); + pic_unlock(s); return 0; } @@ -505,7 +528,7 @@ static void pic_irq_request(void *opaque, int level) s->output = level; if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) { s->pics[0].isr_ack &= ~(1 << irq); - kvm_vcpu_kick(vcpu); + s->wakeup_needed = true; } } diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index 34b15915754d..cd1f362f413d 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h @@ -63,6 +63,7 @@ struct kvm_kpic_state { struct kvm_pic { raw_spinlock_t lock; + bool wakeup_needed; unsigned pending_acks; struct kvm *kvm; struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ -- cgit v1.2.3-59-g8ed1b From 116a4752c82f767a59c27b2630a8474b936a776a Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 23 Feb 2010 17:47:54 +0100 Subject: KVM: SVM: Move svm_queue_exception Move svm_queue_exception past skip_emulated_instruction to allow calling it later on. Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index bd8f52f0823f..908ec61895ce 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -236,23 +236,6 @@ static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) vcpu->arch.efer = efer; } -static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, - bool has_error_code, u32 error_code) -{ - struct vcpu_svm *svm = to_svm(vcpu); - - /* If we are within a nested VM we'd better #VMEXIT and let the - guest handle the exception */ - if (nested_svm_check_exception(svm, nr, has_error_code, error_code)) - return; - - svm->vmcb->control.event_inj = nr - | SVM_EVTINJ_VALID - | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0) - | SVM_EVTINJ_TYPE_EXEPT; - svm->vmcb->control.event_inj_err = error_code; -} - static int is_external_interrupt(u32 info) { info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID; @@ -298,6 +281,23 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) svm_set_interrupt_shadow(vcpu, 0); } +static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, + bool has_error_code, u32 error_code) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + /* If we are within a nested VM we'd better #VMEXIT and let the + guest handle the exception */ + if (nested_svm_check_exception(svm, nr, has_error_code, error_code)) + return; + + svm->vmcb->control.event_inj = nr + | SVM_EVTINJ_VALID + | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0) + | SVM_EVTINJ_TYPE_EXEPT; + svm->vmcb->control.event_inj_err = error_code; +} + static int has_svm(void) { const char *msg; -- cgit v1.2.3-59-g8ed1b From f92653eeb496fe8624ac4b0d628c916a06a3d25c Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 23 Feb 2010 17:47:55 +0100 Subject: KVM: x86: Add kvm_is_linear_rip Based on Gleb's suggestion: Add a helper kvm_is_linear_rip that matches a given linear RIP against the current one. Use this for guest single-stepping, more users will follow. Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_host.h | 4 +++- arch/x86/kvm/x86.c | 21 +++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index d46e791de129..502fff123e29 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -362,8 +362,8 @@ struct kvm_vcpu_arch { u64 *mce_banks; /* used for guest single stepping over the given code position */ - u16 singlestep_cs; unsigned long singlestep_rip; + /* fields used by HYPER-V emulation */ u64 hv_vapic; }; @@ -820,4 +820,6 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v); void kvm_define_shared_msr(unsigned index, u32 msr); void kvm_set_shared_msr(unsigned index, u64 val, u64 mask); +bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip); + #endif /* _ASM_X86_KVM_HOST_H */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index efeeabd84ecd..f2f246ae4a4c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5376,11 +5376,9 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, vcpu->arch.switch_db_regs = (vcpu->arch.dr7 & DR7_BP_EN_MASK); } - if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { - vcpu->arch.singlestep_cs = - get_segment_selector(vcpu, VCPU_SREG_CS); - vcpu->arch.singlestep_rip = kvm_rip_read(vcpu); - } + if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) + vcpu->arch.singlestep_rip = kvm_rip_read(vcpu) + + get_segment_base(vcpu, VCPU_SREG_CS); /* * Trigger an rflags update that will inject or remove the trace @@ -5871,6 +5869,15 @@ int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) return kvm_x86_ops->interrupt_allowed(vcpu); } +bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip) +{ + unsigned long current_rip = kvm_rip_read(vcpu) + + get_segment_base(vcpu, VCPU_SREG_CS); + + return current_rip == linear_rip; +} +EXPORT_SYMBOL_GPL(kvm_is_linear_rip); + unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu) { unsigned long rflags; @@ -5885,9 +5892,7 @@ EXPORT_SYMBOL_GPL(kvm_get_rflags); void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) { if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP && - vcpu->arch.singlestep_cs == - get_segment_selector(vcpu, VCPU_SREG_CS) && - vcpu->arch.singlestep_rip == kvm_rip_read(vcpu)) + kvm_is_linear_rip(vcpu, vcpu->arch.singlestep_rip)) rflags |= X86_EFLAGS_TF | X86_EFLAGS_RF; kvm_x86_ops->set_rflags(vcpu, rflags); } -- cgit v1.2.3-59-g8ed1b From 66b7138f913635b40822890ba8913548f8b285b8 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 23 Feb 2010 17:47:56 +0100 Subject: KVM: SVM: Emulate nRIP feature when reinjecting INT3 When in guest debugging mode, we have to reinject those #BP software exceptions that are caused by guest-injected INT3. As older AMD processors do not support the required nRIP VMCB field, try to emulate it by moving RIP past the instruction on exception injection. Fix it up again in case the injection failed and we were able to catch this. This does not work for unintercepted faults, but it is better than doing nothing. Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 908ec61895ce..468ff6e721ce 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -47,6 +47,7 @@ MODULE_LICENSE("GPL"); #define SVM_FEATURE_NPT (1 << 0) #define SVM_FEATURE_LBRV (1 << 1) #define SVM_FEATURE_SVML (1 << 2) +#define SVM_FEATURE_NRIP (1 << 3) #define SVM_FEATURE_PAUSE_FILTER (1 << 10) #define NESTED_EXIT_HOST 0 /* Exit handled on host level */ @@ -110,6 +111,9 @@ struct vcpu_svm { struct nested_state nested; bool nmi_singlestep; + + unsigned int3_injected; + unsigned long int3_rip; }; /* enable NPT for AMD64 and X86 with PAE */ @@ -291,6 +295,22 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, if (nested_svm_check_exception(svm, nr, has_error_code, error_code)) return; + if (nr == BP_VECTOR && !svm_has(SVM_FEATURE_NRIP)) { + unsigned long rip, old_rip = kvm_rip_read(&svm->vcpu); + + /* + * For guest debugging where we have to reinject #BP if some + * INT3 is guest-owned: + * Emulate nRIP by moving RIP forward. Will fail if injection + * raises a fault that is not intercepted. Still better than + * failing in all cases. + */ + skip_emulated_instruction(&svm->vcpu); + rip = kvm_rip_read(&svm->vcpu); + svm->int3_rip = rip + svm->vmcb->save.cs.base; + svm->int3_injected = rip - old_rip; + } + svm->vmcb->control.event_inj = nr | SVM_EVTINJ_VALID | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0) @@ -2701,6 +2721,9 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) u8 vector; int type; u32 exitintinfo = svm->vmcb->control.exit_int_info; + unsigned int3_injected = svm->int3_injected; + + svm->int3_injected = 0; if (svm->vcpu.arch.hflags & HF_IRET_MASK) svm->vcpu.arch.hflags &= ~(HF_NMI_MASK | HF_IRET_MASK); @@ -2720,12 +2743,21 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) svm->vcpu.arch.nmi_injected = true; break; case SVM_EXITINTINFO_TYPE_EXEPT: - /* In case of software exception do not reinject an exception - vector, but re-execute and instruction instead */ if (is_nested(svm)) break; - if (kvm_exception_is_soft(vector)) + /* + * In case of software exceptions, do not reinject the vector, + * but re-execute the instruction instead. Rewind RIP first + * if we emulated INT3 before. + */ + if (kvm_exception_is_soft(vector)) { + if (vector == BP_VECTOR && int3_injected && + kvm_is_linear_rip(&svm->vcpu, svm->int3_rip)) + kvm_rip_write(&svm->vcpu, + kvm_rip_read(&svm->vcpu) - + int3_injected); break; + } if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { u32 err = svm->vmcb->control.exit_int_info_err; kvm_queue_exception_e(&svm->vcpu, vector, err); -- cgit v1.2.3-59-g8ed1b From c310bac5a20fc37f761bd7297ba2e52cf40d79c6 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 23 Feb 2010 17:47:58 +0100 Subject: KVM: x86: Drop RF manipulation for guest single-stepping RF is not required for injecting TF as the latter will trigger only after an instruction execution anyway. So do not touch RF when arming or disarming guest single-step mode. Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f2f246ae4a4c..a519fc6ed051 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5884,7 +5884,7 @@ unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu) rflags = kvm_x86_ops->get_rflags(vcpu); if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) - rflags &= ~(unsigned long)(X86_EFLAGS_TF | X86_EFLAGS_RF); + rflags &= ~X86_EFLAGS_TF; return rflags; } EXPORT_SYMBOL_GPL(kvm_get_rflags); @@ -5893,7 +5893,7 @@ void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) { if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP && kvm_is_linear_rip(vcpu, vcpu->arch.singlestep_rip)) - rflags |= X86_EFLAGS_TF | X86_EFLAGS_RF; + rflags |= X86_EFLAGS_TF; kvm_x86_ops->set_rflags(vcpu, rflags); } EXPORT_SYMBOL_GPL(kvm_set_rflags); -- cgit v1.2.3-59-g8ed1b From 83bf0002c91b65744db78df36d4f1af27bd9099b Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 23 Feb 2010 17:47:59 +0100 Subject: KVM: x86: Preserve injected TF across emulation Call directly into the vendor services for getting/setting rflags in emulate_instruction to ensure injected TF survives the emulation. Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a519fc6ed051..3a367f35cebf 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3447,7 +3447,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); vcpu->arch.emulate_ctxt.vcpu = vcpu; - vcpu->arch.emulate_ctxt.eflags = kvm_get_rflags(vcpu); + vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu); vcpu->arch.emulate_ctxt.mode = (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL : (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM) @@ -3526,7 +3526,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, return EMULATE_DO_MMIO; } - kvm_set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); + kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); if (vcpu->mmio_is_write) { vcpu->mmio_needed = 0; -- cgit v1.2.3-59-g8ed1b From e02317153e77150fed9609c3212c98204ec3ea74 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 24 Feb 2010 18:59:10 +0100 Subject: KVM: SVM: Coding style cleanup This patch removes whitespace errors, fixes comment formats and most of checkpatch warnings. Now vim does not show c-space-errors anymore. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 148 +++++++++++++++++++++++++++++------------------------ 1 file changed, 81 insertions(+), 67 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 468ff6e721ce..44679530ad5d 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -120,7 +120,7 @@ struct vcpu_svm { #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) static bool npt_enabled = true; #else -static bool npt_enabled = false; +static bool npt_enabled; #endif static int npt = 1; @@ -168,8 +168,8 @@ static unsigned long iopm_base; struct kvm_ldttss_desc { u16 limit0; u16 base0; - unsigned base1 : 8, type : 5, dpl : 2, p : 1; - unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; + unsigned base1:8, type:5, dpl:2, p:1; + unsigned limit1:4, zero0:3, g:1, base2:8; u32 base3; u32 zero1; } __attribute__((packed)); @@ -218,7 +218,7 @@ static inline void stgi(void) static inline void invlpga(unsigned long addr, u32 asid) { - asm volatile (__ex(SVM_INVLPGA) :: "a"(addr), "c"(asid)); + asm volatile (__ex(SVM_INVLPGA) : : "a"(addr), "c"(asid)); } static inline void force_new_asid(struct kvm_vcpu *vcpu) @@ -290,8 +290,10 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, { struct vcpu_svm *svm = to_svm(vcpu); - /* If we are within a nested VM we'd better #VMEXIT and let the - guest handle the exception */ + /* + * If we are within a nested VM we'd better #VMEXIT and let the guest + * handle the exception + */ if (nested_svm_check_exception(svm, nr, has_error_code, error_code)) return; @@ -544,7 +546,7 @@ static void init_seg(struct vmcb_seg *seg) { seg->selector = 0; seg->attrib = SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK | - SVM_SELECTOR_WRITE_MASK; /* Read/Write Data Segment */ + SVM_SELECTOR_WRITE_MASK; /* Read/Write Data Segment */ seg->limit = 0xffff; seg->base = 0; } @@ -564,16 +566,16 @@ static void init_vmcb(struct vcpu_svm *svm) svm->vcpu.fpu_active = 1; - control->intercept_cr_read = INTERCEPT_CR0_MASK | + control->intercept_cr_read = INTERCEPT_CR0_MASK | INTERCEPT_CR3_MASK | INTERCEPT_CR4_MASK; - control->intercept_cr_write = INTERCEPT_CR0_MASK | + control->intercept_cr_write = INTERCEPT_CR0_MASK | INTERCEPT_CR3_MASK | INTERCEPT_CR4_MASK | INTERCEPT_CR8_MASK; - control->intercept_dr_read = INTERCEPT_DR0_MASK | + control->intercept_dr_read = INTERCEPT_DR0_MASK | INTERCEPT_DR1_MASK | INTERCEPT_DR2_MASK | INTERCEPT_DR3_MASK | @@ -582,7 +584,7 @@ static void init_vmcb(struct vcpu_svm *svm) INTERCEPT_DR6_MASK | INTERCEPT_DR7_MASK; - control->intercept_dr_write = INTERCEPT_DR0_MASK | + control->intercept_dr_write = INTERCEPT_DR0_MASK | INTERCEPT_DR1_MASK | INTERCEPT_DR2_MASK | INTERCEPT_DR3_MASK | @@ -596,7 +598,7 @@ static void init_vmcb(struct vcpu_svm *svm) (1 << MC_VECTOR); - control->intercept = (1ULL << INTERCEPT_INTR) | + control->intercept = (1ULL << INTERCEPT_INTR) | (1ULL << INTERCEPT_NMI) | (1ULL << INTERCEPT_SMI) | (1ULL << INTERCEPT_SELECTIVE_CR0) | @@ -657,7 +659,8 @@ static void init_vmcb(struct vcpu_svm *svm) save->rip = 0x0000fff0; svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip; - /* This is the guest-visible cr0 value. + /* + * This is the guest-visible cr0 value. * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. */ svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; @@ -903,7 +906,8 @@ static void svm_get_segment(struct kvm_vcpu *vcpu, var->db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1; var->g = (s->attrib >> SVM_SELECTOR_G_SHIFT) & 1; - /* AMD's VMCB does not have an explicit unusable field, so emulate it + /* + * AMD's VMCB does not have an explicit unusable field, so emulate it * for cross vendor migration purposes by "not present" */ var->unusable = !var->present || (var->type == 0); @@ -939,7 +943,8 @@ static void svm_get_segment(struct kvm_vcpu *vcpu, var->type |= 0x1; break; case VCPU_SREG_SS: - /* On AMD CPUs sometimes the DB bit in the segment + /* + * On AMD CPUs sometimes the DB bit in the segment * descriptor is left as 1, although the whole segment has * been made unusable. Clear it here to pass an Intel VMX * entry check when cross vendor migrating. @@ -1270,7 +1275,7 @@ static int db_interception(struct vcpu_svm *svm) } if (svm->vcpu.guest_debug & - (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)){ + (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) { kvm_run->exit_reason = KVM_EXIT_DEBUG; kvm_run->debug.arch.pc = svm->vmcb->save.cs.base + svm->vmcb->save.rip; @@ -1315,7 +1320,7 @@ static void svm_fpu_activate(struct kvm_vcpu *vcpu) excp = h_excp | n_excp; } else { excp = svm->vmcb->control.intercept_exceptions; - excp &= ~(1 << NM_VECTOR); + excp &= ~(1 << NM_VECTOR); } svm->vmcb->control.intercept_exceptions = excp; @@ -1554,13 +1559,13 @@ static int nested_svm_exit_special(struct vcpu_svm *svm) case SVM_EXIT_INTR: case SVM_EXIT_NMI: return NESTED_EXIT_HOST; - /* For now we are always handling NPFs when using them */ case SVM_EXIT_NPF: + /* For now we are always handling NPFs when using them */ if (npt_enabled) return NESTED_EXIT_HOST; break; - /* When we're shadowing, trap PFs */ case SVM_EXIT_EXCP_BASE + PF_VECTOR: + /* When we're shadowing, trap PFs */ if (!npt_enabled) return NESTED_EXIT_HOST; break; @@ -1795,7 +1800,7 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) if (!nested_msrpm) return false; - for (i=0; i< PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++) + for (i = 0; i < PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++) svm->nested.msrpm[i] = svm->msrpm[i] | nested_msrpm[i]; svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm); @@ -1829,8 +1834,10 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) kvm_clear_exception_queue(&svm->vcpu); kvm_clear_interrupt_queue(&svm->vcpu); - /* Save the old vmcb, so we don't need to pick what we save, but - can restore everything when a VMEXIT occurs */ + /* + * Save the old vmcb, so we don't need to pick what we save, but can + * restore everything when a VMEXIT occurs + */ hsave->save.es = vmcb->save.es; hsave->save.cs = vmcb->save.cs; hsave->save.ss = vmcb->save.ss; @@ -1878,6 +1885,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax); kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp); kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip); + /* In case we don't even reach vcpu_run, the fields are not updated */ svm->vmcb->save.rax = nested_vmcb->save.rax; svm->vmcb->save.rsp = nested_vmcb->save.rsp; @@ -1909,8 +1917,10 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK; } - /* We don't want a nested guest to be more powerful than the guest, - so all intercepts are ORed */ + /* + * We don't want a nested guest to be more powerful than the guest, so + * all intercepts are ORed + */ svm->vmcb->control.intercept_cr_read |= nested_vmcb->control.intercept_cr_read; svm->vmcb->control.intercept_cr_write |= @@ -2224,9 +2234,11 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) case MSR_IA32_SYSENTER_ESP: *data = svm->sysenter_esp; break; - /* Nobody will change the following 5 values in the VMCB so - we can safely return them on rdmsr. They will always be 0 - until LBRV is implemented. */ + /* + * Nobody will change the following 5 values in the VMCB so we can + * safely return them on rdmsr. They will always be 0 until LBRV is + * implemented. + */ case MSR_IA32_DEBUGCTLMSR: *data = svm->vmcb->save.dbgctl; break; @@ -2405,16 +2417,16 @@ static int pause_interception(struct vcpu_svm *svm) } static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { - [SVM_EXIT_READ_CR0] = emulate_on_interception, - [SVM_EXIT_READ_CR3] = emulate_on_interception, - [SVM_EXIT_READ_CR4] = emulate_on_interception, - [SVM_EXIT_READ_CR8] = emulate_on_interception, + [SVM_EXIT_READ_CR0] = emulate_on_interception, + [SVM_EXIT_READ_CR3] = emulate_on_interception, + [SVM_EXIT_READ_CR4] = emulate_on_interception, + [SVM_EXIT_READ_CR8] = emulate_on_interception, [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, - [SVM_EXIT_WRITE_CR0] = emulate_on_interception, - [SVM_EXIT_WRITE_CR3] = emulate_on_interception, - [SVM_EXIT_WRITE_CR4] = emulate_on_interception, - [SVM_EXIT_WRITE_CR8] = cr8_write_interception, - [SVM_EXIT_READ_DR0] = emulate_on_interception, + [SVM_EXIT_WRITE_CR0] = emulate_on_interception, + [SVM_EXIT_WRITE_CR3] = emulate_on_interception, + [SVM_EXIT_WRITE_CR4] = emulate_on_interception, + [SVM_EXIT_WRITE_CR8] = cr8_write_interception, + [SVM_EXIT_READ_DR0] = emulate_on_interception, [SVM_EXIT_READ_DR1] = emulate_on_interception, [SVM_EXIT_READ_DR2] = emulate_on_interception, [SVM_EXIT_READ_DR3] = emulate_on_interception, @@ -2433,15 +2445,14 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception, [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception, [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception, - [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, - [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, - [SVM_EXIT_EXCP_BASE + MC_VECTOR] = mc_interception, - [SVM_EXIT_INTR] = intr_interception, + [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, + [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, + [SVM_EXIT_EXCP_BASE + MC_VECTOR] = mc_interception, + [SVM_EXIT_INTR] = intr_interception, [SVM_EXIT_NMI] = nmi_interception, [SVM_EXIT_SMI] = nop_on_interception, [SVM_EXIT_INIT] = nop_on_interception, [SVM_EXIT_VINTR] = interrupt_window_interception, - /* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */ [SVM_EXIT_CPUID] = cpuid_interception, [SVM_EXIT_IRET] = iret_interception, [SVM_EXIT_INVD] = emulate_on_interception, @@ -2449,7 +2460,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_HLT] = halt_interception, [SVM_EXIT_INVLPG] = invlpg_interception, [SVM_EXIT_INVLPGA] = invlpga_interception, - [SVM_EXIT_IOIO] = io_interception, + [SVM_EXIT_IOIO] = io_interception, [SVM_EXIT_MSR] = msr_interception, [SVM_EXIT_TASK_SWITCH] = task_switch_interception, [SVM_EXIT_SHUTDOWN] = shutdown_interception, @@ -2650,10 +2661,12 @@ static void enable_irq_window(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); - /* In case GIF=0 we can't rely on the CPU to tell us when - * GIF becomes 1, because that's a separate STGI/VMRUN intercept. - * The next time we get that intercept, this function will be - * called again though and we'll get the vintr intercept. */ + /* + * In case GIF=0 we can't rely on the CPU to tell us when GIF becomes + * 1, because that's a separate STGI/VMRUN intercept. The next time we + * get that intercept, this function will be called again though and + * we'll get the vintr intercept. + */ if (gif_set(svm) && nested_svm_intr(svm)) { svm_set_vintr(svm); svm_inject_irq(svm, 0x0); @@ -2668,9 +2681,10 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu) == HF_NMI_MASK) return; /* IRET will cause a vm exit */ - /* Something prevents NMI from been injected. Single step over - possible problem (IRET or exception injection or interrupt - shadow) */ + /* + * Something prevents NMI from been injected. Single step over possible + * problem (IRET or exception injection or interrupt shadow) + */ svm->nmi_singlestep = true; svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); update_db_intercept(vcpu); @@ -2978,24 +2992,24 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) } static const struct trace_print_flags svm_exit_reasons_str[] = { - { SVM_EXIT_READ_CR0, "read_cr0" }, - { SVM_EXIT_READ_CR3, "read_cr3" }, - { SVM_EXIT_READ_CR4, "read_cr4" }, - { SVM_EXIT_READ_CR8, "read_cr8" }, - { SVM_EXIT_WRITE_CR0, "write_cr0" }, - { SVM_EXIT_WRITE_CR3, "write_cr3" }, - { SVM_EXIT_WRITE_CR4, "write_cr4" }, - { SVM_EXIT_WRITE_CR8, "write_cr8" }, - { SVM_EXIT_READ_DR0, "read_dr0" }, - { SVM_EXIT_READ_DR1, "read_dr1" }, - { SVM_EXIT_READ_DR2, "read_dr2" }, - { SVM_EXIT_READ_DR3, "read_dr3" }, - { SVM_EXIT_WRITE_DR0, "write_dr0" }, - { SVM_EXIT_WRITE_DR1, "write_dr1" }, - { SVM_EXIT_WRITE_DR2, "write_dr2" }, - { SVM_EXIT_WRITE_DR3, "write_dr3" }, - { SVM_EXIT_WRITE_DR5, "write_dr5" }, - { SVM_EXIT_WRITE_DR7, "write_dr7" }, + { SVM_EXIT_READ_CR0, "read_cr0" }, + { SVM_EXIT_READ_CR3, "read_cr3" }, + { SVM_EXIT_READ_CR4, "read_cr4" }, + { SVM_EXIT_READ_CR8, "read_cr8" }, + { SVM_EXIT_WRITE_CR0, "write_cr0" }, + { SVM_EXIT_WRITE_CR3, "write_cr3" }, + { SVM_EXIT_WRITE_CR4, "write_cr4" }, + { SVM_EXIT_WRITE_CR8, "write_cr8" }, + { SVM_EXIT_READ_DR0, "read_dr0" }, + { SVM_EXIT_READ_DR1, "read_dr1" }, + { SVM_EXIT_READ_DR2, "read_dr2" }, + { SVM_EXIT_READ_DR3, "read_dr3" }, + { SVM_EXIT_WRITE_DR0, "write_dr0" }, + { SVM_EXIT_WRITE_DR1, "write_dr1" }, + { SVM_EXIT_WRITE_DR2, "write_dr2" }, + { SVM_EXIT_WRITE_DR3, "write_dr3" }, + { SVM_EXIT_WRITE_DR5, "write_dr5" }, + { SVM_EXIT_WRITE_DR7, "write_dr7" }, { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, -- cgit v1.2.3-59-g8ed1b From 0e5cbe368b366f02cf3fe707aea2c0efac1bf70e Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 24 Feb 2010 18:59:11 +0100 Subject: KVM: SVM: Reset MMU on nested_svm_vmrun for NPT too Without resetting the MMU the gva_to_pga function will not work reliably when the vcpu is running in nested context. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 44679530ad5d..ef40b90219f6 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1877,10 +1877,12 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) if (npt_enabled) { svm->vmcb->save.cr3 = nested_vmcb->save.cr3; svm->vcpu.arch.cr3 = nested_vmcb->save.cr3; - } else { + } else kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3); - kvm_mmu_reset_context(&svm->vcpu); - } + + /* Guest paging mode is active - reset mmu */ + kvm_mmu_reset_context(&svm->vcpu); + svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = nested_vmcb->save.cr2; kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax); kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp); -- cgit v1.2.3-59-g8ed1b From 887f500ca1a721cac237ba56374b9c0f578251ec Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 24 Feb 2010 18:59:12 +0100 Subject: KVM: SVM: Check for nested intercepts on NMI injection This patch implements the NMI intercept checking for nested svm. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index ef40b90219f6..9f1143105e00 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1486,6 +1486,21 @@ static inline bool nested_svm_intr(struct vcpu_svm *svm) return true; } +/* This function returns true if it is save to enable the nmi window */ +static inline bool nested_svm_nmi(struct vcpu_svm *svm) +{ + if (!is_nested(svm)) + return true; + + if (!(svm->nested.intercept & (1ULL << INTERCEPT_NMI))) + return true; + + svm->vmcb->control.exit_code = SVM_EXIT_NMI; + svm->nested.exit_required = true; + + return false; +} + static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page) { struct page *page; @@ -2687,9 +2702,11 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu) * Something prevents NMI from been injected. Single step over possible * problem (IRET or exception injection or interrupt shadow) */ - svm->nmi_singlestep = true; - svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); - update_db_intercept(vcpu); + if (gif_set(svm) && nested_svm_nmi(svm)) { + svm->nmi_singlestep = true; + svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); + update_db_intercept(vcpu); + } } static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) -- cgit v1.2.3-59-g8ed1b From ecf1405df235da3efea213427ac7da7f816e9d06 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 24 Feb 2010 18:59:13 +0100 Subject: KVM: SVM: Restore tracing of nested vmcb address A recent change broke tracing of the nested vmcb address. It was reported as 0 all the time. This patch fixes it. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 9f1143105e00..2e4e089646a7 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1839,7 +1839,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) if (!nested_vmcb) return false; - trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, svm->nested.vmcb, + trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, vmcb_gpa, nested_vmcb->save.rip, nested_vmcb->control.int_ctl, nested_vmcb->control.event_inj, -- cgit v1.2.3-59-g8ed1b From 2e554e8d67926024b01e97d2fe652810165354e2 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 24 Feb 2010 18:59:14 +0100 Subject: KVM: SVM: Add kvm_nested_intercepts tracepoint This patch adds a tracepoint to get information about the most important intercept bitmasks from the nested vmcb. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 5 +++++ arch/x86/kvm/trace.h | 22 ++++++++++++++++++++++ arch/x86/kvm/x86.c | 1 + 3 files changed, 28 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 2e4e089646a7..cac761c6d1dc 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1845,6 +1845,11 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) nested_vmcb->control.event_inj, nested_vmcb->control.nested_ctl); + trace_kvm_nested_intercepts(nested_vmcb->control.intercept_cr_read, + nested_vmcb->control.intercept_cr_write, + nested_vmcb->control.intercept_exceptions, + nested_vmcb->control.intercept); + /* Clear internal status */ kvm_clear_exception_queue(&svm->vcpu); kvm_clear_interrupt_queue(&svm->vcpu); diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 12f8d2dee984..17b52ccd9774 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -419,6 +419,28 @@ TRACE_EVENT(kvm_nested_vmrun, __entry->npt ? "on" : "off") ); +TRACE_EVENT(kvm_nested_intercepts, + TP_PROTO(__u16 cr_read, __u16 cr_write, __u32 exceptions, __u64 intercept), + TP_ARGS(cr_read, cr_write, exceptions, intercept), + + TP_STRUCT__entry( + __field( __u16, cr_read ) + __field( __u16, cr_write ) + __field( __u32, exceptions ) + __field( __u64, intercept ) + ), + + TP_fast_assign( + __entry->cr_read = cr_read; + __entry->cr_write = cr_write; + __entry->exceptions = exceptions; + __entry->intercept = intercept; + ), + + TP_printk("cr_read: %04x cr_write: %04x excp: %08x intercept: %016llx", + __entry->cr_read, __entry->cr_write, __entry->exceptions, + __entry->intercept) +); /* * Tracepoint for #VMEXIT while nested */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3a367f35cebf..1aa4d6e26bad 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5909,3 +5909,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_vmexit_inject); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intr_vmexit); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_invlpga); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_skinit); +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intercepts); -- cgit v1.2.3-59-g8ed1b From 4a810181c8bcd73112f5c62b205b5583fd4a197f Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 24 Feb 2010 18:59:15 +0100 Subject: KVM: SVM: Implement emulation of vm_cr msr This patch implements the emulation of the vm_cr msr for nested svm. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/include/asm/svm.h | 4 ++++ arch/x86/kvm/svm.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 38638cd2fa4c..b26a38d85356 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -115,6 +115,10 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT) #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT) +#define SVM_VM_CR_VALID_MASK 0x001fULL +#define SVM_VM_CR_SVM_LOCK_MASK 0x0008ULL +#define SVM_VM_CR_SVM_DIS_MASK 0x0010ULL + struct __attribute__ ((__packed__)) vmcb_seg { u16 selector; u16 attrib; diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index cac761c6d1dc..b4aac5c7ad87 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -71,6 +71,7 @@ struct kvm_vcpu; struct nested_state { struct vmcb *hsave; u64 hsave_msr; + u64 vm_cr_msr; u64 vmcb; /* These are the merged vectors */ @@ -2280,7 +2281,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) *data = svm->nested.hsave_msr; break; case MSR_VM_CR: - *data = 0; + *data = svm->nested.vm_cr_msr; break; case MSR_IA32_UCODE_REV: *data = 0x01000065; @@ -2310,6 +2311,31 @@ static int rdmsr_interception(struct vcpu_svm *svm) return 1; } +static int svm_set_vm_cr(struct kvm_vcpu *vcpu, u64 data) +{ + struct vcpu_svm *svm = to_svm(vcpu); + int svm_dis, chg_mask; + + if (data & ~SVM_VM_CR_VALID_MASK) + return 1; + + chg_mask = SVM_VM_CR_VALID_MASK; + + if (svm->nested.vm_cr_msr & SVM_VM_CR_SVM_DIS_MASK) + chg_mask &= ~(SVM_VM_CR_SVM_LOCK_MASK | SVM_VM_CR_SVM_DIS_MASK); + + svm->nested.vm_cr_msr &= ~chg_mask; + svm->nested.vm_cr_msr |= (data & chg_mask); + + svm_dis = svm->nested.vm_cr_msr & SVM_VM_CR_SVM_DIS_MASK; + + /* check for svm_disable while efer.svme is set */ + if (svm_dis && (vcpu->arch.efer & EFER_SVME)) + return 1; + + return 0; +} + static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) { struct vcpu_svm *svm = to_svm(vcpu); @@ -2376,6 +2402,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) svm->nested.hsave_msr = data; break; case MSR_VM_CR: + return svm_set_vm_cr(vcpu, data); case MSR_VM_IGNNE: pr_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data); break; -- cgit v1.2.3-59-g8ed1b From 82494028dff648c29e3a40915f1fceca51b4490a Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 24 Feb 2010 18:59:16 +0100 Subject: KVM: SVM: Ignore write of hwcr.ignne Hyper-V as a guest wants to write this bit. This patch ignores it. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 1aa4d6e26bad..81b7af5558f9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1090,6 +1090,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) break; case MSR_K7_HWCR: data &= ~(u64)0x40; /* ignore flush filter disable */ + data &= ~(u64)0x100; /* ignore ignne emulation enable */ if (data != 0) { pr_unimpl(vcpu, "unimplemented HWCR wrmsr: 0x%llx\n", data); -- cgit v1.2.3-59-g8ed1b From b44ea385d8cb187e04ec8d901d4c320c8b07c40b Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 24 Feb 2010 18:59:17 +0100 Subject: KVM: x86: Don't set arch.cr0 in kvm_set_cr0 The vcpu->arch.cr0 variable is already set in the architecture specific set_cr0 callbacks. There is no need to set it in the common code. This allows the architecture code to keep the old arch.cr0 value if it wants. This is required for nested svm to decide if a selective_cr0 exit needs to be injected. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 81b7af5558f9..d0b184b5c248 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -475,7 +475,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) } kvm_x86_ops->set_cr0(vcpu, cr0); - vcpu->arch.cr0 = cr0; kvm_mmu_reset_context(vcpu); return; -- cgit v1.2.3-59-g8ed1b From 7f5d8b5600b5294137886b46bf00ef811d0fdf32 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 24 Feb 2010 18:59:18 +0100 Subject: KVM: SVM: Handle nested selective_cr0 intercept correctly If we have the following situation with nested svm: 1. Host KVM intercepts cr0 writes 2. Guest hypervisor intercepts only selective cr0 writes Then we get an cr0 write intercept which is handled on the host. But that intercepts may actually be a selective cr0 intercept for the guest. This patch checks for this condition and injects a selective cr0 intercept if needed. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index b4aac5c7ad87..631d2e544491 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1043,6 +1043,27 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) { struct vcpu_svm *svm = to_svm(vcpu); + if (is_nested(svm)) { + /* + * We are here because we run in nested mode, the host kvm + * intercepts cr0 writes but the l1 hypervisor does not. + * But the L1 hypervisor may intercept selective cr0 writes. + * This needs to be checked here. + */ + unsigned long old, new; + + /* Remove bits that would trigger a real cr0 write intercept */ + old = vcpu->arch.cr0 & SVM_CR0_SELECTIVE_MASK; + new = cr0 & SVM_CR0_SELECTIVE_MASK; + + if (old == new) { + /* cr0 write with ts and mp unchanged */ + svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE; + if (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE) + return; + } + } + #ifdef CONFIG_X86_64 if (vcpu->arch.efer & EFER_LME) { if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { -- cgit v1.2.3-59-g8ed1b From 197717d5813fc39a7185a3177b76f4a3b2405df7 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 24 Feb 2010 18:59:19 +0100 Subject: KVM: SVM: Clear exit_info for injected INTR exits When injecting an vmexit.intr into the nested hypervisor there might be leftover values in the exit_info fields. Clear them to not confuse nested hypervisors. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 631d2e544491..38f1fceefea1 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1491,7 +1491,9 @@ static inline bool nested_svm_intr(struct vcpu_svm *svm) if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) return false; - svm->vmcb->control.exit_code = SVM_EXIT_INTR; + svm->vmcb->control.exit_code = SVM_EXIT_INTR; + svm->vmcb->control.exit_info_1 = 0; + svm->vmcb->control.exit_info_2 = 0; if (svm->nested.intercept & 1ULL) { /* -- cgit v1.2.3-59-g8ed1b From d6ab1ed44627c91d0a857a430b7ec4ed8648c7a5 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 25 Feb 2010 12:43:07 +0200 Subject: KVM: Drop kvm_get_gdt() in favor of generic linux function Linux now has native_store_gdt() to do the same. Use it instead of kvm local version. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_host.h | 5 ----- arch/x86/kvm/svm.c | 2 +- arch/x86/kvm/vmx.c | 4 ++-- arch/x86/kvm/x86.c | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 502fff123e29..e3167224d936 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -723,11 +723,6 @@ static inline void kvm_get_idt(struct desc_ptr *table) asm("sidt %0" : "=m"(*table)); } -static inline void kvm_get_gdt(struct desc_ptr *table) -{ - asm("sgdt %0" : "=m"(*table)); -} - static inline unsigned long kvm_read_tr_base(void) { u16 tr; diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 38f1fceefea1..6882be5b9267 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -368,7 +368,7 @@ static int svm_hardware_enable(void *garbage) sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; sd->next_asid = sd->max_asid + 1; - kvm_get_gdt(&gdt_descr); + native_store_gdt(&gdt_descr); gdt = (struct desc_struct *)gdt_descr.address; sd->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 61f03980adae..68712bdf0407 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -603,7 +603,7 @@ static void reload_tss(void) struct desc_ptr gdt; struct desc_struct *descs; - kvm_get_gdt(&gdt); + native_store_gdt(&gdt); descs = (void *)gdt.address; descs[GDT_ENTRY_TSS].type = 9; /* available TSS */ load_TR_desc(); @@ -767,7 +767,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) * processors. */ vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */ - kvm_get_gdt(&dt); + native_store_gdt(&dt); vmcs_writel(HOST_GDTR_BASE, dt.address); /* 22.2.4 */ rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d0b184b5c248..e07b243055f8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -233,7 +233,7 @@ unsigned long segment_base(u16 selector) if (selector == 0) return 0; - kvm_get_gdt(&gdt); + native_store_gdt(&gdt); table_base = gdt.address; if (selector & 4) { /* from ldt */ -- cgit v1.2.3-59-g8ed1b From 254d4d48a56925622a5592ad590a738735b66135 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 25 Feb 2010 12:43:08 +0200 Subject: KVM: fix segment_base() error checking fix segment_base() to properly check for null segment selector and avoid accessing NULL pointer if ldt selector in null. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e07b243055f8..814e72a02eff 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -230,7 +230,7 @@ unsigned long segment_base(u16 selector) unsigned long table_base; unsigned long v; - if (selector == 0) + if (!(selector & ~3)) return 0; native_store_gdt(&gdt); @@ -239,6 +239,8 @@ unsigned long segment_base(u16 selector) if (selector & 4) { /* from ldt */ u16 ldt_selector = kvm_read_ldt(); + if (!(ldt_selector & ~3)) + return 0; table_base = segment_base(ldt_selector); } d = (struct desc_struct *)(table_base + (selector & ~7)); -- cgit v1.2.3-59-g8ed1b From 2d49ec72d3fab0aa90510a64a973d594c48b1fd1 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 25 Feb 2010 12:43:09 +0200 Subject: KVM: move segment_base() into vmx.c segment_base() is used only by vmx so move it there. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_host.h | 9 --------- arch/x86/kvm/vmx.c | 37 +++++++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.c | 30 ------------------------------ 3 files changed, 37 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index e3167224d936..ec891a2ce86e 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -644,8 +644,6 @@ int emulator_write_emulated(unsigned long addr, unsigned int bytes, struct kvm_vcpu *vcpu); -unsigned long segment_base(u16 selector); - void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu); void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new, int bytes, @@ -723,13 +721,6 @@ static inline void kvm_get_idt(struct desc_ptr *table) asm("sidt %0" : "=m"(*table)); } -static inline unsigned long kvm_read_tr_base(void) -{ - u16 tr; - asm("str %0" : "=g"(tr)); - return segment_base(tr); -} - #ifdef CONFIG_X86_64 static inline unsigned long read_msr(unsigned long msr) { diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 68712bdf0407..8e2a24693be9 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -634,6 +634,43 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) return true; } +static unsigned long segment_base(u16 selector) +{ + struct desc_ptr gdt; + struct desc_struct *d; + unsigned long table_base; + unsigned long v; + + if (!(selector & ~3)) + return 0; + + native_store_gdt(&gdt); + table_base = gdt.address; + + if (selector & 4) { /* from ldt */ + u16 ldt_selector = kvm_read_ldt(); + + if (!(ldt_selector & ~3)) + return 0; + + table_base = segment_base(ldt_selector); + } + d = (struct desc_struct *)(table_base + (selector & ~7)); + v = get_desc_base(d); +#ifdef CONFIG_X86_64 + if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11)) + v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32; +#endif + return v; +} + +static inline unsigned long kvm_read_tr_base(void) +{ + u16 tr; + asm("str %0" : "=g"(tr)); + return segment_base(tr); +} + static void vmx_save_host_state(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 814e72a02eff..2b34dc705cfb 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -223,36 +223,6 @@ static void drop_user_return_notifiers(void *ignore) kvm_on_user_return(&smsr->urn); } -unsigned long segment_base(u16 selector) -{ - struct desc_ptr gdt; - struct desc_struct *d; - unsigned long table_base; - unsigned long v; - - if (!(selector & ~3)) - return 0; - - native_store_gdt(&gdt); - table_base = gdt.address; - - if (selector & 4) { /* from ldt */ - u16 ldt_selector = kvm_read_ldt(); - - if (!(ldt_selector & ~3)) - return 0; - table_base = segment_base(ldt_selector); - } - d = (struct desc_struct *)(table_base + (selector & ~7)); - v = get_desc_base(d); -#ifdef CONFIG_X86_64 - if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11)) - v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32; -#endif - return v; -} -EXPORT_SYMBOL_GPL(segment_base); - u64 kvm_get_apic_base(struct kvm_vcpu *vcpu) { if (irqchip_in_kernel(vcpu->kvm)) -- cgit v1.2.3-59-g8ed1b From e35b7b9c9e7d8768ee34e5904fed4cb0f2c2cb5d Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 25 Feb 2010 16:36:42 +0200 Subject: KVM: x86 emulator: Add decoding of 16bit second in memory argument Add decoding of Ep type of argument used by callf/jmpf. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/kvm/emulate.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index c9f604b0819c..97a740368b30 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -85,6 +85,9 @@ #define Src2ImmByte (2<<29) #define Src2One (3<<29) #define Src2Imm16 (4<<29) +#define Src2Mem16 (5<<29) /* Used for Ep encoding. First argument has to be + in memory and second argument is located + immediately after the first one in memory. */ #define Src2Mask (7<<29) enum { @@ -1163,6 +1166,10 @@ done_prefixes: c->src2.bytes = 1; c->src2.val = 1; break; + case Src2Mem16: + c->src2.bytes = 2; + c->src2.type = OP_MEM; + break; } /* Decode and fetch the destination operand: register or memory. */ @@ -1881,6 +1888,17 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) c->src.orig_val = c->src.val; } + if (c->src2.type == OP_MEM) { + c->src2.ptr = (unsigned long *)(memop + c->src.bytes); + c->src2.val = 0; + rc = ops->read_emulated((unsigned long)c->src2.ptr, + &c->src2.val, + c->src2.bytes, + ctxt->vcpu); + if (rc != X86EMUL_CONTINUE) + goto done; + } + if ((c->d & DstMask) == ImplicitOps) goto special_insn; -- cgit v1.2.3-59-g8ed1b From ea79849d4c8461034b75acb19c8041b6fddee2a5 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 25 Feb 2010 16:36:43 +0200 Subject: KVM: x86 emulator: Implement jmp far opcode ff/5 Implement jmp far opcode ff/5. It is used by multiboot loader. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/kvm/emulate.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 97a740368b30..5b6794adaa2e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -346,7 +346,8 @@ static u32 group_table[] = { [Group5*8] = DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, SrcMem | ModRM | Stack, 0, - SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0, + SrcMem | ModRM | Stack, SrcMem | ModRM | Src2Mem16 | ImplicitOps, + SrcMem | ModRM | Stack, 0, [Group7*8] = 0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv, SrcNone | ModRM | DstMem | Mov, 0, @@ -2322,6 +2323,7 @@ special_insn: case 0xe9: /* jmp rel */ goto jmp; case 0xea: /* jmp far */ + jump_far: if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, VCPU_SREG_CS)) goto done; @@ -2397,11 +2399,16 @@ special_insn: ctxt->eflags |= EFLG_DF; c->dst.type = OP_NONE; /* Disable writeback. */ break; - case 0xfe ... 0xff: /* Grp4/Grp5 */ + case 0xfe: /* Grp4 */ + grp45: rc = emulate_grp45(ctxt, ops); if (rc != X86EMUL_CONTINUE) goto done; break; + case 0xff: /* Grp5 */ + if (c->modrm_reg == 5) + goto jump_far; + goto grp45; } writeback: -- cgit v1.2.3-59-g8ed1b From 7c4584d39a8a144c60adaf4cf998c3233b6683d9 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sat, 24 Apr 2010 11:12:12 +0100 Subject: sh: Assembly friendly __pa and __va definitions This patch defines ___pa and ___va which return the physical and virtual address of an address, respectively. These macros are suitable for calling from assembly because they don't include the C casts required by __pa and __va. Signed-off-by: Matt Fleming --- arch/sh/include/asm/page.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index d71feb359304..0152c040f6c3 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -128,13 +128,18 @@ typedef struct page *pgtable_t; * added or subtracted as required. */ #ifdef CONFIG_PMB -#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET+__MEMORY_START) -#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET-__MEMORY_START)) +#define ___pa(x) ((x)-PAGE_OFFSET+__MEMORY_START) +#define ___va(x) ((x)+PAGE_OFFSET-__MEMORY_START) #else -#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) -#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) +#define ___pa(x) ((x)-PAGE_OFFSET) +#define ___va(x) ((x)+PAGE_OFFSET) #endif +#ifndef __ASSEMBLY__ +#define __pa(x) ___pa((unsigned long)x) +#define __va(x) (void *)___va((unsigned long)x) +#endif /* !__ASSEMBLY__ */ + #ifdef CONFIG_UNCACHED_MAPPING #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start) #define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET) -- cgit v1.2.3-59-g8ed1b From b161313ae8d9c64de589d1de72f975210ce37b48 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sat, 24 Apr 2010 13:28:20 +0100 Subject: sh: Fix address to decompress at when CONFIG_32BIT=y When running in 32BIT mode the P1SEG region doesn't necessarily provide a window onto RAM (it depends how the bootloader setup the PMB). The correct location to place the decompressed kernel is the physical address of _text. Signed-off-by: Matt Fleming --- arch/sh/boot/compressed/head_32.S | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S index 02a30935f0b9..200c1d4f1efe 100644 --- a/arch/sh/boot/compressed/head_32.S +++ b/arch/sh/boot/compressed/head_32.S @@ -97,7 +97,11 @@ init_stack_addr: decompress_kernel_addr: .long decompress_kernel kernel_start_addr: +#ifdef CONFIG_32BIT + .long ___pa(_text+PAGE_SIZE) +#else .long _text+PAGE_SIZE +#endif .align 9 fake_headers_as_bzImage: -- cgit v1.2.3-59-g8ed1b From 9c3d936352fefaadec57bafda1fe3807890cbf2c Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sat, 24 Apr 2010 13:34:44 +0100 Subject: sh: Fix zImage load address when CONFIG_32BIT=y We can't necessarily use the P1SEG region to access RAM when running in 32BIT mode, so use CONFIG_MEMORY_START as the base address. Signed-off-by: Matt Fleming --- arch/sh/boot/compressed/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index 5d660b90943b..cfa5a087a886 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -14,10 +14,16 @@ OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o # # IMAGE_OFFSET is the load offset of the compression loader # +ifeq ($(CONFIG_32BIT),y) +IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \ + $$[$(CONFIG_MEMORY_START) + \ + $(CONFIG_BOOT_LINK_OFFSET)]') +else IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \ $$[$(CONFIG_PAGE_OFFSET) + \ $(KERNEL_MEMORY) + \ $(CONFIG_BOOT_LINK_OFFSET)]') +endif LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) -- cgit v1.2.3-59-g8ed1b From c7b03fa0bdc04e00bfbdc4cc69da144b11108f37 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 25 Apr 2010 17:29:07 +0100 Subject: sh: Do not try merging two 128MB PMB mappings There is a logic error in pmb_merge() that means we will incorrectly try to merge two 128MB PMB mappings into one mapping. However, 256MB isn't a valid PMB map size and pmb_merge() will actually drop the second 128MB mapping. This patch allows my SDK7786 board to boot when configured with CONFIG_MEMORY_SIZE=0x10000000. Signed-off-by: Matt Fleming --- arch/sh/mm/pmb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 3cc21933063b..c0fdc217ece5 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -681,7 +681,7 @@ static void __init pmb_merge(struct pmb_entry *head) /* * The merged page size must be valid. */ - if (!pmb_size_valid(newsize)) + if (!depth || !pmb_size_valid(newsize)) return; head->flags &= ~PMB_SZ_MASK; -- cgit v1.2.3-59-g8ed1b From 035ca59fe8399a67b56511bd5b28130f0c4874a0 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 25 Apr 2010 20:18:41 +0100 Subject: sh: Use correct mask when comparing PMB DATA array values Previously we were masking the PMB DATA array values with the value of __MEMORY_START | PMB_V, which misses some PFN bits off the mask. Signed-off-by: Matt Fleming --- arch/sh/kernel/head_32.S | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index 8c1fc9a9fab2..6e35f012cc03 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -131,6 +131,7 @@ ENTRY(_stext) * r8 = scratch register * r9 = scratch register * r10 = number of PMB entries we've setup + * r11 = scratch register */ mov.l .LMMUCR, r1 /* Flush the TLB */ @@ -167,8 +168,9 @@ ENTRY(_stext) .Lvalidate_existing_mappings: + mov.l .LPMB_DATA_MASK, r11 mov.l @r7, r8 - and r0, r8 + and r11, r8 cmp/eq r0, r8 /* Check for valid __MEMORY_START mappings */ bt .Lpmb_done @@ -341,6 +343,7 @@ ENTRY(stack_start) #ifdef CONFIG_PMB .LPMB_ADDR: .long PMB_ADDR .LPMB_DATA: .long PMB_DATA +.LPMB_DATA_MASK: .long PMB_PFN_MASK | PMB_V .LFIRST_ADDR_ENTRY: .long PAGE_OFFSET | PMB_V .LFIRST_DATA_ENTRY: .long __MEMORY_START | PMB_V .LMMUCR: .long MMUCR -- cgit v1.2.3-59-g8ed1b From 6b6b18e62cfba44ce7b6489c7100f12b199232d7 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Thu, 22 Apr 2010 16:06:26 +0000 Subject: sh: invoke oom-killer from page fault As explained in commit 1c0fe6e3bd, we want to call the architecture independent oom killer when getting an unexplained OOM from handle_mm_fault, rather than simply killing current. Cc: linux-sh@vger.kernel.org Cc: linux-arch@vger.kernel.org Signed-off-by: Nick Piggin Acked-by: David Rientjes Signed-off-by: Paul Mundt --- arch/sh/mm/fault_32.c | 13 ++++--------- arch/sh/mm/tlbflush_64.c | 19 ++++--------------- 2 files changed, 8 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index 8bf79e3b7bdd..93c3447ed40a 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c @@ -290,15 +290,10 @@ no_context: */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { - yield(); - down_read(&mm->mmap_sem); - goto survive; - } - printk("VM: killing process %s\n", tsk->comm); - if (user_mode(regs)) - do_group_exit(SIGKILL); - goto no_context; + if (!user_mode(regs)) + goto no_context; + pagefault_out_of_memory(); + return; do_sigbus: up_read(&mm->mmap_sem); diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c index 706da1d3a67a..25bd64c0977c 100644 --- a/arch/sh/mm/tlbflush_64.c +++ b/arch/sh/mm/tlbflush_64.c @@ -294,22 +294,11 @@ no_context: * us unable to handle the page fault gracefully. */ out_of_memory: - if (is_global_init(current)) { - panic("INIT out of memory\n"); - yield(); - goto survive; - } - printk("fault:Out of memory\n"); up_read(&mm->mmap_sem); - if (is_global_init(current)) { - yield(); - down_read(&mm->mmap_sem); - goto survive; - } - printk("VM: killing process %s\n", tsk->comm); - if (user_mode(regs)) - do_group_exit(SIGKILL); - goto no_context; + if (!user_mode(regs)) + goto no_context; + pagefault_out_of_memory(); + return; do_sigbus: printk("fault:Do sigbus\n"); -- cgit v1.2.3-59-g8ed1b From 5bac942db3d2c4738df04104240d65a5d1eaec6a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 21 Apr 2010 15:36:49 +0000 Subject: SH: constify multiple DMA related objects and references to them Lists of DMA channels and slaves are not changed, make them constant. Besides, SH7724 channel and slave configuration of both DMA controllers is identical, remove the extra copy of the configuration data. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 6 ++-- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 54 +++++----------------------------- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 6 ++-- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 6 ++-- arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 4 +-- drivers/dma/shdma.c | 12 ++++---- include/linux/sh_dma.h | 9 +++--- 7 files changed, 30 insertions(+), 67 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index dc9b30d086a4..24c6167a7181 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -24,7 +24,7 @@ #include #include -static struct sh_dmae_slave_config sh7722_dmae_slaves[] = { +static const struct sh_dmae_slave_config sh7722_dmae_slaves[] = { { .slave_id = SHDMA_SLAVE_SCIF0_TX, .addr = 0xffe0000c, @@ -78,7 +78,7 @@ static struct sh_dmae_slave_config sh7722_dmae_slaves[] = { }, }; -static struct sh_dmae_channel sh7722_dmae_channels[] = { +static const struct sh_dmae_channel sh7722_dmae_channels[] = { { .offset = 0, .dmars = 0, @@ -106,7 +106,7 @@ static struct sh_dmae_channel sh7722_dmae_channels[] = { } }; -static unsigned int ts_shift[] = TS_SHIFT; +static const unsigned int ts_shift[] = TS_SHIFT; static struct sh_dmae_pdata dma_platform_data = { .slave = sh7722_dmae_slaves, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 8a0a4a99f86b..89fe16d20fdb 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -31,7 +31,7 @@ #include /* DMA */ -static struct sh_dmae_channel sh7724_dmae0_channels[] = { +static const struct sh_dmae_channel sh7724_dmae_channels[] = { { .offset = 0, .dmars = 0, @@ -59,51 +59,11 @@ static struct sh_dmae_channel sh7724_dmae0_channels[] = { } }; -static struct sh_dmae_channel sh7724_dmae1_channels[] = { - { - .offset = 0, - .dmars = 0, - .dmars_bit = 0, - }, { - .offset = 0x10, - .dmars = 0, - .dmars_bit = 8, - }, { - .offset = 0x20, - .dmars = 4, - .dmars_bit = 0, - }, { - .offset = 0x30, - .dmars = 4, - .dmars_bit = 8, - }, { - .offset = 0x50, - .dmars = 8, - .dmars_bit = 0, - }, { - .offset = 0x60, - .dmars = 8, - .dmars_bit = 8, - } -}; - -static unsigned int ts_shift[] = TS_SHIFT; - -static struct sh_dmae_pdata dma0_platform_data = { - .channel = sh7724_dmae0_channels, - .channel_num = ARRAY_SIZE(sh7724_dmae0_channels), - .ts_low_shift = CHCR_TS_LOW_SHIFT, - .ts_low_mask = CHCR_TS_LOW_MASK, - .ts_high_shift = CHCR_TS_HIGH_SHIFT, - .ts_high_mask = CHCR_TS_HIGH_MASK, - .ts_shift = ts_shift, - .ts_shift_num = ARRAY_SIZE(ts_shift), - .dmaor_init = DMAOR_INIT, -}; +static const unsigned int ts_shift[] = TS_SHIFT; -static struct sh_dmae_pdata dma1_platform_data = { - .channel = sh7724_dmae1_channels, - .channel_num = ARRAY_SIZE(sh7724_dmae1_channels), +static struct sh_dmae_pdata dma_platform_data = { + .channel = sh7724_dmae_channels, + .channel_num = ARRAY_SIZE(sh7724_dmae_channels), .ts_low_shift = CHCR_TS_LOW_SHIFT, .ts_low_mask = CHCR_TS_LOW_MASK, .ts_high_shift = CHCR_TS_HIGH_SHIFT, @@ -187,7 +147,7 @@ static struct platform_device dma0_device = { .resource = sh7724_dmae0_resources, .num_resources = ARRAY_SIZE(sh7724_dmae0_resources), .dev = { - .platform_data = &dma0_platform_data, + .platform_data = &dma_platform_data, }, .archdata = { .hwblk_id = HWBLK_DMAC0, @@ -200,7 +160,7 @@ static struct platform_device dma1_device = { .resource = sh7724_dmae1_resources, .num_resources = ARRAY_SIZE(sh7724_dmae1_resources), .dev = { - .platform_data = &dma1_platform_data, + .platform_data = &dma_platform_data, }, .archdata = { .hwblk_id = HWBLK_DMAC1, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 05fc38df1582..b12f537e4dde 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -233,7 +233,7 @@ static struct platform_device rtc_device = { }; /* DMA */ -static struct sh_dmae_channel sh7780_dmae0_channels[] = { +static const struct sh_dmae_channel sh7780_dmae0_channels[] = { { .offset = 0, .dmars = 0, @@ -261,7 +261,7 @@ static struct sh_dmae_channel sh7780_dmae0_channels[] = { } }; -static struct sh_dmae_channel sh7780_dmae1_channels[] = { +static const struct sh_dmae_channel sh7780_dmae1_channels[] = { { .offset = 0, }, { @@ -277,7 +277,7 @@ static struct sh_dmae_channel sh7780_dmae1_channels[] = { } }; -static unsigned int ts_shift[] = TS_SHIFT; +static const unsigned int ts_shift[] = TS_SHIFT; static struct sh_dmae_pdata dma0_platform_data = { .channel = sh7780_dmae0_channels, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 07bb2d4619f8..f3e3ea0ce050 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -275,7 +275,7 @@ static struct platform_device tmu5_device = { }; /* DMA */ -static struct sh_dmae_channel sh7785_dmae0_channels[] = { +static const struct sh_dmae_channel sh7785_dmae0_channels[] = { { .offset = 0, .dmars = 0, @@ -303,7 +303,7 @@ static struct sh_dmae_channel sh7785_dmae0_channels[] = { } }; -static struct sh_dmae_channel sh7785_dmae1_channels[] = { +static const struct sh_dmae_channel sh7785_dmae1_channels[] = { { .offset = 0, }, { @@ -319,7 +319,7 @@ static struct sh_dmae_channel sh7785_dmae1_channels[] = { } }; -static unsigned int ts_shift[] = TS_SHIFT; +static const unsigned int ts_shift[] = TS_SHIFT; static struct sh_dmae_pdata dma0_platform_data = { .channel = sh7785_dmae0_channels, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index d7336036d04d..81657091da46 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -445,7 +445,7 @@ static struct platform_device tmu11_device = { .num_resources = ARRAY_SIZE(tmu11_resources), }; -static struct sh_dmae_channel dmac0_channels[] = { +static const struct sh_dmae_channel dmac0_channels[] = { { .offset = 0, .dmars = 0, @@ -473,7 +473,7 @@ static struct sh_dmae_channel dmac0_channels[] = { } }; -static unsigned int ts_shift[] = TS_SHIFT; +static const unsigned int ts_shift[] = TS_SHIFT; static struct sh_dmae_pdata dma0_platform_data = { .channel = dmac0_channels, diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 7a18b580f626..aab352a63a4a 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -188,7 +188,7 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) struct sh_dmae_device *shdev = container_of(sh_chan->common.device, struct sh_dmae_device, common); struct sh_dmae_pdata *pdata = shdev->pdata; - struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id]; + const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id]; u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16); int shift = chan_pdata->dmars_bit; @@ -264,7 +264,7 @@ static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan) return NULL; } -static struct sh_dmae_slave_config *sh_dmae_find_slave( +static const struct sh_dmae_slave_config *sh_dmae_find_slave( struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *param) { struct dma_device *dma_dev = sh_chan->common.device; @@ -296,7 +296,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) * never runs concurrently with itself or free_chan_resources. */ if (param) { - struct sh_dmae_slave_config *cfg; + const struct sh_dmae_slave_config *cfg; cfg = sh_dmae_find_slave(sh_chan, param); if (!cfg) @@ -557,12 +557,14 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( { struct sh_dmae_slave *param; struct sh_dmae_chan *sh_chan; + dma_addr_t slave_addr; if (!chan) return NULL; sh_chan = to_sh_chan(chan); param = chan->private; + slave_addr = param->config->addr; /* Someone calling slave DMA on a public channel? */ if (!param || !sg_len) { @@ -575,7 +577,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( * if (param != NULL), this is a successfully requested slave channel, * therefore param->config != NULL too. */ - return sh_dmae_prep_sg(sh_chan, sgl, sg_len, ¶m->config->addr, + return sh_dmae_prep_sg(sh_chan, sgl, sg_len, &slave_addr, direction, flags); } @@ -856,7 +858,7 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id, int irq, unsigned long flags) { int err; - struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id]; + const struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id]; struct platform_device *pdev = to_platform_device(shdev->common.dev); struct sh_dmae_chan *new_sh_chan; diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h index cdaaff424211..b08cd4efa15c 100644 --- a/include/linux/sh_dma.h +++ b/include/linux/sh_dma.h @@ -17,7 +17,7 @@ struct sh_dmae_slave { unsigned int slave_id; /* Set by the platform */ struct device *dma_dev; /* Set by the platform */ - struct sh_dmae_slave_config *config; /* Set by the driver */ + const struct sh_dmae_slave_config *config; /* Set by the driver */ }; struct sh_dmae_regs { @@ -36,6 +36,7 @@ struct sh_desc { int chunks; int mark; }; + struct sh_dmae_slave_config { unsigned int slave_id; dma_addr_t addr; @@ -50,15 +51,15 @@ struct sh_dmae_channel { }; struct sh_dmae_pdata { - struct sh_dmae_slave_config *slave; + const struct sh_dmae_slave_config *slave; int slave_num; - struct sh_dmae_channel *channel; + const struct sh_dmae_channel *channel; int channel_num; unsigned int ts_low_shift; unsigned int ts_low_mask; unsigned int ts_high_shift; unsigned int ts_high_mask; - unsigned int *ts_shift; + const unsigned int *ts_shift; int ts_shift_num; u16 dmaor_init; }; -- cgit v1.2.3-59-g8ed1b From 364b97d9e2fec32b7c125f67e5a9e5f1cd0e6a37 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 16:15:17 +0900 Subject: sh: Kill off dangling goto labels from oom-killer rework. Signed-off-by: Paul Mundt --- arch/sh/mm/fault_32.c | 1 - arch/sh/mm/tlbflush_64.c | 1 - 2 files changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index 93c3447ed40a..d4c34d757f0d 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c @@ -200,7 +200,6 @@ good_area: * make sure we exit gracefully rather than endlessly redo * the fault. */ -survive: fault = handle_mm_fault(mm, vma, address, writeaccess ? FAULT_FLAG_WRITE : 0); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c index 25bd64c0977c..03db41cc1268 100644 --- a/arch/sh/mm/tlbflush_64.c +++ b/arch/sh/mm/tlbflush_64.c @@ -189,7 +189,6 @@ good_area: * make sure we exit gracefully rather than endlessly redo * the fault. */ -survive: fault = handle_mm_fault(mm, vma, address, writeaccess ? FAULT_FLAG_WRITE : 0); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) -- cgit v1.2.3-59-g8ed1b From e60692b9347d17774cdad00ae2b9afd3dc5444af Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 17:45:34 +0900 Subject: sh: mach-sdk7786: update defconfig for compressed kernel image. Now that compressed image loading is possible for sdk7786, drop the vmlinux.bin default image target and update the defconfig accordingly. Signed-off-by: Paul Mundt --- arch/sh/Makefile | 1 - arch/sh/configs/sdk7786_defconfig | 636 ++++++++++++++++++++++++++------------ 2 files changed, 444 insertions(+), 193 deletions(-) (limited to 'arch') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 588579ac2e35..307b3a4a790b 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -83,7 +83,6 @@ defaultimage-$(CONFIG_SH_AP325RXA) := uImage defaultimage-$(CONFIG_SH_7724_SOLUTION_ENGINE) := uImage defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE) := vmlinux defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE) := vmlinux -defaultimage-$(CONFIG_SH_SDK7786) := vmlinux.bin # Set some sensible Kbuild defaults KBUILD_IMAGE := $(defaultimage-y) diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index 9b331eab968e..740ada659441 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc7 -# Tue Feb 9 15:27:06 2010 +# Linux kernel version: 2.6.34-rc5 +# Mon Apr 26 16:52:58 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -18,6 +18,8 @@ CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_LOCKBREAK=y # CONFIG_ARCH_SUSPEND_POSSIBLE is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_SYS_SUPPORTS_HUGETLBFS=y @@ -27,7 +29,6 @@ CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_NO_VIRT_TO_BUS=y @@ -35,6 +36,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_COHERENT=y # CONFIG_DMA_NONCOHERENT is not set +# CONFIG_NEED_DMA_MAP_STATE is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -42,7 +44,6 @@ CONFIG_CONSTRUCTORS=y # General setup # CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" @@ -51,25 +52,27 @@ CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_LZO=y -CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_GZIP is not set # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_LZO is not set +CONFIG_KERNEL_LZO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_BSD_PROCESS_ACCT_V3=y # CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_TREE=y # # RCU Subsystem # -CONFIG_TREE_RCU=y -# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TREE_RCU is not set +CONFIG_TREE_PREEMPT_RCU=y # CONFIG_TINY_RCU is not set CONFIG_RCU_TRACE=y CONFIG_RCU_FANOUT=32 @@ -77,32 +80,36 @@ CONFIG_RCU_FANOUT=32 CONFIG_TREE_RCU_TRACE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set +CONFIG_LOG_BUF_SHIFT=17 CONFIG_CGROUPS=y -# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_DEBUG=y CONFIG_CGROUP_NS=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y -# CONFIG_CPUSETS is not set +CONFIG_CPUSETS=y +# CONFIG_PROC_PID_CPUSET is not set CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y CONFIG_CGROUP_MEM_RES_CTLR=y -# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set +CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y CONFIG_MM_OWNER=y # CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_RELAY is not set +CONFIG_RELAY=y CONFIG_NAMESPACES=y CONFIG_UTS_NS=y CONFIG_IPC_NS=y CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y -# CONFIG_BLK_DEV_INITRD is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_LZO=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -131,7 +138,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y @@ -142,13 +148,15 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y -# CONFIG_OPROFILE is not set +CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set +CONFIG_KPROBES=y +CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y CONFIG_HAVE_HW_BREAKPOINT=y @@ -157,7 +165,8 @@ CONFIG_HAVE_HW_BREAKPOINT=y # GCOV-based kernel profiling # # CONFIG_GCOV_KERNEL is not set -# CONFIG_SLOW_WORK is not set +CONFIG_SLOW_WORK=y +CONFIG_SLOW_WORK_DEBUG=y CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -168,9 +177,10 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y -# CONFIG_LBDAF is not set -# CONFIG_BLK_DEV_BSG is not set +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y # CONFIG_BLK_DEV_INTEGRITY is not set CONFIG_BLK_CGROUP=y # CONFIG_DEBUG_BLK_CGROUP is not set @@ -215,7 +225,7 @@ CONFIG_DEFAULT_IOSCHED="cfq" # CONFIG_INLINE_WRITE_UNLOCK_BH is not set # CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_FREEZER=y # @@ -272,11 +282,10 @@ CONFIG_MEMORY_SIZE=0x20000000 # CONFIG_29BIT is not set CONFIG_32BIT=y CONFIG_PMB=y -# CONFIG_PMB_LEGACY is not set CONFIG_X2TLB=y CONFIG_VSYSCALL=y -# CONFIG_NUMA is not set -CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_NUMA=y +CONFIG_NODES_SHIFT=1 CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 @@ -286,21 +295,23 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_MEMORY_PROBE=y CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_HUGETLB_PAGE_SIZE_64K is not set # CONFIG_HUGETLB_PAGE_SIZE_256K is not set -CONFIG_HUGETLB_PAGE_SIZE_1MB=y +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set -# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +CONFIG_HUGETLB_PAGE_SIZE_64MB=y # CONFIG_HUGETLB_PAGE_SIZE_512MB is not set CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_FLATMEM_MANUAL is not set # CONFIG_DISCONTIGMEM_MANUAL is not set CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y +CONFIG_NEED_MULTIPLE_NODES=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_STATIC=y CONFIG_MEMORY_HOTPLUG=y @@ -313,6 +324,7 @@ CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=1 CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_SCHED_MC=y # # Cache configuration @@ -328,6 +340,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y CONFIG_SH_STORE_QUEUES=y +CONFIG_SPECULATIVE_EXECUTION=y CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEAEX=y @@ -372,7 +385,10 @@ CONFIG_SH_CPU_FREQ=y # # DMA support # -# CONFIG_SH_DMA is not set +CONFIG_SH_DMA=y +# CONFIG_SH_DMA_API is not set +CONFIG_NR_ONCHIP_DMA_CHANNELS=6 +# CONFIG_NR_DMA_CHANNELS_BOOL is not set # # Companion Chips @@ -388,19 +404,21 @@ CONFIG_HEARTBEAT=y # Kernel features # # CONFIG_HZ_100 is not set -CONFIG_HZ_250=y +# CONFIG_HZ_250 is not set # CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 +CONFIG_HZ_1000=y +CONFIG_HZ=1000 CONFIG_SCHED_HRTICK=y CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set CONFIG_SECCOMP=y -# CONFIG_SMP is not set +CONFIG_SMP=y +CONFIG_NR_CPUS=2 # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y -CONFIG_GUSA=y +CONFIG_INTC_USERIMASK=y +CONFIG_INTC_BALANCING=y # # Boot options @@ -410,7 +428,7 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set -CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200 root=/dev/sda1 nmi_debug=state,debounce rootdelay=10" +CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200 root=/dev/sda1 nmi_debug=state,debounce rootdelay=5 pmb=iomap ignore_loglevel" # # Bus options @@ -424,8 +442,7 @@ CONFIG_PCIEAER_INJECT=y CONFIG_PCIEASPM=y CONFIG_PCIEASPM_DEBUG=y # CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCI_LEGACY is not set -CONFIG_PCI_DEBUG=y +# CONFIG_PCI_DEBUG is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set @@ -435,7 +452,7 @@ CONFIG_PCI_DEBUG=y # Executable file formats # CONFIG_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y # CONFIG_HAVE_AOUT is not set CONFIG_BINFMT_MISC=y @@ -444,9 +461,11 @@ CONFIG_BINFMT_MISC=y # CONFIG_PM=y CONFIG_PM_DEBUG=y +# CONFIG_PM_ADVANCED_DEBUG is not set CONFIG_PM_VERBOSE=y # CONFIG_HIBERNATION is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y @@ -456,7 +475,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -520,19 +538,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NET_TCPPROBE is not set # CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -# CONFIG_LIB80211 is not set - -# -# CFG80211 needs to be enabled for MAC80211 -# +# CONFIG_WIRELESS is not set # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -553,14 +566,118 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +CONFIG_FTL=y +CONFIG_NFTL=y +# CONFIG_NFTL_RW is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +CONFIG_MTD_OOPS=m + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +CONFIG_MTD_PLATRAM=y + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_PHRAM=y +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_PLATFORM=y +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_SH_FLCTL=m +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +CONFIG_MTD_UBI_GLUEBI=m + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y # # DRBD disabled because PROC_FS, INET or CONNECTOR not selected @@ -575,34 +692,63 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set -CONFIG_MISC_DEVICES=y -# CONFIG_AD525X_DPOT is not set -# CONFIG_PHANTOM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -# CONFIG_ISL29003 is not set -# CONFIG_DS1682 is not set -# CONFIG_TI_DAC7512 is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_AT25 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_CB710_CORE is not set +# CONFIG_MISC_DEVICES is not set CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set +CONFIG_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_ATAPI=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_IDE_GD=y +CONFIG_IDE_GD_ATA=y +# CONFIG_IDE_GD_ATAPI is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +CONFIG_BLK_DEV_PLATFORM=y + +# +# PCI IDE chipsets support +# +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8172 is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set +# CONFIG_BLK_DEV_IDEDMA is not set # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -616,11 +762,12 @@ CONFIG_SCSI_PROC_FS=y CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set # CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set CONFIG_SCSI_WAIT_SCAN=m @@ -631,52 +778,10 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set # CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_BNX2_ISCSI is not set -# CONFIG_BE2ISCSI is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_HPSA is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_3W_SAS is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_MPT2SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_FCOE is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_PMCRAID is not set -# CONFIG_SCSI_PM8001 is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y @@ -719,6 +824,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -743,7 +849,17 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_WINBOND is not set CONFIG_PATA_PLATFORM=y # CONFIG_PATA_SCH is not set -# CONFIG_MD is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_DM=y +CONFIG_DM_DEBUG=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_UEVENT=y # CONFIG_FUSION is not set # @@ -820,11 +936,7 @@ CONFIG_SMSC911X=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set -CONFIG_WLAN=y -# CONFIG_ATMEL is not set -# CONFIG_PRISM54 is not set -# CONFIG_USB_ZD1201 is not set -# CONFIG_HOSTAP is not set +# CONFIG_WLAN is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -838,6 +950,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -923,7 +1036,7 @@ CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_NOZOMI is not set @@ -940,9 +1053,11 @@ CONFIG_DEVKMEM=y CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_SH_SCI_DMA=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -986,8 +1101,10 @@ CONFIG_I2C_HELPER_AUTO=y # # CONFIG_I2C_DESIGNWARE is not set # CONFIG_I2C_OCORES is not set +CONFIG_I2C_SDK7786=y # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -1001,15 +1118,9 @@ CONFIG_I2C_HELPER_AUTO=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -1045,7 +1156,8 @@ CONFIG_WATCHDOG=y # # CONFIG_SOFT_WATCHDOG is not set # CONFIG_ALIM7101_WDT is not set -# CONFIG_SH_WDT is not set +CONFIG_SH_WDT=y +# CONFIG_SH_WDT_MMAP is not set # # PCI-based Watchdog Cards @@ -1068,6 +1180,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set @@ -1075,15 +1188,17 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_AB4500_CORE is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1091,6 +1206,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m @@ -1121,6 +1237,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set # CONFIG_HID_A4TECH is not set # CONFIG_HID_APPLE is not set # CONFIG_HID_BELKIN is not set @@ -1135,12 +1252,16 @@ CONFIG_USB_HID=y # CONFIG_HID_KENSINGTON is not set # CONFIG_HID_LOGITECH is not set # CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MOSART is not set # CONFIG_HID_MONTEREY is not set # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set # CONFIG_HID_PANTHERLORD is not set # CONFIG_HID_PETALYNX is not set +# CONFIG_HID_QUANTA is not set # CONFIG_HID_SAMSUNG is not set # CONFIG_HID_SONY is not set +# CONFIG_HID_STANTUM is not set # CONFIG_HID_SUNPLUS is not set # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1241,7 +1362,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1253,7 +1373,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set @@ -1291,6 +1410,7 @@ CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set # CONFIG_USB_G_MULTI is not set # @@ -1370,43 +1490,102 @@ CONFIG_RTC_DRV_MAX6900=y # CONFIG_RTC_DRV_SH=y # CONFIG_RTC_DRV_GENERIC is not set -# CONFIG_DMADEVICES is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_SH_DMAE=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set # CONFIG_AUXDISPLAY is not set CONFIG_UIO=m # CONFIG_UIO_CIF is not set -# CONFIG_UIO_PDRV is not set -# CONFIG_UIO_PDRV_GENIRQ is not set -# CONFIG_UIO_SMX is not set +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m # CONFIG_UIO_AEC is not set # CONFIG_UIO_SERCOS3 is not set -# CONFIG_UIO_PCI_GENERIC is not set +CONFIG_UIO_PCI_GENERIC=m +# CONFIG_UIO_NETX is not set # # TI VLYNQ # -# CONFIG_STAGING is not set +CONFIG_STAGING=y +# CONFIG_STAGING_EXCLUDE_BUILD is not set +# CONFIG_USB_IP_COMMON is not set +# CONFIG_ECHO is not set +# CONFIG_POCH is not set +# CONFIG_COMEDI is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_TRANZPORT is not set + +# +# Qualcomm MSM Camera And Video +# + +# +# Camera Sensor Selection +# +# CONFIG_INPUT_GPIO is not set +# CONFIG_POHMELFS is not set +# CONFIG_IDE_PHISON is not set +# CONFIG_VME_BUS is not set + +# +# RAR Register Driver +# +# CONFIG_RAR_REGISTER is not set +# CONFIG_IIO is not set +CONFIG_RAMZSWAP=m +CONFIG_RAMZSWAP_STATS=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_STRIP is not set +# CONFIG_DT3155 is not set +# CONFIG_CRYSTALHD is not set # # File systems # CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=y +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set +CONFIG_BTRFS_FS=y +# CONFIG_BTRFS_FS_POSIX_ACL is not set # CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y @@ -1415,19 +1594,30 @@ CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=y +CONFIG_CUSE=m # # Caches # -# CONFIG_FSCACHE is not set +CONFIG_FSCACHE=m +# CONFIG_FSCACHE_STATS is not set +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set # # CD-ROM/DVD Filesystems # -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y # # DOS/FAT/NT Filesystems @@ -1448,7 +1638,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y -# CONFIG_CONFIGFS_FS is not set +CONFIG_CONFIGFS_FS=y CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set @@ -1457,30 +1647,60 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_LOGFS=m +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1493,7 +1713,7 @@ CONFIG_SUNRPC=y CONFIG_MSDOS_PARTITION=y CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set +CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set @@ -1508,16 +1728,16 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_865 is not set # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=y +CONFIG_NLS_CODEPAGE_949=m # CONFIG_NLS_CODEPAGE_874 is not set # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -1527,10 +1747,10 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_ISO8859_9 is not set # CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set +CONFIG_NLS_ISO8859_15=m # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set +CONFIG_NLS_UTF8=m # CONFIG_DLM is not set # @@ -1538,7 +1758,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y -CONFIG_ENABLE_WARN_DEPRECATED=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y @@ -1547,7 +1767,7 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_SHIRQ=y +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 @@ -1573,24 +1793,27 @@ CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set -CONFIG_DEBUG_VM=y +# CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set +CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_DEBUG_CREDENTIALS is not set CONFIG_FRAME_POINTER=y # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_RCU_CPU_STALL_DETECTOR=y +# CONFIG_RCU_CPU_STALL_VERBOSE is not set +# CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_PAGE_POISONING is not set CONFIG_NOP_TRACER=y +CONFIG_HAVE_FTRACE_NMI_ENTER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1598,16 +1821,19 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y +CONFIG_FTRACE_NMI_ENTER=y CONFIG_EVENT_TRACING=y CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y -# CONFIG_FUNCTION_TRACER is not set +CONFIG_FUNCTION_TRACER=y +# CONFIG_FUNCTION_GRAPH_TRACER is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set # CONFIG_FTRACE_SYSCALLS is not set # CONFIG_BOOT_TRACER is not set CONFIG_BRANCH_PROFILE_NONE=y @@ -1619,9 +1845,13 @@ CONFIG_KSYM_TRACER=y # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set # CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_DYNAMIC_FTRACE=y +# CONFIG_FUNCTION_PROFILER is not set +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_RING_BUFFER_BENCHMARK is not set # CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_DMA_API_DEBUG is not set +CONFIG_DMA_API_DEBUG=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1632,6 +1862,7 @@ CONFIG_DEBUG_STACK_USAGE=y CONFIG_DUMP_CODE=y CONFIG_DWARF_UNWINDER=y # CONFIG_SH_NO_BSS_INIT is not set +CONFIG_MCOUNT=y # # Security options @@ -1649,10 +1880,21 @@ CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_MANAGER2 is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set # CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_TEST is not set @@ -1667,7 +1909,7 @@ CONFIG_CRYPTO=y # # Block modes # -# CONFIG_CRYPTO_CBC is not set +CONFIG_CRYPTO_CBC=y # CONFIG_CRYPTO_CTR is not set # CONFIG_CRYPTO_CTS is not set # CONFIG_CRYPTO_ECB is not set @@ -1685,10 +1927,10 @@ CONFIG_CRYPTO=y # # Digest # -# CONFIG_CRYPTO_CRC32C is not set +CONFIG_CRYPTO_CRC32C=y # CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set +CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_RMD128 is not set # CONFIG_CRYPTO_RMD160 is not set @@ -1710,7 +1952,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set +CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_SALSA20 is not set @@ -1722,9 +1964,9 @@ CONFIG_CRYPTO=y # # Compression # -# CONFIG_CRYPTO_DEFLATE is not set +CONFIG_CRYPTO_DEFLATE=m # CONFIG_CRYPTO_ZLIB is not set -# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_LZO=m # # Random Number Generation @@ -1740,12 +1982,22 @@ CONFIG_BINARY_PRINTF=y CONFIG_BITREVERSE=y CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set +CONFIG_CRC16=y # CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set +CONFIG_LIBCRC32C=y +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_BTREE=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -- cgit v1.2.3-59-g8ed1b From 9e8c5be8b76b188ec5bc95b378cf67aaeba1f695 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 18:20:29 +0900 Subject: sh: Flag present CPUs hotpluggable in topology registration. When registering CPUs in the topology initialization ensure that all of the present CPUs are flagged as hotpluggable. Signed-off-by: Paul Mundt --- arch/sh/kernel/topology.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/topology.c b/arch/sh/kernel/topology.c index 9b0b633b6c92..948fdb656933 100644 --- a/arch/sh/kernel/topology.c +++ b/arch/sh/kernel/topology.c @@ -52,7 +52,11 @@ static int __init topology_init(void) #endif for_each_present_cpu(i) { - ret = register_cpu(&per_cpu(cpu_devices, i), i); + struct cpu *c = &per_cpu(cpu_devices, i); + + c->hotpluggable = 1; + + ret = register_cpu(c, i); if (unlikely(ret)) printk(KERN_WARNING "%s: register_cpu %d failed (%d)\n", __func__, i, ret); -- cgit v1.2.3-59-g8ed1b From c9f4a3f53b5d61f86eae3512abdf948878ca3498 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 18:35:44 +0900 Subject: sh: arch/sh/kernel/setup.c needs asm/smp.h. With the platform ops migration, the definitions still need to be included in the CONFIG_SMP=n case, so make the asm/smp.h include explicit. Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 29155384d5a8..14735d5ede52 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -39,6 +39,7 @@ #include #include #include +#include #include /* -- cgit v1.2.3-59-g8ed1b From f0ccf2770f523bd4fc436886a38e499f9ec95c0e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 18:39:50 +0900 Subject: sh: convert online CPU map twiddling to cpumask. This converts from cpu_set() for the online map to set_cpu_online(). The two online map modifiers were the last remaining manual map manipulation bits, with this in place everything now goes through cpumask. Signed-off-by: Paul Mundt --- arch/sh/kernel/idle.c | 2 +- arch/sh/kernel/smp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 273f890b17ae..204005329fe1 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -133,7 +133,7 @@ static void do_nothing(void *unused) void stop_this_cpu(void *unused) { local_irq_disable(); - cpu_clear(smp_processor_id(), cpu_online_map); + set_cpu_online(smp_processor_id(), false); for (;;) cpu_sleep(); diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 2f348fda0159..cc87830ace7f 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -102,7 +102,7 @@ asmlinkage void __cpuinit start_secondary(void) smp_store_cpu_info(cpu); - cpu_set(cpu, cpu_online_map); + set_cpu_online(cpu, true); cpu_idle(); } -- cgit v1.2.3-59-g8ed1b From 7acb59eb4b5eee113eb74eeafd1e6536171eeced Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 18:44:04 +0900 Subject: sh: Make sure all SH-X3 cores are populated in the present CPU map. This iterates over the maximum number of CPUs we plan to support and makes sure they're all set in the present CPU map. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/smp-shx3.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c index 5c5d50ccbfcd..dd245e68aa2e 100644 --- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c @@ -74,6 +74,9 @@ static void shx3_prepare_cpus(unsigned int max_cpus) for (i = 0; i < SMP_MSG_NR; i++) request_irq(104 + i, ipi_interrupt_handler, IRQF_DISABLED | IRQF_PERCPU, "IPI", (void *)(long)i); + + for (i = 0; i < max_cpus; i++) + set_cpu_present(i, true); } static void shx3_start_cpu(unsigned int cpu, unsigned long entry_point) -- cgit v1.2.3-59-g8ed1b From 9715b8c7d55912fb6f5dd9b1c084d8eefcd0d848 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 18:49:58 +0900 Subject: sh: provide percpu CPU states for hotplug notifiers. This provides percpu CPU states in preparation for CPU hotplug and the associated notifier chains. Signed-off-by: Paul Mundt --- arch/sh/include/asm/smp.h | 3 +++ arch/sh/kernel/smp.c | 14 ++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h index 7f13d46ec8d7..da5135b2579e 100644 --- a/arch/sh/include/asm/smp.h +++ b/arch/sh/include/asm/smp.h @@ -10,6 +10,7 @@ #include #include #include +#include #define raw_smp_processor_id() (current_thread_info()->cpu) @@ -30,6 +31,8 @@ enum { SMP_MSG_NR, /* must be last */ }; +DECLARE_PER_CPU(int, cpu_state); + void smp_message_recv(unsigned int msg); void smp_timer_broadcast(const struct cpumask *mask); diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index cc87830ace7f..4d27597c5da8 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -33,6 +33,9 @@ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ struct plat_smp_ops *mp_ops = NULL; +/* State of each CPU */ +DEFINE_PER_CPU(int, cpu_state) = { 0 }; + void __cpuinit register_smp_ops(struct plat_smp_ops *ops) { if (mp_ops) @@ -72,11 +75,13 @@ void __devinit smp_prepare_boot_cpu(void) set_cpu_online(cpu, true); set_cpu_possible(cpu, true); + + per_cpu(cpu_state, cpu) = CPU_ONLINE; } asmlinkage void __cpuinit start_secondary(void) { - unsigned int cpu; + unsigned int cpu = smp_processor_id(); struct mm_struct *mm = &init_mm; enable_mmu(); @@ -90,12 +95,10 @@ asmlinkage void __cpuinit start_secondary(void) preempt_disable(); - notify_cpu_starting(smp_processor_id()); + notify_cpu_starting(cpu); local_irq_enable(); - cpu = smp_processor_id(); - /* Enable local timers */ local_timer_setup(cpu); calibrate_delay(); @@ -103,6 +106,7 @@ asmlinkage void __cpuinit start_secondary(void) smp_store_cpu_info(cpu); set_cpu_online(cpu, true); + per_cpu(cpu_state, cpu) = CPU_ONLINE; cpu_idle(); } @@ -127,6 +131,8 @@ int __cpuinit __cpu_up(unsigned int cpu) return PTR_ERR(tsk); } + per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; + /* Fill in data in head.S for secondary cpus */ stack_start.sp = tsk->thread.sp; stack_start.thread_info = tsk->stack; -- cgit v1.2.3-59-g8ed1b From c4b9f9a96eb93994ac42f4ea00bb94b44fa4d500 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Sat, 24 Apr 2010 10:44:11 +0200 Subject: Powerpc: wii: Fix typo in comment discontiguous => discontinuous coealesce => coalesce Signed-off-by: Thomas Weber Signed-off-by: Jiri Kosina --- arch/powerpc/platforms/embedded6xx/wii.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c index 57e5b608fa1a..174a04ac4806 100644 --- a/arch/powerpc/platforms/embedded6xx/wii.c +++ b/arch/powerpc/platforms/embedded6xx/wii.c @@ -69,10 +69,10 @@ void __init wii_memory_fixups(void) /* * This is part of a workaround to allow the use of two - * discontiguous RAM ranges on the Wii, even if this is + * discontinuous RAM ranges on the Wii, even if this is * currently unsupported on 32-bit PowerPC Linux. * - * We coealesce the two memory ranges of the Wii into a + * We coalesce the two memory ranges of the Wii into a * single range, then create a reservation for the "hole" * between both ranges. */ -- cgit v1.2.3-59-g8ed1b From 1cfa1e8f2c824b131612c9a70b48433998237331 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 18:55:01 +0900 Subject: sh: flag smp_store_cpu_info() __cpuinit. smp_store_cpu_info() is presently flagged as __init, but is called by start_secondary() which is __cpuinit, fix it up. Signed-off-by: Paul Mundt --- arch/sh/kernel/smp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 4d27597c5da8..3711a76a18e0 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -44,7 +44,7 @@ void __cpuinit register_smp_ops(struct plat_smp_ops *ops) mp_ops = ops; } -static inline void __init smp_store_cpu_info(unsigned int cpu) +static inline void __cpuinit smp_store_cpu_info(unsigned int cpu) { struct sh_cpuinfo *c = cpu_data + cpu; @@ -66,7 +66,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) #endif } -void __devinit smp_prepare_boot_cpu(void) +void __init smp_prepare_boot_cpu(void) { unsigned int cpu = smp_processor_id(); -- cgit v1.2.3-59-g8ed1b From 8db2bc4559639680a94d4492ae4b7ce71298a74f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 18:59:47 +0900 Subject: sh: cache secondary CPUs idle loop. This provides a cache of the secondary CPUs idle loop for the cases where hotplug simply enters a low power state instead of resetting or powering off the core. Signed-off-by: Paul Mundt --- arch/sh/include/asm/processor.h | 4 ++++ arch/sh/kernel/smp.c | 13 +++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 26b3f026eec9..0a58cb25a658 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -85,6 +85,10 @@ struct sh_cpuinfo { struct tlb_info itlb; struct tlb_info dtlb; +#ifdef CONFIG_SMP + struct task_struct *idle; +#endif + unsigned long flags; } __attribute__ ((aligned(L1_CACHE_BYTES))); diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 3711a76a18e0..21e7f8a9f3e4 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -125,10 +125,15 @@ int __cpuinit __cpu_up(unsigned int cpu) struct task_struct *tsk; unsigned long timeout; - tsk = fork_idle(cpu); - if (IS_ERR(tsk)) { - printk(KERN_ERR "Failed forking idle task for cpu %d\n", cpu); - return PTR_ERR(tsk); + tsk = cpu_data[cpu].idle; + if (!tsk) { + tsk = fork_idle(cpu); + if (IS_ERR(tsk)) { + pr_err("Failed forking idle task for cpu %d\n", cpu); + return PTR_ERR(tsk); + } + + cpu_data[cpu].idle = tsk; } per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; -- cgit v1.2.3-59-g8ed1b From 763142d1efb56effe614d71185781796c4b83c78 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 19:08:55 +0900 Subject: sh: CPU hotplug support. This adds preliminary support for CPU hotplug for SH SMP systems. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 7 +++ arch/sh/include/asm/irq.h | 3 ++ arch/sh/include/asm/smp-ops.h | 16 ++++++- arch/sh/include/asm/smp.h | 19 +++++++- arch/sh/kernel/idle.c | 6 ++- arch/sh/kernel/irq.c | 42 +++++++++++++++++ arch/sh/kernel/localtimer.c | 4 ++ arch/sh/kernel/smp.c | 103 +++++++++++++++++++++++++++++++++++++++++- 8 files changed, 194 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index ba86bfba95ac..d73bd4db5e84 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -706,6 +706,13 @@ config NR_CPUS This is purely to save memory - each supported CPU adds approximately eight kilobytes to the kernel image. +config HOTPLUG_CPU + bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" + depends on SMP && HOTPLUG && EXPERIMENTAL + help + Say Y here to experiment with turning CPUs off and on. CPUs + can be controlled through /sys/devices/system/cpu. + source "kernel/Kconfig.preempt" config GUSA diff --git a/arch/sh/include/asm/irq.h b/arch/sh/include/asm/irq.h index 99c593b3a827..02c2f0102cfa 100644 --- a/arch/sh/include/asm/irq.h +++ b/arch/sh/include/asm/irq.h @@ -1,6 +1,7 @@ #ifndef __ASM_SH_IRQ_H #define __ASM_SH_IRQ_H +#include #include /* @@ -50,6 +51,8 @@ static inline int generic_irq_demux(int irq) #define irq_demux(irq) sh_mv.mv_irq_demux(irq) void init_IRQ(void); +void migrate_irqs(void); + asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs); #ifdef CONFIG_IRQSTACKS diff --git a/arch/sh/include/asm/smp-ops.h b/arch/sh/include/asm/smp-ops.h index 0581b2a4c8ce..c590f76856f1 100644 --- a/arch/sh/include/asm/smp-ops.h +++ b/arch/sh/include/asm/smp-ops.h @@ -7,20 +7,27 @@ struct plat_smp_ops { void (*prepare_cpus)(unsigned int max_cpus); void (*start_cpu)(unsigned int cpu, unsigned long entry_point); void (*send_ipi)(unsigned int cpu, unsigned int message); + int (*cpu_disable)(unsigned int cpu); + void (*cpu_die)(unsigned int cpu); + void (*play_dead)(void); }; +extern struct plat_smp_ops *mp_ops; extern struct plat_smp_ops shx3_smp_ops; #ifdef CONFIG_SMP static inline void plat_smp_setup(void) { - extern struct plat_smp_ops *mp_ops; /* private */ - BUG_ON(!mp_ops); mp_ops->smp_setup(); } +static inline void play_dead(void) +{ + mp_ops->play_dead(); +} + extern void register_smp_ops(struct plat_smp_ops *ops); #else @@ -34,6 +41,11 @@ static inline void register_smp_ops(struct plat_smp_ops *ops) { } +static inline void play_dead(void) +{ + BUG(); +} + #endif /* CONFIG_SMP */ #endif /* __ASM_SH_SMP_OPS_H */ diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h index da5135b2579e..9070d943ddde 100644 --- a/arch/sh/include/asm/smp.h +++ b/arch/sh/include/asm/smp.h @@ -38,9 +38,26 @@ void smp_timer_broadcast(const struct cpumask *mask); void local_timer_interrupt(void); void local_timer_setup(unsigned int cpu); +void local_timer_stop(unsigned int cpu); void arch_send_call_function_single_ipi(int cpu); -extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); +void arch_send_call_function_ipi_mask(const struct cpumask *mask); + +void native_play_dead(void); +void native_cpu_die(unsigned int cpu); +int native_cpu_disable(unsigned int cpu); + +#ifdef CONFIG_HOTPLUG_CPU +void play_dead_common(void); +extern int __cpu_disable(void); + +static inline void __cpu_die(unsigned int cpu) +{ + extern struct plat_smp_ops *mp_ops; /* private */ + + mp_ops->cpu_die(cpu); +} +#endif static inline int hard_smp_processor_id(void) { diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 204005329fe1..425d604e3a28 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -19,6 +19,7 @@ #include #include #include +#include void (*pm_idle)(void) = NULL; @@ -89,10 +90,13 @@ void cpu_idle(void) while (1) { tick_nohz_stop_sched_tick(1); - while (!need_resched() && cpu_online(cpu)) { + while (!need_resched()) { check_pgt_cache(); rmb(); + if (cpu_is_offline(cpu)) + play_dead(); + local_irq_disable(); /* Don't trace irqs off for idle */ stop_critical_timings(); diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index f6a9319c28e2..257de1f0692b 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -292,3 +293,44 @@ int __init arch_probe_nr_irqs(void) return 0; } #endif + +#ifdef CONFIG_HOTPLUG_CPU +static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) +{ + printk(KERN_INFO "IRQ%u: moving from cpu%u to cpu%u\n", + irq, desc->node, cpu); + + raw_spin_lock_irq(&desc->lock); + desc->chip->set_affinity(irq, cpumask_of(cpu)); + raw_spin_unlock_irq(&desc->lock); +} + +/* + * The CPU has been marked offline. Migrate IRQs off this CPU. If + * the affinity settings do not allow other CPUs, force them onto any + * available CPU. + */ +void migrate_irqs(void) +{ + struct irq_desc *desc; + unsigned int irq, cpu = smp_processor_id(); + + for_each_irq_desc(irq, desc) { + if (desc->node == cpu) { + unsigned int newcpu = cpumask_any_and(desc->affinity, + cpu_online_mask); + if (newcpu >= nr_cpu_ids) { + if (printk_ratelimit()) + printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n", + irq, cpu); + + cpumask_setall(desc->affinity); + newcpu = cpumask_any_and(desc->affinity, + cpu_online_mask); + } + + route_irq(desc, irq, newcpu); + } + } +} +#endif diff --git a/arch/sh/kernel/localtimer.c b/arch/sh/kernel/localtimer.c index 865a2f1029b1..8bfc6dfa8b94 100644 --- a/arch/sh/kernel/localtimer.c +++ b/arch/sh/kernel/localtimer.c @@ -60,3 +60,7 @@ void local_timer_setup(unsigned int cpu) clockevents_register_device(clk); } + +void local_timer_stop(unsigned int cpu) +{ +} diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 21e7f8a9f3e4..86cd6f94b53b 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -79,6 +79,105 @@ void __init smp_prepare_boot_cpu(void) per_cpu(cpu_state, cpu) = CPU_ONLINE; } +#ifdef CONFIG_HOTPLUG_CPU +void native_cpu_die(unsigned int cpu) +{ + unsigned int i; + + for (i = 0; i < 10; i++) { + smp_rmb(); + if (per_cpu(cpu_state, cpu) == CPU_DEAD) { + if (system_state == SYSTEM_RUNNING) + pr_info("CPU %u is now offline\n", cpu); + + return; + } + + msleep(100); + } + + pr_err("CPU %u didn't die...\n", cpu); +} + +int native_cpu_disable(unsigned int cpu) +{ + return cpu == 0 ? -EPERM : 0; +} + +void play_dead_common(void) +{ + idle_task_exit(); + irq_ctx_exit(raw_smp_processor_id()); + mb(); + + __get_cpu_var(cpu_state) = CPU_DEAD; + local_irq_disable(); +} + +void native_play_dead(void) +{ + play_dead_common(); +} + +int __cpu_disable(void) +{ + unsigned int cpu = smp_processor_id(); + struct task_struct *p; + int ret; + + ret = mp_ops->cpu_disable(cpu); + if (ret) + return ret; + + /* + * Take this CPU offline. Once we clear this, we can't return, + * and we must not schedule until we're ready to give up the cpu. + */ + set_cpu_online(cpu, false); + + /* + * OK - migrate IRQs away from this CPU + */ + migrate_irqs(); + + /* + * Stop the local timer for this CPU. + */ + local_timer_stop(cpu); + + /* + * Flush user cache and TLB mappings, and then remove this CPU + * from the vm mask set of all processes. + */ + flush_cache_all(); + local_flush_tlb_all(); + + read_lock(&tasklist_lock); + for_each_process(p) + if (p->mm) + cpumask_clear_cpu(cpu, mm_cpumask(p->mm)); + read_unlock(&tasklist_lock); + + return 0; +} +#else /* ... !CONFIG_HOTPLUG_CPU */ +int native_cpu_disable(void) +{ + return -ENOSYS; +} + +void native_cpu_die(unsigned int cpu) +{ + /* We said "no" in __cpu_disable */ + BUG(); +} + +void native_play_dead(void) +{ + BUG(); +} +#endif + asmlinkage void __cpuinit start_secondary(void) { unsigned int cpu = smp_processor_id(); @@ -88,8 +187,8 @@ asmlinkage void __cpuinit start_secondary(void) atomic_inc(&mm->mm_count); atomic_inc(&mm->mm_users); current->active_mm = mm; - BUG_ON(current->mm); enter_lazy_tlb(mm, current); + local_flush_tlb_all(); per_cpu_trap_init(); @@ -156,6 +255,7 @@ int __cpuinit __cpu_up(unsigned int cpu) break; udelay(10); + barrier(); } if (cpu_online(cpu)) @@ -270,7 +370,6 @@ static void flush_tlb_mm_ipi(void *mm) * behalf of debugees, kswapd stealing pages from another process etc). * Kanoj 07/00. */ - void flush_tlb_mm(struct mm_struct *mm) { preempt_disable(); -- cgit v1.2.3-59-g8ed1b From e7dc951eecb708d4aef18db4dbf489ba282d16ff Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 26 Apr 2010 19:09:57 +0900 Subject: sh: CPU hotplug support for SH-X3 SMP. This wires up CPU hotplug for SH-X3 SMP CPUs. Presently only secondary cores can be hotplugged given that the boot CPU has to contend with the broadcast timer. When real local timers are implemented this restriction can be lifted. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/smp-shx3.c | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c index dd245e68aa2e..de865cac02ee 100644 --- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c @@ -9,16 +9,22 @@ * for more details. */ #include +#include #include #include #include #include +#include +#include +#include +#include #define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12)) #define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12)) #define STBCR_MSTP 0x00000001 #define STBCR_RESET 0x00000002 +#define STBCR_SLEEP 0x00000004 #define STBCR_LTSLP 0x80000000 static irqreturn_t ipi_interrupt_handler(int irq, void *arg) @@ -110,10 +116,51 @@ static void shx3_send_ipi(unsigned int cpu, unsigned int message) __raw_writel(1 << (message << 2), addr); /* C0INTICI..CnINTICI */ } +static void shx3_update_boot_vector(unsigned int cpu) +{ + __raw_writel(STBCR_MSTP, STBCR_REG(cpu)); + while (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP)) + cpu_relax(); + __raw_writel(STBCR_RESET, STBCR_REG(cpu)); +} + +static int __cpuinit +shx3_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned int)hcpu; + + switch (action) { + case CPU_UP_PREPARE: + shx3_update_boot_vector(cpu); + break; + case CPU_ONLINE: + pr_info("CPU %u is now online\n", cpu); + break; + case CPU_DEAD: + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block __cpuinitdata shx3_cpu_notifier = { + .notifier_call = shx3_cpu_callback, +}; + +static int __cpuinit register_shx3_cpu_notifier(void) +{ + register_hotcpu_notifier(&shx3_cpu_notifier); + return 0; +} +late_initcall(register_shx3_cpu_notifier); + struct plat_smp_ops shx3_smp_ops = { .smp_setup = shx3_smp_setup, .prepare_cpus = shx3_prepare_cpus, .start_cpu = shx3_start_cpu, .smp_processor_id = shx3_smp_processor_id, .send_ipi = shx3_send_ipi, + .cpu_die = native_cpu_die, + .cpu_disable = native_cpu_disable, + .play_dead = native_play_dead, }; -- cgit v1.2.3-59-g8ed1b From b7386a09ce7e8add333f5d67f2fe1b1eac1f4746 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 27 Apr 2010 16:41:12 +0900 Subject: sh: make latencytop available on SMP, too. The UP dependency was inherited from ARM, which seems to have run in to it due to the stacktrace code not being available for SMP in certain cases, as we don't have this particular limitation there is no specific need to block on the SMP dependency. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index d73bd4db5e84..c497307cf51b 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -157,7 +157,6 @@ config LOCKDEP_SUPPORT config HAVE_LATENCYTOP_SUPPORT def_bool y - depends on !SMP config ARCH_HAS_ILOG2_U32 def_bool n -- cgit v1.2.3-59-g8ed1b From a3be6327163c223c1715c8307a616941fbf8bf73 Mon Sep 17 00:00:00 2001 From: Hans Ulli Kroll Date: Tue, 27 Apr 2010 12:45:10 +0200 Subject: ARM: Gemini: fix compiler error in copypage-fa.c Fix compiler error in copypage-fs.c missing struct vm_area_struct *vma in function fa_copy_user_highpage Signed-off-by: Hans Ulli Kroll --- arch/arm/mm/copypage-fa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mm/copypage-fa.c b/arch/arm/mm/copypage-fa.c index b2a6008b0111..d2852e1635b1 100644 --- a/arch/arm/mm/copypage-fa.c +++ b/arch/arm/mm/copypage-fa.c @@ -40,7 +40,7 @@ fa_copy_user_page(void *kto, const void *kfrom) } void fa_copy_user_highpage(struct page *to, struct page *from, - unsigned long vaddr) + unsigned long vaddr, struct vm_area_struct *vma) { void *kto, *kfrom; -- cgit v1.2.3-59-g8ed1b From e9ddbc075d95b2edf111247cdde16f33c31654a8 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 27 Apr 2010 15:23:01 +0200 Subject: avr32: Fix typo in read_persistent_clock() Fix fallout from the persistent_clock changes. Signed-off-by: Peter Huewe Cc: John Stultz Cc: Haavard Skinnemoen Signed-off-by: Thomas Gleixner --- arch/avr32/kernel/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c index a047d69d17e2..668ed2817e51 100644 --- a/arch/avr32/kernel/time.c +++ b/arch/avr32/kernel/time.c @@ -112,7 +112,7 @@ static struct clock_event_device comparator = { void read_persistent_clock(struct timespec *ts) { - ts->tv.sec = mktime(2007, 1, 1, 0, 0, 0); + ts->tv_sec = mktime(2007, 1, 1, 0, 0, 0); ts->tv_nsec = 0; } -- cgit v1.2.3-59-g8ed1b From 8cd9b13207f9a38e4da2d69bba51eb8dcbe1ead9 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 27 Apr 2010 15:54:50 -0700 Subject: net/sb1250: setup the pdevice within the soc code doing it within the driver does not look good. And surely isn't how platform devices were meat to be used. Acked-by: Ralf Baechle Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: David S. Miller --- arch/mips/sibyte/swarm/platform.c | 54 +++++++++++++++++ drivers/net/sb1250-mac.c | 120 +------------------------------------- 2 files changed, 55 insertions(+), 119 deletions(-) (limited to 'arch') diff --git a/arch/mips/sibyte/swarm/platform.c b/arch/mips/sibyte/swarm/platform.c index 54847fe1e564..097335262fb3 100644 --- a/arch/mips/sibyte/swarm/platform.c +++ b/arch/mips/sibyte/swarm/platform.c @@ -83,3 +83,57 @@ static int __init swarm_pata_init(void) device_initcall(swarm_pata_init); #endif /* defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR) */ + +#define sb1250_dev_struct(num) \ + static struct resource sb1250_res##num = { \ + .name = "SB1250 MAC " __stringify(num), \ + .flags = IORESOURCE_MEM, \ + .start = A_MAC_CHANNEL_BASE(num), \ + .end = A_MAC_CHANNEL_BASE(num + 1) -1, \ + };\ + static struct platform_device sb1250_dev##num = { \ + .name = "sb1250-mac", \ + .id = num, \ + .resource = &sb1250_res##num, \ + .num_resources = 1, \ + } + +sb1250_dev_struct(0); +sb1250_dev_struct(1); +sb1250_dev_struct(2); +sb1250_dev_struct(3); + +static struct platform_device *sb1250_devs[] __initdata = { + &sb1250_dev0, + &sb1250_dev1, + &sb1250_dev2, + &sb1250_dev3, +}; + +static int __init sb1250_device_init(void) +{ + int ret; + + /* Set the number of available units based on the SOC type. */ + switch (soc_type) { + case K_SYS_SOC_TYPE_BCM1250: + case K_SYS_SOC_TYPE_BCM1250_ALT: + ret = platform_add_devices(sb1250_devs, 3); + break; + case K_SYS_SOC_TYPE_BCM1120: + case K_SYS_SOC_TYPE_BCM1125: + case K_SYS_SOC_TYPE_BCM1125H: + case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */ + ret = platform_add_devices(sb1250_devs, 2); + break; + case K_SYS_SOC_TYPE_BCM1x55: + case K_SYS_SOC_TYPE_BCM1x80: + ret = platform_add_devices(sb1250_devs, 4); + break; + default: + ret = -ENODEV; + break; + } + return ret; +} +device_initcall(sb1250_device_init); diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 6ed92d62af22..ba4770a6c2e4 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -332,7 +332,6 @@ static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int regidx, ********************************************************************* */ static char sbmac_string[] = "sb1250-mac"; -static char sbmac_pretty[] = "SB1250 MAC"; static char sbmac_mdio_string[] = "sb1250-mac-mdio"; @@ -2670,114 +2669,6 @@ static int __exit sbmac_remove(struct platform_device *pldev) return 0; } - -static struct platform_device **sbmac_pldev; -static int sbmac_max_units; - -static int __init sbmac_platform_probe_one(int idx) -{ - struct platform_device *pldev; - struct { - struct resource r; - char name[strlen(sbmac_pretty) + 4]; - } *res; - int err; - - res = kzalloc(sizeof(*res), GFP_KERNEL); - if (!res) { - printk(KERN_ERR "%s.%d: unable to allocate memory\n", - sbmac_string, idx); - err = -ENOMEM; - goto out_err; - } - - /* - * This is the base address of the MAC. - */ - snprintf(res->name, sizeof(res->name), "%s %d", sbmac_pretty, idx); - res->r.name = res->name; - res->r.flags = IORESOURCE_MEM; - res->r.start = A_MAC_CHANNEL_BASE(idx); - res->r.end = A_MAC_CHANNEL_BASE(idx + 1) - 1; - - pldev = platform_device_register_simple(sbmac_string, idx, &res->r, 1); - if (IS_ERR(pldev)) { - printk(KERN_ERR "%s.%d: unable to register platform device\n", - sbmac_string, idx); - err = PTR_ERR(pldev); - goto out_kfree; - } - - if (!pldev->dev.driver) { - err = 0; /* No hardware at this address. */ - goto out_unregister; - } - - sbmac_pldev[idx] = pldev; - return 0; - -out_unregister: - platform_device_unregister(pldev); - -out_kfree: - kfree(res); - -out_err: - return err; -} - -static void __init sbmac_platform_probe(void) -{ - int i; - - /* Set the number of available units based on the SOC type. */ - switch (soc_type) { - case K_SYS_SOC_TYPE_BCM1250: - case K_SYS_SOC_TYPE_BCM1250_ALT: - sbmac_max_units = 3; - break; - case K_SYS_SOC_TYPE_BCM1120: - case K_SYS_SOC_TYPE_BCM1125: - case K_SYS_SOC_TYPE_BCM1125H: - case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */ - sbmac_max_units = 2; - break; - case K_SYS_SOC_TYPE_BCM1x55: - case K_SYS_SOC_TYPE_BCM1x80: - sbmac_max_units = 4; - break; - default: - return; /* none */ - } - - sbmac_pldev = kcalloc(sbmac_max_units, sizeof(*sbmac_pldev), - GFP_KERNEL); - if (!sbmac_pldev) { - printk(KERN_ERR "%s: unable to allocate memory\n", - sbmac_string); - return; - } - - /* - * Walk through the Ethernet controllers and find - * those who have their MAC addresses set. - */ - for (i = 0; i < sbmac_max_units; i++) - if (sbmac_platform_probe_one(i)) - break; -} - - -static void __exit sbmac_platform_cleanup(void) -{ - int i; - - for (i = 0; i < sbmac_max_units; i++) - platform_device_unregister(sbmac_pldev[i]); - kfree(sbmac_pldev); -} - - static struct platform_driver sbmac_driver = { .probe = sbmac_probe, .remove = __exit_p(sbmac_remove), @@ -2788,20 +2679,11 @@ static struct platform_driver sbmac_driver = { static int __init sbmac_init_module(void) { - int err; - - err = platform_driver_register(&sbmac_driver); - if (err) - return err; - - sbmac_platform_probe(); - - return err; + return platform_driver_register(&sbmac_driver); } static void __exit sbmac_cleanup_module(void) { - sbmac_platform_cleanup(); platform_driver_unregister(&sbmac_driver); } -- cgit v1.2.3-59-g8ed1b From 402af0d7c692ddcfa2333e93d3f275ebd0487926 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 21 Apr 2010 15:21:51 +0100 Subject: x86, asm: Introduce and use percpu_inc() ... generating slightly smaller code. Signed-off-by: Jan Beulich LKML-Reference: <4BCF261F020000780003B33C@vpn.id2.novell.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/hardirq.h | 2 +- arch/x86/include/asm/percpu.h | 24 ++++++++++++++++++++++++ arch/x86/kernel/cpu/mcheck/mce.c | 4 ++-- 3 files changed, 27 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h index 0f8576427cfe..aeab29aee617 100644 --- a/arch/x86/include/asm/hardirq.h +++ b/arch/x86/include/asm/hardirq.h @@ -35,7 +35,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); #define __ARCH_IRQ_STAT -#define inc_irq_stat(member) percpu_add(irq_stat.member, 1) +#define inc_irq_stat(member) percpu_inc(irq_stat.member) #define local_softirq_pending() percpu_read(irq_stat.__softirq_pending) diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 66a272dfd8b8..0ec6d12d84e6 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -190,6 +190,29 @@ do { \ pfo_ret__; \ }) +#define percpu_unary_op(op, var) \ +({ \ + switch (sizeof(var)) { \ + case 1: \ + asm(op "b "__percpu_arg(0) \ + : "+m" (var)); \ + break; \ + case 2: \ + asm(op "w "__percpu_arg(0) \ + : "+m" (var)); \ + break; \ + case 4: \ + asm(op "l "__percpu_arg(0) \ + : "+m" (var)); \ + break; \ + case 8: \ + asm(op "q "__percpu_arg(0) \ + : "+m" (var)); \ + break; \ + default: __bad_percpu_size(); \ + } \ +}) + /* * percpu_read() makes gcc load the percpu variable every time it is * accessed while percpu_read_stable() allows the value to be cached. @@ -207,6 +230,7 @@ do { \ #define percpu_and(var, val) percpu_to_op("and", var, val) #define percpu_or(var, val) percpu_to_op("or", var, val) #define percpu_xor(var, val) percpu_to_op("xor", var, val) +#define percpu_inc(var) percpu_unary_op("inc", var) #define __this_cpu_read_1(pcp) percpu_from_op("mov", (pcp), "m"(pcp)) #define __this_cpu_read_2(pcp) percpu_from_op("mov", (pcp), "m"(pcp)) diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 8a6f0afa767e..7a355ddcc64b 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -539,7 +539,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) struct mce m; int i; - __get_cpu_var(mce_poll_count)++; + percpu_inc(mce_poll_count); mce_setup(&m); @@ -934,7 +934,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) atomic_inc(&mce_entry); - __get_cpu_var(mce_exception_count)++; + percpu_inc(mce_exception_count); if (notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL) == NOTIFY_STOP) -- cgit v1.2.3-59-g8ed1b From 2e61878698781d6a9a8bfbaa4ea9c5ddb5a178c3 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 21 Apr 2010 16:13:20 +0100 Subject: x86-64: Combine SRAT regions when possible ... i.e. when the hole between two regions isn't occupied by memory on another node. This reduces the memory->node table size, thus reducing cache footprint of lookups, which got increased significantly some time ago, and things go back to how they were before that change on the systems I looked at. Signed-off-by: Jan Beulich LKML-Reference: <4BCF3230020000780003B3CA@vpn.id2.novell.com> Signed-off-by: H. Peter Anvin --- arch/x86/mm/srat_64.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'arch') diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 28c68762648f..3ebe6519bd87 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -363,6 +363,54 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) for (i = 0; i < MAX_NUMNODES; i++) cutoff_node(i, start, end); + /* + * Join together blocks on the same node, holes between + * which don't overlap with memory on other nodes. + */ + for (i = 0; i < num_node_memblks; ++i) { + int j, k; + + for (j = i + 1; j < num_node_memblks; ++j) { + unsigned long start, end; + + if (memblk_nodeid[i] != memblk_nodeid[j]) + continue; + start = min(node_memblk_range[i].end, + node_memblk_range[j].end); + end = max(node_memblk_range[i].start, + node_memblk_range[j].start); + for (k = 0; k < num_node_memblks; ++k) { + if (memblk_nodeid[i] == memblk_nodeid[k]) + continue; + if (start < node_memblk_range[k].end && + end > node_memblk_range[k].start) + break; + } + if (k < num_node_memblks) + continue; + start = min(node_memblk_range[i].start, + node_memblk_range[j].start); + end = max(node_memblk_range[i].end, + node_memblk_range[j].end); + printk(KERN_INFO "SRAT: Node %d " + "[%Lx,%Lx) + [%Lx,%Lx) -> [%lx,%lx)\n", + memblk_nodeid[i], + node_memblk_range[i].start, + node_memblk_range[i].end, + node_memblk_range[j].start, + node_memblk_range[j].end, + start, end); + node_memblk_range[i].start = start; + node_memblk_range[i].end = end; + k = --num_node_memblks - j; + memmove(memblk_nodeid + j, memblk_nodeid + j+1, + k * sizeof(*memblk_nodeid)); + memmove(node_memblk_range + j, node_memblk_range + j+1, + k * sizeof(*node_memblk_range)); + --j; + } + } + memnode_shift = compute_hash_shift(node_memblk_range, num_node_memblks, memblk_nodeid); if (memnode_shift < 0) { -- cgit v1.2.3-59-g8ed1b From 5967ed87ade85a421ef814296c3c7f182b08c225 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 21 Apr 2010 16:08:14 +0100 Subject: x86-64: Reduce SMP locks table size Reduce the SMP locks table size by using relative pointers instead of absolute ones, thus cutting the table size by half. Signed-off-by: Jan Beulich LKML-Reference: <4BCF30FE020000780003B3B6@vpn.id2.novell.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/alternative-asm.h | 4 +-- arch/x86/include/asm/alternative.h | 4 +-- arch/x86/kernel/alternative.c | 45 +++++++++++++++++++--------------- 3 files changed, 29 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h index b97f786a48d5..a63a68be1cce 100644 --- a/arch/x86/include/asm/alternative-asm.h +++ b/arch/x86/include/asm/alternative-asm.h @@ -6,8 +6,8 @@ .macro LOCK_PREFIX 1: lock .section .smp_locks,"a" - _ASM_ALIGN - _ASM_PTR 1b + .balign 4 + .long 1b - . .previous .endm #else diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index b09ec55650b3..714bf2417284 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -30,8 +30,8 @@ #ifdef CONFIG_SMP #define LOCK_PREFIX \ ".section .smp_locks,\"a\"\n" \ - _ASM_ALIGN "\n" \ - _ASM_PTR "661f\n" /* address */ \ + ".balign 4\n" \ + ".long 661f - .\n" /* offset */ \ ".previous\n" \ "661:\n\tlock; " diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 1a160d5d44d0..936738427223 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -194,7 +194,7 @@ static void __init_or_module add_nops(void *insns, unsigned int len) } extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; -extern u8 *__smp_locks[], *__smp_locks_end[]; +extern s32 __smp_locks[], __smp_locks_end[]; static void *text_poke_early(void *addr, const void *opcode, size_t len); /* Replace instructions with better alternatives for this CPU type. @@ -235,37 +235,39 @@ void __init_or_module apply_alternatives(struct alt_instr *start, #ifdef CONFIG_SMP -static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) +static void alternatives_smp_lock(const s32 *start, const s32 *end, + u8 *text, u8 *text_end) { - u8 **ptr; + const s32 *poff; mutex_lock(&text_mutex); - for (ptr = start; ptr < end; ptr++) { - if (*ptr < text) - continue; - if (*ptr > text_end) + for (poff = start; poff < end; poff++) { + u8 *ptr = (u8 *)poff + *poff; + + if (!*poff || ptr < text || ptr >= text_end) continue; /* turn DS segment override prefix into lock prefix */ - text_poke(*ptr, ((unsigned char []){0xf0}), 1); + text_poke(ptr, ((unsigned char []){0xf0}), 1); }; mutex_unlock(&text_mutex); } -static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) +static void alternatives_smp_unlock(const s32 *start, const s32 *end, + u8 *text, u8 *text_end) { - u8 **ptr; + const s32 *poff; if (noreplace_smp) return; mutex_lock(&text_mutex); - for (ptr = start; ptr < end; ptr++) { - if (*ptr < text) - continue; - if (*ptr > text_end) + for (poff = start; poff < end; poff++) { + u8 *ptr = (u8 *)poff + *poff; + + if (!*poff || ptr < text || ptr >= text_end) continue; /* turn lock prefix into DS segment override prefix */ - text_poke(*ptr, ((unsigned char []){0x3E}), 1); + text_poke(ptr, ((unsigned char []){0x3E}), 1); }; mutex_unlock(&text_mutex); } @@ -276,8 +278,8 @@ struct smp_alt_module { char *name; /* ptrs to lock prefixes */ - u8 **locks; - u8 **locks_end; + const s32 *locks; + const s32 *locks_end; /* .text segment, needed to avoid patching init code ;) */ u8 *text; @@ -398,16 +400,19 @@ void alternatives_smp_switch(int smp) int alternatives_text_reserved(void *start, void *end) { struct smp_alt_module *mod; - u8 **ptr; + const s32 *poff; u8 *text_start = start; u8 *text_end = end; list_for_each_entry(mod, &smp_alt_modules, next) { if (mod->text > text_end || mod->text_end < text_start) continue; - for (ptr = mod->locks; ptr < mod->locks_end; ptr++) - if (text_start <= *ptr && text_end >= *ptr) + for (poff = mod->locks; poff < mod->locks_end; poff++) { + const u8 *ptr = (const u8 *)poff + *poff; + + if (text_start <= ptr && text_end > ptr) return 1; + } } return 0; -- cgit v1.2.3-59-g8ed1b From d706c1b050274b3bf97d7cb0542c0d070c9ccb8b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:28 -0700 Subject: driver-core: Add device node pointer to struct device Currently, platforms using CONFIG_OF add a 'struct device_node *of_node' to dev->archdata. However, with CONFIG_OF becoming generic for all architectures, it makes sense for commonality to move it out of archdata and into struct device proper. This patch adds a struct device_node *of_node member to struct device and updates all locations which currently write the device_node pointer into archdata to also update dev->of_node. Subsequent patches will modify callers to use the archdata location and ultimately remove the archdata member entirely. Signed-off-by: Grant Likely Acked-by: Greg Kroah-Hartman CC: Michal Simek CC: Greg Kroah-Hartman CC: Benjamin Herrenschmidt CC: "David S. Miller" CC: Stephen Rothwell CC: Jeremy Kerr CC: microblaze-uclinux@itee.uq.edu.au CC: linux-kernel@vger.kernel.org CC: linuxppc-dev@ozlabs.org CC: sparclinux@vger.kernel.org --- arch/microblaze/kernel/of_device.c | 1 + arch/powerpc/kernel/of_device.c | 1 + arch/powerpc/kernel/pci-common.c | 3 ++- arch/powerpc/kernel/vio.c | 3 ++- arch/powerpc/platforms/ps3/system-bus.c | 1 + arch/sparc/kernel/of_device_32.c | 1 + arch/sparc/kernel/of_device_64.c | 1 + arch/sparc/kernel/pci.c | 1 + drivers/of/of_mdio.c | 1 + drivers/of/of_spi.c | 1 + include/linux/device.h | 4 ++++ 11 files changed, 16 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index 9a0f7632c47c..f6c521898ebf 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -54,6 +54,7 @@ struct of_device *of_device_alloc(struct device_node *np, dev->dev.parent = parent; dev->dev.release = of_release_dev; dev->dev.archdata.of_node = np; + dev->dev.of_node = np; if (bus_id) dev_set_name(&dev->dev, bus_id); diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index a359cb08e900..9577e6f4e3bf 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -74,6 +74,7 @@ struct of_device *of_device_alloc(struct device_node *np, dev->dev.parent = parent; dev->dev.release = of_release_dev; dev->dev.archdata.of_node = np; + dev->dev.of_node = np; if (bus_id) dev_set_name(&dev->dev, "%s", bus_id); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 0c0567e58409..88da282047c3 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1097,8 +1097,9 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) if (dev->is_added) continue; - /* Setup OF node pointer in archdata */ + /* Setup OF node pointer in the device */ sd->of_node = pci_device_to_OF_node(dev); + dev->dev.of_node = pci_device_to_OF_node(dev); /* Fixup NUMA node as it may not be setup yet by the generic * code and is needed by the DMA init diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 82237176a2a3..d6708da114ee 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -1230,7 +1230,8 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) if (unit_address != NULL) viodev->unit_address = *unit_address; } - viodev->dev.archdata.of_node = of_node_get(of_node); + viodev->dev.of_node = of_node_get(of_node); + viodev->dev.archdata.of_node = viodev->dev.of_node; if (firmware_has_feature(FW_FEATURE_CMO)) vio_cmo_set_dma_ops(viodev); diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 6d09f5e3e7e4..e546c86a539b 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -766,6 +766,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) BUG(); }; + dev->core.of_node = NULL; dev->core.archdata.of_node = NULL; set_dev_node(&dev->core, 0); diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index da527b33ebc7..4926c1babd84 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -348,6 +348,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, sd->prom_node = dp; sd->op = op; + op->dev.of_node = dp; op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index b3d4cb5d21b3..5bc74161667c 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -643,6 +643,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, sd->prom_node = dp; sd->op = op; + op->dev.of_node = dp; op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 5ac539a5930f..0c920147b4ef 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -262,6 +262,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, sd->stc = &pbm->stc; sd->host_controller = pbm; sd->prom_node = node; + dev->dev.of_node = node; sd->op = op = of_find_device_by_node(node); sd->numa_node = pbm->numa_node; diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 18ecae4a4375..12090f57dc87 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -80,6 +80,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) * can be looked up later */ of_node_get(child); dev_archdata_set_node(&phy->dev.archdata, child); + phy->dev.of_node = child; /* All data is now stored in the phy struct; register it */ rc = phy_device_register(phy); diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index f65f48b98448..f3119a0836af 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -79,6 +79,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) /* Store a pointer to the node in the device structure */ of_node_get(nc); + spi->dev.of_node = nc; spi->dev.archdata.of_node = nc; /* Register the new device */ diff --git a/include/linux/device.h b/include/linux/device.h index 182192892d45..7a968bdb02e2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -34,6 +34,7 @@ struct class; struct class_private; struct bus_type; struct bus_type_private; +struct device_node; struct bus_attribute { struct attribute attr; @@ -433,6 +434,9 @@ struct device { override */ /* arch specific additions */ struct dev_archdata archdata; +#ifdef CONFIG_OF + struct device_node *of_node; +#endif dev_t devt; /* dev_t, creates the sysfs "dev" */ -- cgit v1.2.3-59-g8ed1b From 47f9fe26299ae022ac1e3fa12e7e73def62b7898 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 21 Apr 2010 16:19:57 +0100 Subject: x86-64: Don't export init_level4_pgt It's not used by any module, and i386 (as well as some other arches) also doesn't export its equivalent (swapper_pg_dir). Signed-off-by: Jan Beulich LKML-Reference: <4BCF33BD020000780003B3E4@vpn.id2.novell.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/x8664_ksyms_64.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index 693920b22496..1b950d151e58 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c @@ -54,7 +54,6 @@ EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(empty_zero_page); -EXPORT_SYMBOL(init_level4_pgt); #ifndef CONFIG_PARAVIRT EXPORT_SYMBOL(native_load_gs_index); #endif -- cgit v1.2.3-59-g8ed1b From 6fc108a08dcddf8f9113cc7102ddaacf7ed37a6b Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 21 Apr 2010 15:23:44 +0100 Subject: x86: Clean up arch/x86/Kconfig* No functional change intended. Signed-off-by: Jan Beulich LKML-Reference: <4BCF2690020000780003B340@vpn.id2.novell.com> Signed-off-by: H. Peter Anvin --- arch/x86/Kconfig | 49 ++++++++++++++------------------------------- arch/x86/Kconfig.debug | 2 -- arch/x86/include/asm/boot.h | 2 +- 3 files changed, 16 insertions(+), 37 deletions(-) (limited to 'arch') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 9458685902bd..85e2252625bc 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -197,20 +197,17 @@ config HAVE_INTEL_TXT # Use the generic interrupt handling code in kernel/irq/: config GENERIC_HARDIRQS - bool - default y + def_bool y config GENERIC_HARDIRQS_NO__DO_IRQ def_bool y config GENERIC_IRQ_PROBE - bool - default y + def_bool y config GENERIC_PENDING_IRQ - bool + def_bool y depends on GENERIC_HARDIRQS && SMP - default y config USE_GENERIC_SMP_HELPERS def_bool y @@ -225,14 +222,12 @@ config X86_64_SMP depends on X86_64 && SMP config X86_HT - bool + def_bool y depends on SMP - default y config X86_TRAMPOLINE - bool + def_bool y depends on SMP || (64BIT && ACPI_SLEEP) - default y config X86_32_LAZY_GS def_bool y @@ -447,7 +442,7 @@ config X86_NUMAQ firmware with - send email to . config X86_SUPPORTS_MEMORY_FAILURE - bool + def_bool y # MCE code calls memory_failure(): depends on X86_MCE # On 32-bit this adds too big of NODES_SHIFT and we run out of page flags: @@ -455,7 +450,6 @@ config X86_SUPPORTS_MEMORY_FAILURE # On 32-bit SPARSEMEM adds too big of SECTIONS_WIDTH: depends on X86_64 || !SPARSEMEM select ARCH_SUPPORTS_MEMORY_FAILURE - default y config X86_VISWS bool "SGI 320/540 (Visual Workstation)" @@ -570,7 +564,6 @@ config PARAVIRT_SPINLOCKS config PARAVIRT_CLOCK bool - default n endif @@ -749,7 +742,6 @@ config MAXSMP bool "Configure Maximum number of SMP Processors and NUMA Nodes" depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL select CPUMASK_OFFSTACK - default n ---help--- Configure maximum number of CPUS and NUMA Nodes for this architecture. If unsure, say N. @@ -829,7 +821,6 @@ config X86_VISWS_APIC config X86_REROUTE_FOR_BROKEN_BOOT_IRQS bool "Reroute for broken boot IRQs" - default n depends on X86_IO_APIC ---help--- This option enables a workaround that fixes a source of @@ -876,9 +867,8 @@ config X86_MCE_AMD the DRAM Error Threshold. config X86_ANCIENT_MCE - def_bool n + bool "Support for old Pentium 5 / WinChip machine checks" depends on X86_32 && X86_MCE - prompt "Support for old Pentium 5 / WinChip machine checks" ---help--- Include support for machine check handling on old Pentium 5 or WinChip systems. These typically need to be enabled explicitely on the command @@ -886,8 +876,7 @@ config X86_ANCIENT_MCE config X86_MCE_THRESHOLD depends on X86_MCE_AMD || X86_MCE_INTEL - bool - default y + def_bool y config X86_MCE_INJECT depends on X86_MCE @@ -1026,8 +1015,8 @@ config X86_CPUID choice prompt "High Memory Support" - default HIGHMEM4G if !X86_NUMAQ default HIGHMEM64G if X86_NUMAQ + default HIGHMEM4G depends on X86_32 config NOHIGHMEM @@ -1285,7 +1274,7 @@ source "mm/Kconfig" config HIGHPTE bool "Allocate 3rd-level pagetables from highmem" - depends on X86_32 && (HIGHMEM4G || HIGHMEM64G) + depends on HIGHMEM ---help--- The VM uses one page table entry for each page of physical memory. For systems with a lot of RAM, this can be wasteful of precious @@ -1369,8 +1358,7 @@ config MATH_EMULATION kernel, it won't hurt. config MTRR - bool - default y + def_bool y prompt "MTRR (Memory Type Range Register) support" if EMBEDDED ---help--- On Intel P6 family processors (Pentium Pro, Pentium II and later) @@ -1436,8 +1424,7 @@ config MTRR_SANITIZER_SPARE_REG_NR_DEFAULT mtrr_spare_reg_nr=N on the kernel command line. config X86_PAT - bool - default y + def_bool y prompt "x86 PAT support" if EMBEDDED depends on MTRR ---help--- @@ -1605,8 +1592,7 @@ config X86_NEED_RELOCS depends on X86_32 && RELOCATABLE config PHYSICAL_ALIGN - hex - prompt "Alignment value to which kernel should be aligned" if X86_32 + hex "Alignment value to which kernel should be aligned" if X86_32 default "0x1000000" range 0x2000 0x1000000 ---help--- @@ -1653,7 +1639,6 @@ config COMPAT_VDSO config CMDLINE_BOOL bool "Built-in kernel command line" - default n ---help--- Allow for specifying boot arguments to the kernel at build time. On some systems (e.g. embedded ones), it is @@ -1687,7 +1672,6 @@ config CMDLINE config CMDLINE_OVERRIDE bool "Built-in command line overrides boot loader arguments" - default n depends on CMDLINE_BOOL ---help--- Set this option to 'Y' to have the kernel ignore the boot loader @@ -1723,8 +1707,7 @@ source "drivers/acpi/Kconfig" source "drivers/sfi/Kconfig" config X86_APM_BOOT - bool - default y + def_bool y depends on APM || APM_MODULE menuconfig APM @@ -1953,8 +1936,7 @@ config DMAR_DEFAULT_ON experimental. config DMAR_BROKEN_GFX_WA - def_bool n - prompt "Workaround broken graphics drivers (going away soon)" + bool "Workaround broken graphics drivers (going away soon)" depends on DMAR && BROKEN ---help--- Current Graphics drivers tend to use physical address @@ -2052,7 +2034,6 @@ config SCx200HR_TIMER config OLPC bool "One Laptop Per Child support" select GPIOLIB - default n ---help--- Add support for detecting the unique features of the OLPC XO hardware. diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index bc01e3ebfeb2..e7edd66d866e 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -45,7 +45,6 @@ config EARLY_PRINTK config EARLY_PRINTK_DBGP bool "Early printk via EHCI debug port" - default n depends on EARLY_PRINTK && PCI ---help--- Write kernel log output directly into the EHCI debug port. @@ -76,7 +75,6 @@ config DEBUG_PER_CPU_MAPS bool "Debug access to per_cpu maps" depends on DEBUG_KERNEL depends on SMP - default n ---help--- Say Y to verify that the per_cpu map being accessed has been setup. Adds a fair amount of code to kernel memory diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h index 7a1065958ba9..3b62ab56c7a0 100644 --- a/arch/x86/include/asm/boot.h +++ b/arch/x86/include/asm/boot.h @@ -24,7 +24,7 @@ #define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2) #if (CONFIG_PHYSICAL_ALIGN & (CONFIG_PHYSICAL_ALIGN-1)) || \ - (CONFIG_PHYSICAL_ALIGN < (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2)) + (CONFIG_PHYSICAL_ALIGN < MIN_KERNEL_ALIGN) #error "Invalid value for CONFIG_PHYSICAL_ALIGN" #endif -- cgit v1.2.3-59-g8ed1b From 30a564be9d9554c168a654eddc2165869cc0d7bf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 13 Apr 2010 15:31:36 +0200 Subject: x86, hpet: Restrict read back to affected ATI chipsets After programming the HPET, we do a readback as a workaround for ATI/SBx00 chipsets as a synchronization. Unfortunately this triggers an erratum in newer ICH chipsets (ICH9+) where reading the comparator immediately after the write returns the old value. Furthermore, as always, I/O reads are bad for performance. Therefore, restrict the readback to the chipsets that need it, or, for debugging purposes, when we are running with hpet=verbose. Signed-off-by: Thomas Gleixner Acked-by: Venkatesh Pallipadi LKML-Reference: <20100225185348.GA9674@linux-os.sc.intel.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/hpet.h | 1 + arch/x86/kernel/hpet.c | 29 +++++++++++++++++------------ arch/x86/kernel/quirks.c | 5 +++++ 3 files changed, 23 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h index 1d5c08a1bdfd..004e6e25e913 100644 --- a/arch/x86/include/asm/hpet.h +++ b/arch/x86/include/asm/hpet.h @@ -68,6 +68,7 @@ extern unsigned long force_hpet_address; extern u8 hpet_blockid; extern int hpet_force_user; extern u8 hpet_msi_disable; +extern u8 hpet_readback_cmp; extern int is_hpet_enabled(void); extern int hpet_enable(void); extern void hpet_disable(void); diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 23b4ecdffa9b..a198b7c87a12 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -36,6 +36,7 @@ unsigned long hpet_address; u8 hpet_blockid; /* OS timer block num */ u8 hpet_msi_disable; +u8 hpet_readback_cmp; #ifdef CONFIG_PCI_MSI static unsigned long hpet_num_timers; @@ -395,19 +396,23 @@ static int hpet_next_event(unsigned long delta, * at that point and we would wait for the next hpet interrupt * forever. We found out that reading the CMP register back * forces the transfer so we can rely on the comparison with - * the counter register below. If the read back from the - * compare register does not match the value we programmed - * then we might have a real hardware problem. We can not do - * much about it here, but at least alert the user/admin with - * a prominent warning. - * An erratum on some chipsets (ICH9,..), results in comparator read - * immediately following a write returning old value. Workaround - * for this is to read this value second time, when first - * read returns old value. + * the counter register below. + * + * That works fine on those ATI chipsets, but on newer Intel + * chipsets (ICH9...) this triggers due to an erratum: Reading + * the comparator immediately following a write is returning + * the old value. + * + * We restrict the read back to the affected ATI chipsets (set + * by quirks) and also run it with hpet=verbose for debugging + * purposes. */ - if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) { - WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt, - KERN_WARNING "hpet: compare register read back failed.\n"); + if (hpet_readback_cmp || hpet_verbose) { + u32 cmp = hpet_readl(HPET_Tn_CMP(timer)); + + if (cmp != cnt) + printk_once(KERN_WARNING + "hpet: compare register read back failed.\n"); } return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 12e9feaa2f7a..cd2c336c8d09 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -495,10 +495,15 @@ void force_hpet_resume(void) /* * HPET MSI on some boards (ATI SB700/SB800) has side effect on * floppy DMA. Disable HPET MSI on such platforms. + * + * Also force the read back of the CMP register in hpet_next_event() + * to work around the problem that the CMP register write seems to be + * delayed. See hpet_next_event() for details. */ static void force_disable_hpet_msi(struct pci_dev *unused) { hpet_msi_disable = 1; + hpet_readback_cmp = 1; } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, -- cgit v1.2.3-59-g8ed1b From 5f737b39be9110bd64874f508bd89ba27746b17e Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 28 Apr 2010 05:46:11 +0000 Subject: sh: add CONFIG_VIRTUALIZATION for virtio support Add CONFIG_VIRTUALIZATION to the SH architecture and include the virtio code there. Used to enable the virtio drivers under QEMU. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index c497307cf51b..c2325bd48fd3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -871,4 +871,20 @@ source "security/Kconfig" source "crypto/Kconfig" +menuconfig VIRTUALIZATION + bool "Virtualization" + default n + ---help--- + Say Y here to get to see options for using your Linux host to run other + operating systems inside virtual machines (guests). + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + +if VIRTUALIZATION + +source drivers/virtio/Kconfig + +endif # VIRTUALIZATION + source "lib/Kconfig" -- cgit v1.2.3-59-g8ed1b From 1483feac74fdfd84a7ed7586c66482842e3b6e86 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 28 Apr 2010 11:11:30 +0000 Subject: sh: native_cpu_disable() build error when CONFIG_HOTPLUG_CPU=n arch/sh/kernel/smp.c:164: error: conflicting types for 'native_cpu_disable' /home/matt/src/kernels/sh-2.6/arch/sh/include/asm/smp.h:48: error: previous declaration of 'native_cpu_disable' was here Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 86cd6f94b53b..509b36b45115 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -161,7 +161,7 @@ int __cpu_disable(void) return 0; } #else /* ... !CONFIG_HOTPLUG_CPU */ -int native_cpu_disable(void) +int native_cpu_disable(unsigned int cpu) { return -ENOSYS; } -- cgit v1.2.3-59-g8ed1b From 28d7f4ec98a8edb029ef24c1ee4af6a1ccbc9633 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 29 Apr 2010 17:11:45 +0100 Subject: ARM: 6063/1: pmu: add enum describing PMU types This patch adds an enum describing the potential PMU device types in preparation for PMU device registration via platform devices. Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/pmu.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 2829b9f981a1..44bec1f02cb0 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h @@ -12,6 +12,11 @@ #ifndef __ARM_PMU_H__ #define __ARM_PMU_H__ +enum arm_pmu_type { + ARM_PMU_DEVICE_CPU = 0, + ARM_NUM_PMU_DEVICES, +}; + #ifdef CONFIG_CPU_HAS_PMU struct pmu_irqs { -- cgit v1.2.3-59-g8ed1b From 8716011315a5b2fa932fa1e7570c34975ed2cb14 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 9 Apr 2010 13:55:54 +0100 Subject: ARM: 6047/1: ARM: BCMRING: register PMU IRQ during board initialisation This patch updates the initialisation routine for the BCMRING platform so that it registers its PMU IRQ with the PMU framework in the Kernel. Acked-by: Leo Chen Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/mach-bcmring/arch.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-bcmring/arch.c b/arch/arm/mach-bcmring/arch.c index 53dd2a9eecf9..2f139196d63d 100644 --- a/arch/arm/mach-bcmring/arch.c +++ b/arch/arm/mach-bcmring/arch.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -85,8 +86,23 @@ static struct platform_device nand_device = { .num_resources = ARRAY_SIZE(nand_resource), }; +static struct resource pmu_resource = { + .start = IRQ_PMUIRQ, + .end = IRQ_PMUIRQ, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .resource = &pmu_resource, + .num_resources = 1, +}; + + static struct platform_device *devices[] __initdata = { &nand_device, + &pmu_device, }; /**************************************************************************** -- cgit v1.2.3-59-g8ed1b From cc761beda2426cf663a649b905b6643673ff7b30 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 16 Feb 2010 22:06:14 +0100 Subject: ARM: 5943/1: iop: n2100: enable serial interrupt Thecus N2100 has a jumper (J3/J4) to select whether the XINT1 interrupt line is connected to the second UHCI controller (position J3) or to the serial port UART (position J4). Currently, the kernel is hardcoded to assume the J3 position, and the serial port is always being used in polling mode. The patch adds the IRQ autodetection flag for the serial port interrupt, and also marks it as shared (as the driver for the second UHCI controller will request the interrupt in any case). Now, when the jumper is set to the J4 position, the serial port will have an interrupt line, resulting in less CPU overhead and faster throughput. Tested-by: Mikael Pettersson Signed-off-by: Aaro Koskinen Acked-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/mach-iop32x/n2100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index 2a5c637639bb..266b1f58a784 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c @@ -177,7 +177,7 @@ static struct plat_serial8250_port n2100_serial_port[] = { .mapbase = N2100_UART, .membase = (char *)N2100_UART, .irq = 0, - .flags = UPF_SKIP_TEST, + .flags = UPF_SKIP_TEST | UPF_AUTO_IRQ | UPF_SHARE_IRQ, .iotype = UPIO_MEM, .regshift = 0, .uartclk = 1843200, -- cgit v1.2.3-59-g8ed1b From de4338f40e48da3b604219909a1d4aa7aa60870f Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 9 Apr 2010 13:57:02 +0100 Subject: ARM: 6048/1: ARM: iop3xx: register PMU IRQs during board initialisation This patch adds an initcall for the iop3xx platforms so that they register their PMU IRQS with the PMU framework in the Kernel. Cc: Lennert Buytenhek Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/plat-iop/Makefile | 2 ++ arch/arm/plat-iop/pmu.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 arch/arm/plat-iop/pmu.c (limited to 'arch') diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile index 36bff0325959..69b09c1cec8b 100644 --- a/arch/arm/plat-iop/Makefile +++ b/arch/arm/plat-iop/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_IOP32X) += time.o obj-$(CONFIG_ARCH_IOP32X) += io.o obj-$(CONFIG_ARCH_IOP32X) += cp6.o obj-$(CONFIG_ARCH_IOP32X) += adma.o +obj-$(CONFIG_ARCH_IOP32X) += pmu.o # IOP33X obj-$(CONFIG_ARCH_IOP33X) += gpio.o @@ -23,6 +24,7 @@ obj-$(CONFIG_ARCH_IOP33X) += time.o obj-$(CONFIG_ARCH_IOP33X) += io.o obj-$(CONFIG_ARCH_IOP33X) += cp6.o obj-$(CONFIG_ARCH_IOP33X) += adma.o +obj-$(CONFIG_ARCH_IOP33X) += pmu.o # IOP13XX obj-$(CONFIG_ARCH_IOP13XX) += cp6.o diff --git a/arch/arm/plat-iop/pmu.c b/arch/arm/plat-iop/pmu.c new file mode 100644 index 000000000000..a2024b8685a1 --- /dev/null +++ b/arch/arm/plat-iop/pmu.c @@ -0,0 +1,40 @@ +/* + * PMU IRQ registration for the iop3xx xscale PMU families. + * Copyright (C) 2010 Will Deacon, ARM Ltd. + * + * 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 +#include +#include + +static struct resource pmu_resource = { +#ifdef CONFIG_ARCH_IOP32X + .start = IRQ_IOP32X_CORE_PMU, + .end = IRQ_IOP32X_CORE_PMU, +#endif +#ifdef CONFIG_ARCH_IOP33X + .start = IRQ_IOP33X_CORE_PMU, + .end = IRQ_IOP33X_CORE_PMU, +#endif + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .resource = &pmu_resource, + .num_resources = 1, +}; + +static int __init iop3xx_pmu_init(void) +{ + platform_device_register(&pmu_device); + return 0; +} + +arch_initcall(iop3xx_pmu_init); -- cgit v1.2.3-59-g8ed1b From a285edcf18b8838814d645c7e411a337a825236e Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Jan 2010 19:59:37 +0000 Subject: ARM: Fix Versatile&Integrator includes to behave in the same way as Realview Realview doesn't include mach/platform.h in mach/hardware.h, so make versatile behave in the same way. Also, move the definition of __io_address() into mach/hardware.h, just like Realview. Signed-off-by: Russell King --- arch/arm/mach-integrator/core.c | 1 + arch/arm/mach-integrator/cpu.c | 1 + arch/arm/mach-integrator/include/mach/entry-macro.S | 1 + arch/arm/mach-integrator/include/mach/hardware.h | 3 ++- arch/arm/mach-integrator/integrator_ap.c | 1 + arch/arm/mach-integrator/integrator_cp.c | 1 + arch/arm/mach-integrator/leds.c | 1 + arch/arm/mach-integrator/pci_v3.c | 1 + arch/arm/mach-versatile/core.c | 4 ++-- arch/arm/mach-versatile/include/mach/entry-macro.S | 1 + arch/arm/mach-versatile/include/mach/hardware.h | 3 ++- 11 files changed, 14 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 8b390e36ba69..096f899625f8 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index 44d4c2e8207b..b7618790460a 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -20,6 +20,7 @@ #include #include +#include #include #include diff --git a/arch/arm/mach-integrator/include/mach/entry-macro.S b/arch/arm/mach-integrator/include/mach/entry-macro.S index 7649c57acb53..3d029c9f3ef6 100644 --- a/arch/arm/mach-integrator/include/mach/entry-macro.S +++ b/arch/arm/mach-integrator/include/mach/entry-macro.S @@ -8,6 +8,7 @@ * warranty of any kind, whether express or implied. */ #include +#include #include .macro disable_fiq diff --git a/arch/arm/mach-integrator/include/mach/hardware.h b/arch/arm/mach-integrator/include/mach/hardware.h index d795642fad22..d44af7209b48 100644 --- a/arch/arm/mach-integrator/include/mach/hardware.h +++ b/arch/arm/mach-integrator/include/mach/hardware.h @@ -23,7 +23,6 @@ #define __ASM_ARCH_HARDWARE_H #include -#include /* * Where in virtual memory the IO devices (timers, system controllers @@ -48,5 +47,7 @@ #define PCIBIOS_MIN_IO 0x6000 #define PCIBIOS_MIN_MEM 0x00100000 +#define __io_address(n) ((void __iomem *)IO_ADDRESS(n)) + #endif diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 8138a7e24562..018c32da4c86 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include /* HZ */ diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 66ef86d6d9e3..c66e8fa0e622 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c index 8dcc823f4135..28be186adb89 100644 --- a/arch/arm/mach-integrator/leds.c +++ b/arch/arm/mach-integrator/leds.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 148d25fc636f..e87fe9fa4344 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 9ddb49b1cb71..b77bc407b77d 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -35,7 +35,6 @@ #include #include -#include #include #include #include @@ -48,6 +47,8 @@ #include #include #include +#include +#include #include "core.h" #include "clock.h" @@ -58,7 +59,6 @@ * * Setup a VA for the Versatile Vectored Interrupt Controller. */ -#define __io_address(n) __io(IO_ADDRESS(n)) #define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE) #define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE) diff --git a/arch/arm/mach-versatile/include/mach/entry-macro.S b/arch/arm/mach-versatile/include/mach/entry-macro.S index 8c8020980585..e6f7c1663160 100644 --- a/arch/arm/mach-versatile/include/mach/entry-macro.S +++ b/arch/arm/mach-versatile/include/mach/entry-macro.S @@ -8,6 +8,7 @@ * warranty of any kind, whether express or implied. */ #include +#include #include .macro disable_fiq diff --git a/arch/arm/mach-versatile/include/mach/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h index 7aa906c93154..4f8f99aac938 100644 --- a/arch/arm/mach-versatile/include/mach/hardware.h +++ b/arch/arm/mach-versatile/include/mach/hardware.h @@ -23,7 +23,6 @@ #define __ASM_ARCH_HARDWARE_H #include -#include /* * PCI space virtual addresses @@ -49,4 +48,6 @@ /* macro to get at IO space when running virtually */ #define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) +#define __io_address(n) __io(IO_ADDRESS(n)) + #endif -- cgit v1.2.3-59-g8ed1b From ba02a21544b41a65e58506f1d79353203d94b8b6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Jan 2010 15:07:08 +0000 Subject: ARM: Improve documentation in arm_timer.h Signed-off-by: Russell King --- arch/arm/include/asm/hardware/arm_timer.h | 39 +++++++++++++++++++------------ 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h index 04be3bdf46b8..c0f4e7bf22de 100644 --- a/arch/arm/include/asm/hardware/arm_timer.h +++ b/arch/arm/include/asm/hardware/arm_timer.h @@ -1,21 +1,30 @@ #ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H #define __ASM_ARM_HARDWARE_ARM_TIMER_H -#define TIMER_LOAD 0x00 -#define TIMER_VALUE 0x04 -#define TIMER_CTRL 0x08 -#define TIMER_CTRL_ONESHOT (1 << 0) -#define TIMER_CTRL_32BIT (1 << 1) -#define TIMER_CTRL_DIV1 (0 << 2) -#define TIMER_CTRL_DIV16 (1 << 2) -#define TIMER_CTRL_DIV256 (2 << 2) -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ -#define TIMER_CTRL_PERIODIC (1 << 6) -#define TIMER_CTRL_ENABLE (1 << 7) +/* + * ARM timer implementation, found in Integrator, Versatile and Realview + * platforms. Not all platforms support all registers and bits in these + * registers, so we mark them with A for Integrator AP, C for Integrator + * CP, V for Versatile and R for Realview. + * + * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview + * can have 16-bit or 32-bit selectable via a bit in the control register. + */ +#define TIMER_LOAD 0x00 /* ACVR rw */ +#define TIMER_VALUE 0x04 /* ACVR ro */ +#define TIMER_CTRL 0x08 /* ACVR rw */ +#define TIMER_CTRL_ONESHOT (1 << 0) /* CVR */ +#define TIMER_CTRL_32BIT (1 << 1) /* CVR */ +#define TIMER_CTRL_DIV1 (0 << 2) /* ACVR */ +#define TIMER_CTRL_DIV16 (1 << 2) /* ACVR */ +#define TIMER_CTRL_DIV256 (2 << 2) /* ACVR */ +#define TIMER_CTRL_IE (1 << 5) /* VR */ +#define TIMER_CTRL_PERIODIC (1 << 6) /* ACVR */ +#define TIMER_CTRL_ENABLE (1 << 7) /* ACVR */ -#define TIMER_INTCLR 0x0c -#define TIMER_RIS 0x10 -#define TIMER_MIS 0x14 -#define TIMER_BGLOAD 0x18 +#define TIMER_INTCLR 0x0c /* ACVR wo */ +#define TIMER_RIS 0x10 /* CVR ro */ +#define TIMER_MIS 0x14 /* CVR ro */ +#define TIMER_BGLOAD 0x18 /* CVR rw */ #endif -- cgit v1.2.3-59-g8ed1b From b9cedda230793cbf58eb012ddadedd490cc8e129 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 15 Jan 2010 18:10:33 +0000 Subject: ARM: Integrator: convert to generic time support Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-integrator/common.h | 1 - arch/arm/mach-integrator/core.c | 62 ++++++++++++++++---------------- arch/arm/mach-integrator/integrator_ap.c | 1 - arch/arm/mach-integrator/integrator_cp.c | 1 - 5 files changed, 31 insertions(+), 35 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5408bf1bf43..7698d8705a8f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -241,6 +241,7 @@ config ARCH_INTEGRATOR select HAVE_CLK select COMMON_CLKDEV select ICST525 + select GENERIC_TIME help Support for ARM's Integrator platform. diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h index 609c49de3d47..7dc24bb9bdc1 100644 --- a/arch/arm/mach-integrator/common.h +++ b/arch/arm/mach-integrator/common.h @@ -1,2 +1 @@ extern void integrator_time_init(unsigned long, unsigned int); -extern unsigned long integrator_gettimeoffset(void); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 096f899625f8..87c6f980944d 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -225,7 +226,6 @@ EXPORT_SYMBOL(cm_control); #define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000) #define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100) #define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200) -#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) /* * How long is the timer interval? @@ -241,42 +241,38 @@ EXPORT_SYMBOL(cm_control); static unsigned long timer_reload; -/* - * Returns number of ms since last clock interrupt. Note that interrupts - * will have been disabled by do_gettimeoffset() - */ -unsigned long integrator_gettimeoffset(void) +static void __iomem * const clksrc_base = (void __iomem *)TIMER2_VA_BASE; + +static cycle_t timersp_read(struct clocksource *cs) { - unsigned long ticks1, ticks2, status; + return ~(readl(clksrc_base + TIMER_VALUE) & 0xffff); +} - /* - * Get the current number of ticks. Note that there is a race - * condition between us reading the timer and checking for - * an interrupt. We get around this by ensuring that the - * counter has not reloaded between our two reads. - */ - ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; - do { - ticks1 = ticks2; - status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); - ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; - } while (ticks2 > ticks1); +static struct clocksource clocksource_timersp = { + .name = "timer2", + .rating = 200, + .read = timersp_read, + .mask = CLOCKSOURCE_MASK(16), + .shift = 16, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; - /* - * Number of ticks since last interrupt. - */ - ticks1 = timer_reload - ticks2; +static void integrator_clocksource_init(u32 khz) +{ + struct clocksource *cs = &clocksource_timersp; + void __iomem *base = clksrc_base; + u32 ctrl = TIMER_CTRL_ENABLE; - /* - * Interrupt pending? If so, we've reloaded once already. - */ - if (status & (1 << IRQ_TIMERINT1)) - ticks1 += timer_reload; + if (khz >= 1500) { + khz /= 16; + ctrl = TIMER_CTRL_DIV16; + } - /* - * Convert the ticks to usecs - */ - return TICKS2USECS(ticks1); + writel(ctrl, base + TIMER_CTRL); + writel(0xffff, base + TIMER_LOAD); + + cs->mult = clocksource_khz2mult(khz, cs->shift); + clocksource_register(cs); } /* @@ -308,6 +304,8 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl) { unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; + integrator_clocksource_init(reload * HZ / 1000); + timer_reload = reload; timer_ctrl |= ctrl; diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 018c32da4c86..cfb718fe31a8 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -342,7 +342,6 @@ static void __init ap_init_timer(void) static struct sys_timer ap_timer = { .init = ap_init_timer, - .offset = integrator_gettimeoffset, }; MACHINE_START(INTEGRATOR, "ARM-Integrator") diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index c66e8fa0e622..3e84732163ea 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -577,7 +577,6 @@ static void __init intcp_timer_init(void) static struct sys_timer cp_timer = { .init = intcp_timer_init, - .offset = integrator_gettimeoffset, }; MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") -- cgit v1.2.3-59-g8ed1b From 13edd86d7a8b64735c60c308faac785a6f2257b2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 15 Jan 2010 21:49:23 +0000 Subject: ARM: Integrator: convert to generic clockevent support Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-integrator/core.c | 107 +++++++++++++++++++++++++++------------- 2 files changed, 74 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7698d8705a8f..86fecec1600d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -242,6 +242,7 @@ config ARCH_INTEGRATOR select COMMON_CLKDEV select ICST525 select GENERIC_TIME + select GENERIC_CLOCKEVENTS help Support for ARM's Integrator platform. diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 87c6f980944d..b1ccbe3f233f 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -275,61 +276,99 @@ static void integrator_clocksource_init(u32 khz) clocksource_register(cs); } +static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; + /* * IRQ handler for the timer */ -static irqreturn_t -integrator_timer_interrupt(int irq, void *dev_id) +static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id) { - /* - * clear the interrupt - */ - writel(1, TIMER1_VA_BASE + TIMER_INTCLR); + struct clock_event_device *evt = dev_id; + + /* clear the interrupt */ + writel(1, clkevt_base + TIMER_INTCLR); - timer_tick(); + evt->event_handler(evt); return IRQ_HANDLED; } +static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) +{ + u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; + + BUG_ON(mode == CLOCK_EVT_MODE_ONESHOT); + + if (mode == CLOCK_EVT_MODE_PERIODIC) { + writel(ctrl, clkevt_base + TIMER_CTRL); + writel(timer_reload, clkevt_base + TIMER_LOAD); + ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; + } + + writel(ctrl, clkevt_base + TIMER_CTRL); +} + +static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) +{ + unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); + + writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); + writel(next, clkevt_base + TIMER_LOAD); + writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); + + return 0; +} + +static struct clock_event_device integrator_clockevent = { + .name = "timer1", + .shift = 34, + .features = CLOCK_EVT_FEAT_PERIODIC, + .set_mode = clkevt_set_mode, + .set_next_event = clkevt_set_next_event, + .rating = 300, + .cpumask = cpu_all_mask, +}; + static struct irqaction integrator_timer_irq = { - .name = "Integrator Timer Tick", + .name = "timer", .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, .handler = integrator_timer_interrupt, + .dev_id = &integrator_clockevent, }; -/* - * Set up timer interrupt, and return the current time in seconds. - */ -void __init integrator_time_init(unsigned long reload, unsigned int ctrl) +static void integrator_clockevent_init(u32 khz, unsigned int ctrl) { - unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; + struct clock_event_device *evt = &integrator_clockevent; - integrator_clocksource_init(reload * HZ / 1000); + if (khz * 1000 > 0x100000 * HZ) { + khz /= 256; + ctrl |= TIMER_CTRL_DIV256; + } else if (khz * 1000 > 0x10000 * HZ) { + khz /= 16; + ctrl |= TIMER_CTRL_DIV16; + } - timer_reload = reload; - timer_ctrl |= ctrl; + timer_reload = khz * 1000 / HZ; + writel(ctrl, clkevt_base + TIMER_CTRL); - if (timer_reload > 0x100000) { - timer_reload >>= 8; - timer_ctrl |= TIMER_CTRL_DIV256; - } else if (timer_reload > 0x010000) { - timer_reload >>= 4; - timer_ctrl |= TIMER_CTRL_DIV16; - } + evt->irq = IRQ_TIMERINT1; + evt->mult = div_sc(khz, NSEC_PER_MSEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(0xffff, evt); + evt->min_delta_ns = clockevent_delta2ns(0xf, evt); - /* - * Initialise to a known state (all timers off) - */ + setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); + clockevents_register_device(evt); +} + +/* + * Set up timer(s). + */ +void __init integrator_time_init(unsigned long reload, unsigned int ctrl) +{ writel(0, TIMER0_VA_BASE + TIMER_CTRL); writel(0, TIMER1_VA_BASE + TIMER_CTRL); writel(0, TIMER2_VA_BASE + TIMER_CTRL); - writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD); - writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE); - writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL); - - /* - * Make irqs happen for the system timer - */ - setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); + integrator_clocksource_init(reload * HZ / 1000); + integrator_clockevent_init(reload * HZ / 1000, ctrl); } -- cgit v1.2.3-59-g8ed1b From 861248d177145fc5861507e4607fec89fd0a0462 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 15 Jan 2010 22:12:46 +0000 Subject: ARM: Integrator: pass 'khz' to integrator_time_init This is now what the clocksource/clockevent initialization functions want, so give them the timer tick rate directly. Signed-off-by: Russell King --- arch/arm/mach-integrator/common.h | 2 +- arch/arm/mach-integrator/core.c | 6 +++--- arch/arm/mach-integrator/integrator_ap.c | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h index 7dc24bb9bdc1..cdbe71091516 100644 --- a/arch/arm/mach-integrator/common.h +++ b/arch/arm/mach-integrator/common.h @@ -1 +1 @@ -extern void integrator_time_init(unsigned long, unsigned int); +extern void integrator_time_init(u32, unsigned int); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index b1ccbe3f233f..d02f0e3afdcb 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -363,12 +363,12 @@ static void integrator_clockevent_init(u32 khz, unsigned int ctrl) /* * Set up timer(s). */ -void __init integrator_time_init(unsigned long reload, unsigned int ctrl) +void __init integrator_time_init(u32 khz, unsigned int ctrl) { writel(0, TIMER0_VA_BASE + TIMER_CTRL); writel(0, TIMER1_VA_BASE + TIMER_CTRL); writel(0, TIMER2_VA_BASE + TIMER_CTRL); - integrator_clocksource_init(reload * HZ / 1000); - integrator_clockevent_init(reload * HZ / 1000, ctrl); + integrator_clocksource_init(khz); + integrator_clockevent_init(khz, ctrl); } diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index cfb718fe31a8..93da7d4e459b 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -337,7 +337,7 @@ static void __init ap_init(void) static void __init ap_init_timer(void) { - integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, 0); + integrator_time_init(TICKS_PER_uSEC * 1000, 0); } static struct sys_timer ap_timer = { diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 3e84732163ea..108bc480237a 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -572,7 +572,7 @@ static void __init intcp_init(void) static void __init intcp_timer_init(void) { - integrator_time_init(1000000 / HZ, TIMER_CTRL_IE); + integrator_time_init(1000, TIMER_CTRL_IE); } static struct sys_timer cp_timer = { -- cgit v1.2.3-59-g8ed1b From 3e9cc70590287f7cb7e38793bbf968b3362b7612 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 9 Apr 2010 13:57:51 +0100 Subject: ARM: 6049/1: ARM: pxa: register PMU IRQs during board initialisation This patch adds an initcall for the pxa platforms so that they register their PMU IRQs with the PMU framework in the Kernel. Cc: Eric Miao Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/plat-pxa/Makefile | 2 +- arch/arm/plat-pxa/pmu.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 arch/arm/plat-pxa/pmu.c (limited to 'arch') diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile index 0264bfb0ca4f..f68da35f4fb3 100644 --- a/arch/arm/plat-pxa/Makefile +++ b/arch/arm/plat-pxa/Makefile @@ -2,7 +2,7 @@ # Makefile for code common across different PXA processor families # -obj-y := dma.o +obj-y := dma.o pmu.o obj-$(CONFIG_GENERIC_GPIO) += gpio.o obj-$(CONFIG_PXA3xx) += mfp.o diff --git a/arch/arm/plat-pxa/pmu.c b/arch/arm/plat-pxa/pmu.c new file mode 100644 index 000000000000..267ceb6feb2f --- /dev/null +++ b/arch/arm/plat-pxa/pmu.c @@ -0,0 +1,33 @@ +/* + * PMU IRQ registration for the PXA xscale PMU families. + * Copyright (C) 2010 Will Deacon, ARM Ltd. + * + * 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 +#include +#include + +static struct resource pmu_resource = { + .start = IRQ_PMU, + .end = IRQ_PMU, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .resource = &pmu_resource, + .num_resources = 1, +}; + +static int __init pxa_pmu_init(void) +{ + platform_device_register(&pmu_device); + return 0; +} +arch_initcall(pxa_pmu_init); -- cgit v1.2.3-59-g8ed1b From 883413341e479d4e9f9c69def4884b4c6e1cef4e Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 9 Apr 2010 13:54:43 +0100 Subject: ARM: 6046/1: ARM: OMAP: register PMU IRQs during board initialisation This patch updates the initialisation routines for the OMAP2 and OMAP3 boards so that they register their PMU IRQs with the PMU framework in the Kernel. Cc: Tony Lindgren Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/mach-omap2/devices.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 23e4d7733610..4a1c2328bcc3 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -17,8 +17,10 @@ #include #include +#include #include #include +#include #include #include @@ -453,6 +455,37 @@ static void omap_init_mcspi(void) static inline void omap_init_mcspi(void) {} #endif +static struct resource omap2_pmu_resource = { + .start = 3, + .end = 3, + .flags = IORESOURCE_IRQ, +}; + +static struct resource omap3_pmu_resource = { + .start = INT_34XX_BENCH_MPU_EMUL, + .end = INT_34XX_BENCH_MPU_EMUL, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device omap_pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .num_resources = 1, +}; + +static void omap_init_pmu(void) +{ + if (cpu_is_omap24xx()) + omap_pmu_device.resource = &omap2_pmu_resource; + else if (cpu_is_omap34xx()) + omap_pmu_device.resource = &omap3_pmu_resource; + else + return; + + platform_device_register(&omap_pmu_device); +} + + #ifdef CONFIG_OMAP_SHA1_MD5 static struct resource sha1_md5_resources[] = { { @@ -797,6 +830,7 @@ static int __init omap2_init_devices(void) omap_init_camera(); omap_init_mbox(); omap_init_mcspi(); + omap_init_pmu(); omap_hdq_init(); omap_init_sti(); omap_init_sha1_md5(); -- cgit v1.2.3-59-g8ed1b From b701a47ba48b698976fb2fe05fb285b0edc1d26a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 29 Apr 2010 16:03:57 -0700 Subject: x86: Fix LOCK_PREFIX_HERE for uniprocessor build Checkin b3ac891b67bd4b1fc728d1c784cad1212dea433d: x86: Add support for lock prefix in alternatives ... did not define LOCK_PREFIX_HERE in the case of a uniprocessor build. As a result, it would cause any of the usages of this macro to fail on a uniprocessor build. Fix this by defining LOCK_PREFIX_HERE as a null string. Signed-off-by: H. Peter Anvin Cc: Luca Barbieri LKML-Reference: <1267005265-27958-2-git-send-email-luca@luca-barbieri.com> --- arch/x86/include/asm/alternative.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 55fee12cea6d..e29a6c9bba00 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -38,6 +38,7 @@ #define LOCK_PREFIX LOCK_PREFIX_HERE "\n\tlock; " #else /* ! CONFIG_SMP */ +#define LOCK_PREFIX_HERE "" #define LOCK_PREFIX "" #endif -- cgit v1.2.3-59-g8ed1b From 73266fc1df2f94cf72b3beba3eee3b88ed0b0664 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 22 Apr 2010 05:05:45 +0200 Subject: hw-breakpoints: Tag ptrace breakpoint as exclude_kernel Tag ptrace breakpoints with the exclude_kernel attribute set. This will make it easier to set generic policies on breakpoints, when it comes to ensure nobody unpriviliged try to breakpoint on the kernel. Signed-off-by: Frederic Weisbecker Acked-by: Paul Mundt Cc: Will Deacon Cc: Mahesh Salgaonkar Cc: K. Prasad Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Ingo Molnar --- arch/sh/kernel/ptrace_32.c | 2 +- arch/x86/kernel/ptrace.c | 2 +- include/linux/hw_breakpoint.h | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 7759a9a93211..d4104ce9fe53 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -85,7 +85,7 @@ static int set_single_step(struct task_struct *tsk, unsigned long addr) bp = thread->ptrace_bps[0]; if (!bp) { - hw_breakpoint_init(&attr); + ptrace_breakpoint_init(&attr); attr.bp_addr = addr; attr.bp_len = HW_BREAKPOINT_LEN_2; diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 055be0afd330..70c4872cd8aa 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -688,7 +688,7 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr, struct perf_event_attr attr; if (!t->ptrace_bps[nr]) { - hw_breakpoint_init(&attr); + ptrace_breakpoint_init(&attr); /* * Put stub len and type to register (reserve) an inactive but * correct bp diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h index c70d27af03f9..a0aa5a9cfb0e 100644 --- a/include/linux/hw_breakpoint.h +++ b/include/linux/hw_breakpoint.h @@ -34,6 +34,12 @@ static inline void hw_breakpoint_init(struct perf_event_attr *attr) attr->sample_period = 1; } +static inline void ptrace_breakpoint_init(struct perf_event_attr *attr) +{ + hw_breakpoint_init(attr); + attr->exclude_kernel = 1; +} + static inline unsigned long hw_breakpoint_addr(struct perf_event *bp) { return bp->attr.bp_addr; -- cgit v1.2.3-59-g8ed1b From b2812d031dea86926e9c10f7714af33ac2f6b43d Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 18 Apr 2010 18:11:53 +0200 Subject: hw-breakpoints: Change/Enforce some breakpoints policies The current policies of breakpoints in x86 and SH are the following: - task bound breakpoints can only break on userspace addresses - cpu wide breakpoints can only break on kernel addresses The former rule prevents ptrace breakpoints to be set to trigger on kernel addresses, which is good. But as a side effect, we can't breakpoint on kernel addresses for task bound breakpoints. The latter rule simply makes no sense, there is no reason why we can't set breakpoints on userspace while performing cpu bound profiles. We want the following new policies: - task bound breakpoint can set userspace address breakpoints, with no particular privilege required. - task bound breakpoints can set kernelspace address breakpoints but must be privileged to do that. - cpu bound breakpoints can do what they want as they are privileged already. To implement these new policies, this patch checks if we are dealing with a kernel address breakpoint, if so and if the exclude_kernel parameter is set, we tell the user that the breakpoint is invalid, which makes a good generic ptrace protection. If we don't have exclude_kernel, ensure the user has the right privileges as kernel breakpoints are quite sensitive (risk of trap recursion attacks and global performance impacts). [ Paul Mundt: keep addr space check for sh signal delivery and fix double function declaration] Signed-off-by: Frederic Weisbecker Cc: Will Deacon Cc: Mahesh Salgaonkar Cc: K. Prasad Cc: Paul Mundt Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Jason Wessel Cc: Ingo Molnar Signed-off-by: Paul Mundt --- arch/sh/include/asm/hw_breakpoint.h | 5 ++--- arch/sh/kernel/hw_breakpoint.c | 34 ++++++------------------------ arch/x86/include/asm/hw_breakpoint.h | 5 ++--- arch/x86/kernel/hw_breakpoint.c | 41 ++++++------------------------------ kernel/hw_breakpoint.c | 26 +++++++++++++++++++++-- 5 files changed, 41 insertions(+), 70 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h index 965dd780d51b..382bad937dcc 100644 --- a/arch/sh/include/asm/hw_breakpoint.h +++ b/arch/sh/include/asm/hw_breakpoint.h @@ -47,9 +47,8 @@ struct pmu; #define HBP_NUM 2 /* arch/sh/kernel/hw_breakpoint.c */ -extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len); -extern int arch_validate_hwbkpt_settings(struct perf_event *bp, - struct task_struct *tsk); +extern int arch_check_bp_in_kernelspace(struct perf_event *bp); +extern int arch_validate_hwbkpt_settings(struct perf_event *bp); extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, unsigned long val, void *data); diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c index 675eea7785d9..1f2cf6229862 100644 --- a/arch/sh/kernel/hw_breakpoint.c +++ b/arch/sh/kernel/hw_breakpoint.c @@ -119,26 +119,17 @@ static int get_hbp_len(u16 hbp_len) return len_in_bytes; } -/* - * Check for virtual address in user space. - */ -int arch_check_va_in_userspace(unsigned long va, u16 hbp_len) -{ - unsigned int len; - - len = get_hbp_len(hbp_len); - - return (va <= TASK_SIZE - len); -} - /* * Check for virtual address in kernel space. */ -static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len) +int arch_check_bp_in_kernelspace(struct perf_event *bp) { unsigned int len; + unsigned long va; + struct arch_hw_breakpoint *info = counter_arch_bp(bp); - len = get_hbp_len(hbp_len); + va = info->address; + len = get_hbp_len(info->len); return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); } @@ -226,8 +217,7 @@ static int arch_build_bp_info(struct perf_event *bp) /* * Validate the arch-specific HW Breakpoint register settings */ -int arch_validate_hwbkpt_settings(struct perf_event *bp, - struct task_struct *tsk) +int arch_validate_hwbkpt_settings(struct perf_event *bp) { struct arch_hw_breakpoint *info = counter_arch_bp(bp); unsigned int align; @@ -270,15 +260,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp, if (info->address & align) return -EINVAL; - /* Check that the virtual address is in the proper range */ - if (tsk) { - if (!arch_check_va_in_userspace(info->address, info->len)) - return -EFAULT; - } else { - if (!arch_check_va_in_kernelspace(info->address, info->len)) - return -EFAULT; - } - return 0; } @@ -363,8 +344,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args) perf_bp_event(bp, args->regs); /* Deliver the signal to userspace */ - if (arch_check_va_in_userspace(bp->attr.bp_addr, - bp->attr.bp_len)) { + if (!arch_check_bp_in_kernelspace(bp)) { siginfo_t info; info.si_signo = args->signr; diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h index 2a1bd8f4f23a..c77a5a6fab9d 100644 --- a/arch/x86/include/asm/hw_breakpoint.h +++ b/arch/x86/include/asm/hw_breakpoint.h @@ -44,9 +44,8 @@ struct arch_hw_breakpoint { struct perf_event; struct pmu; -extern int arch_check_va_in_userspace(unsigned long va, u8 hbp_len); -extern int arch_validate_hwbkpt_settings(struct perf_event *bp, - struct task_struct *tsk); +extern int arch_check_bp_in_kernelspace(struct perf_event *bp); +extern int arch_validate_hwbkpt_settings(struct perf_event *bp); extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, unsigned long val, void *data); diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index d6cc065f519f..a8f1b803d2fd 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -188,26 +188,17 @@ static int get_hbp_len(u8 hbp_len) return len_in_bytes; } -/* - * Check for virtual address in user space. - */ -int arch_check_va_in_userspace(unsigned long va, u8 hbp_len) -{ - unsigned int len; - - len = get_hbp_len(hbp_len); - - return (va <= TASK_SIZE - len); -} - /* * Check for virtual address in kernel space. */ -static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len) +int arch_check_bp_in_kernelspace(struct perf_event *bp) { unsigned int len; + unsigned long va; + struct arch_hw_breakpoint *info = counter_arch_bp(bp); - len = get_hbp_len(hbp_len); + va = info->address; + len = get_hbp_len(info->len); return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); } @@ -300,8 +291,7 @@ static int arch_build_bp_info(struct perf_event *bp) /* * Validate the arch-specific HW Breakpoint register settings */ -int arch_validate_hwbkpt_settings(struct perf_event *bp, - struct task_struct *tsk) +int arch_validate_hwbkpt_settings(struct perf_event *bp) { struct arch_hw_breakpoint *info = counter_arch_bp(bp); unsigned int align; @@ -314,16 +304,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp, ret = -EINVAL; - if (info->type == X86_BREAKPOINT_EXECUTE) - /* - * Ptrace-refactoring code - * For now, we'll allow instruction breakpoint only for user-space - * addresses - */ - if ((!arch_check_va_in_userspace(info->address, info->len)) && - info->len != X86_BREAKPOINT_EXECUTE) - return ret; - switch (info->len) { case X86_BREAKPOINT_LEN_1: align = 0; @@ -350,15 +330,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp, if (info->address & align) return -EINVAL; - /* Check that the virtual address is in the proper range */ - if (tsk) { - if (!arch_check_va_in_userspace(info->address, info->len)) - return -EFAULT; - } else { - if (!arch_check_va_in_kernelspace(info->address, info->len)) - return -EFAULT; - } - return 0; } diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index 9ed9ae3a48b3..89e8a050c43a 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c @@ -308,6 +308,28 @@ int dbg_release_bp_slot(struct perf_event *bp) return 0; } +static int validate_hw_breakpoint(struct perf_event *bp) +{ + int ret; + + ret = arch_validate_hwbkpt_settings(bp); + if (ret) + return ret; + + if (arch_check_bp_in_kernelspace(bp)) { + if (bp->attr.exclude_kernel) + return -EINVAL; + /* + * Don't let unprivileged users set a breakpoint in the trap + * path to avoid trap recursion attacks. + */ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + } + + return 0; +} + int register_perf_hw_breakpoint(struct perf_event *bp) { int ret; @@ -316,7 +338,7 @@ int register_perf_hw_breakpoint(struct perf_event *bp) if (ret) return ret; - ret = arch_validate_hwbkpt_settings(bp, bp->ctx->task); + ret = validate_hw_breakpoint(bp); /* if arch_validate_hwbkpt_settings() fails then release bp slot */ if (ret) @@ -363,7 +385,7 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att if (attr->disabled) goto end; - err = arch_validate_hwbkpt_settings(bp, bp->ctx->task); + err = validate_hw_breakpoint(bp); if (!err) perf_event_enable(bp); -- cgit v1.2.3-59-g8ed1b From 0102752e4c9e0655b39734550d4c35327954f7f9 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 11 Apr 2010 18:55:56 +0200 Subject: hw-breakpoints: Separate constraint space for data and instruction breakpoints There are two outstanding fashions for archs to implement hardware breakpoints. The first is to separate breakpoint address pattern definition space between data and instruction breakpoints. We then have typically distinct instruction address breakpoint registers and data address breakpoint registers, delivered with separate control registers for data and instruction breakpoints as well. This is the case of PowerPc and ARM for example. The second consists in having merged breakpoint address space definition between data and instruction breakpoint. Address registers can host either instruction or data address and the access mode for the breakpoint is defined in a control register. This is the case of x86 and Super H. This patch adds a new CONFIG_HAVE_MIXED_BREAKPOINTS_REGS config that archs can select if they belong to the second case. Those will have their slot allocation merged for instructions and data breakpoints. The others will have a separate slot tracking between data and instruction breakpoints. Signed-off-by: Frederic Weisbecker Acked-by: Paul Mundt Cc: Will Deacon Cc: Mahesh Salgaonkar Cc: K. Prasad Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Ingo Molnar --- arch/Kconfig | 11 ++++++ arch/sh/Kconfig | 1 + arch/x86/Kconfig | 1 + include/linux/hw_breakpoint.h | 9 +++-- kernel/hw_breakpoint.c | 86 +++++++++++++++++++++++++++++-------------- 5 files changed, 78 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/Kconfig b/arch/Kconfig index f06010fb4838..acda512da2e2 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -137,6 +137,17 @@ config HAVE_HW_BREAKPOINT bool depends on PERF_EVENTS +config HAVE_MIXED_BREAKPOINTS_REGS + bool + depends on HAVE_HW_BREAKPOINT + help + Depending on the arch implementation of hardware breakpoints, + some of them have separate registers for data and instruction + breakpoints addresses, others have mixed registers to store + them but define the access type in a control register. + Select this option if your arch implements breakpoints under the + latter fashion. + config HAVE_USER_RETURN_NOTIFIER bool diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 8d90564c2bcf..e6d8ab5cfa9d 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -44,6 +44,7 @@ config SUPERH32 select HAVE_FUNCTION_GRAPH_TRACER select HAVE_ARCH_KGDB select HAVE_HW_BREAKPOINT + select HAVE_MIXED_BREAKPOINTS_REGS select PERF_EVENTS if HAVE_HW_BREAKPOINT select ARCH_HIBERNATION_POSSIBLE if MMU diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 97a95dfd1181..01177dcbe261 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -53,6 +53,7 @@ config X86 select HAVE_KERNEL_LZMA select HAVE_KERNEL_LZO select HAVE_HW_BREAKPOINT + select HAVE_MIXED_BREAKPOINTS_REGS select PERF_EVENTS select ANON_INODES select HAVE_ARCH_KMEMCHECK diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h index a0aa5a9cfb0e..7e8899093098 100644 --- a/include/linux/hw_breakpoint.h +++ b/include/linux/hw_breakpoint.h @@ -9,9 +9,12 @@ enum { }; enum { - HW_BREAKPOINT_R = 1, - HW_BREAKPOINT_W = 2, - HW_BREAKPOINT_X = 4, + HW_BREAKPOINT_EMPTY = 0, + HW_BREAKPOINT_R = 1, + HW_BREAKPOINT_W = 2, + HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W, + HW_BREAKPOINT_X = 4, + HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X, }; #ifdef __KERNEL__ diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index 89e8a050c43a..8ead1345e33b 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c @@ -45,18 +45,28 @@ #include +enum bp_type_idx { + TYPE_INST = 0, +#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS + TYPE_DATA = 0, +#else + TYPE_DATA = 1, +#endif + TYPE_MAX +}; + /* * Constraints data */ /* Number of pinned cpu breakpoints in a cpu */ -static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned); +static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned[TYPE_MAX]); /* Number of pinned task breakpoints in a cpu */ -static DEFINE_PER_CPU(unsigned int, nr_task_bp_pinned[HBP_NUM]); +static DEFINE_PER_CPU(unsigned int, nr_task_bp_pinned[TYPE_MAX][HBP_NUM]); /* Number of non-pinned cpu/task breakpoints in a cpu */ -static DEFINE_PER_CPU(unsigned int, nr_bp_flexible); +static DEFINE_PER_CPU(unsigned int, nr_bp_flexible[TYPE_MAX]); /* Gather the number of total pinned and un-pinned bp in a cpuset */ struct bp_busy_slots { @@ -67,14 +77,22 @@ struct bp_busy_slots { /* Serialize accesses to the above constraints */ static DEFINE_MUTEX(nr_bp_mutex); +static inline enum bp_type_idx find_slot_idx(struct perf_event *bp) +{ + if (bp->attr.bp_type & HW_BREAKPOINT_RW) + return TYPE_DATA; + + return TYPE_INST; +} + /* * Report the maximum number of pinned breakpoints a task * have in this cpu */ -static unsigned int max_task_bp_pinned(int cpu) +static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type) { int i; - unsigned int *tsk_pinned = per_cpu(nr_task_bp_pinned, cpu); + unsigned int *tsk_pinned = per_cpu(nr_task_bp_pinned[type], cpu); for (i = HBP_NUM -1; i >= 0; i--) { if (tsk_pinned[i] > 0) @@ -84,7 +102,7 @@ static unsigned int max_task_bp_pinned(int cpu) return 0; } -static int task_bp_pinned(struct task_struct *tsk) +static int task_bp_pinned(struct task_struct *tsk, enum bp_type_idx type) { struct perf_event_context *ctx = tsk->perf_event_ctxp; struct list_head *list; @@ -105,7 +123,8 @@ static int task_bp_pinned(struct task_struct *tsk) */ list_for_each_entry(bp, list, event_entry) { if (bp->attr.type == PERF_TYPE_BREAKPOINT) - count++; + if (find_slot_idx(bp) == type) + count++; } raw_spin_unlock_irqrestore(&ctx->lock, flags); @@ -118,18 +137,19 @@ static int task_bp_pinned(struct task_struct *tsk) * a given cpu (cpu > -1) or in all of them (cpu = -1). */ static void -fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp) +fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, + enum bp_type_idx type) { int cpu = bp->cpu; struct task_struct *tsk = bp->ctx->task; if (cpu >= 0) { - slots->pinned = per_cpu(nr_cpu_bp_pinned, cpu); + slots->pinned = per_cpu(nr_cpu_bp_pinned[type], cpu); if (!tsk) - slots->pinned += max_task_bp_pinned(cpu); + slots->pinned += max_task_bp_pinned(cpu, type); else - slots->pinned += task_bp_pinned(tsk); - slots->flexible = per_cpu(nr_bp_flexible, cpu); + slots->pinned += task_bp_pinned(tsk, type); + slots->flexible = per_cpu(nr_bp_flexible[type], cpu); return; } @@ -137,16 +157,16 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp) for_each_online_cpu(cpu) { unsigned int nr; - nr = per_cpu(nr_cpu_bp_pinned, cpu); + nr = per_cpu(nr_cpu_bp_pinned[type], cpu); if (!tsk) - nr += max_task_bp_pinned(cpu); + nr += max_task_bp_pinned(cpu, type); else - nr += task_bp_pinned(tsk); + nr += task_bp_pinned(tsk, type); if (nr > slots->pinned) slots->pinned = nr; - nr = per_cpu(nr_bp_flexible, cpu); + nr = per_cpu(nr_bp_flexible[type], cpu); if (nr > slots->flexible) slots->flexible = nr; @@ -156,14 +176,15 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp) /* * Add a pinned breakpoint for the given task in our constraint table */ -static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable) +static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable, + enum bp_type_idx type) { unsigned int *tsk_pinned; int count = 0; - count = task_bp_pinned(tsk); + count = task_bp_pinned(tsk, type); - tsk_pinned = per_cpu(nr_task_bp_pinned, cpu); + tsk_pinned = per_cpu(nr_task_bp_pinned[type], cpu); if (enable) { tsk_pinned[count]++; if (count > 0) @@ -178,7 +199,8 @@ static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable) /* * Add/remove the given breakpoint in our constraint table */ -static void toggle_bp_slot(struct perf_event *bp, bool enable) +static void +toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type) { int cpu = bp->cpu; struct task_struct *tsk = bp->ctx->task; @@ -186,20 +208,20 @@ static void toggle_bp_slot(struct perf_event *bp, bool enable) /* Pinned counter task profiling */ if (tsk) { if (cpu >= 0) { - toggle_bp_task_slot(tsk, cpu, enable); + toggle_bp_task_slot(tsk, cpu, enable, type); return; } for_each_online_cpu(cpu) - toggle_bp_task_slot(tsk, cpu, enable); + toggle_bp_task_slot(tsk, cpu, enable, type); return; } /* Pinned counter cpu profiling */ if (enable) - per_cpu(nr_cpu_bp_pinned, bp->cpu)++; + per_cpu(nr_cpu_bp_pinned[type], bp->cpu)++; else - per_cpu(nr_cpu_bp_pinned, bp->cpu)--; + per_cpu(nr_cpu_bp_pinned[type], bp->cpu)--; } /* @@ -246,14 +268,21 @@ static void toggle_bp_slot(struct perf_event *bp, bool enable) static int __reserve_bp_slot(struct perf_event *bp) { struct bp_busy_slots slots = {0}; + enum bp_type_idx type; - fetch_bp_busy_slots(&slots, bp); + /* Basic checks */ + if (bp->attr.bp_type == HW_BREAKPOINT_EMPTY || + bp->attr.bp_type == HW_BREAKPOINT_INVALID) + return -EINVAL; + + type = find_slot_idx(bp); + fetch_bp_busy_slots(&slots, bp, type); /* Flexible counters need to keep at least one slot */ if (slots.pinned + (!!slots.flexible) == HBP_NUM) return -ENOSPC; - toggle_bp_slot(bp, true); + toggle_bp_slot(bp, true, type); return 0; } @@ -273,7 +302,10 @@ int reserve_bp_slot(struct perf_event *bp) static void __release_bp_slot(struct perf_event *bp) { - toggle_bp_slot(bp, false); + enum bp_type_idx type; + + type = find_slot_idx(bp); + toggle_bp_slot(bp, false, type); } void release_bp_slot(struct perf_event *bp) -- cgit v1.2.3-59-g8ed1b From feef47d0cb530e8419dfa0b48141b538b89b1b1a Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 23 Apr 2010 05:59:55 +0200 Subject: hw-breakpoints: Get the number of available registers on boot dynamically The breakpoint generic layer assumes that archs always know in advance the static number of address registers available to host breakpoints through the HBP_NUM macro. However this is not true for every archs. For example Arm needs to get this information dynamically to handle the compatiblity between different versions. To solve this, this patch proposes to drop the static HBP_NUM macro and let the arch provide the number of available slots through a new hw_breakpoint_slots() function. For archs that have CONFIG_HAVE_MIXED_BREAKPOINTS_REGS selected, it will be called once as the number of registers fits for instruction and data breakpoints together. For the others it will be called first to get the number of instruction breakpoint registers and another time to get the data breakpoint registers, the targeted type is given as a parameter of hw_breakpoint_slots(). Reported-by: Will Deacon Signed-off-by: Frederic Weisbecker Acked-by: Paul Mundt Cc: Mahesh Salgaonkar Cc: K. Prasad Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Jason Wessel Cc: Ingo Molnar --- arch/sh/include/asm/hw_breakpoint.h | 5 ++++ arch/x86/include/asm/hw_breakpoint.h | 5 ++++ include/linux/hw_breakpoint.h | 10 +++++++ kernel/hw_breakpoint.c | 53 ++++++++++++++++++++++++++++-------- kernel/trace/trace_ksym.c | 26 +++++------------- 5 files changed, 68 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h index 382bad937dcc..e14cad96798f 100644 --- a/arch/sh/include/asm/hw_breakpoint.h +++ b/arch/sh/include/asm/hw_breakpoint.h @@ -46,6 +46,11 @@ struct pmu; /* Maximum number of UBC channels */ #define HBP_NUM 2 +static inline int hw_breakpoint_slots(int type) +{ + return HBP_NUM; +} + /* arch/sh/kernel/hw_breakpoint.c */ extern int arch_check_bp_in_kernelspace(struct perf_event *bp); extern int arch_validate_hwbkpt_settings(struct perf_event *bp); diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h index c77a5a6fab9d..942255310e6a 100644 --- a/arch/x86/include/asm/hw_breakpoint.h +++ b/arch/x86/include/asm/hw_breakpoint.h @@ -41,6 +41,11 @@ struct arch_hw_breakpoint { /* Total number of available HW breakpoint registers */ #define HBP_NUM 4 +static inline int hw_breakpoint_slots(int type) +{ + return HBP_NUM; +} + struct perf_event; struct pmu; diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h index 7e8899093098..a2d6ea49ec56 100644 --- a/include/linux/hw_breakpoint.h +++ b/include/linux/hw_breakpoint.h @@ -17,6 +17,16 @@ enum { HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X, }; +enum bp_type_idx { + TYPE_INST = 0, +#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS + TYPE_DATA = 0, +#else + TYPE_DATA = 1, +#endif + TYPE_MAX +}; + #ifdef __KERNEL__ #include diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index 974498b858fc..684b710cbb91 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c @@ -40,20 +40,12 @@ #include #include #include +#include #include #include #include -enum bp_type_idx { - TYPE_INST = 0, -#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS - TYPE_DATA = 0, -#else - TYPE_DATA = 1, -#endif - TYPE_MAX -}; /* * Constraints data @@ -63,11 +55,15 @@ enum bp_type_idx { static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned[TYPE_MAX]); /* Number of pinned task breakpoints in a cpu */ -static DEFINE_PER_CPU(unsigned int, nr_task_bp_pinned[TYPE_MAX][HBP_NUM]); +static DEFINE_PER_CPU(unsigned int, *nr_task_bp_pinned[TYPE_MAX]); /* Number of non-pinned cpu/task breakpoints in a cpu */ static DEFINE_PER_CPU(unsigned int, nr_bp_flexible[TYPE_MAX]); +static int nr_slots[TYPE_MAX]; + +static int constraints_initialized; + /* Gather the number of total pinned and un-pinned bp in a cpuset */ struct bp_busy_slots { unsigned int pinned; @@ -99,7 +95,7 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type) int i; unsigned int *tsk_pinned = per_cpu(nr_task_bp_pinned[type], cpu); - for (i = HBP_NUM -1; i >= 0; i--) { + for (i = nr_slots[type] - 1; i >= 0; i--) { if (tsk_pinned[i] > 0) return i + 1; } @@ -292,6 +288,10 @@ static int __reserve_bp_slot(struct perf_event *bp) enum bp_type_idx type; int weight; + /* We couldn't initialize breakpoint constraints on boot */ + if (!constraints_initialized) + return -ENOMEM; + /* Basic checks */ if (bp->attr.bp_type == HW_BREAKPOINT_EMPTY || bp->attr.bp_type == HW_BREAKPOINT_INVALID) @@ -304,7 +304,7 @@ static int __reserve_bp_slot(struct perf_event *bp) fetch_this_slot(&slots, weight); /* Flexible counters need to keep at least one slot */ - if (slots.pinned + (!!slots.flexible) > HBP_NUM) + if (slots.pinned + (!!slots.flexible) > nr_slots[type]) return -ENOSPC; toggle_bp_slot(bp, true, type, weight); @@ -551,7 +551,36 @@ static struct notifier_block hw_breakpoint_exceptions_nb = { static int __init init_hw_breakpoint(void) { + unsigned int **task_bp_pinned; + int cpu, err_cpu; + int i; + + for (i = 0; i < TYPE_MAX; i++) + nr_slots[i] = hw_breakpoint_slots(i); + + for_each_possible_cpu(cpu) { + for (i = 0; i < TYPE_MAX; i++) { + task_bp_pinned = &per_cpu(nr_task_bp_pinned[i], cpu); + *task_bp_pinned = kzalloc(sizeof(int) * nr_slots[i], + GFP_KERNEL); + if (!*task_bp_pinned) + goto err_alloc; + } + } + + constraints_initialized = 1; + return register_die_notifier(&hw_breakpoint_exceptions_nb); + + err_alloc: + for_each_possible_cpu(err_cpu) { + if (err_cpu == cpu) + break; + for (i = 0; i < TYPE_MAX; i++) + kfree(per_cpu(nr_task_bp_pinned[i], cpu)); + } + + return -ENOMEM; } core_initcall(init_hw_breakpoint); diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index d59cd6879477..8eaf00749b65 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c @@ -34,12 +34,6 @@ #include -/* - * For now, let us restrict the no. of symbols traced simultaneously to number - * of available hardware breakpoint registers. - */ -#define KSYM_TRACER_MAX HBP_NUM - #define KSYM_TRACER_OP_LEN 3 /* rw- */ struct trace_ksym { @@ -53,7 +47,6 @@ struct trace_ksym { static struct trace_array *ksym_trace_array; -static unsigned int ksym_filter_entry_count; static unsigned int ksym_tracing_enabled; static HLIST_HEAD(ksym_filter_head); @@ -181,13 +174,6 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr) struct trace_ksym *entry; int ret = -ENOMEM; - if (ksym_filter_entry_count >= KSYM_TRACER_MAX) { - printk(KERN_ERR "ksym_tracer: Maximum limit:(%d) reached. No" - " new requests for tracing can be accepted now.\n", - KSYM_TRACER_MAX); - return -ENOSPC; - } - entry = kzalloc(sizeof(struct trace_ksym), GFP_KERNEL); if (!entry) return -ENOMEM; @@ -203,13 +189,17 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr) if (IS_ERR(entry->ksym_hbp)) { ret = PTR_ERR(entry->ksym_hbp); - printk(KERN_INFO "ksym_tracer request failed. Try again" - " later!!\n"); + if (ret == -ENOSPC) { + printk(KERN_ERR "ksym_tracer: Maximum limit reached." + " No new requests for tracing can be accepted now.\n"); + } else { + printk(KERN_INFO "ksym_tracer request failed. Try again" + " later!!\n"); + } goto err; } hlist_add_head_rcu(&(entry->ksym_hlist), &ksym_filter_head); - ksym_filter_entry_count++; return 0; @@ -265,7 +255,6 @@ static void __ksym_trace_reset(void) hlist_for_each_entry_safe(entry, node, node1, &ksym_filter_head, ksym_hlist) { unregister_wide_hw_breakpoint(entry->ksym_hbp); - ksym_filter_entry_count--; hlist_del_rcu(&(entry->ksym_hlist)); synchronize_rcu(); kfree(entry); @@ -338,7 +327,6 @@ static ssize_t ksym_trace_filter_write(struct file *file, goto out_unlock; } /* Error or "symbol:---" case: drop it */ - ksym_filter_entry_count--; hlist_del_rcu(&(entry->ksym_hlist)); synchronize_rcu(); kfree(entry); -- cgit v1.2.3-59-g8ed1b From da7ba956c84d3c85c5ec619af794a6ca0ee3faae Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 17 Jan 2010 19:59:58 +0000 Subject: ARM: Integrator: fix Integrator/CP definitions, move to platform.h Signed-off-by: Russell King --- arch/arm/mach-integrator/include/mach/platform.h | 14 +++++---- arch/arm/mach-integrator/integrator_ap.c | 4 +-- arch/arm/mach-integrator/integrator_cp.c | 38 +++++++++++------------- 3 files changed, 28 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/include/mach/platform.h index e00a2624f269..0e172e48bc85 100644 --- a/arch/arm/mach-integrator/include/mach/platform.h +++ b/arch/arm/mach-integrator/include/mach/platform.h @@ -290,12 +290,14 @@ #define INTEGRATOR_DBG_LEDS (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_LEDS_OFFSET) #define INTEGRATOR_DBG_SWITCH (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET) - -#if defined(CONFIG_ARCH_INTEGRATOR_AP) -#define INTEGRATOR_GPIO_BASE 0x1B000000 /* GPIO */ -#elif defined(CONFIG_ARCH_INTEGRATOR_CP) -#define INTEGRATOR_GPIO_BASE 0xC9000000 /* GPIO */ -#endif +#define INTEGRATOR_AP_GPIO_BASE 0x1B000000 /* GPIO */ + +#define INTEGRATOR_CP_MMC_BASE 0x1C000000 /* MMC */ +#define INTEGRATOR_CP_AACI_BASE 0x1D000000 /* AACI */ +#define INTEGRATOR_CP_ETH_BASE 0xC8000000 /* Ethernet */ +#define INTEGRATOR_CP_GPIO_BASE 0xC9000000 /* GPIO */ +#define INTEGRATOR_CP_SIC_BASE 0xCA000000 /* SIC */ +#define INTEGRATOR_CP_CTL_BASE 0xCB000000 /* CP system control */ /* ------------------------------------------------------------------------ * KMI keyboard/mouse definitions diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 93da7d4e459b..45bba041c8d0 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -118,8 +118,8 @@ static struct map_desc ap_io_desc[] __initdata = { .length = SZ_4K, .type = MT_DEVICE }, { - .virtual = IO_ADDRESS(INTEGRATOR_GPIO_BASE), - .pfn = __phys_to_pfn(INTEGRATOR_GPIO_BASE), + .virtual = IO_ADDRESS(INTEGRATOR_AP_GPIO_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_AP_GPIO_BASE), .length = SZ_4K, .type = MT_DEVICE }, { diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 108bc480237a..333c297a97cc 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -42,9 +42,6 @@ #include "common.h" -#define INTCP_PA_MMC_BASE 0x1c000000 -#define INTCP_PA_AACI_BASE 0x1d000000 - #define INTCP_PA_FLASH_BASE 0x24000000 #define INTCP_FLASH_SIZE SZ_32M @@ -52,12 +49,11 @@ #define INTCP_VA_CIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + 0x40 #define INTCP_VA_PIC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) -#define INTCP_VA_SIC_BASE IO_ADDRESS(0xca000000) +#define INTCP_VA_SIC_BASE IO_ADDRESS(INTEGRATOR_CP_SIC_BASE) -#define INTCP_PA_ETH_BASE 0xc8000000 #define INTCP_ETH_SIZE 0x10 -#define INTCP_VA_CTRL_BASE IO_ADDRESS(0xcb000000) +#define INTCP_VA_CTRL_BASE IO_ADDRESS(INTEGRATOR_CP_CTL_BASE) #define INTCP_FLASHPROG 0x04 #define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0) #define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1) @@ -72,7 +68,9 @@ * f1600000 16000000 UART 0 * f1700000 17000000 UART 1 * f1a00000 1a000000 Debug LEDs - * f1b00000 1b000000 GPIO + * fc900000 c9000000 GPIO + * fca00000 ca000000 SIC + * fcb00000 cb000000 CP system control */ static struct map_desc intcp_io_desc[] __initdata = { @@ -117,18 +115,18 @@ static struct map_desc intcp_io_desc[] __initdata = { .length = SZ_4K, .type = MT_DEVICE }, { - .virtual = IO_ADDRESS(INTEGRATOR_GPIO_BASE), - .pfn = __phys_to_pfn(INTEGRATOR_GPIO_BASE), + .virtual = IO_ADDRESS(INTEGRATOR_CP_GPIO_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_CP_GPIO_BASE), .length = SZ_4K, .type = MT_DEVICE }, { - .virtual = IO_ADDRESS(0xca000000), - .pfn = __phys_to_pfn(0xca000000), + .virtual = IO_ADDRESS(INTEGRATOR_CP_SIC_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_CP_SIC_BASE), .length = SZ_4K, .type = MT_DEVICE }, { - .virtual = IO_ADDRESS(0xcb000000), - .pfn = __phys_to_pfn(0xcb000000), + .virtual = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE), .length = SZ_4K, .type = MT_DEVICE } @@ -364,8 +362,8 @@ static struct platform_device intcp_flash_device = { static struct resource smc91x_resources[] = { [0] = { - .start = INTCP_PA_ETH_BASE, - .end = INTCP_PA_ETH_BASE + INTCP_ETH_SIZE - 1, + .start = INTEGRATOR_CP_ETH_BASE, + .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -396,7 +394,7 @@ static struct platform_device *intcp_devs[] __initdata = { static unsigned int mmc_status(struct device *dev) { unsigned int status = readl(IO_ADDRESS(0xca000000) + 4); - writel(8, IO_ADDRESS(0xcb000000) + 8); + writel(8, IO_ADDRESS(INTEGRATOR_CP_CTL_BASE) + 8); return status & 8; } @@ -414,8 +412,8 @@ static struct amba_device mmc_device = { .platform_data = &mmc_data, }, .res = { - .start = INTCP_PA_MMC_BASE, - .end = INTCP_PA_MMC_BASE + SZ_4K - 1, + .start = INTEGRATOR_CP_MMC_BASE, + .end = INTEGRATOR_CP_MMC_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, .irq = { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }, @@ -427,8 +425,8 @@ static struct amba_device aaci_device = { .init_name = "mb:1d", }, .res = { - .start = INTCP_PA_AACI_BASE, - .end = INTCP_PA_AACI_BASE + SZ_4K - 1, + .start = INTEGRATOR_CP_AACI_BASE, + .end = INTEGRATOR_CP_AACI_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, .irq = { IRQ_CP_AACIINT, NO_IRQ }, -- cgit v1.2.3-59-g8ed1b From 7d60a044c8226d86fa93c2cf90ccdb97e3ba28fa Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 17 Jan 2010 20:23:57 +0000 Subject: ARM: Integrator: allow IO_ADDRESS() to be used for register addresses Signed-off-by: Russell King --- arch/arm/mach-integrator/include/mach/hardware.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-integrator/include/mach/hardware.h b/arch/arm/mach-integrator/include/mach/hardware.h index d44af7209b48..8e26360ce9a3 100644 --- a/arch/arm/mach-integrator/include/mach/hardware.h +++ b/arch/arm/mach-integrator/include/mach/hardware.h @@ -35,18 +35,18 @@ #define PCIO_BASE PCI_IO_VADDR #define PCIMEM_BASE PCI_MEMORY_VADDR -#ifdef CONFIG_MMU -/* macro to get at IO space when running virtually */ -#define IO_ADDRESS(x) (((x) >> 4) + IO_BASE) -#else -#define IO_ADDRESS(x) (x) -#endif - #define pcibios_assign_all_busses() 1 #define PCIBIOS_MIN_IO 0x6000 #define PCIBIOS_MIN_MEM 0x00100000 +/* macro to get at IO space when running virtually */ +#ifdef CONFIG_MMU +#define IO_ADDRESS(x) (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE) +#else +#define IO_ADDRESS(x) (x) +#endif + #define __io_address(n) ((void __iomem *)IO_ADDRESS(n)) #endif -- cgit v1.2.3-59-g8ed1b From b830b9b5b3d04bc22f0b9ded85b713f7d3c11b7f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 17 Jan 2010 20:45:12 +0000 Subject: ARM: Integrator: convert to use register definitions Rather than using converted base address plus offset, use the register address itself now that IO_ADDRESS() can cope with these. Signed-off-by: Russell King --- arch/arm/mach-integrator/core.c | 12 ++++++------ arch/arm/mach-integrator/cpu.c | 8 ++++---- arch/arm/mach-integrator/integrator_ap.c | 2 +- arch/arm/mach-integrator/integrator_cp.c | 10 +++++----- arch/arm/mach-integrator/pci_v3.c | 6 +++--- 5 files changed, 19 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index d02f0e3afdcb..ac2b0c5c991b 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -166,8 +166,8 @@ arch_initcall(integrator_init); * UART0 7 6 * UART1 5 4 */ -#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET) -#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET) +#define SC_CTRLC IO_ADDRESS(INTEGRATOR_SC_CTRLC) +#define SC_CTRLS IO_ADDRESS(INTEGRATOR_SC_CTRLS) static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl) { @@ -199,7 +199,7 @@ static struct amba_pl010_data integrator_uart_data = { .set_mctrl = integrator_uart_set_mctrl, }; -#define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET +#define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_CTRL) static DEFINE_SPINLOCK(cm_lock); @@ -224,9 +224,9 @@ EXPORT_SYMBOL(cm_control); /* * Where is the timer (VA)? */ -#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000) -#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100) -#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200) +#define TIMER0_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER0_BASE) +#define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE) +#define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE) /* * How long is the timer interval? diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index b7618790460a..7f1b73b776a7 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -26,10 +26,10 @@ static struct cpufreq_driver integrator_driver; -#define CM_ID (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_ID_OFFSET) -#define CM_OSC (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_OSC_OFFSET) -#define CM_STAT (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_STAT_OFFSET) -#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET) +#define CM_ID IO_ADDRESS(INTEGRATOR_HDR_ID) +#define CM_OSC IO_ADDRESS(INTEGRATOR_HDR_OSC) +#define CM_STAT IO_ADDRESS(INTEGRATOR_HDR_STAT) +#define CM_LOCK IO_ADDRESS(INTEGRATOR_HDR_LOCK) static const struct icst525_params lclk_params = { .ref = 24000, diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 45bba041c8d0..c89b231898e6 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -56,7 +56,7 @@ #define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) #define VA_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE) #define VA_EBI_BASE IO_ADDRESS(INTEGRATOR_EBI_BASE) -#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET +#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_IC) /* * Logical Physical diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 333c297a97cc..c0161df9d9a2 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -47,7 +47,7 @@ #define INTCP_PA_CLCD_BASE 0xc0000000 -#define INTCP_VA_CIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + 0x40 +#define INTCP_VA_CIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x40) #define INTCP_VA_PIC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) #define INTCP_VA_SIC_BASE IO_ADDRESS(INTEGRATOR_CP_SIC_BASE) @@ -265,8 +265,8 @@ static void __init intcp_init_irq(void) /* * Clock handling */ -#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET) -#define CM_AUXOSC (IO_ADDRESS(INTEGRATOR_HDR_BASE)+0x1c) +#define CM_LOCK IO_ADDRESS(INTEGRATOR_HDR_LOCK) +#define CM_AUXOSC IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x1c) static const struct icst525_params cp_auxvco_params = { .ref = 24000, @@ -393,8 +393,8 @@ static struct platform_device *intcp_devs[] __initdata = { */ static unsigned int mmc_status(struct device *dev) { - unsigned int status = readl(IO_ADDRESS(0xca000000) + 4); - writel(8, IO_ADDRESS(INTEGRATOR_CP_CTL_BASE) + 8); + unsigned int status = readl(IO_ADDRESS(0xca000000 + 4)); + writel(8, IO_ADDRESS(INTEGRATOR_CP_CTL_BASE + 8)); return status & 8; } diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index e87fe9fa4344..e5491629c6da 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -391,9 +391,9 @@ static int __init pci_v3_setup_resources(struct resource **resource) * means I can't get additional information on the reason for the pm2fb * problems. I suppose I'll just have to mind-meld with the machine. ;) */ -#define SC_PCI (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_PCIENABLE_OFFSET) -#define SC_LBFADDR (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x20) -#define SC_LBFCODE (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x24) +#define SC_PCI IO_ADDRESS(INTEGRATOR_SC_PCIENABLE) +#define SC_LBFADDR IO_ADDRESS(INTEGRATOR_SC_BASE + 0x20) +#define SC_LBFCODE IO_ADDRESS(INTEGRATOR_SC_BASE + 0x24) static int v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) -- cgit v1.2.3-59-g8ed1b From 39c0cb02db5b8fdfac76d506b7a008b70bc960e9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Jan 2010 16:27:28 +0000 Subject: ARM: ICST: merge common ICST VCO structures The structures for the ICST307 and ICST525 VCO devices are identical, so merge them together. Signed-off-by: Russell King --- arch/arm/common/icst307.c | 14 +++++------ arch/arm/common/icst525.c | 14 +++++------ arch/arm/include/asm/hardware/icst.h | 32 ++++++++++++++++++++++++++ arch/arm/include/asm/hardware/icst307.h | 21 ++++------------- arch/arm/include/asm/hardware/icst525.h | 21 ++++------------- arch/arm/mach-integrator/clock.c | 5 ++-- arch/arm/mach-integrator/cpu.c | 10 ++++---- arch/arm/mach-integrator/impd1.c | 4 ++-- arch/arm/mach-integrator/include/mach/clkdev.h | 6 ++--- arch/arm/mach-integrator/integrator_cp.c | 4 ++-- arch/arm/mach-realview/clock.c | 4 ++-- arch/arm/mach-realview/clock.h | 7 +++--- arch/arm/mach-realview/core.c | 4 ++-- arch/arm/mach-versatile/clock.c | 4 ++-- arch/arm/mach-versatile/clock.h | 7 +++--- arch/arm/mach-versatile/core.c | 4 ++-- 16 files changed, 85 insertions(+), 76 deletions(-) create mode 100644 arch/arm/include/asm/hardware/icst.h (limited to 'arch') diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c index 6d094c157540..2eebd960c01b 100644 --- a/arch/arm/common/icst307.c +++ b/arch/arm/common/icst307.c @@ -24,7 +24,7 @@ */ static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 }; -unsigned long icst307_khz(const struct icst307_params *p, struct icst307_vco vco) +unsigned long icst307_khz(const struct icst_params *p, struct icst_vco vco) { return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]); } @@ -36,10 +36,10 @@ EXPORT_SYMBOL(icst307_khz); */ static unsigned char idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 }; -struct icst307_vco -icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq) +struct icst_vco +icst307_khz_to_vco(const struct icst_params *p, unsigned long freq) { - struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; unsigned long f; unsigned int i = 0, rd, best = (unsigned int)-1; @@ -96,10 +96,10 @@ icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq) EXPORT_SYMBOL(icst307_khz_to_vco); -struct icst307_vco -icst307_ps_to_vco(const struct icst307_params *p, unsigned long period) +struct icst_vco +icst307_ps_to_vco(const struct icst_params *p, unsigned long period) { - struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; unsigned long f, ps; unsigned int i = 0, rd, best = (unsigned int)-1; diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c index 3d377c5bdef6..fd5c2e7ed176 100644 --- a/arch/arm/common/icst525.c +++ b/arch/arm/common/icst525.c @@ -21,7 +21,7 @@ */ static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 }; -unsigned long icst525_khz(const struct icst525_params *p, struct icst525_vco vco) +unsigned long icst525_khz(const struct icst_params *p, struct icst_vco vco) { return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]); } @@ -33,10 +33,10 @@ EXPORT_SYMBOL(icst525_khz); */ static unsigned char idx2s[] = { 1, 3, 4, 7, 5, 2, 6, 0 }; -struct icst525_vco -icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq) +struct icst_vco +icst525_khz_to_vco(const struct icst_params *p, unsigned long freq) { - struct icst525_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; unsigned long f; unsigned int i = 0, rd, best = (unsigned int)-1; @@ -94,10 +94,10 @@ icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq) EXPORT_SYMBOL(icst525_khz_to_vco); -struct icst525_vco -icst525_ps_to_vco(const struct icst525_params *p, unsigned long period) +struct icst_vco +icst525_ps_to_vco(const struct icst_params *p, unsigned long period) { - struct icst525_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; unsigned long f, ps; unsigned int i = 0, rd, best = (unsigned int)-1; diff --git a/arch/arm/include/asm/hardware/icst.h b/arch/arm/include/asm/hardware/icst.h new file mode 100644 index 000000000000..65b1edd4452b --- /dev/null +++ b/arch/arm/include/asm/hardware/icst.h @@ -0,0 +1,32 @@ +/* + * arch/arm/include/asm/hardware/icst.h + * + * Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 version 2 as + * published by the Free Software Foundation. + * + * Support functions for calculating clocks/divisors for the ICST + * clock generators. See http://www.icst.com/ for more information + * on these devices. + */ +#ifndef ASMARM_HARDWARE_ICST_H +#define ASMARM_HARDWARE_ICST_H + +struct icst_params { + unsigned long ref; + unsigned long vco_max; /* inclusive */ + unsigned short vd_min; /* inclusive */ + unsigned short vd_max; /* inclusive */ + unsigned char rd_min; /* inclusive */ + unsigned char rd_max; /* inclusive */ +}; + +struct icst_vco { + unsigned short v; + unsigned char r; + unsigned char s; +}; + +#endif diff --git a/arch/arm/include/asm/hardware/icst307.h b/arch/arm/include/asm/hardware/icst307.h index 554f128a1046..85932e902e99 100644 --- a/arch/arm/include/asm/hardware/icst307.h +++ b/arch/arm/include/asm/hardware/icst307.h @@ -16,23 +16,10 @@ #ifndef ASMARM_HARDWARE_ICST307_H #define ASMARM_HARDWARE_ICST307_H -struct icst307_params { - unsigned long ref; - unsigned long vco_max; /* inclusive */ - unsigned short vd_min; /* inclusive */ - unsigned short vd_max; /* inclusive */ - unsigned char rd_min; /* inclusive */ - unsigned char rd_max; /* inclusive */ -}; +#include -struct icst307_vco { - unsigned short v; - unsigned char r; - unsigned char s; -}; - -unsigned long icst307_khz(const struct icst307_params *p, struct icst307_vco vco); -struct icst307_vco icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq); -struct icst307_vco icst307_ps_to_vco(const struct icst307_params *p, unsigned long period); +unsigned long icst307_khz(const struct icst_params *p, struct icst_vco vco); +struct icst_vco icst307_khz_to_vco(const struct icst_params *p, unsigned long freq); +struct icst_vco icst307_ps_to_vco(const struct icst_params *p, unsigned long period); #endif diff --git a/arch/arm/include/asm/hardware/icst525.h b/arch/arm/include/asm/hardware/icst525.h index 58f0dc43e2ed..170deb2b605b 100644 --- a/arch/arm/include/asm/hardware/icst525.h +++ b/arch/arm/include/asm/hardware/icst525.h @@ -14,23 +14,10 @@ #ifndef ASMARM_HARDWARE_ICST525_H #define ASMARM_HARDWARE_ICST525_H -struct icst525_params { - unsigned long ref; - unsigned long vco_max; /* inclusive */ - unsigned short vd_min; /* inclusive */ - unsigned short vd_max; /* inclusive */ - unsigned char rd_min; /* inclusive */ - unsigned char rd_max; /* inclusive */ -}; +#include -struct icst525_vco { - unsigned short v; - unsigned char r; - unsigned char s; -}; - -unsigned long icst525_khz(const struct icst525_params *p, struct icst525_vco vco); -struct icst525_vco icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq); -struct icst525_vco icst525_ps_to_vco(const struct icst525_params *p, unsigned long period); +unsigned long icst525_khz(const struct icst_params *p, struct icst_vco vco); +struct icst_vco icst525_khz_to_vco(const struct icst_params *p, unsigned long freq); +struct icst_vco icst525_ps_to_vco(const struct icst_params *p, unsigned long period); #endif diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c index 989ecf5f5c46..bb70b64a6563 100644 --- a/arch/arm/mach-integrator/clock.c +++ b/arch/arm/mach-integrator/clock.c @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -36,7 +37,7 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { - struct icst525_vco vco; + struct icst_vco vco; vco = icst525_khz_to_vco(clk->params, rate / 1000); return icst525_khz(clk->params, vco) * 1000; } @@ -47,7 +48,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) int ret = -EIO; if (clk->setvco) { - struct icst525_vco vco; + struct icst_vco vco; vco = icst525_khz_to_vco(clk->params, rate / 1000); clk->rate = icst525_khz(clk->params, vco) * 1000; diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index 7f1b73b776a7..c4e5debeb48c 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -31,7 +31,7 @@ static struct cpufreq_driver integrator_driver; #define CM_STAT IO_ADDRESS(INTEGRATOR_HDR_STAT) #define CM_LOCK IO_ADDRESS(INTEGRATOR_HDR_LOCK) -static const struct icst525_params lclk_params = { +static const struct icst_params lclk_params = { .ref = 24000, .vco_max = 320000, .vd_min = 8, @@ -40,7 +40,7 @@ static const struct icst525_params lclk_params = { .rd_max = 24, }; -static const struct icst525_params cclk_params = { +static const struct icst_params cclk_params = { .ref = 24000, .vco_max = 320000, .vd_min = 12, @@ -54,7 +54,7 @@ static const struct icst525_params cclk_params = { */ static int integrator_verify_policy(struct cpufreq_policy *policy) { - struct icst525_vco vco; + struct icst_vco vco; cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, @@ -80,7 +80,7 @@ static int integrator_set_target(struct cpufreq_policy *policy, { cpumask_t cpus_allowed; int cpu = policy->cpu; - struct icst525_vco vco; + struct icst_vco vco; struct cpufreq_freqs freqs; u_int cm_osc; @@ -156,7 +156,7 @@ static unsigned int integrator_get(unsigned int cpu) cpumask_t cpus_allowed; unsigned int current_freq; u_int cm_osc; - struct icst525_vco vco; + struct icst_vco vco; cpus_allowed = current->cpus_allowed; diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 0058c937719e..dfb961b67afa 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -40,7 +40,7 @@ struct impd1_module { struct clk_lookup *clks[3]; }; -static const struct icst525_params impd1_vco_params = { +static const struct icst_params impd1_vco_params = { .ref = 24000, /* 24 MHz */ .vco_max = 200000, /* 200 MHz */ .vd_min = 12, @@ -49,7 +49,7 @@ static const struct icst525_params impd1_vco_params = { .rd_max = 120, }; -static void impd1_setvco(struct clk *clk, struct icst525_vco vco) +static void impd1_setvco(struct clk *clk, struct icst_vco vco) { struct impd1_module *impd1 = clk->data; int vconr = clk - impd1->vcos; diff --git a/arch/arm/mach-integrator/include/mach/clkdev.h b/arch/arm/mach-integrator/include/mach/clkdev.h index 9293e410832a..89ea93803998 100644 --- a/arch/arm/mach-integrator/include/mach/clkdev.h +++ b/arch/arm/mach-integrator/include/mach/clkdev.h @@ -2,14 +2,14 @@ #define __ASM_MACH_CLKDEV_H #include -#include +#include struct clk { unsigned long rate; struct module *owner; - const struct icst525_params *params; + const struct icst_params *params; void *data; - void (*setvco)(struct clk *, struct icst525_vco vco); + void (*setvco)(struct clk *, struct icst_vco vco); }; static inline int __clk_get(struct clk *clk) diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index c0161df9d9a2..15bfbe2e1df8 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -268,7 +268,7 @@ static void __init intcp_init_irq(void) #define CM_LOCK IO_ADDRESS(INTEGRATOR_HDR_LOCK) #define CM_AUXOSC IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x1c) -static const struct icst525_params cp_auxvco_params = { +static const struct icst_params cp_auxvco_params = { .ref = 24000, .vco_max = 320000, .vd_min = 8, @@ -277,7 +277,7 @@ static const struct icst525_params cp_auxvco_params = { .rd_max = 65, }; -static void cp_auxvco_set(struct clk *clk, struct icst525_vco vco) +static void cp_auxvco_set(struct clk *clk, struct icst_vco vco) { u32 val; diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c index a7043115de72..83646579bc45 100644 --- a/arch/arm/mach-realview/clock.c +++ b/arch/arm/mach-realview/clock.c @@ -41,7 +41,7 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { - struct icst307_vco vco; + struct icst_vco vco; vco = icst307_khz_to_vco(clk->params, rate / 1000); return icst307_khz(clk->params, vco) * 1000; } @@ -52,7 +52,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) int ret = -EIO; if (clk->setvco) { - struct icst307_vco vco; + struct icst_vco vco; vco = icst307_khz_to_vco(clk->params, rate / 1000); clk->rate = icst307_khz(clk->params, vco) * 1000; diff --git a/arch/arm/mach-realview/clock.h b/arch/arm/mach-realview/clock.h index ebbb0f06b600..fa64c854258d 100644 --- a/arch/arm/mach-realview/clock.h +++ b/arch/arm/mach-realview/clock.h @@ -8,12 +8,13 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include + struct module; -struct icst307_params; struct clk { unsigned long rate; - const struct icst307_params *params; + const struct icst_params *params; void *data; - void (*setvco)(struct clk *, struct icst307_vco vco); + void (*setvco)(struct clk *, struct icst_vco vco); }; diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 90bd4ef71b2c..ac504745fed1 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -273,7 +273,7 @@ struct mmci_platform_data realview_mmc1_plat_data = { /* * Clock handling */ -static const struct icst307_params realview_oscvco_params = { +static const struct icst_params realview_oscvco_params = { .ref = 24000, .vco_max = 200000, .vd_min = 4 + 8, @@ -282,7 +282,7 @@ static const struct icst307_params realview_oscvco_params = { .rd_max = 127 + 2, }; -static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco) +static void realview_oscvco_set(struct clk *clk, struct icst_vco vco) { void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET; void __iomem *sys_osc; diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c index c50a44ea7ee6..530e16aa7ad6 100644 --- a/arch/arm/mach-versatile/clock.c +++ b/arch/arm/mach-versatile/clock.c @@ -42,7 +42,7 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { - struct icst307_vco vco; + struct icst_vco vco; vco = icst307_khz_to_vco(clk->params, rate / 1000); return icst307_khz(clk->params, vco) * 1000; } @@ -53,7 +53,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) int ret = -EIO; if (clk->setvco) { - struct icst307_vco vco; + struct icst_vco vco; vco = icst307_khz_to_vco(clk->params, rate / 1000); clk->rate = icst307_khz(clk->params, vco) * 1000; diff --git a/arch/arm/mach-versatile/clock.h b/arch/arm/mach-versatile/clock.h index 03468fdc3e58..aed7e22d102b 100644 --- a/arch/arm/mach-versatile/clock.h +++ b/arch/arm/mach-versatile/clock.h @@ -8,13 +8,14 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include + struct module; -struct icst307_params; struct clk { unsigned long rate; - const struct icst307_params *params; + const struct icst_params *params; u32 oscoff; void *data; - void (*setvco)(struct clk *, struct icst307_vco vco); + void (*setvco)(struct clk *, struct icst_vco vco); }; diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index b77bc407b77d..ded71343553f 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -379,7 +379,7 @@ static struct mmci_platform_data mmc0_plat_data = { /* * Clock handling */ -static const struct icst307_params versatile_oscvco_params = { +static const struct icst_params versatile_oscvco_params = { .ref = 24000, .vco_max = 200000, .vd_min = 4 + 8, @@ -388,7 +388,7 @@ static const struct icst307_params versatile_oscvco_params = { .rd_max = 127 + 2, }; -static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco) +static void versatile_oscvco_set(struct clk *clk, struct icst_vco vco) { void __iomem *sys = __io_address(VERSATILE_SYS_BASE); void __iomem *sys_lock = sys + VERSATILE_SYS_LOCK_OFFSET; -- cgit v1.2.3-59-g8ed1b From 643761ac43dfe4bea1195e966fc65a9403cdcb9f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Jan 2010 17:15:07 +0000 Subject: ARM: ICST: icst.*_ps_to_vco() functions are unused, remove them These functions were originally implemented for the CLCD driver before we had clk API support. Since the CLCD driver does not use these anymore, we can remove them. Signed-off-by: Russell King --- arch/arm/common/icst307.c | 64 -------------------------------- arch/arm/common/icst525.c | 65 --------------------------------- arch/arm/include/asm/hardware/icst307.h | 1 - arch/arm/include/asm/hardware/icst525.h | 1 - 4 files changed, 131 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c index 2eebd960c01b..f78f5b5880c2 100644 --- a/arch/arm/common/icst307.c +++ b/arch/arm/common/icst307.c @@ -95,67 +95,3 @@ icst307_khz_to_vco(const struct icst_params *p, unsigned long freq) } EXPORT_SYMBOL(icst307_khz_to_vco); - -struct icst_vco -icst307_ps_to_vco(const struct icst_params *p, unsigned long period) -{ - struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; - unsigned long f, ps; - unsigned int i = 0, rd, best = (unsigned int)-1; - - ps = 1000000000UL / p->vco_max; - - /* - * First, find the PLL output divisor such - * that the PLL output is within spec. - */ - do { - f = period / s2div[idx2s[i]]; - - /* - * f must be between 6MHz and 200MHz (3.3 or 5V) - */ - if (f >= ps && f < 1000000000UL / 6000 + 1) - break; - } while (i < ARRAY_SIZE(idx2s)); - - if (i >= ARRAY_SIZE(idx2s)) - return vco; - - vco.s = idx2s[i]; - - ps = 500000000UL / p->ref; - - /* - * Now find the closest divisor combination - * which gives a PLL output of 'f'. - */ - for (rd = p->rd_min; rd <= p->rd_max; rd++) { - unsigned long f_in_div, f_pll; - unsigned int vd; - int f_diff; - - f_in_div = ps * rd; - - vd = (f_in_div + f / 2) / f; - if (vd < p->vd_min || vd > p->vd_max) - continue; - - f_pll = (f_in_div + vd / 2) / vd; - f_diff = f_pll - f; - if (f_diff < 0) - f_diff = -f_diff; - - if ((unsigned)f_diff < best) { - vco.v = vd - 8; - vco.r = rd - 2; - if (f_diff == 0) - break; - best = f_diff; - } - } - - return vco; -} - -EXPORT_SYMBOL(icst307_ps_to_vco); diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c index fd5c2e7ed176..eadf983ee434 100644 --- a/arch/arm/common/icst525.c +++ b/arch/arm/common/icst525.c @@ -93,68 +93,3 @@ icst525_khz_to_vco(const struct icst_params *p, unsigned long freq) } EXPORT_SYMBOL(icst525_khz_to_vco); - -struct icst_vco -icst525_ps_to_vco(const struct icst_params *p, unsigned long period) -{ - struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; - unsigned long f, ps; - unsigned int i = 0, rd, best = (unsigned int)-1; - - ps = 1000000000UL / p->vco_max; - - /* - * First, find the PLL output divisor such - * that the PLL output is within spec. - */ - do { - f = period / s2div[idx2s[i]]; - - /* - * f must be between 10MHz and - * 320MHz (5V) or 200MHz (3V) - */ - if (f >= ps && f < 100000) - break; - } while (i < ARRAY_SIZE(idx2s)); - - if (i >= ARRAY_SIZE(idx2s)) - return vco; - - vco.s = idx2s[i]; - - ps = 500000000UL / p->ref; - - /* - * Now find the closest divisor combination - * which gives a PLL output of 'f'. - */ - for (rd = p->rd_min; rd <= p->rd_max; rd++) { - unsigned long f_in_div, f_pll; - unsigned int vd; - int f_diff; - - f_in_div = ps * rd; - - vd = (f_in_div + f / 2) / f; - if (vd < p->vd_min || vd > p->vd_max) - continue; - - f_pll = (f_in_div + vd / 2) / vd; - f_diff = f_pll - f; - if (f_diff < 0) - f_diff = -f_diff; - - if ((unsigned)f_diff < best) { - vco.v = vd - 8; - vco.r = rd - 2; - if (f_diff == 0) - break; - best = f_diff; - } - } - - return vco; -} - -EXPORT_SYMBOL(icst525_ps_to_vco); diff --git a/arch/arm/include/asm/hardware/icst307.h b/arch/arm/include/asm/hardware/icst307.h index 85932e902e99..8d0820a654db 100644 --- a/arch/arm/include/asm/hardware/icst307.h +++ b/arch/arm/include/asm/hardware/icst307.h @@ -20,6 +20,5 @@ unsigned long icst307_khz(const struct icst_params *p, struct icst_vco vco); struct icst_vco icst307_khz_to_vco(const struct icst_params *p, unsigned long freq); -struct icst_vco icst307_ps_to_vco(const struct icst_params *p, unsigned long period); #endif diff --git a/arch/arm/include/asm/hardware/icst525.h b/arch/arm/include/asm/hardware/icst525.h index 170deb2b605b..42a274e59fa2 100644 --- a/arch/arm/include/asm/hardware/icst525.h +++ b/arch/arm/include/asm/hardware/icst525.h @@ -18,6 +18,5 @@ unsigned long icst525_khz(const struct icst_params *p, struct icst_vco vco); struct icst_vco icst525_khz_to_vco(const struct icst_params *p, unsigned long freq); -struct icst_vco icst525_ps_to_vco(const struct icst_params *p, unsigned long period); #endif -- cgit v1.2.3-59-g8ed1b From 4de2edbd15ff70c77e1d018611d06f7801fc2b72 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Jan 2010 18:08:47 +0000 Subject: ARM: ICST: provide definitions for max/min VCO frequencies Signed-off-by: Russell King --- arch/arm/common/icst307.c | 2 +- arch/arm/common/icst525.c | 2 +- arch/arm/include/asm/hardware/icst307.h | 7 +++++++ arch/arm/include/asm/hardware/icst525.h | 8 ++++++++ arch/arm/mach-integrator/cpu.c | 4 ++-- arch/arm/mach-integrator/impd1.c | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-versatile/core.c | 2 +- 9 files changed, 23 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c index f78f5b5880c2..f6063c95e256 100644 --- a/arch/arm/common/icst307.c +++ b/arch/arm/common/icst307.c @@ -53,7 +53,7 @@ icst307_khz_to_vco(const struct icst_params *p, unsigned long freq) /* * f must be between 6MHz and 200MHz (3.3 or 5V) */ - if (f > 6000 && f <= p->vco_max) + if (f > ICST307_VCO_MIN && f <= p->vco_max) break; } while (i < ARRAY_SIZE(idx2s)); diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c index eadf983ee434..34dc2e1b9efc 100644 --- a/arch/arm/common/icst525.c +++ b/arch/arm/common/icst525.c @@ -51,7 +51,7 @@ icst525_khz_to_vco(const struct icst_params *p, unsigned long freq) * f must be between 10MHz and * 320MHz (5V) or 200MHz (3V) */ - if (f > 10000 && f <= p->vco_max) + if (f > ICST525_VCO_MIN && f <= p->vco_max) break; } while (i < ARRAY_SIZE(idx2s)); diff --git a/arch/arm/include/asm/hardware/icst307.h b/arch/arm/include/asm/hardware/icst307.h index 8d0820a654db..0c4e37e3fdef 100644 --- a/arch/arm/include/asm/hardware/icst307.h +++ b/arch/arm/include/asm/hardware/icst307.h @@ -21,4 +21,11 @@ unsigned long icst307_khz(const struct icst_params *p, struct icst_vco vco); struct icst_vco icst307_khz_to_vco(const struct icst_params *p, unsigned long freq); +/* + * ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V). + * This frequency is pre-output divider. + */ +#define ICST307_VCO_MIN 6000 +#define ICST307_VCO_MAX 200000 + #endif diff --git a/arch/arm/include/asm/hardware/icst525.h b/arch/arm/include/asm/hardware/icst525.h index 42a274e59fa2..3b72c132e24f 100644 --- a/arch/arm/include/asm/hardware/icst525.h +++ b/arch/arm/include/asm/hardware/icst525.h @@ -19,4 +19,12 @@ unsigned long icst525_khz(const struct icst_params *p, struct icst_vco vco); struct icst_vco icst525_khz_to_vco(const struct icst_params *p, unsigned long freq); +/* + * ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V). + * This frequency is pre-output divider. + */ +#define ICST525_VCO_MIN 10000 +#define ICST525_VCO_MAX_3V 200000 +#define ICST525_VCO_MAX_5V 320000 + #endif diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index c4e5debeb48c..1671b4a363b1 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -33,7 +33,7 @@ static struct cpufreq_driver integrator_driver; static const struct icst_params lclk_params = { .ref = 24000, - .vco_max = 320000, + .vco_max = ICST525_VCO_MAX_5V, .vd_min = 8, .vd_max = 132, .rd_min = 24, @@ -42,7 +42,7 @@ static const struct icst_params lclk_params = { static const struct icst_params cclk_params = { .ref = 24000, - .vco_max = 320000, + .vco_max = ICST525_VCO_MAX_5V, .vd_min = 12, .vd_max = 160, .rd_min = 24, diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index dfb961b67afa..5aca7ebea3ce 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -42,7 +42,7 @@ struct impd1_module { static const struct icst_params impd1_vco_params = { .ref = 24000, /* 24 MHz */ - .vco_max = 200000, /* 200 MHz */ + .vco_max = ICST525_VCO_MAX_3V, .vd_min = 12, .vd_max = 519, .rd_min = 3, diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 15bfbe2e1df8..27f95106b47c 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -270,7 +270,7 @@ static void __init intcp_init_irq(void) static const struct icst_params cp_auxvco_params = { .ref = 24000, - .vco_max = 320000, + .vco_max = ICST525_VCO_MAX_5V, .vd_min = 8, .vd_max = 263, .rd_min = 3, diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index ac504745fed1..5a850f0dc36c 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -275,7 +275,7 @@ struct mmci_platform_data realview_mmc1_plat_data = { */ static const struct icst_params realview_oscvco_params = { .ref = 24000, - .vco_max = 200000, + .vco_max = ICST307_VCO_MAX, .vd_min = 4 + 8, .vd_max = 511 + 8, .rd_min = 1 + 2, diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index ded71343553f..f8ed561ec698 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -381,7 +381,7 @@ static struct mmci_platform_data mmc0_plat_data = { */ static const struct icst_params versatile_oscvco_params = { .ref = 24000, - .vco_max = 200000, + .vco_max = ICST307_VCO_MAX, .vd_min = 4 + 8, .vd_max = 511 + 8, .rd_min = 1 + 2, -- cgit v1.2.3-59-g8ed1b From 64fceb1dcd1aa6a9f2e53cf8830b38bb007b375b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Jan 2010 17:28:44 +0000 Subject: ARM: ICST: use Hz instead of kHz This makes the ICST support fit more nicely with the clk API, eliminating the need to *1000 and /1000 in places. Signed-off-by: Russell King --- arch/arm/common/icst307.c | 8 ++++---- arch/arm/common/icst525.c | 8 ++++---- arch/arm/include/asm/hardware/icst307.h | 8 ++++---- arch/arm/include/asm/hardware/icst525.h | 10 +++++----- arch/arm/mach-integrator/clock.c | 8 ++++---- arch/arm/mach-integrator/cpu.c | 22 +++++++++++----------- arch/arm/mach-integrator/impd1.c | 6 +++--- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-realview/clock.c | 8 ++++---- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-versatile/clock.c | 8 ++++---- arch/arm/mach-versatile/core.c | 2 +- 12 files changed, 46 insertions(+), 46 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c index f6063c95e256..66c69e597b70 100644 --- a/arch/arm/common/icst307.c +++ b/arch/arm/common/icst307.c @@ -24,12 +24,12 @@ */ static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 }; -unsigned long icst307_khz(const struct icst_params *p, struct icst_vco vco) +unsigned long icst307_hz(const struct icst_params *p, struct icst_vco vco) { return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]); } -EXPORT_SYMBOL(icst307_khz); +EXPORT_SYMBOL(icst307_hz); /* * Ascending divisor S values. @@ -37,7 +37,7 @@ EXPORT_SYMBOL(icst307_khz); static unsigned char idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 }; struct icst_vco -icst307_khz_to_vco(const struct icst_params *p, unsigned long freq) +icst307_hz_to_vco(const struct icst_params *p, unsigned long freq) { struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; unsigned long f; @@ -94,4 +94,4 @@ icst307_khz_to_vco(const struct icst_params *p, unsigned long freq) return vco; } -EXPORT_SYMBOL(icst307_khz_to_vco); +EXPORT_SYMBOL(icst307_hz_to_vco); diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c index 34dc2e1b9efc..c1d22b7c4763 100644 --- a/arch/arm/common/icst525.c +++ b/arch/arm/common/icst525.c @@ -21,12 +21,12 @@ */ static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 }; -unsigned long icst525_khz(const struct icst_params *p, struct icst_vco vco) +unsigned long icst525_hz(const struct icst_params *p, struct icst_vco vco) { return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]); } -EXPORT_SYMBOL(icst525_khz); +EXPORT_SYMBOL(icst525_hz); /* * Ascending divisor S values. @@ -34,7 +34,7 @@ EXPORT_SYMBOL(icst525_khz); static unsigned char idx2s[] = { 1, 3, 4, 7, 5, 2, 6, 0 }; struct icst_vco -icst525_khz_to_vco(const struct icst_params *p, unsigned long freq) +icst525_hz_to_vco(const struct icst_params *p, unsigned long freq) { struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; unsigned long f; @@ -92,4 +92,4 @@ icst525_khz_to_vco(const struct icst_params *p, unsigned long freq) return vco; } -EXPORT_SYMBOL(icst525_khz_to_vco); +EXPORT_SYMBOL(icst525_hz_to_vco); diff --git a/arch/arm/include/asm/hardware/icst307.h b/arch/arm/include/asm/hardware/icst307.h index 0c4e37e3fdef..0f096181e832 100644 --- a/arch/arm/include/asm/hardware/icst307.h +++ b/arch/arm/include/asm/hardware/icst307.h @@ -18,14 +18,14 @@ #include -unsigned long icst307_khz(const struct icst_params *p, struct icst_vco vco); -struct icst_vco icst307_khz_to_vco(const struct icst_params *p, unsigned long freq); +unsigned long icst307_hz(const struct icst_params *p, struct icst_vco vco); +struct icst_vco icst307_hz_to_vco(const struct icst_params *p, unsigned long freq); /* * ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V). * This frequency is pre-output divider. */ -#define ICST307_VCO_MIN 6000 -#define ICST307_VCO_MAX 200000 +#define ICST307_VCO_MIN 6000000 +#define ICST307_VCO_MAX 200000000 #endif diff --git a/arch/arm/include/asm/hardware/icst525.h b/arch/arm/include/asm/hardware/icst525.h index 3b72c132e24f..1000a6096fcb 100644 --- a/arch/arm/include/asm/hardware/icst525.h +++ b/arch/arm/include/asm/hardware/icst525.h @@ -16,15 +16,15 @@ #include -unsigned long icst525_khz(const struct icst_params *p, struct icst_vco vco); -struct icst_vco icst525_khz_to_vco(const struct icst_params *p, unsigned long freq); +unsigned long icst525_hz(const struct icst_params *p, struct icst_vco vco); +struct icst_vco icst525_hz_to_vco(const struct icst_params *p, unsigned long freq); /* * ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V). * This frequency is pre-output divider. */ -#define ICST525_VCO_MIN 10000 -#define ICST525_VCO_MAX_3V 200000 -#define ICST525_VCO_MAX_5V 320000 +#define ICST525_VCO_MIN 10000000 +#define ICST525_VCO_MAX_3V 200000000 +#define ICST525_VCO_MAX_5V 320000000 #endif diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c index bb70b64a6563..a4f80d33429d 100644 --- a/arch/arm/mach-integrator/clock.c +++ b/arch/arm/mach-integrator/clock.c @@ -38,8 +38,8 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { struct icst_vco vco; - vco = icst525_khz_to_vco(clk->params, rate / 1000); - return icst525_khz(clk->params, vco) * 1000; + vco = icst525_hz_to_vco(clk->params, rate); + return icst525_hz(clk->params, vco); } EXPORT_SYMBOL(clk_round_rate); @@ -50,8 +50,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk->setvco) { struct icst_vco vco; - vco = icst525_khz_to_vco(clk->params, rate / 1000); - clk->rate = icst525_khz(clk->params, vco) * 1000; + vco = icst525_hz_to_vco(clk->params, rate); + clk->rate = icst525_hz(clk->params, vco); clk->setvco(clk, vco); ret = 0; } diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index 1671b4a363b1..3ebb785f30c1 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -32,7 +32,7 @@ static struct cpufreq_driver integrator_driver; #define CM_LOCK IO_ADDRESS(INTEGRATOR_HDR_LOCK) static const struct icst_params lclk_params = { - .ref = 24000, + .ref = 24000000, .vco_max = ICST525_VCO_MAX_5V, .vd_min = 8, .vd_max = 132, @@ -41,7 +41,7 @@ static const struct icst_params lclk_params = { }; static const struct icst_params cclk_params = { - .ref = 24000, + .ref = 24000000, .vco_max = ICST525_VCO_MAX_5V, .vd_min = 12, .vd_max = 160, @@ -60,11 +60,11 @@ static int integrator_verify_policy(struct cpufreq_policy *policy) policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); - vco = icst525_khz_to_vco(&cclk_params, policy->max); - policy->max = icst525_khz(&cclk_params, vco); + vco = icst525_hz_to_vco(&cclk_params, policy->max * 1000); + policy->max = icst525_hz(&cclk_params, vco) / 1000; - vco = icst525_khz_to_vco(&cclk_params, policy->min); - policy->min = icst525_khz(&cclk_params, vco); + vco = icst525_hz_to_vco(&cclk_params, policy->min * 1000); + policy->min = icst525_hz(&cclk_params, vco) / 1000; cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, @@ -106,17 +106,17 @@ static int integrator_set_target(struct cpufreq_policy *policy, } vco.v = cm_osc & 255; vco.r = 22; - freqs.old = icst525_khz(&cclk_params, vco); + freqs.old = icst525_hz(&cclk_params, vco) / 1000; - /* icst525_khz_to_vco rounds down -- so we need the next + /* icst525_hz_to_vco rounds down -- so we need the next * larger freq in case of CPUFREQ_RELATION_L. */ if (relation == CPUFREQ_RELATION_L) target_freq += 999; if (target_freq > policy->max) target_freq = policy->max; - vco = icst525_khz_to_vco(&cclk_params, target_freq); - freqs.new = icst525_khz(&cclk_params, vco); + vco = icst525_hz_to_vco(&cclk_params, target_freq * 1000); + freqs.new = icst525_hz(&cclk_params, vco) / 1000; freqs.cpu = policy->cpu; @@ -174,7 +174,7 @@ static unsigned int integrator_get(unsigned int cpu) vco.v = cm_osc & 255; vco.r = 22; - current_freq = icst525_khz(&cclk_params, vco); /* current freq */ + current_freq = icst525_hz(&cclk_params, vco) / 1000; /* current freq */ set_cpus_allowed(current, cpus_allowed); diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 5aca7ebea3ce..ecce3eb8fe00 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -41,7 +41,7 @@ struct impd1_module { }; static const struct icst_params impd1_vco_params = { - .ref = 24000, /* 24 MHz */ + .ref = 24000000, /* 24 MHz */ .vco_max = ICST525_VCO_MAX_3V, .vd_min = 12, .vd_max = 519, @@ -73,8 +73,8 @@ static void impd1_setvco(struct clk *clk, struct icst_vco vco) vco.r = (val >> 9) & 0x7f; vco.s = (val >> 16) & 7; - pr_debug("IM-PD1: VCO%d clock is %ld kHz\n", - vconr, icst525_khz(&impd1_vco_params, vco)); + pr_debug("IM-PD1: VCO%d clock is %ld Hz\n", + vconr, icst525_hz(&impd1_vco_params, vco)); #endif } diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 27f95106b47c..335af99acb79 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -269,7 +269,7 @@ static void __init intcp_init_irq(void) #define CM_AUXOSC IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x1c) static const struct icst_params cp_auxvco_params = { - .ref = 24000, + .ref = 24000000, .vco_max = ICST525_VCO_MAX_5V, .vd_min = 8, .vd_max = 263, diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c index 83646579bc45..2ba0667d18f5 100644 --- a/arch/arm/mach-realview/clock.c +++ b/arch/arm/mach-realview/clock.c @@ -42,8 +42,8 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { struct icst_vco vco; - vco = icst307_khz_to_vco(clk->params, rate / 1000); - return icst307_khz(clk->params, vco) * 1000; + vco = icst307_hz_to_vco(clk->params, rate); + return icst307_hz(clk->params, vco); } EXPORT_SYMBOL(clk_round_rate); @@ -54,8 +54,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk->setvco) { struct icst_vco vco; - vco = icst307_khz_to_vco(clk->params, rate / 1000); - clk->rate = icst307_khz(clk->params, vco) * 1000; + vco = icst307_hz_to_vco(clk->params, rate); + clk->rate = icst307_hz(clk->params, vco); clk->setvco(clk, vco); ret = 0; } diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 5a850f0dc36c..02d48371c09b 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -274,7 +274,7 @@ struct mmci_platform_data realview_mmc1_plat_data = { * Clock handling */ static const struct icst_params realview_oscvco_params = { - .ref = 24000, + .ref = 24000000, .vco_max = ICST307_VCO_MAX, .vd_min = 4 + 8, .vd_max = 511 + 8, diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c index 530e16aa7ad6..82753be453d0 100644 --- a/arch/arm/mach-versatile/clock.c +++ b/arch/arm/mach-versatile/clock.c @@ -43,8 +43,8 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { struct icst_vco vco; - vco = icst307_khz_to_vco(clk->params, rate / 1000); - return icst307_khz(clk->params, vco) * 1000; + vco = icst307_hz_to_vco(clk->params, rate); + return icst307_hz(clk->params, vco); } EXPORT_SYMBOL(clk_round_rate); @@ -55,8 +55,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk->setvco) { struct icst_vco vco; - vco = icst307_khz_to_vco(clk->params, rate / 1000); - clk->rate = icst307_khz(clk->params, vco) * 1000; + vco = icst307_hz_to_vco(clk->params, rate); + clk->rate = icst307_hz(clk->params, vco); clk->setvco(clk, vco); ret = 0; } diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index f8ed561ec698..ff5d24f80b29 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -380,7 +380,7 @@ static struct mmci_platform_data mmc0_plat_data = { * Clock handling */ static const struct icst_params versatile_oscvco_params = { - .ref = 24000, + .ref = 24000000, .vco_max = ICST307_VCO_MAX, .vd_min = 4 + 8, .vd_max = 511 + 8, -- cgit v1.2.3-59-g8ed1b From e73a46a3d3df22b379d8adcb59999eafea1d60d5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Jan 2010 19:49:39 +0000 Subject: ARM: ICST: move minimum VCO frequency to icst_params Signed-off-by: Russell King --- arch/arm/common/icst307.c | 2 +- arch/arm/common/icst525.c | 2 +- arch/arm/include/asm/hardware/icst.h | 1 + arch/arm/mach-integrator/cpu.c | 2 ++ arch/arm/mach-integrator/impd1.c | 1 + arch/arm/mach-integrator/integrator_cp.c | 1 + arch/arm/mach-realview/core.c | 1 + arch/arm/mach-versatile/core.c | 1 + 8 files changed, 9 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c index 66c69e597b70..312485fab4a6 100644 --- a/arch/arm/common/icst307.c +++ b/arch/arm/common/icst307.c @@ -53,7 +53,7 @@ icst307_hz_to_vco(const struct icst_params *p, unsigned long freq) /* * f must be between 6MHz and 200MHz (3.3 or 5V) */ - if (f > ICST307_VCO_MIN && f <= p->vco_max) + if (f > p->vco_min && f <= p->vco_max) break; } while (i < ARRAY_SIZE(idx2s)); diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c index c1d22b7c4763..da58965da311 100644 --- a/arch/arm/common/icst525.c +++ b/arch/arm/common/icst525.c @@ -51,7 +51,7 @@ icst525_hz_to_vco(const struct icst_params *p, unsigned long freq) * f must be between 10MHz and * 320MHz (5V) or 200MHz (3V) */ - if (f > ICST525_VCO_MIN && f <= p->vco_max) + if (f > p->vco_min && f <= p->vco_max) break; } while (i < ARRAY_SIZE(idx2s)); diff --git a/arch/arm/include/asm/hardware/icst.h b/arch/arm/include/asm/hardware/icst.h index 65b1edd4452b..6707c6a9132f 100644 --- a/arch/arm/include/asm/hardware/icst.h +++ b/arch/arm/include/asm/hardware/icst.h @@ -17,6 +17,7 @@ struct icst_params { unsigned long ref; unsigned long vco_max; /* inclusive */ + unsigned long vco_min; /* exclusive */ unsigned short vd_min; /* inclusive */ unsigned short vd_max; /* inclusive */ unsigned char rd_min; /* inclusive */ diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index 3ebb785f30c1..569306b8fdb5 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -34,6 +34,7 @@ static struct cpufreq_driver integrator_driver; static const struct icst_params lclk_params = { .ref = 24000000, .vco_max = ICST525_VCO_MAX_5V, + .vco_min = ICST525_VCO_MIN, .vd_min = 8, .vd_max = 132, .rd_min = 24, @@ -43,6 +44,7 @@ static const struct icst_params lclk_params = { static const struct icst_params cclk_params = { .ref = 24000000, .vco_max = ICST525_VCO_MAX_5V, + .vco_min = ICST525_VCO_MIN, .vd_min = 12, .vd_max = 160, .rd_min = 24, diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index ecce3eb8fe00..036cfb452735 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -43,6 +43,7 @@ struct impd1_module { static const struct icst_params impd1_vco_params = { .ref = 24000000, /* 24 MHz */ .vco_max = ICST525_VCO_MAX_3V, + .vco_min = ICST525_VCO_MIN, .vd_min = 12, .vd_max = 519, .rd_min = 3, diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 335af99acb79..34c120ad1292 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -271,6 +271,7 @@ static void __init intcp_init_irq(void) static const struct icst_params cp_auxvco_params = { .ref = 24000000, .vco_max = ICST525_VCO_MAX_5V, + .vco_min = ICST525_VCO_MIN, .vd_min = 8, .vd_max = 263, .rd_min = 3, diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 02d48371c09b..3ac44138bf75 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -276,6 +276,7 @@ struct mmci_platform_data realview_mmc1_plat_data = { static const struct icst_params realview_oscvco_params = { .ref = 24000000, .vco_max = ICST307_VCO_MAX, + .vco_min = ICST307_VCO_MIN, .vd_min = 4 + 8, .vd_max = 511 + 8, .rd_min = 1 + 2, diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index ff5d24f80b29..c4bf6802df5b 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -382,6 +382,7 @@ static struct mmci_platform_data mmc0_plat_data = { static const struct icst_params versatile_oscvco_params = { .ref = 24000000, .vco_max = ICST307_VCO_MAX, + .vco_min = ICST307_VCO_MIN, .vd_min = 4 + 8, .vd_max = 511 + 8, .rd_min = 1 + 2, -- cgit v1.2.3-59-g8ed1b From 232eaf7f268f765b52170bec42bfa0c5825aa239 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Jan 2010 19:46:19 +0000 Subject: ARM: ICST: indirect s2div and idx2s arrays via icst_params Signed-off-by: Russell King --- arch/arm/common/icst307.c | 18 +++++++++++------- arch/arm/common/icst525.c | 18 +++++++++++------- arch/arm/include/asm/hardware/icst.h | 2 ++ arch/arm/include/asm/hardware/icst307.h | 3 +++ arch/arm/include/asm/hardware/icst525.h | 3 +++ arch/arm/mach-integrator/cpu.c | 4 ++++ arch/arm/mach-integrator/impd1.c | 2 ++ arch/arm/mach-integrator/integrator_cp.c | 2 ++ arch/arm/mach-realview/core.c | 2 ++ arch/arm/mach-versatile/core.c | 2 ++ 10 files changed, 42 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c index 312485fab4a6..8332c0726e73 100644 --- a/arch/arm/common/icst307.c +++ b/arch/arm/common/icst307.c @@ -22,11 +22,13 @@ /* * Divisors for each OD setting. */ -static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 }; +const unsigned char icst307_s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 }; + +EXPORT_SYMBOL(icst307_s2div); unsigned long icst307_hz(const struct icst_params *p, struct icst_vco vco) { - return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]); + return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); } EXPORT_SYMBOL(icst307_hz); @@ -34,7 +36,9 @@ EXPORT_SYMBOL(icst307_hz); /* * Ascending divisor S values. */ -static unsigned char idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 }; +const unsigned char icst307_idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 }; + +EXPORT_SYMBOL(icst307_idx2s); struct icst_vco icst307_hz_to_vco(const struct icst_params *p, unsigned long freq) @@ -48,19 +52,19 @@ icst307_hz_to_vco(const struct icst_params *p, unsigned long freq) * that the PLL output is within spec. */ do { - f = freq * s2div[idx2s[i]]; + f = freq * p->s2div[p->idx2s[i]]; /* * f must be between 6MHz and 200MHz (3.3 or 5V) */ if (f > p->vco_min && f <= p->vco_max) break; - } while (i < ARRAY_SIZE(idx2s)); + } while (i < 8); - if (i >= ARRAY_SIZE(idx2s)) + if (i >= 8) return vco; - vco.s = idx2s[i]; + vco.s = p->idx2s[i]; /* * Now find the closest divisor combination diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c index da58965da311..4180255eb078 100644 --- a/arch/arm/common/icst525.c +++ b/arch/arm/common/icst525.c @@ -19,11 +19,13 @@ /* * Divisors for each OD setting. */ -static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 }; +const unsigned char icst525_s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 }; + +EXPORT_SYMBOL(icst525_s2div); unsigned long icst525_hz(const struct icst_params *p, struct icst_vco vco) { - return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]); + return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); } EXPORT_SYMBOL(icst525_hz); @@ -31,7 +33,9 @@ EXPORT_SYMBOL(icst525_hz); /* * Ascending divisor S values. */ -static unsigned char idx2s[] = { 1, 3, 4, 7, 5, 2, 6, 0 }; +const unsigned char icst525_idx2s[8] = { 1, 3, 4, 7, 5, 2, 6, 0 }; + +EXPORT_SYMBOL(icst525_idx2s); struct icst_vco icst525_hz_to_vco(const struct icst_params *p, unsigned long freq) @@ -45,7 +49,7 @@ icst525_hz_to_vco(const struct icst_params *p, unsigned long freq) * that the PLL output is within spec. */ do { - f = freq * s2div[idx2s[i]]; + f = freq * p->s2div[p->idx2s[i]]; /* * f must be between 10MHz and @@ -53,12 +57,12 @@ icst525_hz_to_vco(const struct icst_params *p, unsigned long freq) */ if (f > p->vco_min && f <= p->vco_max) break; - } while (i < ARRAY_SIZE(idx2s)); + } while (i < 8); - if (i >= ARRAY_SIZE(idx2s)) + if (i >= 8) return vco; - vco.s = idx2s[i]; + vco.s = p->idx2s[i]; /* * Now find the closest divisor combination diff --git a/arch/arm/include/asm/hardware/icst.h b/arch/arm/include/asm/hardware/icst.h index 6707c6a9132f..4d403680fa47 100644 --- a/arch/arm/include/asm/hardware/icst.h +++ b/arch/arm/include/asm/hardware/icst.h @@ -22,6 +22,8 @@ struct icst_params { unsigned short vd_max; /* inclusive */ unsigned char rd_min; /* inclusive */ unsigned char rd_max; /* inclusive */ + const unsigned char *s2div; /* chip specific s2div array */ + const unsigned char *idx2s; /* chip specific idx2s array */ }; struct icst_vco { diff --git a/arch/arm/include/asm/hardware/icst307.h b/arch/arm/include/asm/hardware/icst307.h index 0f096181e832..d76fc6e09e47 100644 --- a/arch/arm/include/asm/hardware/icst307.h +++ b/arch/arm/include/asm/hardware/icst307.h @@ -28,4 +28,7 @@ struct icst_vco icst307_hz_to_vco(const struct icst_params *p, unsigned long fre #define ICST307_VCO_MIN 6000000 #define ICST307_VCO_MAX 200000000 +extern const unsigned char icst307_s2div[]; +extern const unsigned char icst307_idx2s[]; + #endif diff --git a/arch/arm/include/asm/hardware/icst525.h b/arch/arm/include/asm/hardware/icst525.h index 1000a6096fcb..2f9b95386b1b 100644 --- a/arch/arm/include/asm/hardware/icst525.h +++ b/arch/arm/include/asm/hardware/icst525.h @@ -27,4 +27,7 @@ struct icst_vco icst525_hz_to_vco(const struct icst_params *p, unsigned long fre #define ICST525_VCO_MAX_3V 200000000 #define ICST525_VCO_MAX_5V 320000000 +extern const unsigned char icst525_s2div[]; +extern const unsigned char icst525_idx2s[]; + #endif diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index 569306b8fdb5..9481c5408bf8 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -39,6 +39,8 @@ static const struct icst_params lclk_params = { .vd_max = 132, .rd_min = 24, .rd_max = 24, + .s2div = icst525_s2div, + .idx2s = icst525_idx2s, }; static const struct icst_params cclk_params = { @@ -49,6 +51,8 @@ static const struct icst_params cclk_params = { .vd_max = 160, .rd_min = 24, .rd_max = 24, + .s2div = icst525_s2div, + .idx2s = icst525_idx2s, }; /* diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 036cfb452735..e24cfc357ffb 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -48,6 +48,8 @@ static const struct icst_params impd1_vco_params = { .vd_max = 519, .rd_min = 3, .rd_max = 120, + .s2div = icst525_s2div, + .idx2s = icst525_idx2s, }; static void impd1_setvco(struct clk *clk, struct icst_vco vco) diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 34c120ad1292..9997d1f6c184 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -276,6 +276,8 @@ static const struct icst_params cp_auxvco_params = { .vd_max = 263, .rd_min = 3, .rd_max = 65, + .s2div = icst525_s2div, + .idx2s = icst525_idx2s, }; static void cp_auxvco_set(struct clk *clk, struct icst_vco vco) diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 3ac44138bf75..26d44caad540 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -281,6 +281,8 @@ static const struct icst_params realview_oscvco_params = { .vd_max = 511 + 8, .rd_min = 1 + 2, .rd_max = 127 + 2, + .s2div = icst307_s2div, + .idx2s = icst307_idx2s, }; static void realview_oscvco_set(struct clk *clk, struct icst_vco vco) diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index c4bf6802df5b..51d7aeb6a507 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -387,6 +387,8 @@ static const struct icst_params versatile_oscvco_params = { .vd_max = 511 + 8, .rd_min = 1 + 2, .rd_max = 127 + 2, + .s2div = icst307_s2div, + .idx2s = icst307_idx2s, }; static void versatile_oscvco_set(struct clk *clk, struct icst_vco vco) -- cgit v1.2.3-59-g8ed1b From c5a0adb51002e51a4254cb7f0ab7190d41d8b930 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Jan 2010 20:16:10 +0000 Subject: ARM: ICST: kill duplicate icst code The only difference between ICST307 and ICST525 are the two arrays for calculating the S parameter; the code is now identical. Merge the two files and kill the duplicated code. Signed-off-by: Russell King --- arch/arm/Kconfig | 6 +- arch/arm/common/Kconfig | 5 +- arch/arm/common/Makefile | 3 +- arch/arm/common/icst.c | 100 ++++++++++++++++++++++++++++++ arch/arm/common/icst307.c | 101 ------------------------------- arch/arm/common/icst525.c | 99 ------------------------------ arch/arm/include/asm/hardware/icst.h | 24 ++++++++ arch/arm/include/asm/hardware/icst307.h | 34 ----------- arch/arm/include/asm/hardware/icst525.h | 33 ---------- arch/arm/mach-integrator/clock.c | 10 +-- arch/arm/mach-integrator/cpu.c | 20 +++--- arch/arm/mach-integrator/impd1.c | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-realview/clock.c | 10 +-- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-realview/realview_eb.c | 1 - arch/arm/mach-realview/realview_pb1176.c | 1 - arch/arm/mach-realview/realview_pb11mp.c | 1 - arch/arm/mach-realview/realview_pba8.c | 1 - arch/arm/mach-versatile/clock.c | 10 +-- arch/arm/mach-versatile/core.c | 2 +- 21 files changed, 158 insertions(+), 309 deletions(-) create mode 100644 arch/arm/common/icst.c delete mode 100644 arch/arm/common/icst307.c delete mode 100644 arch/arm/common/icst525.c delete mode 100644 arch/arm/include/asm/hardware/icst307.h delete mode 100644 arch/arm/include/asm/hardware/icst525.h (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 86fecec1600d..3c436fdbe2a0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -240,7 +240,7 @@ config ARCH_INTEGRATOR select ARCH_HAS_CPUFREQ select HAVE_CLK select COMMON_CLKDEV - select ICST525 + select ICST select GENERIC_TIME select GENERIC_CLOCKEVENTS help @@ -251,7 +251,7 @@ config ARCH_REALVIEW select ARM_AMBA select HAVE_CLK select COMMON_CLKDEV - select ICST307 + select ICST select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB @@ -264,7 +264,7 @@ config ARCH_VERSATILE select ARM_VIC select HAVE_CLK select COMMON_CLKDEV - select ICST307 + select ICST select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 4efbb9df0444..323d2d289523 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -12,10 +12,7 @@ config ARM_VIC_NR The maximum number of VICs available in the system, for power management. -config ICST525 - bool - -config ICST307 +config ICST bool config SA1111 diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 76be7ff2a7ca..5e8ad0d6c917 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -4,8 +4,7 @@ obj-$(CONFIG_ARM_GIC) += gic.o obj-$(CONFIG_ARM_VIC) += vic.o -obj-$(CONFIG_ICST525) += icst525.o -obj-$(CONFIG_ICST307) += icst307.o +obj-$(CONFIG_ICST) += icst.o obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c new file mode 100644 index 000000000000..9a7f09cff300 --- /dev/null +++ b/arch/arm/common/icst.c @@ -0,0 +1,100 @@ +/* + * linux/arch/arm/common/icst307.c + * + * Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 version 2 as + * published by the Free Software Foundation. + * + * Support functions for calculating clocks/divisors for the ICST307 + * clock generators. See http://www.icst.com/ for more information + * on these devices. + * + * This is an almost identical implementation to the ICST525 clock generator. + * The s2div and idx2s files are different + */ +#include +#include + +#include + +/* + * Divisors for each OD setting. + */ +const unsigned char icst307_s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 }; +const unsigned char icst525_s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 }; +EXPORT_SYMBOL(icst307_s2div); +EXPORT_SYMBOL(icst525_s2div); + +unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco) +{ + return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); +} + +EXPORT_SYMBOL(icst_hz); + +/* + * Ascending divisor S values. + */ +const unsigned char icst307_idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 }; +const unsigned char icst525_idx2s[8] = { 1, 3, 4, 7, 5, 2, 6, 0 }; +EXPORT_SYMBOL(icst307_idx2s); +EXPORT_SYMBOL(icst525_idx2s); + +struct icst_vco +icst_hz_to_vco(const struct icst_params *p, unsigned long freq) +{ + struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + unsigned long f; + unsigned int i = 0, rd, best = (unsigned int)-1; + + /* + * First, find the PLL output divisor such + * that the PLL output is within spec. + */ + do { + f = freq * p->s2div[p->idx2s[i]]; + + if (f > p->vco_min && f <= p->vco_max) + break; + } while (i < 8); + + if (i >= 8) + return vco; + + vco.s = p->idx2s[i]; + + /* + * Now find the closest divisor combination + * which gives a PLL output of 'f'. + */ + for (rd = p->rd_min; rd <= p->rd_max; rd++) { + unsigned long fref_div, f_pll; + unsigned int vd; + int f_diff; + + fref_div = (2 * p->ref) / rd; + + vd = (f + fref_div / 2) / fref_div; + if (vd < p->vd_min || vd > p->vd_max) + continue; + + f_pll = fref_div * vd; + f_diff = f_pll - f; + if (f_diff < 0) + f_diff = -f_diff; + + if ((unsigned)f_diff < best) { + vco.v = vd - 8; + vco.r = rd - 2; + if (f_diff == 0) + break; + best = f_diff; + } + } + + return vco; +} + +EXPORT_SYMBOL(icst_hz_to_vco); diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c deleted file mode 100644 index 8332c0726e73..000000000000 --- a/arch/arm/common/icst307.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * linux/arch/arm/common/icst307.c - * - * Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 version 2 as - * published by the Free Software Foundation. - * - * Support functions for calculating clocks/divisors for the ICST307 - * clock generators. See http://www.icst.com/ for more information - * on these devices. - * - * This is an almost identical implementation to the ICST525 clock generator. - * The s2div and idx2s files are different - */ -#include -#include - -#include - -/* - * Divisors for each OD setting. - */ -const unsigned char icst307_s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 }; - -EXPORT_SYMBOL(icst307_s2div); - -unsigned long icst307_hz(const struct icst_params *p, struct icst_vco vco) -{ - return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); -} - -EXPORT_SYMBOL(icst307_hz); - -/* - * Ascending divisor S values. - */ -const unsigned char icst307_idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 }; - -EXPORT_SYMBOL(icst307_idx2s); - -struct icst_vco -icst307_hz_to_vco(const struct icst_params *p, unsigned long freq) -{ - struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; - unsigned long f; - unsigned int i = 0, rd, best = (unsigned int)-1; - - /* - * First, find the PLL output divisor such - * that the PLL output is within spec. - */ - do { - f = freq * p->s2div[p->idx2s[i]]; - - /* - * f must be between 6MHz and 200MHz (3.3 or 5V) - */ - if (f > p->vco_min && f <= p->vco_max) - break; - } while (i < 8); - - if (i >= 8) - return vco; - - vco.s = p->idx2s[i]; - - /* - * Now find the closest divisor combination - * which gives a PLL output of 'f'. - */ - for (rd = p->rd_min; rd <= p->rd_max; rd++) { - unsigned long fref_div, f_pll; - unsigned int vd; - int f_diff; - - fref_div = (2 * p->ref) / rd; - - vd = (f + fref_div / 2) / fref_div; - if (vd < p->vd_min || vd > p->vd_max) - continue; - - f_pll = fref_div * vd; - f_diff = f_pll - f; - if (f_diff < 0) - f_diff = -f_diff; - - if ((unsigned)f_diff < best) { - vco.v = vd - 8; - vco.r = rd - 2; - if (f_diff == 0) - break; - best = f_diff; - } - } - - return vco; -} - -EXPORT_SYMBOL(icst307_hz_to_vco); diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c deleted file mode 100644 index 4180255eb078..000000000000 --- a/arch/arm/common/icst525.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * linux/arch/arm/common/icst525.c - * - * Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 version 2 as - * published by the Free Software Foundation. - * - * Support functions for calculating clocks/divisors for the ICST525 - * clock generators. See http://www.icst.com/ for more information - * on these devices. - */ -#include -#include - -#include - -/* - * Divisors for each OD setting. - */ -const unsigned char icst525_s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 }; - -EXPORT_SYMBOL(icst525_s2div); - -unsigned long icst525_hz(const struct icst_params *p, struct icst_vco vco) -{ - return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); -} - -EXPORT_SYMBOL(icst525_hz); - -/* - * Ascending divisor S values. - */ -const unsigned char icst525_idx2s[8] = { 1, 3, 4, 7, 5, 2, 6, 0 }; - -EXPORT_SYMBOL(icst525_idx2s); - -struct icst_vco -icst525_hz_to_vco(const struct icst_params *p, unsigned long freq) -{ - struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; - unsigned long f; - unsigned int i = 0, rd, best = (unsigned int)-1; - - /* - * First, find the PLL output divisor such - * that the PLL output is within spec. - */ - do { - f = freq * p->s2div[p->idx2s[i]]; - - /* - * f must be between 10MHz and - * 320MHz (5V) or 200MHz (3V) - */ - if (f > p->vco_min && f <= p->vco_max) - break; - } while (i < 8); - - if (i >= 8) - return vco; - - vco.s = p->idx2s[i]; - - /* - * Now find the closest divisor combination - * which gives a PLL output of 'f'. - */ - for (rd = p->rd_min; rd <= p->rd_max; rd++) { - unsigned long fref_div, f_pll; - unsigned int vd; - int f_diff; - - fref_div = (2 * p->ref) / rd; - - vd = (f + fref_div / 2) / fref_div; - if (vd < p->vd_min || vd > p->vd_max) - continue; - - f_pll = fref_div * vd; - f_diff = f_pll - f; - if (f_diff < 0) - f_diff = -f_diff; - - if ((unsigned)f_diff < best) { - vco.v = vd - 8; - vco.r = rd - 2; - if (f_diff == 0) - break; - best = f_diff; - } - } - - return vco; -} - -EXPORT_SYMBOL(icst525_hz_to_vco); diff --git a/arch/arm/include/asm/hardware/icst.h b/arch/arm/include/asm/hardware/icst.h index 4d403680fa47..10382a3dcec9 100644 --- a/arch/arm/include/asm/hardware/icst.h +++ b/arch/arm/include/asm/hardware/icst.h @@ -32,4 +32,28 @@ struct icst_vco { unsigned char s; }; +unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco); +struct icst_vco icst_hz_to_vco(const struct icst_params *p, unsigned long freq); + +/* + * ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V). + * This frequency is pre-output divider. + */ +#define ICST307_VCO_MIN 6000000 +#define ICST307_VCO_MAX 200000000 + +extern const unsigned char icst307_s2div[]; +extern const unsigned char icst307_idx2s[]; + +/* + * ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V). + * This frequency is pre-output divider. + */ +#define ICST525_VCO_MIN 10000000 +#define ICST525_VCO_MAX_3V 200000000 +#define ICST525_VCO_MAX_5V 320000000 + +extern const unsigned char icst525_s2div[]; +extern const unsigned char icst525_idx2s[]; + #endif diff --git a/arch/arm/include/asm/hardware/icst307.h b/arch/arm/include/asm/hardware/icst307.h deleted file mode 100644 index d76fc6e09e47..000000000000 --- a/arch/arm/include/asm/hardware/icst307.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * arch/arm/include/asm/hardware/icst307.h - * - * Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 version 2 as - * published by the Free Software Foundation. - * - * Support functions for calculating clocks/divisors for the ICS307 - * clock generators. See http://www.icst.com/ for more information - * on these devices. - * - * This file is similar to the icst525.h file - */ -#ifndef ASMARM_HARDWARE_ICST307_H -#define ASMARM_HARDWARE_ICST307_H - -#include - -unsigned long icst307_hz(const struct icst_params *p, struct icst_vco vco); -struct icst_vco icst307_hz_to_vco(const struct icst_params *p, unsigned long freq); - -/* - * ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V). - * This frequency is pre-output divider. - */ -#define ICST307_VCO_MIN 6000000 -#define ICST307_VCO_MAX 200000000 - -extern const unsigned char icst307_s2div[]; -extern const unsigned char icst307_idx2s[]; - -#endif diff --git a/arch/arm/include/asm/hardware/icst525.h b/arch/arm/include/asm/hardware/icst525.h deleted file mode 100644 index 2f9b95386b1b..000000000000 --- a/arch/arm/include/asm/hardware/icst525.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/include/asm/hardware/icst525.h - * - * Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 version 2 as - * published by the Free Software Foundation. - * - * Support functions for calculating clocks/divisors for the ICST525 - * clock generators. See http://www.icst.com/ for more information - * on these devices. - */ -#ifndef ASMARM_HARDWARE_ICST525_H -#define ASMARM_HARDWARE_ICST525_H - -#include - -unsigned long icst525_hz(const struct icst_params *p, struct icst_vco vco); -struct icst_vco icst525_hz_to_vco(const struct icst_params *p, unsigned long freq); - -/* - * ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V). - * This frequency is pre-output divider. - */ -#define ICST525_VCO_MIN 10000000 -#define ICST525_VCO_MAX_3V 200000000 -#define ICST525_VCO_MAX_5V 320000000 - -extern const unsigned char icst525_s2div[]; -extern const unsigned char icst525_idx2s[]; - -#endif diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c index a4f80d33429d..52fc294eac74 100644 --- a/arch/arm/mach-integrator/clock.c +++ b/arch/arm/mach-integrator/clock.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include @@ -38,8 +38,8 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { struct icst_vco vco; - vco = icst525_hz_to_vco(clk->params, rate); - return icst525_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + return icst_hz(clk->params, vco); } EXPORT_SYMBOL(clk_round_rate); @@ -50,8 +50,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk->setvco) { struct icst_vco vco; - vco = icst525_hz_to_vco(clk->params, rate); - clk->rate = icst525_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + clk->rate = icst_hz(clk->params, vco); clk->setvco(clk, vco); ret = 0; } diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index 9481c5408bf8..1cb222daa06d 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include static struct cpufreq_driver integrator_driver; @@ -66,11 +66,11 @@ static int integrator_verify_policy(struct cpufreq_policy *policy) policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); - vco = icst525_hz_to_vco(&cclk_params, policy->max * 1000); - policy->max = icst525_hz(&cclk_params, vco) / 1000; + vco = icst_hz_to_vco(&cclk_params, policy->max * 1000); + policy->max = icst_hz(&cclk_params, vco) / 1000; - vco = icst525_hz_to_vco(&cclk_params, policy->min * 1000); - policy->min = icst525_hz(&cclk_params, vco) / 1000; + vco = icst_hz_to_vco(&cclk_params, policy->min * 1000); + policy->min = icst_hz(&cclk_params, vco) / 1000; cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, @@ -112,17 +112,17 @@ static int integrator_set_target(struct cpufreq_policy *policy, } vco.v = cm_osc & 255; vco.r = 22; - freqs.old = icst525_hz(&cclk_params, vco) / 1000; + freqs.old = icst_hz(&cclk_params, vco) / 1000; - /* icst525_hz_to_vco rounds down -- so we need the next + /* icst_hz_to_vco rounds down -- so we need the next * larger freq in case of CPUFREQ_RELATION_L. */ if (relation == CPUFREQ_RELATION_L) target_freq += 999; if (target_freq > policy->max) target_freq = policy->max; - vco = icst525_hz_to_vco(&cclk_params, target_freq * 1000); - freqs.new = icst525_hz(&cclk_params, vco) / 1000; + vco = icst_hz_to_vco(&cclk_params, target_freq * 1000); + freqs.new = icst_hz(&cclk_params, vco) / 1000; freqs.cpu = policy->cpu; @@ -180,7 +180,7 @@ static unsigned int integrator_get(unsigned int cpu) vco.v = cm_osc & 255; vco.r = 22; - current_freq = icst525_hz(&cclk_params, vco) / 1000; /* current freq */ + current_freq = icst_hz(&cclk_params, vco) / 1000; /* current freq */ set_cpus_allowed(current, cpus_allowed); diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index e24cfc357ffb..3e2110216851 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 9997d1f6c184..a9ab8fda3992 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c index 2ba0667d18f5..18c545921e41 100644 --- a/arch/arm/mach-realview/clock.c +++ b/arch/arm/mach-realview/clock.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include "clock.h" @@ -42,8 +42,8 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { struct icst_vco vco; - vco = icst307_hz_to_vco(clk->params, rate); - return icst307_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + return icst_hz(clk->params, vco); } EXPORT_SYMBOL(clk_round_rate); @@ -54,8 +54,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk->setvco) { struct icst_vco vco; - vco = icst307_hz_to_vco(clk->params, rate); - clk->rate = icst307_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + clk->rate = icst_hz(clk->params, vco); clk->setvco(clk, vco); ret = 0; } diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 26d44caad540..a8c215a406a2 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 7d857d300558..39d953c89d9a 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index 44392e51dd50..a93aac5f473e 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index 3e02731af959..c7c656e235cc 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index fe4e25c4201a..3e3aaa3a2bc0 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c index 82753be453d0..adc67d771c78 100644 --- a/arch/arm/mach-versatile/clock.c +++ b/arch/arm/mach-versatile/clock.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include "clock.h" @@ -43,8 +43,8 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { struct icst_vco vco; - vco = icst307_hz_to_vco(clk->params, rate); - return icst307_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + return icst_hz(clk->params, vco); } EXPORT_SYMBOL(clk_round_rate); @@ -55,8 +55,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk->setvco) { struct icst_vco vco; - vco = icst307_hz_to_vco(clk->params, rate); - clk->rate = icst307_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + clk->rate = icst_hz(clk->params, vco); clk->setvco(clk, vco); ret = 0; } diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 51d7aeb6a507..3c67691d4e72 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include -- cgit v1.2.3-59-g8ed1b From f4b8b319bf21bf3576014ce7336763cd3e1684ef Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Jan 2010 12:48:06 +0000 Subject: ARM: Realview/Versatile/Integrator: separate out common clock code Signed-off-by: Russell King --- arch/arm/Kconfig | 6 +++ arch/arm/Makefile | 1 + arch/arm/mach-integrator/Makefile | 2 +- arch/arm/mach-integrator/clock.c | 60 ------------------------- arch/arm/mach-realview/Makefile | 2 +- arch/arm/mach-realview/clock.c | 64 -------------------------- arch/arm/mach-realview/clock.h | 20 --------- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-realview/include/mach/clkdev.h | 9 ++++ arch/arm/mach-realview/realview_eb.c | 1 - arch/arm/mach-realview/realview_pb1176.c | 1 - arch/arm/mach-realview/realview_pb11mp.c | 1 - arch/arm/mach-realview/realview_pba8.c | 1 - arch/arm/mach-versatile/Makefile | 2 +- arch/arm/mach-versatile/clock.c | 65 --------------------------- arch/arm/mach-versatile/clock.h | 21 --------- arch/arm/mach-versatile/core.c | 2 +- arch/arm/mach-versatile/include/mach/clkdev.h | 9 ++++ arch/arm/plat-versatile/Makefile | 1 + arch/arm/plat-versatile/clock.c | 60 +++++++++++++++++++++++++ 20 files changed, 91 insertions(+), 239 deletions(-) delete mode 100644 arch/arm/mach-integrator/clock.c delete mode 100644 arch/arm/mach-realview/clock.c delete mode 100644 arch/arm/mach-realview/clock.h delete mode 100644 arch/arm/mach-versatile/clock.c delete mode 100644 arch/arm/mach-versatile/clock.h create mode 100644 arch/arm/plat-versatile/Makefile create mode 100644 arch/arm/plat-versatile/clock.c (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3c436fdbe2a0..e8265f257674 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -243,6 +243,7 @@ config ARCH_INTEGRATOR select ICST select GENERIC_TIME select GENERIC_CLOCKEVENTS + select PLAT_VERSATILE help Support for ARM's Integrator platform. @@ -255,6 +256,7 @@ config ARCH_REALVIEW select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB + select PLAT_VERSATILE help This enables support for ARM Ltd RealView boards. @@ -268,6 +270,7 @@ config ARCH_VERSATILE select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB + select PLAT_VERSATILE help This enables support for ARM Ltd Versatile board. @@ -938,6 +941,9 @@ config PLAT_ORION config PLAT_PXA bool +config PLAT_VERSATILE + bool + source arch/arm/mm/Kconfig config IWMMXT diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ed820e737a8a..1962deb90730 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -192,6 +192,7 @@ plat-$(CONFIG_PLAT_PXA) := pxa plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx samsung plat-$(CONFIG_PLAT_S5P) := s5p samsung +plat-$(CONFIG_PLAT_VERSATILE) := versatile ifeq ($(CONFIG_ARCH_EBSA110),y) # This is what happens if you forget the IOCS16 line. diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile index 6a5ef8d30b10..ebeef966e1f5 100644 --- a/arch/arm/mach-integrator/Makefile +++ b/arch/arm/mach-integrator/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y := clock.o core.o lm.o +obj-y := core.o lm.o obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c deleted file mode 100644 index 52fc294eac74..000000000000 --- a/arch/arm/mach-integrator/clock.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * linux/arch/arm/mach-integrator/clock.c - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * 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 -#include -#include -#include -#include - -#include -#include -#include - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - struct icst_vco vco; - vco = icst_hz_to_vco(clk->params, rate); - return icst_hz(clk->params, vco); -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EIO; - - if (clk->setvco) { - struct icst_vco vco; - - vco = icst_hz_to_vco(clk->params, rate); - clk->rate = icst_hz(clk->params, vco); - clk->setvco(clk, vco); - ret = 0; - } - return ret; -} -EXPORT_SYMBOL(clk_set_rate); diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile index e704edb733c0..a01b76b7c956 100644 --- a/arch/arm/mach-realview/Makefile +++ b/arch/arm/mach-realview/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := core.o clock.o +obj-y := core.o obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o obj-$(CONFIG_MACH_REALVIEW_PB11MP) += realview_pb11mp.o obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.o diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c deleted file mode 100644 index 18c545921e41..000000000000 --- a/arch/arm/mach-realview/clock.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * linux/arch/arm/mach-realview/clock.c - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "clock.h" - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - struct icst_vco vco; - vco = icst_hz_to_vco(clk->params, rate); - return icst_hz(clk->params, vco); -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EIO; - - if (clk->setvco) { - struct icst_vco vco; - - vco = icst_hz_to_vco(clk->params, rate); - clk->rate = icst_hz(clk->params, vco); - clk->setvco(clk, vco); - ret = 0; - } - return ret; -} -EXPORT_SYMBOL(clk_set_rate); diff --git a/arch/arm/mach-realview/clock.h b/arch/arm/mach-realview/clock.h deleted file mode 100644 index fa64c854258d..000000000000 --- a/arch/arm/mach-realview/clock.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * linux/arch/arm/mach-realview/clock.h - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * 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 - -struct module; - -struct clk { - unsigned long rate; - const struct icst_params *params; - void *data; - void (*setvco)(struct clk *, struct icst_vco vco); -}; diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index a8c215a406a2..17eb7eb780d8 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -48,11 +48,11 @@ #include +#include #include #include #include "core.h" -#include "clock.h" #define REALVIEW_REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET) diff --git a/arch/arm/mach-realview/include/mach/clkdev.h b/arch/arm/mach-realview/include/mach/clkdev.h index 04b37a89801c..fefe4671255c 100644 --- a/arch/arm/mach-realview/include/mach/clkdev.h +++ b/arch/arm/mach-realview/include/mach/clkdev.h @@ -1,6 +1,15 @@ #ifndef __ASM_MACH_CLKDEV_H #define __ASM_MACH_CLKDEV_H +#include + +struct clk { + unsigned long rate; + const struct icst_params *params; + u32 oscoff; + void (*setvco)(struct clk *, struct icst_vco vco); +}; + #define __clk_get(clk) ({ 1; }) #define __clk_put(clk) do { } while (0) diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 39d953c89d9a..006765fd204c 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -43,7 +43,6 @@ #include #include "core.h" -#include "clock.h" static struct map_desc realview_eb_io_desc[] __initdata = { { diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index a93aac5f473e..217f7c19551e 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -43,7 +43,6 @@ #include #include "core.h" -#include "clock.h" static struct map_desc realview_pb1176_io_desc[] __initdata = { { diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index c7c656e235cc..9ef2ecc3c098 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -44,7 +44,6 @@ #include #include "core.h" -#include "clock.h" static struct map_desc realview_pb11mp_io_desc[] __initdata = { { diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index 3e3aaa3a2bc0..2fab3a6d566b 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -41,7 +41,6 @@ #include #include "core.h" -#include "clock.h" static struct map_desc realview_pba8_io_desc[] __initdata = { { diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile index ba81e70ed813..97cf4d831b0c 100644 --- a/arch/arm/mach-versatile/Makefile +++ b/arch/arm/mach-versatile/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := core.o clock.o +obj-y := core.o obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o obj-$(CONFIG_PCI) += pci.o diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c deleted file mode 100644 index adc67d771c78..000000000000 --- a/arch/arm/mach-versatile/clock.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * linux/arch/arm/mach-versatile/clock.c - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "clock.h" - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - struct icst_vco vco; - vco = icst_hz_to_vco(clk->params, rate); - return icst_hz(clk->params, vco); -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EIO; - - if (clk->setvco) { - struct icst_vco vco; - - vco = icst_hz_to_vco(clk->params, rate); - clk->rate = icst_hz(clk->params, vco); - clk->setvco(clk, vco); - ret = 0; - } - return ret; -} -EXPORT_SYMBOL(clk_set_rate); diff --git a/arch/arm/mach-versatile/clock.h b/arch/arm/mach-versatile/clock.h deleted file mode 100644 index aed7e22d102b..000000000000 --- a/arch/arm/mach-versatile/clock.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * linux/arch/arm/mach-versatile/clock.h - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * 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 - -struct module; - -struct clk { - unsigned long rate; - const struct icst_params *params; - u32 oscoff; - void *data; - void (*setvco)(struct clk *, struct icst_vco vco); -}; diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 3c67691d4e72..e9d255f33674 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -47,11 +47,11 @@ #include #include #include +#include #include #include #include "core.h" -#include "clock.h" /* * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h index 04b37a89801c..fefe4671255c 100644 --- a/arch/arm/mach-versatile/include/mach/clkdev.h +++ b/arch/arm/mach-versatile/include/mach/clkdev.h @@ -1,6 +1,15 @@ #ifndef __ASM_MACH_CLKDEV_H #define __ASM_MACH_CLKDEV_H +#include + +struct clk { + unsigned long rate; + const struct icst_params *params; + u32 oscoff; + void (*setvco)(struct clk *, struct icst_vco vco); +}; + #define __clk_get(clk) ({ 1; }) #define __clk_put(clk) do { } while (0) diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile new file mode 100644 index 000000000000..2228fd1725ac --- /dev/null +++ b/arch/arm/plat-versatile/Makefile @@ -0,0 +1 @@ +obj-y := clock.o diff --git a/arch/arm/plat-versatile/clock.c b/arch/arm/plat-versatile/clock.c new file mode 100644 index 000000000000..2fa34de92325 --- /dev/null +++ b/arch/arm/plat-versatile/clock.c @@ -0,0 +1,60 @@ +/* + * linux/arch/arm/plat-versatile/clock.c + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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 +#include +#include +#include +#include + +#include + +#include + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + struct icst_vco vco; + vco = icst_hz_to_vco(clk->params, rate); + return icst_hz(clk->params, vco); +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EIO; + + if (clk->setvco) { + struct icst_vco vco; + + vco = icst_hz_to_vco(clk->params, rate); + clk->rate = icst_hz(clk->params, vco); + clk->setvco(clk, vco); + ret = 0; + } + return ret; +} +EXPORT_SYMBOL(clk_set_rate); -- cgit v1.2.3-59-g8ed1b From e388771458b4ff3ad81ab70e390b24d069647da4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Jan 2010 13:30:16 +0000 Subject: ARM: Realview/Versatile: separate out common SP804 timer code Signed-off-by: Russell King --- arch/arm/Kconfig | 5 + arch/arm/mach-realview/core.c | 139 +------------------- arch/arm/mach-versatile/core.c | 135 +------------------ arch/arm/plat-versatile/Makefile | 1 + arch/arm/plat-versatile/include/plat/timer-sp.h | 2 + arch/arm/plat-versatile/timer-sp.c | 168 ++++++++++++++++++++++++ 6 files changed, 182 insertions(+), 268 deletions(-) create mode 100644 arch/arm/plat-versatile/include/plat/timer-sp.h create mode 100644 arch/arm/plat-versatile/timer-sp.c (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e8265f257674..553487052772 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -257,6 +257,7 @@ config ARCH_REALVIEW select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB select PLAT_VERSATILE + select ARM_TIMER_SP804 help This enables support for ARM Ltd RealView boards. @@ -271,6 +272,7 @@ config ARCH_VERSATILE select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB select PLAT_VERSATILE + select ARM_TIMER_SP804 help This enables support for ARM Ltd Versatile board. @@ -944,6 +946,9 @@ config PLAT_PXA config PLAT_VERSATILE bool +config ARM_TIMER_SP804 + bool + source arch/arm/mm/Kconfig config IWMMXT diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 17eb7eb780d8..80b8142463c1 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -25,8 +25,6 @@ #include #include #include -#include -#include #include #include #include @@ -51,6 +49,7 @@ #include #include #include +#include #include "core.h" @@ -645,133 +644,6 @@ void __iomem *timer1_va_base; void __iomem *timer2_va_base; void __iomem *timer3_va_base; -/* - * How long is the timer interval? - */ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) -#if TIMER_INTERVAL >= 0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) -#define TIMER_DIVISOR (TIMER_CTRL_DIV256) -#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) -#elif TIMER_INTERVAL >= 0x10000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ -#define TIMER_DIVISOR (TIMER_CTRL_DIV16) -#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) -#else -#define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_DIVISOR (TIMER_CTRL_DIV1) -#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) -#endif - -static void timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *clk) -{ - unsigned long ctrl; - - switch(mode) { - case CLOCK_EVT_MODE_PERIODIC: - writel(TIMER_RELOAD, timer0_va_base + TIMER_LOAD); - - ctrl = TIMER_CTRL_PERIODIC; - ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE; - break; - case CLOCK_EVT_MODE_ONESHOT: - /* period set, and timer enabled in 'next_event' hook */ - ctrl = TIMER_CTRL_ONESHOT; - ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE; - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - default: - ctrl = 0; - } - - writel(ctrl, timer0_va_base + TIMER_CTRL); -} - -static int timer_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long ctrl = readl(timer0_va_base + TIMER_CTRL); - - writel(evt, timer0_va_base + TIMER_LOAD); - writel(ctrl | TIMER_CTRL_ENABLE, timer0_va_base + TIMER_CTRL); - - return 0; -} - -static struct clock_event_device timer0_clockevent = { - .name = "timer0", - .shift = 32, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_mode = timer_set_mode, - .set_next_event = timer_set_next_event, - .rating = 300, - .cpumask = cpu_all_mask, -}; - -static void __init realview_clockevents_init(unsigned int timer_irq) -{ - timer0_clockevent.irq = timer_irq; - timer0_clockevent.mult = - div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift); - timer0_clockevent.max_delta_ns = - clockevent_delta2ns(0xffffffff, &timer0_clockevent); - timer0_clockevent.min_delta_ns = - clockevent_delta2ns(0xf, &timer0_clockevent); - - clockevents_register_device(&timer0_clockevent); -} - -/* - * IRQ handler for the timer - */ -static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &timer0_clockevent; - - /* clear the interrupt */ - writel(1, timer0_va_base + TIMER_INTCLR); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction realview_timer_irq = { - .name = "RealView Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = realview_timer_interrupt, -}; - -static cycle_t realview_get_cycles(struct clocksource *cs) -{ - return ~readl(timer3_va_base + TIMER_VALUE); -} - -static struct clocksource clocksource_realview = { - .name = "timer3", - .rating = 200, - .read = realview_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .shift = 20, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static void __init realview_clocksource_init(void) -{ - /* setup timer 0 as free-running clocksource */ - writel(0, timer3_va_base + TIMER_CTRL); - writel(0xffffffff, timer3_va_base + TIMER_LOAD); - writel(0xffffffff, timer3_va_base + TIMER_VALUE); - writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, - timer3_va_base + TIMER_CTRL); - - clocksource_realview.mult = - clocksource_khz2mult(1000, clocksource_realview.shift); - clocksource_register(&clocksource_realview); -} - /* * Set up the clock source and clock events devices */ @@ -799,13 +671,8 @@ void __init realview_timer_init(unsigned int timer_irq) writel(0, timer2_va_base + TIMER_CTRL); writel(0, timer3_va_base + TIMER_CTRL); - /* - * Make irqs happen for the system timer - */ - setup_irq(timer_irq, &realview_timer_irq); - - realview_clocksource_init(); - realview_clockevents_init(timer_irq); + sp804_clocksource_init(timer3_va_base); + sp804_clockevents_init(timer0_va_base, timer_irq); } /* diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index e9d255f33674..b68ddd349f12 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include #include @@ -50,6 +48,7 @@ #include #include #include +#include #include "core.h" @@ -877,120 +876,6 @@ void __init versatile_init(void) #define TIMER1_VA_BASE (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20) #define TIMER2_VA_BASE __io_address(VERSATILE_TIMER2_3_BASE) #define TIMER3_VA_BASE (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20) -#define VA_IC_BASE __io_address(VERSATILE_VIC_BASE) - -/* - * How long is the timer interval? - */ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) -#if TIMER_INTERVAL >= 0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) -#define TIMER_DIVISOR (TIMER_CTRL_DIV256) -#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) -#elif TIMER_INTERVAL >= 0x10000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ -#define TIMER_DIVISOR (TIMER_CTRL_DIV16) -#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) -#else -#define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_DIVISOR (TIMER_CTRL_DIV1) -#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) -#endif - -static void timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *clk) -{ - unsigned long ctrl; - - switch(mode) { - case CLOCK_EVT_MODE_PERIODIC: - writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); - - ctrl = TIMER_CTRL_PERIODIC; - ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE; - break; - case CLOCK_EVT_MODE_ONESHOT: - /* period set, and timer enabled in 'next_event' hook */ - ctrl = TIMER_CTRL_ONESHOT; - ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE; - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - default: - ctrl = 0; - } - - writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL); -} - -static int timer_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL); - - writel(evt, TIMER0_VA_BASE + TIMER_LOAD); - writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL); - - return 0; -} - -static struct clock_event_device timer0_clockevent = { - .name = "timer0", - .shift = 32, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_mode = timer_set_mode, - .set_next_event = timer_set_next_event, -}; - -/* - * IRQ handler for the timer - */ -static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &timer0_clockevent; - - writel(1, TIMER0_VA_BASE + TIMER_INTCLR); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction versatile_timer_irq = { - .name = "Versatile Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = versatile_timer_interrupt, -}; - -static cycle_t versatile_get_cycles(struct clocksource *cs) -{ - return ~readl(TIMER3_VA_BASE + TIMER_VALUE); -} - -static struct clocksource clocksource_versatile = { - .name = "timer3", - .rating = 200, - .read = versatile_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .shift = 20, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int __init versatile_clocksource_init(void) -{ - /* setup timer3 as free-running clocksource */ - writel(0, TIMER3_VA_BASE + TIMER_CTRL); - writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD); - writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE); - writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, - TIMER3_VA_BASE + TIMER_CTRL); - - clocksource_versatile.mult = - clocksource_khz2mult(1000, clocksource_versatile.shift); - clocksource_register(&clocksource_versatile); - - return 0; -} /* * Set up timer interrupt, and return the current time in seconds. @@ -1019,22 +904,8 @@ static void __init versatile_timer_init(void) writel(0, TIMER2_VA_BASE + TIMER_CTRL); writel(0, TIMER3_VA_BASE + TIMER_CTRL); - /* - * Make irqs happen for the system timer - */ - setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq); - - versatile_clocksource_init(); - - timer0_clockevent.mult = - div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift); - timer0_clockevent.max_delta_ns = - clockevent_delta2ns(0xffffffff, &timer0_clockevent); - timer0_clockevent.min_delta_ns = - clockevent_delta2ns(0xf, &timer0_clockevent); - - timer0_clockevent.cpumask = cpumask_of(0); - clockevents_register_device(&timer0_clockevent); + sp804_clocksource_init(TIMER3_VA_BASE); + sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1); } struct sys_timer versatile_timer = { diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile index 2228fd1725ac..334d2f14232c 100644 --- a/arch/arm/plat-versatile/Makefile +++ b/arch/arm/plat-versatile/Makefile @@ -1 +1,2 @@ obj-y := clock.o +obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o diff --git a/arch/arm/plat-versatile/include/plat/timer-sp.h b/arch/arm/plat-versatile/include/plat/timer-sp.h new file mode 100644 index 000000000000..21e75e30d497 --- /dev/null +++ b/arch/arm/plat-versatile/include/plat/timer-sp.h @@ -0,0 +1,2 @@ +void sp804_clocksource_init(void __iomem *); +void sp804_clockevents_init(void __iomem *, unsigned int); diff --git a/arch/arm/plat-versatile/timer-sp.c b/arch/arm/plat-versatile/timer-sp.c new file mode 100644 index 000000000000..98722f44640c --- /dev/null +++ b/arch/arm/plat-versatile/timer-sp.c @@ -0,0 +1,168 @@ +/* + * linux/arch/arm/plat-versatile/timer-sp.c + * + * Copyright (C) 1999 - 2003 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * 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 +#include +#include +#include +#include + +#include + +#include + +#include + +/* + * How long is the timer interval? + */ +#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) +#if TIMER_INTERVAL >= 0x100000 +#define TIMER_RELOAD (TIMER_INTERVAL >> 8) +#define TIMER_DIVISOR (TIMER_CTRL_DIV256) +#elif TIMER_INTERVAL >= 0x10000 +#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ +#define TIMER_DIVISOR (TIMER_CTRL_DIV16) +#else +#define TIMER_RELOAD (TIMER_INTERVAL) +#define TIMER_DIVISOR (TIMER_CTRL_DIV1) +#endif + + +static void __iomem *clksrc_base; + +static cycle_t sp804_read(struct clocksource *cs) +{ + return ~readl(clksrc_base + TIMER_VALUE); +} + +static struct clocksource clocksource_sp804 = { + .name = "timer3", + .rating = 200, + .read = sp804_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 20, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +void __init sp804_clocksource_init(void __iomem *base) +{ + struct clocksource *cs = &clocksource_sp804; + + clksrc_base = base; + + /* setup timer 0 as free-running clocksource */ + writel(0, clksrc_base + TIMER_CTRL); + writel(0xffffffff, clksrc_base + TIMER_LOAD); + writel(0xffffffff, clksrc_base + TIMER_VALUE); + writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, + clksrc_base + TIMER_CTRL); + + cs->mult = clocksource_khz2mult(1000, cs->shift); + clocksource_register(cs); +} + + +static void __iomem *clkevt_base; + +/* + * IRQ handler for the timer + */ +static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + + /* clear the interrupt */ + writel(1, clkevt_base + TIMER_INTCLR); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static void sp804_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE; + + writel(ctrl, clkevt_base + TIMER_CTRL); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + writel(TIMER_RELOAD, clkevt_base + TIMER_LOAD); + ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* period set, and timer enabled in 'next_event' hook */ + ctrl |= TIMER_CTRL_ONESHOT; + break; + + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + default: + break; + } + + writel(ctrl, clkevt_base + TIMER_CTRL); +} + +static int sp804_set_next_event(unsigned long next, + struct clock_event_device *evt) +{ + unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); + + writel(next, clkevt_base + TIMER_LOAD); + writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); + + return 0; +} + +static struct clock_event_device sp804_clockevent = { + .name = "timer0", + .shift = 32, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_mode = sp804_set_mode, + .set_next_event = sp804_set_next_event, + .rating = 300, + .cpumask = cpu_all_mask, +}; + +static struct irqaction sp804_timer_irq = { + .name = "timer", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = sp804_timer_interrupt, + .dev_id = &sp804_clockevent, +}; + +void __init sp804_clockevents_init(void __iomem *base, unsigned int timer_irq) +{ + struct clock_event_device *evt = &sp804_clockevent; + + clkevt_base = base; + + evt->irq = timer_irq; + evt->mult = div_sc(1000000, NSEC_PER_SEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt); + evt->min_delta_ns = clockevent_delta2ns(0xf, evt); + + setup_irq(timer_irq, &sp804_timer_irq); + clockevents_register_device(evt); +} -- cgit v1.2.3-59-g8ed1b From fe8e1a57f0ccdaede41618ca9ced7d746b6298d3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Jan 2010 22:37:12 +0000 Subject: ARM: Realview/Versatile: remove useless TIMER_RELOAD calculations Realview/Versatile copied the Integrator timer code, including the calculations for ensuring that the reload value fits into the 16-bit counter. However, these platforms have a 32-bit counter which is clocked at a slower rate. The result is that the preprocessor conditions are never triggered: TICKS_PER_uSEC = 1, mSEC_10 = 10000, which is 0x2710 - less than 0x10000. So, remove the unnecessary complexity, reducing the TIMER_RELOAD calculation to just: TICKS_PER_uSEC * mSEC_10 Signed-off-by: Russell King --- arch/arm/plat-versatile/timer-sp.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-versatile/timer-sp.c b/arch/arm/plat-versatile/timer-sp.c index 98722f44640c..d1dbef5b17b1 100644 --- a/arch/arm/plat-versatile/timer-sp.c +++ b/arch/arm/plat-versatile/timer-sp.c @@ -33,17 +33,7 @@ /* * How long is the timer interval? */ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) -#if TIMER_INTERVAL >= 0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) -#define TIMER_DIVISOR (TIMER_CTRL_DIV256) -#elif TIMER_INTERVAL >= 0x10000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ -#define TIMER_DIVISOR (TIMER_CTRL_DIV16) -#else -#define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_DIVISOR (TIMER_CTRL_DIV1) -#endif +#define TIMER_RELOAD (TICKS_PER_uSEC * mSEC_10) static void __iomem *clksrc_base; -- cgit v1.2.3-59-g8ed1b From 4ce1755275c13eb0de90fe23c950bce5e81e680f Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 15 Jan 2010 18:19:56 +0000 Subject: ARM: Realview/Versatile: don't use magic numbers for timer frequency Signed-off-by: Russell King --- arch/arm/plat-versatile/timer-sp.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-versatile/timer-sp.c b/arch/arm/plat-versatile/timer-sp.c index d1dbef5b17b1..fb0d1c299718 100644 --- a/arch/arm/plat-versatile/timer-sp.c +++ b/arch/arm/plat-versatile/timer-sp.c @@ -26,15 +26,13 @@ #include -#include - #include /* - * How long is the timer interval? + * These timers are currently always setup to be clocked at 1MHz. */ -#define TIMER_RELOAD (TICKS_PER_uSEC * mSEC_10) - +#define TIMER_FREQ_KHZ (1000) +#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) static void __iomem *clksrc_base; @@ -65,7 +63,7 @@ void __init sp804_clocksource_init(void __iomem *base) writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, clksrc_base + TIMER_CTRL); - cs->mult = clocksource_khz2mult(1000, cs->shift); + cs->mult = clocksource_khz2mult(TIMER_FREQ_KHZ, cs->shift); clocksource_register(cs); } @@ -149,7 +147,7 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int timer_irq) clkevt_base = base; evt->irq = timer_irq; - evt->mult = div_sc(1000000, NSEC_PER_SEC, evt->shift); + evt->mult = div_sc(TIMER_FREQ_KHZ, NSEC_PER_MSEC, evt->shift); evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt); evt->min_delta_ns = clockevent_delta2ns(0xf, evt); -- cgit v1.2.3-59-g8ed1b From e606a940cba4083b9c382c17251636856e03346b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 17 Jan 2010 19:27:09 +0000 Subject: ARM: Realview/Versatile/Integrator: remove unused definitions from platform.h Signed-off-by: Russell King --- arch/arm/mach-integrator/include/mach/platform.h | 42 ++---------------------- arch/arm/mach-realview/include/mach/platform.h | 20 ----------- arch/arm/mach-versatile/include/mach/platform.h | 26 ++------------- 3 files changed, 4 insertions(+), 84 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/include/mach/platform.h index 0e172e48bc85..5e6ea5cfea6e 100644 --- a/arch/arm/mach-integrator/include/mach/platform.h +++ b/arch/arm/mach-integrator/include/mach/platform.h @@ -23,9 +23,6 @@ * * Integrator address map * - * NOTE: This is a multi-hosted header file for use with uHAL and - * supported debuggers. - * * ***********************************************************************/ #ifndef __address_h @@ -330,20 +327,6 @@ */ #define PHYS_PCI_V3_BASE 0x62000000 -#define PCI_DRAMSIZE INTEGRATOR_SSRAM_SIZE - -/* 'export' these to UHAL */ -#define UHAL_PCI_IO PCI_IO_BASE -#define UHAL_PCI_MEM PCI_MEM_BASE -#define UHAL_PCI_ALLOC_IO_BASE 0x00004000 -#define UHAL_PCI_ALLOC_MEM_BASE PCI_MEM_BASE -#define UHAL_PCI_MAX_SLOT 20 - -/* ======================================================================== - * Start of uHAL definitions - * ======================================================================== - */ - /* ------------------------------------------------------------------------ * Integrator Interrupt Controllers * ------------------------------------------------------------------------ @@ -391,7 +374,7 @@ */ /* ------------------------------------------------------------------------ - * LED's - The header LED is not accessible via the uHAL API + * LED's * ------------------------------------------------------------------------ * */ @@ -403,35 +386,19 @@ #define LED_BANK INTEGRATOR_DBG_LEDS -/* - * Memory definitions - run uHAL out of SSRAM. - * - */ -#define uHAL_MEMORY_SIZE INTEGRATOR_SSRAM_SIZE - -/* - * Clean base - dummy - * - */ -#define CLEAN_BASE INTEGRATOR_BOOT_ROM_HI - /* * Timer definitions * * Only use timer 1 & 2 * (both run at 24MHz and will need the clock divider set to 16). * - * Timer 0 runs at bus frequency and therefore could vary and currently - * uHAL can't handle that. - * + * Timer 0 runs at bus frequency */ #define INTEGRATOR_TIMER0_BASE INTEGRATOR_CT_BASE #define INTEGRATOR_TIMER1_BASE (INTEGRATOR_CT_BASE + 0x100) #define INTEGRATOR_TIMER2_BASE (INTEGRATOR_CT_BASE + 0x200) -#define MAX_TIMER 2 -#define MAX_PERIOD 699050 #define TICKS_PER_uSEC 24 /* @@ -439,14 +406,9 @@ * */ #define mSEC_1 1000 -#define mSEC_5 (mSEC_1 * 5) #define mSEC_10 (mSEC_1 * 10) -#define mSEC_25 (mSEC_1 * 25) -#define SEC_1 (mSEC_1 * 1000) #define INTEGRATOR_CSR_BASE 0x10000000 #define INTEGRATOR_CSR_SIZE 0x10000000 #endif - -/* END */ diff --git a/arch/arm/mach-realview/include/mach/platform.h b/arch/arm/mach-realview/include/mach/platform.h index 86c0c4435a46..1b77a27badaf 100644 --- a/arch/arm/mach-realview/include/mach/platform.h +++ b/arch/arm/mach-realview/include/mach/platform.h @@ -231,12 +231,6 @@ #define REALVIEW_INTREG_OFFSET 0x8 /* Interrupt control */ #define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */ -/* - * Clean base - dummy - * - */ -#define CLEAN_BASE REALVIEW_BOOT_ROM_HI - /* * System controller bit assignment */ @@ -249,20 +243,6 @@ #define REALVIEW_TIMER4_EnSel 21 -#define MAX_TIMER 2 -#define MAX_PERIOD 699050 -#define TICKS_PER_uSEC 1 - -/* - * These are useconds NOT ticks. - * - */ -#define mSEC_1 1000 -#define mSEC_5 (mSEC_1 * 5) -#define mSEC_10 (mSEC_1 * 10) -#define mSEC_25 (mSEC_1 * 25) -#define SEC_1 (mSEC_1 * 1000) - #define REALVIEW_CSR_BASE 0x10000000 #define REALVIEW_CSR_SIZE 0x10000000 diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h index 83207395191a..ec087407b163 100644 --- a/arch/arm/mach-versatile/include/mach/platform.h +++ b/arch/arm/mach-versatile/include/mach/platform.h @@ -205,7 +205,7 @@ #define VERSATILE_CLCD_BASE 0x10120000 /* CLCD */ #define VERSATILE_DMAC_BASE 0x10130000 /* DMA controller */ #define VERSATILE_VIC_BASE 0x10140000 /* Vectored interrupt controller */ -#define VERSATILE_PERIPH_BASE 0x10150000 /* off-chip peripherals alias from */ +#define VERSATILE_PERIPH_BASE 0x10150000 /* off-chip peripherals alias from */ /* 0x10000000 - 0x100FFFFF */ #define VERSATILE_AHBM_BASE 0x101D0000 /* AHB monitor */ #define VERSATILE_SCTL_BASE 0x101E0000 /* System controller */ @@ -213,7 +213,7 @@ #define VERSATILE_TIMER0_1_BASE 0x101E2000 /* Timer 0 and 1 */ #define VERSATILE_TIMER2_3_BASE 0x101E3000 /* Timer 2 and 3 */ #define VERSATILE_GPIO0_BASE 0x101E4000 /* GPIO port 0 */ -#define VERSATILE_GPIO1_BASE 0x101E5000 /* GPIO port 1 */ +#define VERSATILE_GPIO1_BASE 0x101E5000 /* GPIO port 1 */ #define VERSATILE_GPIO2_BASE 0x101E6000 /* GPIO port 2 */ #define VERSATILE_GPIO3_BASE 0x101E7000 /* GPIO port 3 */ #define VERSATILE_RTC_BASE 0x101E8000 /* Real Time Clock */ @@ -379,12 +379,6 @@ #define SIC_INT_PCI3 30 -/* - * Clean base - dummy - * - */ -#define CLEAN_BASE VERSATILE_BOOT_ROM_HI - /* * System controller bit assignment */ @@ -397,20 +391,6 @@ #define VERSATILE_TIMER4_EnSel 21 -#define MAX_TIMER 2 -#define MAX_PERIOD 699050 -#define TICKS_PER_uSEC 1 - -/* - * These are useconds NOT ticks. - * - */ -#define mSEC_1 1000 -#define mSEC_5 (mSEC_1 * 5) -#define mSEC_10 (mSEC_1 * 10) -#define mSEC_25 (mSEC_1 * 25) -#define SEC_1 (mSEC_1 * 1000) - #define VERSATILE_CSR_BASE 0x10000000 #define VERSATILE_CSR_SIZE 0x10000000 @@ -432,5 +412,3 @@ #endif #endif - -/* END */ -- cgit v1.2.3-59-g8ed1b From 5a46334ac688fb538b335599e1ff3b6cfaf769e9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Jan 2010 23:52:12 +0000 Subject: ARM: Integrator: convert Integrator/CP to use SP804 timer support The Integrator/CP board has SP804-compatible timer modules, so use the SP804-compatible code from Versatile and Realview. Signed-off-by: Russell King --- arch/arm/mach-integrator/Kconfig | 1 + arch/arm/mach-integrator/integrator_cp.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig index df97d16390e3..27db275b367c 100644 --- a/arch/arm/mach-integrator/Kconfig +++ b/arch/arm/mach-integrator/Kconfig @@ -11,6 +11,7 @@ config ARCH_INTEGRATOR_AP config ARCH_INTEGRATOR_CP bool "Support Integrator/CP platform" select ARCH_CINTEGRATOR + select ARM_TIMER_SP804 help Include support for the ARM(R) Integrator CP platform. diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index a9ab8fda3992..a7575c431a22 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,8 @@ #include #include +#include + #include "common.h" #define INTCP_PA_FLASH_BASE 0x24000000 @@ -569,11 +572,18 @@ static void __init intcp_init(void) } } -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ +#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) +#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE) +#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE) static void __init intcp_timer_init(void) { - integrator_time_init(1000, TIMER_CTRL_IE); + writel(0, TIMER0_VA_BASE + TIMER_CTRL); + writel(0, TIMER1_VA_BASE + TIMER_CTRL); + writel(0, TIMER2_VA_BASE + TIMER_CTRL); + + sp804_clocksource_init(TIMER2_VA_BASE); + sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1); } static struct sys_timer cp_timer = { -- cgit v1.2.3-59-g8ed1b From 6be4826e37122b25cb10b215fc84c3a0b1fe1402 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 17 Jan 2010 16:20:56 +0000 Subject: ARM: Integrator: move 16-bit timer support to Integrator/AP Only Integrator/AP has 16-bit timers, so move the support into the Integrator/AP specific support files. Signed-off-by: Russell King --- arch/arm/mach-integrator/common.h | 1 - arch/arm/mach-integrator/core.c | 157 ------------------------------ arch/arm/mach-integrator/integrator_ap.c | 158 ++++++++++++++++++++++++++++++- arch/arm/mach-integrator/integrator_cp.c | 2 - 4 files changed, 155 insertions(+), 163 deletions(-) delete mode 100644 arch/arm/mach-integrator/common.h (limited to 'arch') diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h deleted file mode 100644 index cdbe71091516..000000000000 --- a/arch/arm/mach-integrator/common.h +++ /dev/null @@ -1 +0,0 @@ -extern void integrator_time_init(u32, unsigned int); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index ac2b0c5c991b..b02cfc06e0ae 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include @@ -28,14 +26,11 @@ #include #include #include -#include #include #include #include #include -#include "common.h" - static struct amba_pl010_data integrator_uart_data; static struct amba_device rtc_device = { @@ -220,155 +215,3 @@ void cm_control(u32 mask, u32 set) } EXPORT_SYMBOL(cm_control); - -/* - * Where is the timer (VA)? - */ -#define TIMER0_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER0_BASE) -#define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE) -#define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE) - -/* - * How long is the timer interval? - */ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) -#if TIMER_INTERVAL >= 0x100000 -#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) -#elif TIMER_INTERVAL >= 0x10000 -#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) -#else -#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) -#endif - -static unsigned long timer_reload; - -static void __iomem * const clksrc_base = (void __iomem *)TIMER2_VA_BASE; - -static cycle_t timersp_read(struct clocksource *cs) -{ - return ~(readl(clksrc_base + TIMER_VALUE) & 0xffff); -} - -static struct clocksource clocksource_timersp = { - .name = "timer2", - .rating = 200, - .read = timersp_read, - .mask = CLOCKSOURCE_MASK(16), - .shift = 16, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static void integrator_clocksource_init(u32 khz) -{ - struct clocksource *cs = &clocksource_timersp; - void __iomem *base = clksrc_base; - u32 ctrl = TIMER_CTRL_ENABLE; - - if (khz >= 1500) { - khz /= 16; - ctrl = TIMER_CTRL_DIV16; - } - - writel(ctrl, base + TIMER_CTRL); - writel(0xffff, base + TIMER_LOAD); - - cs->mult = clocksource_khz2mult(khz, cs->shift); - clocksource_register(cs); -} - -static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; - -/* - * IRQ handler for the timer - */ -static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = dev_id; - - /* clear the interrupt */ - writel(1, clkevt_base + TIMER_INTCLR); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) -{ - u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; - - BUG_ON(mode == CLOCK_EVT_MODE_ONESHOT); - - if (mode == CLOCK_EVT_MODE_PERIODIC) { - writel(ctrl, clkevt_base + TIMER_CTRL); - writel(timer_reload, clkevt_base + TIMER_LOAD); - ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; - } - - writel(ctrl, clkevt_base + TIMER_CTRL); -} - -static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) -{ - unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); - - writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); - writel(next, clkevt_base + TIMER_LOAD); - writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); - - return 0; -} - -static struct clock_event_device integrator_clockevent = { - .name = "timer1", - .shift = 34, - .features = CLOCK_EVT_FEAT_PERIODIC, - .set_mode = clkevt_set_mode, - .set_next_event = clkevt_set_next_event, - .rating = 300, - .cpumask = cpu_all_mask, -}; - -static struct irqaction integrator_timer_irq = { - .name = "timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = integrator_timer_interrupt, - .dev_id = &integrator_clockevent, -}; - -static void integrator_clockevent_init(u32 khz, unsigned int ctrl) -{ - struct clock_event_device *evt = &integrator_clockevent; - - if (khz * 1000 > 0x100000 * HZ) { - khz /= 256; - ctrl |= TIMER_CTRL_DIV256; - } else if (khz * 1000 > 0x10000 * HZ) { - khz /= 16; - ctrl |= TIMER_CTRL_DIV16; - } - - timer_reload = khz * 1000 / HZ; - writel(ctrl, clkevt_base + TIMER_CTRL); - - evt->irq = IRQ_TIMERINT1; - evt->mult = div_sc(khz, NSEC_PER_MSEC, evt->shift); - evt->max_delta_ns = clockevent_delta2ns(0xffff, evt); - evt->min_delta_ns = clockevent_delta2ns(0xf, evt); - - setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); - clockevents_register_device(evt); -} - -/* - * Set up timer(s). - */ -void __init integrator_time_init(u32 khz, unsigned int ctrl) -{ - writel(0, TIMER0_VA_BASE + TIMER_CTRL); - writel(0, TIMER1_VA_BASE + TIMER_CTRL); - writel(0, TIMER2_VA_BASE + TIMER_CTRL); - - integrator_clocksource_init(khz); - integrator_clockevent_init(khz, ctrl); -} diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index c89b231898e6..227cf4d05088 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -27,10 +27,14 @@ #include #include #include +#include +#include +#include #include #include #include +#include #include #include #include /* HZ */ @@ -44,8 +48,6 @@ #include #include -#include "common.h" - /* * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx * is the (PA >> 12). @@ -335,9 +337,159 @@ static void __init ap_init(void) } } +/* + * Where is the timer (VA)? + */ +#define TIMER0_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER0_BASE) +#define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE) +#define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE) + +/* + * How long is the timer interval? + */ +#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) +#if TIMER_INTERVAL >= 0x100000 +#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) +#elif TIMER_INTERVAL >= 0x10000 +#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) +#else +#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) +#endif + +static unsigned long timer_reload; + +static void __iomem * const clksrc_base = (void __iomem *)TIMER2_VA_BASE; + +static cycle_t timersp_read(struct clocksource *cs) +{ + return ~(readl(clksrc_base + TIMER_VALUE) & 0xffff); +} + +static struct clocksource clocksource_timersp = { + .name = "timer2", + .rating = 200, + .read = timersp_read, + .mask = CLOCKSOURCE_MASK(16), + .shift = 16, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static void integrator_clocksource_init(u32 khz) +{ + struct clocksource *cs = &clocksource_timersp; + void __iomem *base = clksrc_base; + u32 ctrl = TIMER_CTRL_ENABLE; + + if (khz >= 1500) { + khz /= 16; + ctrl = TIMER_CTRL_DIV16; + } + + writel(ctrl, base + TIMER_CTRL); + writel(0xffff, base + TIMER_LOAD); + + cs->mult = clocksource_khz2mult(khz, cs->shift); + clocksource_register(cs); +} + +static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; + +/* + * IRQ handler for the timer + */ +static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + + /* clear the interrupt */ + writel(1, clkevt_base + TIMER_INTCLR); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) +{ + u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; + + BUG_ON(mode == CLOCK_EVT_MODE_ONESHOT); + + if (mode == CLOCK_EVT_MODE_PERIODIC) { + writel(ctrl, clkevt_base + TIMER_CTRL); + writel(timer_reload, clkevt_base + TIMER_LOAD); + ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; + } + + writel(ctrl, clkevt_base + TIMER_CTRL); +} + +static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) +{ + unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); + + writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); + writel(next, clkevt_base + TIMER_LOAD); + writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); + + return 0; +} + +static struct clock_event_device integrator_clockevent = { + .name = "timer1", + .shift = 34, + .features = CLOCK_EVT_FEAT_PERIODIC, + .set_mode = clkevt_set_mode, + .set_next_event = clkevt_set_next_event, + .rating = 300, + .cpumask = cpu_all_mask, +}; + +static struct irqaction integrator_timer_irq = { + .name = "timer", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = integrator_timer_interrupt, + .dev_id = &integrator_clockevent, +}; + +static void integrator_clockevent_init(u32 khz) +{ + struct clock_event_device *evt = &integrator_clockevent; + unsigned int ctrl = 0; + + if (khz * 1000 > 0x100000 * HZ) { + khz /= 256; + ctrl |= TIMER_CTRL_DIV256; + } else if (khz * 1000 > 0x10000 * HZ) { + khz /= 16; + ctrl |= TIMER_CTRL_DIV16; + } + + timer_reload = khz * 1000 / HZ; + writel(ctrl, clkevt_base + TIMER_CTRL); + + evt->irq = IRQ_TIMERINT1; + evt->mult = div_sc(khz, NSEC_PER_MSEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(0xffff, evt); + evt->min_delta_ns = clockevent_delta2ns(0xf, evt); + + setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); + clockevents_register_device(evt); +} + +/* + * Set up timer(s). + */ static void __init ap_init_timer(void) { - integrator_time_init(TICKS_PER_uSEC * 1000, 0); + u32 khz = TICKS_PER_uSEC * 1000; + + writel(0, TIMER0_VA_BASE + TIMER_CTRL); + writel(0, TIMER1_VA_BASE + TIMER_CTRL); + writel(0, TIMER2_VA_BASE + TIMER_CTRL); + + integrator_clocksource_init(khz); + integrator_clockevent_init(khz); } static struct sys_timer ap_timer = { diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index a7575c431a22..5a5a8c1c087f 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -43,8 +43,6 @@ #include -#include "common.h" - #define INTCP_PA_FLASH_BASE 0x24000000 #define INTCP_FLASH_SIZE SZ_32M -- cgit v1.2.3-59-g8ed1b From f5fc00826d1e60af0e22cb9f65b933d823a8ed84 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Jan 2010 20:07:35 +0000 Subject: ARM: Realview/Versatile: separate out common sched_clock() Provide a common sched_clock() implementation for Versatile and Realview. Signed-off-by: Russell King --- arch/arm/mach-realview/core.c | 16 ----------- arch/arm/mach-versatile/core.c | 22 --------------- arch/arm/plat-versatile/Makefile | 2 ++ arch/arm/plat-versatile/sched-clock.c | 53 +++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 38 deletions(-) create mode 100644 arch/arm/plat-versatile/sched-clock.c (limited to 'arch') diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 80b8142463c1..f97f001e874b 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -53,8 +53,6 @@ #include "core.h" -#define REALVIEW_REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET) - /* used by entry-macro.S and platsmp.c */ void __iomem *gic_cpu_base_addr; @@ -77,20 +75,6 @@ void __init realview_adjust_zones(int node, unsigned long *size, } #endif -/* - * This is the RealView sched_clock implementation. This has - * a resolution of 41.7ns, and a maximum value of about 179s. - */ -unsigned long long sched_clock(void) -{ - unsigned long long v; - - v = (unsigned long long)readl(REALVIEW_REFCOUNTER) * 125; - do_div(v, 3); - - return v; -} - #define REALVIEW_FLASHCTRL (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET) diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index b68ddd349f12..490fc7597bb6 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -227,27 +226,6 @@ void __init versatile_map_io(void) iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc)); } -#define VERSATILE_REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET) - -/* - * This is the Versatile sched_clock implementation. This has - * a resolution of 41.7ns, and a maximum value of about 35583 days. - * - * The return value is guaranteed to be monotonic in that range as - * long as there is always less than 89 seconds between successive - * calls to this function. - */ -unsigned long long sched_clock(void) -{ - unsigned long long v = cnt32_to_63(readl(VERSATILE_REFCOUNTER)); - - /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */ - v *= 125<<1; - do_div(v, 3<<1); - - return v; -} - #define VERSATILE_FLASHCTRL (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET) diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile index 334d2f14232c..9b1a66816aa6 100644 --- a/arch/arm/plat-versatile/Makefile +++ b/arch/arm/plat-versatile/Makefile @@ -1,2 +1,4 @@ obj-y := clock.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o +obj-$(CONFIG_ARCH_REALVIEW) += sched-clock.o +obj-$(CONFIG_ARCH_VERSATILE) += sched-clock.o diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c new file mode 100644 index 000000000000..9768cf7e83d7 --- /dev/null +++ b/arch/arm/plat-versatile/sched-clock.c @@ -0,0 +1,53 @@ +/* + * linux/arch/arm/plat-versatile/sched-clock.c + * + * Copyright (C) 1999 - 2003 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * 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 +#include +#include + +#include +#include + +#ifdef VERSATILE_SYS_BASE +#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET) +#endif + +#ifdef REALVIEW_SYS_BASE +#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET) +#endif + +/* + * This is the Realview and Versatile sched_clock implementation. This + * has a resolution of 41.7ns, and a maximum value of about 35583 days. + * + * The return value is guaranteed to be monotonic in that range as + * long as there is always less than 89 seconds between successive + * calls to this function. + */ +unsigned long long sched_clock(void) +{ + unsigned long long v = cnt32_to_63(readl(REFCOUNTER)); + + /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */ + v *= 125<<1; + do_div(v, 3<<1); + + return v; +} -- cgit v1.2.3-59-g8ed1b From d1914c7e75cff736e2c2dac13ad2fe20c2567e68 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Jan 2010 20:09:34 +0000 Subject: ARM: Make Integrator/Versatile/Reaview VCO code similar Signed-off-by: Russell King --- arch/arm/mach-integrator/impd1.c | 16 ++++------------ arch/arm/mach-integrator/include/mach/clkdev.h | 3 ++- arch/arm/mach-integrator/integrator_cp.c | 9 +++++---- arch/arm/mach-realview/core.c | 16 ++++++++-------- arch/arm/mach-realview/include/mach/clkdev.h | 2 +- arch/arm/mach-versatile/core.c | 10 +++++----- arch/arm/mach-versatile/include/mach/clkdev.h | 2 +- 7 files changed, 26 insertions(+), 32 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 3e2110216851..2f9de622d1fa 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -55,20 +55,10 @@ static const struct icst_params impd1_vco_params = { static void impd1_setvco(struct clk *clk, struct icst_vco vco) { struct impd1_module *impd1 = clk->data; - int vconr = clk - impd1->vcos; - u32 val; - - val = vco.v | (vco.r << 9) | (vco.s << 16); + u32 val = vco.v | (vco.r << 9) | (vco.s << 16); writel(0xa05f, impd1->base + IMPD1_LOCK); - switch (vconr) { - case 0: - writel(val, impd1->base + IMPD1_OSC1); - break; - case 1: - writel(val, impd1->base + IMPD1_OSC2); - break; - } + writel(val, clk->vcoreg); writel(0, impd1->base + IMPD1_LOCK); #ifdef DEBUG @@ -381,6 +371,8 @@ static int impd1_probe(struct lm_device *dev) impd1->vcos[i].data = impd1, impd1->vcos[i].setvco = impd1_setvco; } + impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1; + impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2; impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000", dev->id); diff --git a/arch/arm/mach-integrator/include/mach/clkdev.h b/arch/arm/mach-integrator/include/mach/clkdev.h index 89ea93803998..ed67e8edc0d1 100644 --- a/arch/arm/mach-integrator/include/mach/clkdev.h +++ b/arch/arm/mach-integrator/include/mach/clkdev.h @@ -8,8 +8,9 @@ struct clk { unsigned long rate; struct module *owner; const struct icst_params *params; - void *data; + void __iomem *vcoreg; void (*setvco)(struct clk *, struct icst_vco vco); + void *data; }; static inline int __clk_get(struct clk *clk) diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 5a5a8c1c087f..590858004ef6 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -266,8 +266,8 @@ static void __init intcp_init_irq(void) /* * Clock handling */ -#define CM_LOCK IO_ADDRESS(INTEGRATOR_HDR_LOCK) -#define CM_AUXOSC IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x1c) +#define CM_LOCK (__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET) +#define CM_AUXOSC (__io_address(INTEGRATOR_HDR_BASE)+0x1c) static const struct icst_params cp_auxvco_params = { .ref = 24000000, @@ -285,16 +285,17 @@ static void cp_auxvco_set(struct clk *clk, struct icst_vco vco) { u32 val; - val = readl(CM_AUXOSC) & ~0x7ffff; + val = readl(clk->vcoreg) & ~0x7ffff; val |= vco.v | (vco.r << 9) | (vco.s << 16); writel(0xa05f, CM_LOCK); - writel(val, CM_AUXOSC); + writel(val, clk->vcoreg); writel(0, CM_LOCK); } static struct clk cp_auxclk = { .params = &cp_auxvco_params, + .vcoreg = CM_AUXOSC, .setvco = cp_auxvco_set, }; diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index f97f001e874b..043b93bab7df 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -271,19 +271,13 @@ static const struct icst_params realview_oscvco_params = { static void realview_oscvco_set(struct clk *clk, struct icst_vco vco) { void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET; - void __iomem *sys_osc; u32 val; - if (machine_is_realview_pb1176()) - sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET; - else - sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET; - - val = readl(sys_osc) & ~0x7ffff; + val = readl(clk->vcoreg) & ~0x7ffff; val |= vco.v | (vco.r << 9) | (vco.s << 16); writel(0xa05f, sys_lock); - writel(val, sys_osc); + writel(val, clk->vcoreg); writel(0, sys_lock); } @@ -332,7 +326,13 @@ static struct clk_lookup lookups[] = { static int __init clk_init(void) { + if (machine_is_realview_pb1176()) + oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET; + else + oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET; + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + return 0; } arch_initcall(clk_init); diff --git a/arch/arm/mach-realview/include/mach/clkdev.h b/arch/arm/mach-realview/include/mach/clkdev.h index fefe4671255c..baea03c9ad45 100644 --- a/arch/arm/mach-realview/include/mach/clkdev.h +++ b/arch/arm/mach-realview/include/mach/clkdev.h @@ -6,7 +6,7 @@ struct clk { unsigned long rate; const struct icst_params *params; - u32 oscoff; + void __iomem *vcoreg; void (*setvco)(struct clk *, struct icst_vco vco); }; diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 490fc7597bb6..957bbde83d34 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -370,21 +370,19 @@ static const struct icst_params versatile_oscvco_params = { static void versatile_oscvco_set(struct clk *clk, struct icst_vco vco) { - void __iomem *sys = __io_address(VERSATILE_SYS_BASE); - void __iomem *sys_lock = sys + VERSATILE_SYS_LOCK_OFFSET; + void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET; u32 val; - val = readl(sys + clk->oscoff) & ~0x7ffff; + val = readl(clk->vcoreg) & ~0x7ffff; val |= vco.v | (vco.r << 9) | (vco.s << 16); writel(0xa05f, sys_lock); - writel(val, sys + clk->oscoff); + writel(val, clk->vcoreg); writel(0, sys_lock); } static struct clk osc4_clk = { .params = &versatile_oscvco_params, - .oscoff = VERSATILE_SYS_OSCCLCD_OFFSET, .setvco = versatile_oscvco_set, }; @@ -831,6 +829,8 @@ void __init versatile_init(void) { int i; + osc4_clk.vcoreg = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET; + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); platform_device_register(&versatile_flash_device); diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h index fefe4671255c..baea03c9ad45 100644 --- a/arch/arm/mach-versatile/include/mach/clkdev.h +++ b/arch/arm/mach-versatile/include/mach/clkdev.h @@ -6,7 +6,7 @@ struct clk { unsigned long rate; const struct icst_params *params; - u32 oscoff; + void __iomem *vcoreg; void (*setvco)(struct clk *, struct icst_vco vco); }; -- cgit v1.2.3-59-g8ed1b From 3081e43b97cb50a80ebd98ce4b60e4853ad38424 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 20 Jan 2010 19:06:26 +0100 Subject: ARM: 5890/1: Fix incorrect Realview board IRQs for L220 and PMU In anticipation of PMU support for Realview boards, the IRQs defined for some of these boards need updating. This patch removes incorrect L220 IRQ definitions, corrects incorrect PMU IRQs and adds any missing IRQs that are required. Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/mach-realview/include/mach/irqs-pb1176.h | 1 + arch/arm/mach-realview/include/mach/irqs-pba8.h | 8 ++------ arch/arm/mach-realview/include/mach/irqs-pbx.h | 14 ++++---------- 3 files changed, 7 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-realview/include/mach/irqs-pb1176.h b/arch/arm/mach-realview/include/mach/irqs-pb1176.h index 2410d4f8ddd3..830055bb8628 100644 --- a/arch/arm/mach-realview/include/mach/irqs-pb1176.h +++ b/arch/arm/mach-realview/include/mach/irqs-pb1176.h @@ -31,6 +31,7 @@ #define IRQ_DC1176_SOFTINT (IRQ_DC1176_GIC_START + 1) /* Software interrupt */ #define IRQ_DC1176_COMMRx (IRQ_DC1176_GIC_START + 2) /* Debug Comm Rx interrupt */ #define IRQ_DC1176_COMMTx (IRQ_DC1176_GIC_START + 3) /* Debug Comm Tx interrupt */ +#define IRQ_DC1176_CORE_PMU (IRQ_DC1176_GIC_START + 7) /* Core PMU interrupt */ #define IRQ_DC1176_TIMER0 (IRQ_DC1176_GIC_START + 8) /* Timer 0 */ #define IRQ_DC1176_TIMER1 (IRQ_DC1176_GIC_START + 9) /* Timer 1 */ #define IRQ_DC1176_TIMER2 (IRQ_DC1176_GIC_START + 10) /* Timer 2 */ diff --git a/arch/arm/mach-realview/include/mach/irqs-pba8.h b/arch/arm/mach-realview/include/mach/irqs-pba8.h index 86792a9f2ab6..4a88a4edb651 100644 --- a/arch/arm/mach-realview/include/mach/irqs-pba8.h +++ b/arch/arm/mach-realview/include/mach/irqs-pba8.h @@ -23,12 +23,6 @@ #define IRQ_PBA8_GIC_START 32 -/* L220 -#define IRQ_PBA8_L220_EVENT (IRQ_PBA8_GIC_START + 29) -#define IRQ_PBA8_L220_SLAVE (IRQ_PBA8_GIC_START + 30) -#define IRQ_PBA8_L220_DECODE (IRQ_PBA8_GIC_START + 31) -*/ - /* * PB-A8 on-board gic irq sources */ @@ -65,6 +59,8 @@ #define IRQ_PBA8_TSPEN (IRQ_PBA8_GIC_START + 30) /* Touchscreen pen */ #define IRQ_PBA8_TSKPAD (IRQ_PBA8_GIC_START + 31) /* Touchscreen keypad */ +#define IRQ_PBA8_PMU (IRQ_PBA8_GIC_START + 47) /* Cortex-A8 PMU */ + /* ... */ #define IRQ_PBA8_PCI0 (IRQ_PBA8_GIC_START + 50) #define IRQ_PBA8_PCI1 (IRQ_PBA8_GIC_START + 51) diff --git a/arch/arm/mach-realview/include/mach/irqs-pbx.h b/arch/arm/mach-realview/include/mach/irqs-pbx.h index deaad4302b17..206a3001f46b 100644 --- a/arch/arm/mach-realview/include/mach/irqs-pbx.h +++ b/arch/arm/mach-realview/include/mach/irqs-pbx.h @@ -22,12 +22,6 @@ #define IRQ_PBX_GIC_START 32 -/* L220 -#define IRQ_PBX_L220_EVENT (IRQ_PBX_GIC_START + 29) -#define IRQ_PBX_L220_SLAVE (IRQ_PBX_GIC_START + 30) -#define IRQ_PBX_L220_DECODE (IRQ_PBX_GIC_START + 31) -*/ - /* * PBX on-board gic irq sources */ @@ -77,10 +71,10 @@ #define IRQ_PBX_TIMER4_5 (IRQ_PBX_GIC_START + 41) /* Timer 0/1 (default timer) */ #define IRQ_PBX_TIMER6_7 (IRQ_PBX_GIC_START + 42) /* Timer 2/3 */ /* ... */ -#define IRQ_PBX_PMU_CPU3 (IRQ_PBX_GIC_START + 44) /* CPU PMU Interrupts */ -#define IRQ_PBX_PMU_CPU2 (IRQ_PBX_GIC_START + 45) -#define IRQ_PBX_PMU_CPU1 (IRQ_PBX_GIC_START + 46) -#define IRQ_PBX_PMU_CPU0 (IRQ_PBX_GIC_START + 47) +#define IRQ_PBX_PMU_CPU0 (IRQ_PBX_GIC_START + 44) /* CPU PMU Interrupts */ +#define IRQ_PBX_PMU_CPU1 (IRQ_PBX_GIC_START + 45) +#define IRQ_PBX_PMU_CPU2 (IRQ_PBX_GIC_START + 46) +#define IRQ_PBX_PMU_CPU3 (IRQ_PBX_GIC_START + 47) /* ... */ #define IRQ_PBX_PCI0 (IRQ_PBX_GIC_START + 50) -- cgit v1.2.3-59-g8ed1b From 9bf5b2ef673237e0e43161c56f70ac8bf24e43f9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 1 Mar 2010 16:18:39 +0000 Subject: ARM: Indirect round/set_rate operations through clk structure Signed-off-by: Russell King --- arch/arm/mach-integrator/impd1.c | 10 +++++-- arch/arm/mach-integrator/include/mach/clkdev.h | 4 +-- arch/arm/mach-integrator/integrator_cp.c | 8 +++++- arch/arm/mach-realview/core.c | 8 +++++- arch/arm/mach-realview/include/mach/clkdev.h | 4 +-- arch/arm/mach-versatile/core.c | 8 +++++- arch/arm/mach-versatile/include/mach/clkdev.h | 4 +-- arch/arm/plat-versatile/clock.c | 38 ++++++++++++++++++-------- arch/arm/plat-versatile/include/plat/clock.h | 15 ++++++++++ 9 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 arch/arm/plat-versatile/include/plat/clock.h (limited to 'arch') diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 2f9de622d1fa..1a0ee93e4519 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -71,6 +71,12 @@ static void impd1_setvco(struct clk *clk, struct icst_vco vco) #endif } +static const struct clk_ops impd1_clk_ops = { + .round = icst_clk_round, + .set = icst_clk_set, + .setvco = impd1_setvco, +}; + void impd1_tweak_control(struct device *dev, u32 mask, u32 val) { struct impd1_module *impd1 = dev_get_drvdata(dev); @@ -366,10 +372,10 @@ static int impd1_probe(struct lm_device *dev) (unsigned long)dev->resource.start); for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) { + impd1->vcos[i].ops = &impd1_clk_ops, impd1->vcos[i].owner = THIS_MODULE, impd1->vcos[i].params = &impd1_vco_params, - impd1->vcos[i].data = impd1, - impd1->vcos[i].setvco = impd1_setvco; + impd1->vcos[i].data = impd1; } impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1; impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2; diff --git a/arch/arm/mach-integrator/include/mach/clkdev.h b/arch/arm/mach-integrator/include/mach/clkdev.h index ed67e8edc0d1..bfe07679faec 100644 --- a/arch/arm/mach-integrator/include/mach/clkdev.h +++ b/arch/arm/mach-integrator/include/mach/clkdev.h @@ -2,14 +2,14 @@ #define __ASM_MACH_CLKDEV_H #include -#include +#include struct clk { unsigned long rate; + const struct clk_ops *ops; struct module *owner; const struct icst_params *params; void __iomem *vcoreg; - void (*setvco)(struct clk *, struct icst_vco vco); void *data; }; diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 590858004ef6..54edb6b8504f 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -293,10 +293,16 @@ static void cp_auxvco_set(struct clk *clk, struct icst_vco vco) writel(0, CM_LOCK); } +static const struct clk_ops cp_auxclk_ops = { + .round = icst_clk_round, + .set = icst_clk_set, + .setvco = cp_auxvco_set, +}; + static struct clk cp_auxclk = { + .ops = &cp_auxclk_ops, .params = &cp_auxvco_params, .vcoreg = CM_AUXOSC, - .setvco = cp_auxvco_set, }; static struct clk_lookup cp_lookups[] = { diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 043b93bab7df..1b468bd490af 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -281,9 +281,15 @@ static void realview_oscvco_set(struct clk *clk, struct icst_vco vco) writel(0, sys_lock); } +static const struct clk_ops oscvco_clk_ops = { + .round = icst_clk_round, + .set = icst_clk_set, + .setvco = realview_oscvco_set, +}; + static struct clk oscvco_clk = { + .ops = &oscvco_clk_ops, .params = &realview_oscvco_params, - .setvco = realview_oscvco_set, }; /* diff --git a/arch/arm/mach-realview/include/mach/clkdev.h b/arch/arm/mach-realview/include/mach/clkdev.h index baea03c9ad45..e58d0771b64e 100644 --- a/arch/arm/mach-realview/include/mach/clkdev.h +++ b/arch/arm/mach-realview/include/mach/clkdev.h @@ -1,13 +1,13 @@ #ifndef __ASM_MACH_CLKDEV_H #define __ASM_MACH_CLKDEV_H -#include +#include struct clk { unsigned long rate; + const struct clk_ops *ops; const struct icst_params *params; void __iomem *vcoreg; - void (*setvco)(struct clk *, struct icst_vco vco); }; #define __clk_get(clk) ({ 1; }) diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 957bbde83d34..60baba65635e 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -381,9 +381,15 @@ static void versatile_oscvco_set(struct clk *clk, struct icst_vco vco) writel(0, sys_lock); } +static const struct clk_ops osc4_clk_ops = { + .round = icst_clk_round, + .set = icst_clk_set, + .setvco = versatile_oscvco_set, +}; + static struct clk osc4_clk = { + .ops = &osc4_clk_ops, .params = &versatile_oscvco_params, - .setvco = versatile_oscvco_set, }; /* diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h index baea03c9ad45..e58d0771b64e 100644 --- a/arch/arm/mach-versatile/include/mach/clkdev.h +++ b/arch/arm/mach-versatile/include/mach/clkdev.h @@ -1,13 +1,13 @@ #ifndef __ASM_MACH_CLKDEV_H #define __ASM_MACH_CLKDEV_H -#include +#include struct clk { unsigned long rate; + const struct clk_ops *ops; const struct icst_params *params; void __iomem *vcoreg; - void (*setvco)(struct clk *, struct icst_vco vco); }; #define __clk_get(clk) ({ 1; }) diff --git a/arch/arm/plat-versatile/clock.c b/arch/arm/plat-versatile/clock.c index 2fa34de92325..5c8b6564fdc2 100644 --- a/arch/arm/plat-versatile/clock.c +++ b/arch/arm/plat-versatile/clock.c @@ -37,24 +37,38 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { - struct icst_vco vco; - vco = icst_hz_to_vco(clk->params, rate); - return icst_hz(clk->params, vco); + long ret = -EIO; + if (clk->ops && clk->ops->round) + ret = clk->ops->round(clk, rate); + return ret; } EXPORT_SYMBOL(clk_round_rate); int clk_set_rate(struct clk *clk, unsigned long rate) { int ret = -EIO; - - if (clk->setvco) { - struct icst_vco vco; - - vco = icst_hz_to_vco(clk->params, rate); - clk->rate = icst_hz(clk->params, vco); - clk->setvco(clk, vco); - ret = 0; - } + if (clk->ops && clk->ops->set) + ret = clk->ops->set(clk, rate); return ret; } EXPORT_SYMBOL(clk_set_rate); + +long icst_clk_round(struct clk *clk, unsigned long rate) +{ + struct icst_vco vco; + vco = icst_hz_to_vco(clk->params, rate); + return icst_hz(clk->params, vco); +} +EXPORT_SYMBOL(icst_clk_round); + +int icst_clk_set(struct clk *clk, unsigned long rate) +{ + struct icst_vco vco; + + vco = icst_hz_to_vco(clk->params, rate); + clk->rate = icst_hz(clk->params, vco); + clk->ops->setvco(clk, vco); + + return 0; +} +EXPORT_SYMBOL(icst_clk_set); diff --git a/arch/arm/plat-versatile/include/plat/clock.h b/arch/arm/plat-versatile/include/plat/clock.h new file mode 100644 index 000000000000..3cfb024ccd70 --- /dev/null +++ b/arch/arm/plat-versatile/include/plat/clock.h @@ -0,0 +1,15 @@ +#ifndef PLAT_CLOCK_H +#define PLAT_CLOCK_H + +#include + +struct clk_ops { + long (*round)(struct clk *, unsigned long); + int (*set)(struct clk *, unsigned long); + void (*setvco)(struct clk *, struct icst_vco); +}; + +int icst_clk_set(struct clk *, unsigned long); +long icst_clk_round(struct clk *, unsigned long); + +#endif -- cgit v1.2.3-59-g8ed1b From ceade897f31b8bb66f378cc35859fcfd0d46aaa2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 11 Feb 2010 21:44:53 +0000 Subject: ARM: Add Versatile Express support Signed-off-by: Russell King --- arch/arm/Kconfig | 16 + arch/arm/Makefile | 1 + arch/arm/mach-vexpress/Kconfig | 4 + arch/arm/mach-vexpress/Makefile | 5 + arch/arm/mach-vexpress/Makefile.boot | 3 + arch/arm/mach-vexpress/core.h | 26 ++ arch/arm/mach-vexpress/include/mach/clkdev.h | 15 + arch/arm/mach-vexpress/include/mach/debug-macro.S | 23 ++ arch/arm/mach-vexpress/include/mach/entry-macro.S | 67 ++++ arch/arm/mach-vexpress/include/mach/hardware.h | 1 + arch/arm/mach-vexpress/include/mach/io.h | 28 ++ arch/arm/mach-vexpress/include/mach/irqs.h | 4 + arch/arm/mach-vexpress/include/mach/memory.h | 25 ++ arch/arm/mach-vexpress/include/mach/motherboard.h | 121 ++++++++ arch/arm/mach-vexpress/include/mach/system.h | 37 +++ arch/arm/mach-vexpress/include/mach/timex.h | 23 ++ arch/arm/mach-vexpress/include/mach/uncompress.h | 52 ++++ arch/arm/mach-vexpress/include/mach/vmalloc.h | 21 ++ arch/arm/mach-vexpress/v2m.c | 361 ++++++++++++++++++++++ drivers/i2c/busses/Kconfig | 2 +- 20 files changed, 834 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-vexpress/Kconfig create mode 100644 arch/arm/mach-vexpress/Makefile create mode 100644 arch/arm/mach-vexpress/Makefile.boot create mode 100644 arch/arm/mach-vexpress/core.h create mode 100644 arch/arm/mach-vexpress/include/mach/clkdev.h create mode 100644 arch/arm/mach-vexpress/include/mach/debug-macro.S create mode 100644 arch/arm/mach-vexpress/include/mach/entry-macro.S create mode 100644 arch/arm/mach-vexpress/include/mach/hardware.h create mode 100644 arch/arm/mach-vexpress/include/mach/io.h create mode 100644 arch/arm/mach-vexpress/include/mach/irqs.h create mode 100644 arch/arm/mach-vexpress/include/mach/memory.h create mode 100644 arch/arm/mach-vexpress/include/mach/motherboard.h create mode 100644 arch/arm/mach-vexpress/include/mach/system.h create mode 100644 arch/arm/mach-vexpress/include/mach/timex.h create mode 100644 arch/arm/mach-vexpress/include/mach/uncompress.h create mode 100644 arch/arm/mach-vexpress/include/mach/vmalloc.h create mode 100644 arch/arm/mach-vexpress/v2m.c (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 553487052772..58080e17c28b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -276,6 +276,20 @@ config ARCH_VERSATILE help This enables support for ARM Ltd Versatile board. +config ARCH_VEXPRESS + bool "ARM Ltd. Versatile Express family" + select ARCH_WANT_OPTIONAL_GPIOLIB + select ARM_AMBA + select ARM_TIMER_SP804 + select COMMON_CLKDEV + select GENERIC_CLOCKEVENTS + select GENERIC_TIME + select HAVE_CLK + select ICST + select PLAT_VERSATILE + help + This enables support for the ARM Ltd Versatile Express boards. + config ARCH_AT91 bool "Atmel AT91" select GENERIC_GPIO @@ -926,6 +940,8 @@ source "arch/arm/mach-ux500/Kconfig" source "arch/arm/mach-versatile/Kconfig" +source "arch/arm/mach-vexpress/Kconfig" + source "arch/arm/mach-w90x900/Kconfig" # Definitions to make life easier diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1962deb90730..67c92efa3112 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -175,6 +175,7 @@ machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx machine-$(CONFIG_ARCH_U300) := u300 machine-$(CONFIG_ARCH_U8500) := ux500 machine-$(CONFIG_ARCH_VERSATILE) := versatile +machine-$(CONFIG_ARCH_VEXPRESS) := vexpress machine-$(CONFIG_ARCH_W90X900) := w90x900 machine-$(CONFIG_ARCH_NUC93X) := nuc93x machine-$(CONFIG_FOOTBRIDGE) := footbridge diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig new file mode 100644 index 000000000000..751858c97e6a --- /dev/null +++ b/arch/arm/mach-vexpress/Kconfig @@ -0,0 +1,4 @@ +menu "Versatile Express platform type" + depends on ARCH_VEXPRESS + +endmenu diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile new file mode 100644 index 000000000000..b47cf732981f --- /dev/null +++ b/arch/arm/mach-vexpress/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the linux kernel. +# + +obj-y := v2m.o diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot new file mode 100644 index 000000000000..07c2d9c457ec --- /dev/null +++ b/arch/arm/mach-vexpress/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x60008000 +params_phys-y := 0x60000100 +initrd_phys-y := 0x60800000 diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h new file mode 100644 index 000000000000..57dd95ce41f9 --- /dev/null +++ b/arch/arm/mach-vexpress/core.h @@ -0,0 +1,26 @@ +#define __MMIO_P2V(x) (((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000) +#define MMIO_P2V(x) ((void __iomem *)__MMIO_P2V(x)) + +#define AMBA_DEVICE(name,busid,base,plat) \ +struct amba_device name##_device = { \ + .dev = { \ + .coherent_dma_mask = ~0UL, \ + .init_name = busid, \ + .platform_data = plat, \ + }, \ + .res = { \ + .start = base, \ + .end = base + SZ_4K - 1, \ + .flags = IORESOURCE_MEM, \ + }, \ + .dma_mask = ~0UL, \ + .irq = IRQ_##base, \ + /* .dma = DMA_##base,*/ \ +} + +struct map_desc; + +void v2m_map_io(struct map_desc *tile, size_t num); +extern struct sys_timer v2m_timer; + +extern void __iomem *gic_cpu_base_addr; diff --git a/arch/arm/mach-vexpress/include/mach/clkdev.h b/arch/arm/mach-vexpress/include/mach/clkdev.h new file mode 100644 index 000000000000..3f8307d73cad --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/clkdev.h @@ -0,0 +1,15 @@ +#ifndef __ASM_MACH_CLKDEV_H +#define __ASM_MACH_CLKDEV_H + +#include + +struct clk { + const struct clk_ops *ops; + unsigned long rate; + const struct icst_params *params; +}; + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S new file mode 100644 index 000000000000..5167e2aceeba --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/debug-macro.S @@ -0,0 +1,23 @@ +/* arch/arm/mach-realview/include/mach/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * 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. + */ + +#define DEBUG_LL_UART_OFFSET 0x00009000 + + .macro addruart,rx,tmp + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, #0x10000000 + movne \rx, #0xf8000000 @ virtual base + orr \rx, \rx, #DEBUG_LL_UART_OFFSET + .endm + +#include diff --git a/arch/arm/mach-vexpress/include/mach/entry-macro.S b/arch/arm/mach-vexpress/include/mach/entry-macro.S new file mode 100644 index 000000000000..20e9fb514f0a --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/entry-macro.S @@ -0,0 +1,67 @@ +#include + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =gic_cpu_base_addr + ldr \base, [\base] + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + /* + * The interrupt numbering scheme is defined in the + * interrupt controller spec. To wit: + * + * Interrupts 0-15 are IPI + * 16-28 are reserved + * 29-31 are local. We allow 30 to be used for the watchdog. + * 32-1020 are global + * 1021-1022 are reserved + * 1023 is "spurious" (no interrupt) + * + * For now, we ignore all local interrupts so only return an interrupt if it's + * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. + * + * A simple read from the controller will tell us the number of the highest + * priority enabled interrupt. We then just need to check whether it is in the + * valid range for an IRQ (30-1020 inclusive). + */ + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */ + ldr \tmp, =1021 + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #29 + cmpcc \irqnr, \irqnr + cmpne \irqnr, \tmp + cmpcs \irqnr, \irqnr + .endm + + /* We assume that irqstat (the raw value of the IRQ acknowledge + * register) is preserved from the macro above. + * If there is an IPI, we immediately signal end of interrupt on the + * controller, since this requires the original irqstat value which + * we won't easily be able to recreate later. + */ + + .macro test_for_ipi, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #16 + strcc \irqstat, [\base, #GIC_CPU_EOI] + cmpcs \irqnr, \irqnr + .endm + + /* As above, this assumes that irqstat and base are preserved.. */ + + .macro test_for_ltirq, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + mov \tmp, #0 + cmp \irqnr, #29 + moveq \tmp, #1 + streq \irqstat, [\base, #GIC_CPU_EOI] + cmp \tmp, #0 + .endm + diff --git a/arch/arm/mach-vexpress/include/mach/hardware.h b/arch/arm/mach-vexpress/include/mach/hardware.h new file mode 100644 index 000000000000..40a8c178f10d --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/hardware.h @@ -0,0 +1 @@ +/* empty */ diff --git a/arch/arm/mach-vexpress/include/mach/io.h b/arch/arm/mach-vexpress/include/mach/io.h new file mode 100644 index 000000000000..748bb524ee71 --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/io.h @@ -0,0 +1,28 @@ +/* + * arch/arm/mach-vexpress/include/mach/io.h + * + * Copyright (C) 2003 ARM Limited + * + * 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 + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/irqs.h b/arch/arm/mach-vexpress/include/mach/irqs.h new file mode 100644 index 000000000000..7054cbfc9de5 --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/irqs.h @@ -0,0 +1,4 @@ +#define IRQ_LOCALTIMER 29 +#define IRQ_LOCALWDOG 30 + +#define NR_IRQS 128 diff --git a/arch/arm/mach-vexpress/include/mach/memory.h b/arch/arm/mach-vexpress/include/mach/memory.h new file mode 100644 index 000000000000..be28232ae639 --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/memory.h @@ -0,0 +1,25 @@ +/* + * arch/arm/mach-vexpress/include/mach/memory.h + * + * Copyright (C) 2003 ARM Limited + * + * 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 + */ +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#define PHYS_OFFSET UL(0x60000000) + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h new file mode 100644 index 000000000000..98a8ded055bf --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/motherboard.h @@ -0,0 +1,121 @@ +#ifndef __MACH_MOTHERBOARD_H +#define __MACH_MOTHERBOARD_H + +/* + * Physical addresses, offset from V2M_PA_CS0-3 + */ +#define V2M_NOR0 (V2M_PA_CS0) +#define V2M_NOR1 (V2M_PA_CS1) +#define V2M_SRAM (V2M_PA_CS2) +#define V2M_VIDEO_SRAM (V2M_PA_CS3 + 0x00000000) +#define V2M_LAN9118 (V2M_PA_CS3 + 0x02000000) +#define V2M_ISP1761 (V2M_PA_CS3 + 0x03000000) + +/* + * Physical addresses, offset from V2M_PA_CS7 + */ +#define V2M_SYSREGS (V2M_PA_CS7 + 0x00000000) +#define V2M_SYSCTL (V2M_PA_CS7 + 0x00001000) +#define V2M_SERIAL_BUS_PCI (V2M_PA_CS7 + 0x00002000) + +#define V2M_AACI (V2M_PA_CS7 + 0x00004000) +#define V2M_MMCI (V2M_PA_CS7 + 0x00005000) +#define V2M_KMI0 (V2M_PA_CS7 + 0x00006000) +#define V2M_KMI1 (V2M_PA_CS7 + 0x00007000) + +#define V2M_UART0 (V2M_PA_CS7 + 0x00009000) +#define V2M_UART1 (V2M_PA_CS7 + 0x0000a000) +#define V2M_UART2 (V2M_PA_CS7 + 0x0000b000) +#define V2M_UART3 (V2M_PA_CS7 + 0x0000c000) + +#define V2M_WDT (V2M_PA_CS7 + 0x0000f000) + +#define V2M_TIMER01 (V2M_PA_CS7 + 0x00011000) +#define V2M_TIMER23 (V2M_PA_CS7 + 0x00012000) + +#define V2M_SERIAL_BUS_DVI (V2M_PA_CS7 + 0x00016000) +#define V2M_RTC (V2M_PA_CS7 + 0x00017000) + +#define V2M_CF (V2M_PA_CS7 + 0x0001a000) +#define V2M_CLCD (V2M_PA_CS7 + 0x0001f000) + +#define V2M_SYS_ID (V2M_SYSREGS + 0x000) +#define V2M_SYS_SW (V2M_SYSREGS + 0x004) +#define V2M_SYS_LED (V2M_SYSREGS + 0x008) +#define V2M_SYS_100HZ (V2M_SYSREGS + 0x024) +#define V2M_SYS_FLAGS (V2M_SYSREGS + 0x030) +#define V2M_SYS_FLAGSSET (V2M_SYSREGS + 0x030) +#define V2M_SYS_FLAGSCLR (V2M_SYSREGS + 0x034) +#define V2M_SYS_NVFLAGS (V2M_SYSREGS + 0x038) +#define V2M_SYS_NVFLAGSSET (V2M_SYSREGS + 0x038) +#define V2M_SYS_NVFLAGSCLR (V2M_SYSREGS + 0x03c) +#define V2M_SYS_MCI (V2M_SYSREGS + 0x048) +#define V2M_SYS_FLASH (V2M_SYSREGS + 0x03c) +#define V2M_SYS_CFGSW (V2M_SYSREGS + 0x058) +#define V2M_SYS_24MHZ (V2M_SYSREGS + 0x05c) +#define V2M_SYS_MISC (V2M_SYSREGS + 0x060) +#define V2M_SYS_DMA (V2M_SYSREGS + 0x064) +#define V2M_SYS_PROCID0 (V2M_SYSREGS + 0x084) +#define V2M_SYS_PROCID1 (V2M_SYSREGS + 0x088) +#define V2M_SYS_CFGDATA (V2M_SYSREGS + 0x0a0) +#define V2M_SYS_CFGCTRL (V2M_SYSREGS + 0x0a4) +#define V2M_SYS_CFGSTAT (V2M_SYSREGS + 0x0a8) + +#define V2M_TIMER0 (V2M_TIMER01 + 0x000) +#define V2M_TIMER1 (V2M_TIMER01 + 0x020) + +#define V2M_TIMER2 (V2M_TIMER23 + 0x000) +#define V2M_TIMER3 (V2M_TIMER23 + 0x020) + + +/* + * Interrupts. Those in {} are for AMBA devices + */ +#define IRQ_V2M_WDT { (32 + 0) } +#define IRQ_V2M_TIMER0 (32 + 2) +#define IRQ_V2M_TIMER1 (32 + 2) +#define IRQ_V2M_TIMER2 (32 + 3) +#define IRQ_V2M_TIMER3 (32 + 3) +#define IRQ_V2M_RTC { (32 + 4) } +#define IRQ_V2M_UART0 { (32 + 5) } +#define IRQ_V2M_UART1 { (32 + 6) } +#define IRQ_V2M_UART2 { (32 + 7) } +#define IRQ_V2M_UART3 { (32 + 8) } +#define IRQ_V2M_MMCI { (32 + 9), (32 + 10) } +#define IRQ_V2M_AACI { (32 + 11) } +#define IRQ_V2M_KMI0 { (32 + 12) } +#define IRQ_V2M_KMI1 { (32 + 13) } +#define IRQ_V2M_CLCD { (32 + 14) } +#define IRQ_V2M_LAN9118 (32 + 15) +#define IRQ_V2M_ISP1761 (32 + 16) +#define IRQ_V2M_PCIE (32 + 17) + + +/* + * Configuration + */ +#define SYS_CFG_START (1 << 31) +#define SYS_CFG_WRITE (1 << 30) +#define SYS_CFG_OSC (1 << 20) +#define SYS_CFG_VOLT (2 << 20) +#define SYS_CFG_AMP (3 << 20) +#define SYS_CFG_TEMP (4 << 20) +#define SYS_CFG_RESET (5 << 20) +#define SYS_CFG_SCC (6 << 20) +#define SYS_CFG_MUXFPGA (7 << 20) +#define SYS_CFG_SHUTDOWN (8 << 20) +#define SYS_CFG_REBOOT (9 << 20) +#define SYS_CFG_DVIMODE (11 << 20) +#define SYS_CFG_POWER (12 << 20) +#define SYS_CFG_SITE_MB (0 << 16) +#define SYS_CFG_SITE_DB1 (1 << 16) +#define SYS_CFG_SITE_DB2 (2 << 16) +#define SYS_CFG_STACK(n) ((n) << 12) + +#define SYS_CFG_ERR (1 << 1) +#define SYS_CFG_COMPLETE (1 << 0) + +int v2m_cfg_write(u32 devfn, u32 data); +int v2m_cfg_read(u32 devfn, u32 *data); + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/system.h b/arch/arm/mach-vexpress/include/mach/system.h new file mode 100644 index 000000000000..899a4e628a4c --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/system.h @@ -0,0 +1,37 @@ +/* + * arch/arm/mach-vexpress/include/mach/system.h + * + * Copyright (C) 2003 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * 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 + */ +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +static inline void arch_idle(void) +{ + /* + * This should do all the clock switching + * and wait for interrupt tricks + */ + cpu_do_idle(); +} + +static inline void arch_reset(char mode, const char *cmd) +{ +} + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/timex.h b/arch/arm/mach-vexpress/include/mach/timex.h new file mode 100644 index 000000000000..00029bacd43c --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/timex.h @@ -0,0 +1,23 @@ +/* + * arch/arm/mach-vexpress/include/mach/timex.h + * + * RealView architecture timex specifications + * + * Copyright (C) 2003 ARM Limited + * + * 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 + */ + +#define CLOCK_TICK_RATE (50000000 / 16) diff --git a/arch/arm/mach-vexpress/include/mach/uncompress.h b/arch/arm/mach-vexpress/include/mach/uncompress.h new file mode 100644 index 000000000000..7972c5748d0e --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/uncompress.h @@ -0,0 +1,52 @@ +/* + * arch/arm/mach-vexpress/include/mach/uncompress.h + * + * Copyright (C) 2003 ARM Limited + * + * 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 + */ +#define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00)) +#define AMBA_UART_LCRH(base) (*(volatile unsigned char *)((base) + 0x2c)) +#define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30)) +#define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18)) + +#define get_uart_base() (0x10000000 + 0x00009000) + +/* + * This does not append a newline + */ +static inline void putc(int c) +{ + unsigned long base = get_uart_base(); + + while (AMBA_UART_FR(base) & (1 << 5)) + barrier(); + + AMBA_UART_DR(base) = c; +} + +static inline void flush(void) +{ + unsigned long base = get_uart_base(); + + while (AMBA_UART_FR(base) & (1 << 3)) + barrier(); +} + +/* + * nothing to do + */ +#define arch_decomp_setup() +#define arch_decomp_wdog() diff --git a/arch/arm/mach-vexpress/include/mach/vmalloc.h b/arch/arm/mach-vexpress/include/mach/vmalloc.h new file mode 100644 index 000000000000..f43a36ef678b --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/vmalloc.h @@ -0,0 +1,21 @@ +/* + * arch/arm/mach-vexpress/include/mach/vmalloc.h + * + * Copyright (C) 2003 ARM Limited + * Copyright (C) 2000 Russell King. + * + * 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 + */ +#define VMALLOC_END 0xf8000000UL diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c new file mode 100644 index 000000000000..d250711b8c7a --- /dev/null +++ b/arch/arm/mach-vexpress/v2m.c @@ -0,0 +1,361 @@ +/* + * Versatile Express V2M Motherboard Support + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "core.h" + +#define V2M_PA_CS0 0x40000000 +#define V2M_PA_CS1 0x44000000 +#define V2M_PA_CS2 0x48000000 +#define V2M_PA_CS3 0x4c000000 +#define V2M_PA_CS7 0x10000000 + +static struct map_desc v2m_io_desc[] __initdata = { + { + .virtual = __MMIO_P2V(V2M_PA_CS7), + .pfn = __phys_to_pfn(V2M_PA_CS7), + .length = SZ_128K, + .type = MT_DEVICE, + }, +}; + +void __init v2m_map_io(struct map_desc *tile, size_t num) +{ + iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); + iotable_init(tile, num); +} + + +static void v2m_timer_init(void) +{ + writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); + writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); + + sp804_clocksource_init(MMIO_P2V(V2M_TIMER1)); + sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0); +} + +struct sys_timer v2m_timer = { + .init = v2m_timer_init, +}; + + +static DEFINE_SPINLOCK(v2m_cfg_lock); + +int v2m_cfg_write(u32 devfn, u32 data) +{ + /* Configuration interface broken? */ + u32 val; + + printk("%s: writing %08x to %08x\n", __func__, data, devfn); + + devfn |= SYS_CFG_START | SYS_CFG_WRITE; + + spin_lock(&v2m_cfg_lock); + val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); + writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT)); + + writel(data, MMIO_P2V(V2M_SYS_CFGDATA)); + writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); + + do { + val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); + } while (val == 0); + spin_unlock(&v2m_cfg_lock); + + return !!(val & SYS_CFG_ERR); +} + +int v2m_cfg_read(u32 devfn, u32 *data) +{ + u32 val; + + devfn |= SYS_CFG_START; + + spin_lock(&v2m_cfg_lock); + writel(0, MMIO_P2V(V2M_SYS_CFGSTAT)); + writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); + + mb(); + + do { + cpu_relax(); + val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); + } while (val == 0); + + *data = readl(MMIO_P2V(V2M_SYS_CFGDATA)); + spin_unlock(&v2m_cfg_lock); + + return !!(val & SYS_CFG_ERR); +} + + +static struct resource v2m_pcie_i2c_resource = { + .start = V2M_SERIAL_BUS_PCI, + .end = V2M_SERIAL_BUS_PCI + SZ_4K - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device v2m_pcie_i2c_device = { + .name = "versatile-i2c", + .id = 0, + .num_resources = 1, + .resource = &v2m_pcie_i2c_resource, +}; + +static struct resource v2m_ddc_i2c_resource = { + .start = V2M_SERIAL_BUS_DVI, + .end = V2M_SERIAL_BUS_DVI + SZ_4K - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device v2m_ddc_i2c_device = { + .name = "versatile-i2c", + .id = 1, + .num_resources = 1, + .resource = &v2m_ddc_i2c_resource, +}; + +static struct resource v2m_eth_resources[] = { + { + .start = V2M_LAN9118, + .end = V2M_LAN9118 + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_V2M_LAN9118, + .end = IRQ_V2M_LAN9118, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct smsc911x_platform_config v2m_eth_config = { + .flags = SMSC911X_USE_32BIT, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, + .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device v2m_eth_device = { + .name = "smsc911x", + .id = -1, + .resource = v2m_eth_resources, + .num_resources = ARRAY_SIZE(v2m_eth_resources), + .dev.platform_data = &v2m_eth_config, +}; + +static struct resource v2m_usb_resources[] = { + { + .start = V2M_ISP1761, + .end = V2M_ISP1761 + SZ_128K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_V2M_ISP1761, + .end = IRQ_V2M_ISP1761, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct isp1760_platform_data v2m_usb_config = { + .is_isp1761 = true, + .bus_width_16 = false, + .port1_otg = true, + .analog_oc = false, + .dack_polarity_high = false, + .dreq_polarity_high = false, +}; + +static struct platform_device v2m_usb_device = { + .name = "isp1760", + .id = -1, + .resource = v2m_usb_resources, + .num_resources = ARRAY_SIZE(v2m_usb_resources), + .dev.platform_data = &v2m_usb_config, +}; + +static int v2m_flash_init(void) +{ + writel(0, MMIO_P2V(V2M_SYS_FLASH)); + return 0; +} + +static void v2m_flash_exit(void) +{ + writel(0, MMIO_P2V(V2M_SYS_FLASH)); +} + +static void v2m_flash_set_vpp(int on) +{ + writel(on != 0, MMIO_P2V(V2M_SYS_FLASH)); +} + +static struct flash_platform_data v2m_flash_data = { + .map_name = "cfi_probe", + .width = 4, + .init = v2m_flash_init, + .exit = v2m_flash_exit, + .set_vpp = v2m_flash_set_vpp, +}; + +static struct resource v2m_flash_resources[] = { + { + .start = V2M_NOR0, + .end = V2M_NOR0 + SZ_64M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = V2M_NOR1, + .end = V2M_NOR1 + SZ_64M - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device v2m_flash_device = { + .name = "armflash", + .id = -1, + .resource = v2m_flash_resources, + .num_resources = ARRAY_SIZE(v2m_flash_resources), + .dev.platform_data = &v2m_flash_data, +}; + + +static unsigned int v2m_mmci_status(struct device *dev) +{ + return !(readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0)); +} + +static struct mmci_platform_data v2m_mmci_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .status = v2m_mmci_status, +}; + +static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL); +static AMBA_DEVICE(mmci, "mb:mmci", V2M_MMCI, &v2m_mmci_data); +static AMBA_DEVICE(kmi0, "mb:kmi0", V2M_KMI0, NULL); +static AMBA_DEVICE(kmi1, "mb:kmi1", V2M_KMI1, NULL); +static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL); +static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL); +static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL); +static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL); +static AMBA_DEVICE(wdt, "mb:wdt", V2M_WDT, NULL); +static AMBA_DEVICE(rtc, "mb:rtc", V2M_RTC, NULL); + +static struct amba_device *v2m_amba_devs[] __initdata = { + &aaci_device, + &mmci_device, + &kmi0_device, + &kmi1_device, + &uart0_device, + &uart1_device, + &uart2_device, + &uart3_device, + &wdt_device, + &rtc_device, +}; + + +static long v2m_osc_round(struct clk *clk, unsigned long rate) +{ + return rate; +} + +static int v2m_osc1_set(struct clk *clk, unsigned long rate) +{ + return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate); +} + +static const struct clk_ops osc1_clk_ops = { + .round = v2m_osc_round, + .set = v2m_osc1_set, +}; + +static struct clk osc1_clk = { + .ops = &osc1_clk_ops, + .rate = 24000000, +}; + +static struct clk osc2_clk = { + .rate = 24000000, +}; + +static struct clk_lookup v2m_lookups[] = { + { /* UART0 */ + .dev_id = "mb:uart0", + .clk = &osc2_clk, + }, { /* UART1 */ + .dev_id = "mb:uart1", + .clk = &osc2_clk, + }, { /* UART2 */ + .dev_id = "mb:uart2", + .clk = &osc2_clk, + }, { /* UART3 */ + .dev_id = "mb:uart3", + .clk = &osc2_clk, + }, { /* KMI0 */ + .dev_id = "mb:kmi0", + .clk = &osc2_clk, + }, { /* KMI1 */ + .dev_id = "mb:kmi1", + .clk = &osc2_clk, + }, { /* MMC0 */ + .dev_id = "mb:mmci", + .clk = &osc2_clk, + }, { /* CLCD */ + .dev_id = "mb:clcd", + .clk = &osc1_clk, + }, +}; + +static void v2m_power_off(void) +{ + if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0)) + printk(KERN_EMERG "Unable to shutdown\n"); +} + +static void v2m_restart(char str, const char *cmd) +{ + if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0)) + printk(KERN_EMERG "Unable to reboot\n"); +} + +static int __init v2m_init(void) +{ + int i; + + clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups)); + + platform_device_register(&v2m_pcie_i2c_device); + platform_device_register(&v2m_ddc_i2c_device); + platform_device_register(&v2m_flash_device); + platform_device_register(&v2m_eth_device); + platform_device_register(&v2m_usb_device); + + for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) + amba_device_register(v2m_amba_devs[i], &iomem_resource); + + pm_power_off = v2m_power_off; + arm_pm_restart = v2m_restart; + + return 0; +} +arch_initcall(v2m_init); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 9c6170cd9aac..87ab0568bb0e 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -564,7 +564,7 @@ config I2C_STU300 config I2C_VERSATILE tristate "ARM Versatile/Realview I2C bus support" - depends on ARCH_VERSATILE || ARCH_REALVIEW + depends on ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS select I2C_ALGOBIT help Say yes if you want to support the I2C serial bus on ARMs Versatile -- cgit v1.2.3-59-g8ed1b From fef88f10767cfd9f9b4eebb5d5490214c5e13ad5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 28 Feb 2010 17:26:25 +0000 Subject: ARM: Add Versatile Express CA9x4 processor support Signed-off-by: Russell King --- arch/arm/mach-vexpress/Kconfig | 5 + arch/arm/mach-vexpress/Makefile | 1 + arch/arm/mach-vexpress/ct-ca9x4.c | 215 +++++++++++++++++++++++++ arch/arm/mach-vexpress/include/mach/ct-ca9x4.h | 43 +++++ arch/arm/mm/Kconfig | 3 +- 5 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-vexpress/ct-ca9x4.c create mode 100644 arch/arm/mach-vexpress/include/mach/ct-ca9x4.h (limited to 'arch') diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 751858c97e6a..3f19b660a165 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig @@ -1,4 +1,9 @@ menu "Versatile Express platform type" depends on ARCH_VEXPRESS +config ARCH_VEXPRESS_CA9X4 + bool "Versatile Express Cortex-A9x4 tile" + select CPU_V7 + select ARM_GIC + endmenu diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile index b47cf732981f..3c5e1609fc4f 100644 --- a/arch/arm/mach-vexpress/Makefile +++ b/arch/arm/mach-vexpress/Makefile @@ -3,3 +3,4 @@ # obj-y := v2m.o +obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c new file mode 100644 index 000000000000..5a0449c6f50d --- /dev/null +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -0,0 +1,215 @@ +/* + * Versatile Express Core Tile Cortex A9x4 Support + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include "core.h" + +#include + +#define V2M_PA_CS7 0x10000000 + +static struct map_desc ct_ca9x4_io_desc[] __initdata = { + { + .virtual = __MMIO_P2V(CT_CA9X4_MPIC), + .pfn = __phys_to_pfn(CT_CA9X4_MPIC), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = __MMIO_P2V(CT_CA9X4_SP804_TIMER), + .pfn = __phys_to_pfn(CT_CA9X4_SP804_TIMER), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = __MMIO_P2V(CT_CA9X4_L2CC), + .pfn = __phys_to_pfn(CT_CA9X4_L2CC), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static void __init ct_ca9x4_map_io(void) +{ + v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); +} + +void __iomem *gic_cpu_base_addr; + +static void __init ct_ca9x4_init_irq(void) +{ + gic_cpu_base_addr = MMIO_P2V(A9_MPCORE_GIC_CPU); + gic_dist_init(0, MMIO_P2V(A9_MPCORE_GIC_DIST), 29); + gic_cpu_init(0, gic_cpu_base_addr); +} + +#if 0 +static void ct_ca9x4_timer_init(void) +{ + writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); + writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); + + sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1)); + sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0); +} + +static struct sys_timer ct_ca9x4_timer = { + .init = ct_ca9x4_timer_init, +}; +#endif + +static struct clcd_panel xvga_panel = { + .mode = { + .name = "XVGA", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 15384, + .left_margin = 168, + .right_margin = 8, + .upper_margin = 29, + .lower_margin = 3, + .hsync_len = 144, + .vsync_len = 6, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), + .bpp = 16, +}; + +static void ct_ca9x4_clcd_enable(struct clcd_fb *fb) +{ + v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0); + v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2); +} + +static int ct_ca9x4_clcd_setup(struct clcd_fb *fb) +{ + unsigned long framesize = 1024 * 768 * 2; + dma_addr_t dma; + + fb->panel = &xvga_panel; + + fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, + &dma, GFP_KERNEL); + if (!fb->fb.screen_base) { + printk(KERN_ERR "CLCD: unable to map frame buffer\n"); + return -ENOMEM; + } + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = framesize; + + return 0; +} + +static int ct_ca9x4_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base, + fb->fb.fix.smem_start, fb->fb.fix.smem_len); +} + +static void ct_ca9x4_clcd_remove(struct clcd_fb *fb) +{ + dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} + +static struct clcd_board ct_ca9x4_clcd_data = { + .name = "CT-CA9X4", + .check = clcdfb_check, + .decode = clcdfb_decode, + .enable = ct_ca9x4_clcd_enable, + .setup = ct_ca9x4_clcd_setup, + .mmap = ct_ca9x4_clcd_mmap, + .remove = ct_ca9x4_clcd_remove, +}; + +static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data); +static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL); +static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL); +static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL); + +static struct amba_device *ct_ca9x4_amba_devs[] __initdata = { + &clcd_device, + &dmc_device, + &smc_device, + &gpio_device, +}; + + +static long ct_round(struct clk *clk, unsigned long rate) +{ + return rate; +} + +static int ct_set(struct clk *clk, unsigned long rate) +{ + return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate); +} + +static const struct clk_ops osc1_clk_ops = { + .round = ct_round, + .set = ct_set, +}; + +static struct clk osc1_clk = { + .ops = &osc1_clk_ops, + .rate = 24000000, +}; + +static struct clk_lookup lookups[] = { + { /* CLCD */ + .dev_id = "ct:clcd", + .clk = &osc1_clk, + }, +}; + +static void ct_ca9x4_init(void) +{ + int i; + +#ifdef CONFIG_CACHE_L2X0 + l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff); +#endif + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++) + amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); +} + +MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4") + .phys_io = V2M_UART0, + .io_pg_offst = (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x00000100, + .map_io = ct_ca9x4_map_io, + .init_irq = ct_ca9x4_init_irq, +#if 0 + .timer = &ct_ca9x4_timer, +#else + .timer = &v2m_timer, +#endif + .init_machine = ct_ca9x4_init, +MACHINE_END diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h new file mode 100644 index 000000000000..10718e654c6a --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h @@ -0,0 +1,43 @@ +#ifndef __MACH_CT_CA9X4_H +#define __MACH_CT_CA9X4_H + +/* + * Physical base addresses + */ +#define CT_CA9X4_CLCDC (0x10020000) +#define CT_CA9X4_AXIRAM (0x10060000) +#define CT_CA9X4_DMC (0x100e0000) +#define CT_CA9X4_SMC (0x100e1000) +#define CT_CA9X4_SCC (0x100e2000) +#define CT_CA9X4_SP804_TIMER (0x100e4000) +#define CT_CA9X4_SP805_WDT (0x100e5000) +#define CT_CA9X4_TZPC (0x100e6000) +#define CT_CA9X4_GPIO (0x100e8000) +#define CT_CA9X4_FASTAXI (0x100e9000) +#define CT_CA9X4_SLOWAXI (0x100ea000) +#define CT_CA9X4_TZASC (0x100ec000) +#define CT_CA9X4_CORESIGHT (0x10200000) +#define CT_CA9X4_MPIC (0x1e000000) +#define CT_CA9X4_SYSTIMER (0x1e004000) +#define CT_CA9X4_SYSWDT (0x1e007000) +#define CT_CA9X4_L2CC (0x1e00a000) + +#define CT_CA9X4_TIMER0 (CT_CA9X4_SP804_TIMER + 0x000) +#define CT_CA9X4_TIMER1 (CT_CA9X4_SP804_TIMER + 0x020) + +#define A9_MPCORE_SCU (CT_CA9X4_MPIC + 0x0000) +#define A9_MPCORE_GIC_CPU (CT_CA9X4_MPIC + 0x0100) +#define A9_MPCORE_GIT (CT_CA9X4_MPIC + 0x0200) +#define A9_MPCORE_GIC_DIST (CT_CA9X4_MPIC + 0x1000) + +/* + * Interrupts. Those in {} are for AMBA devices + */ +#define IRQ_CT_CA9X4_CLCDC { 76 } +#define IRQ_CT_CA9X4_DMC { -1 } +#define IRQ_CT_CA9X4_SMC { 77, 78 } +#define IRQ_CT_CA9X4_TIMER0 80 +#define IRQ_CT_CA9X4_TIMER1 81 +#define IRQ_CT_CA9X4_GPIO { 82 } + +#endif diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c4ed9f93f646..270c8e2a4490 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -754,7 +754,8 @@ config CACHE_FEROCEON_L2_WRITETHROUGH config CACHE_L2X0 bool "Enable the L2x0 outer cache controller" depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ - REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4 + REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \ + ARCH_NOMADIK || ARCH_OMAP4 || ARCH_VEXPRESS_CA9X4 default y select OUTER_CACHE help -- cgit v1.2.3-59-g8ed1b From 59ac59f6f1432aa9417d2592bdfd17c99804dd66 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 11 Feb 2010 21:56:07 +0000 Subject: ARM: Add Versatile Express SMP support Signed-off-by: Russell King --- arch/arm/Kconfig | 5 +- arch/arm/mach-vexpress/Makefile | 2 + arch/arm/mach-vexpress/headsmp.S | 39 ++++++ arch/arm/mach-vexpress/include/mach/smp.h | 21 ++++ arch/arm/mach-vexpress/localtimer.c | 26 ++++ arch/arm/mach-vexpress/platsmp.c | 190 ++++++++++++++++++++++++++++++ 6 files changed, 281 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-vexpress/headsmp.S create mode 100644 arch/arm/mach-vexpress/include/mach/smp.h create mode 100644 arch/arm/mach-vexpress/localtimer.c create mode 100644 arch/arm/mach-vexpress/platsmp.c (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 58080e17c28b..4bb7730a2682 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1121,10 +1121,11 @@ source "kernel/time/Kconfig" config SMP bool "Symmetric Multi-Processing (EXPERIMENTAL)" depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\ - MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500) + MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\ + ARCH_U8500 || ARCH_VEXPRESS_CA9X4) depends on GENERIC_CLOCKEVENTS select USE_GENERIC_SMP_HELPERS - select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500) + select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4) help This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile index 3c5e1609fc4f..1b71b77ade22 100644 --- a/arch/arm/mach-vexpress/Makefile +++ b/arch/arm/mach-vexpress/Makefile @@ -4,3 +4,5 @@ obj-y := v2m.o obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o +obj-$(CONFIG_SMP) += platsmp.o headsmp.o +obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o diff --git a/arch/arm/mach-vexpress/headsmp.S b/arch/arm/mach-vexpress/headsmp.S new file mode 100644 index 000000000000..8a78ff68e1ee --- /dev/null +++ b/arch/arm/mach-vexpress/headsmp.S @@ -0,0 +1,39 @@ +/* + * linux/arch/arm/mach-vexpress/headsmp.S + * + * Copyright (c) 2003 ARM Limited + * 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 version 2 as + * published by the Free Software Foundation. + */ +#include +#include + + __INIT + +/* + * Versatile Express specific entry point for secondary CPUs. This + * provides a "holding pen" into which all secondary cores are held + * until we're ready for them to initialise. + */ +ENTRY(vexpress_secondary_startup) + mrc p15, 0, r0, c0, c0, 5 + and r0, r0, #15 + adr r4, 1f + ldmia r4, {r5, r6} + sub r4, r4, r5 + add r6, r6, r4 +pen: ldr r7, [r6] + cmp r7, r0 + bne pen + + /* + * we've been released from the holding pen: secondary_stack + * should now contain the SVC stack for this core + */ + b secondary_startup + +1: .long . + .long pen_release diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h new file mode 100644 index 000000000000..72a9621ed087 --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/smp.h @@ -0,0 +1,21 @@ +#ifndef __MACH_SMP_H +#define __MACH_SMP_H + +#include + +#define hard_smp_processor_id() \ + ({ \ + unsigned int cpunum; \ + __asm__("mrc p15, 0, %0, c0, c0, 5" \ + : "=r" (cpunum)); \ + cpunum &= 0x0F; \ + }) + +/* + * We use IRQ1 as the IPI + */ +static inline void smp_cross_call(const struct cpumask *mask) +{ + gic_raise_softirq(mask, 1); +} +#endif diff --git a/arch/arm/mach-vexpress/localtimer.c b/arch/arm/mach-vexpress/localtimer.c new file mode 100644 index 000000000000..c0e3a59a0bfc --- /dev/null +++ b/arch/arm/mach-vexpress/localtimer.c @@ -0,0 +1,26 @@ +/* + * linux/arch/arm/mach-vexpress/localtimer.c + * + * Copyright (C) 2002 ARM Ltd. + * 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 version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include + +#include +#include +#include + +/* + * Setup the local clock events for a CPU. + */ +void __cpuinit local_timer_setup(struct clock_event_device *evt) +{ + evt->irq = IRQ_LOCALTIMER; + twd_timer_setup(evt); +} diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c new file mode 100644 index 000000000000..670970699ba9 --- /dev/null +++ b/arch/arm/mach-vexpress/platsmp.c @@ -0,0 +1,190 @@ +/* + * linux/arch/arm/mach-vexpress/platsmp.c + * + * Copyright (C) 2002 ARM Ltd. + * 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 version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#define V2M_PA_CS7 0x10000000 + +#include "core.h" + +extern void vexpress_secondary_startup(void); + +/* + * control for which core is the next to come out of the secondary + * boot "holding pen" + */ +volatile int __cpuinitdata pen_release = -1; + +static void __iomem *scu_base_addr(void) +{ + return MMIO_P2V(A9_MPCORE_SCU); +} + +static DEFINE_SPINLOCK(boot_lock); + +void __cpuinit platform_secondary_init(unsigned int cpu) +{ + trace_hardirqs_off(); + + /* + * if any interrupts are already enabled for the primary + * core (e.g. timer irq), then they will not have been enabled + * for us: do so + */ + gic_cpu_init(0, gic_cpu_base_addr); + + /* + * let the primary processor know we're out of the + * pen, then head off into the C entry point + */ + pen_release = -1; + smp_wmb(); + + /* + * Synchronise with the boot thread. + */ + spin_lock(&boot_lock); + spin_unlock(&boot_lock); +} + +int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + unsigned long timeout; + + /* + * Set synchronisation state between this boot processor + * and the secondary one + */ + spin_lock(&boot_lock); + + /* + * This is really belt and braces; we hold unintended secondary + * CPUs in the holding pen until we're ready for them. However, + * since we haven't sent them a soft interrupt, they shouldn't + * be there. + */ + pen_release = cpu; + __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); + outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); + + /* + * Send the secondary CPU a soft interrupt, thereby causing + * the boot monitor to read the system wide flags register, + * and branch to the address found there. + */ + smp_cross_call(cpumask_of(cpu)); + + timeout = jiffies + (1 * HZ); + while (time_before(jiffies, timeout)) { + smp_rmb(); + if (pen_release == -1) + break; + + udelay(10); + } + + /* + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ + spin_unlock(&boot_lock); + + return pen_release != -1 ? -ENOSYS : 0; +} + +/* + * Initialise the CPU possible map early - this describes the CPUs + * which may be present or become present in the system. + */ +void __init smp_init_cpus(void) +{ + void __iomem *scu_base = scu_base_addr(); + unsigned int i, ncores; + + ncores = scu_base ? scu_get_core_count(scu_base) : 1; + + /* sanity check */ + if (ncores == 0) { + printk(KERN_ERR + "vexpress: strange CM count of 0? Default to 1\n"); + + ncores = 1; + } + + if (ncores > NR_CPUS) { + printk(KERN_WARNING + "vexpress: no. of cores (%d) greater than configured " + "maximum of %d - clipping\n", + ncores, NR_CPUS); + ncores = NR_CPUS; + } + + for (i = 0; i < ncores; i++) + set_cpu_possible(i, true); +} + +void __init smp_prepare_cpus(unsigned int max_cpus) +{ + unsigned int ncores = num_possible_cpus(); + unsigned int cpu = smp_processor_id(); + int i; + + smp_store_cpu_info(cpu); + + /* + * are we trying to boot more cores than exist? + */ + if (max_cpus > ncores) + max_cpus = ncores; + + /* + * Initialise the present map, which describes the set of CPUs + * actually populated at the present time. + */ + for (i = 0; i < max_cpus; i++) + set_cpu_present(i, true); + + /* + * Initialise the SCU if there are more than one CPU and let + * them know where to start. + */ + if (max_cpus > 1) { + /* + * Enable the local timer or broadcast device for the + * boot CPU, but only if we have more than one CPU. + */ + percpu_timer_setup(); + + scu_enable(scu_base_addr()); + + /* + * Write the address of secondary startup into the + * system-wide flags register. The boot monitor waits + * until it receives a soft interrupt, and then the + * secondary CPU branches to this address. + */ + writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR)); + writel(BSYM(virt_to_phys(vexpress_secondary_startup)), + MMIO_P2V(V2M_SYS_FLAGSSET)); + } +} -- cgit v1.2.3-59-g8ed1b From f417cbad7394fdccec850d13d7d5621516d693ce Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 15 Apr 2010 10:16:26 +0100 Subject: ARM: 6057/1: Realview: register PMU IRQs during board initialisation This patch updates the initialisation routines for the Realview boards and the Versatile Express board [ca9x4 tile] so that they register their PMU IRQs with the PMU framework in the Kernel. Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/mach-realview/realview_eb.c | 32 ++++++++++++++++++++++++ arch/arm/mach-realview/realview_pb1176.c | 15 ++++++++++++ arch/arm/mach-realview/realview_pb11mp.c | 32 ++++++++++++++++++++++++ arch/arm/mach-realview/realview_pba8.c | 15 ++++++++++++ arch/arm/mach-realview/realview_pbx.c | 32 ++++++++++++++++++++++++ arch/arm/mach-vexpress/ct-ca9x4.c | 34 ++++++++++++++++++++++++++ arch/arm/mach-vexpress/include/mach/ct-ca9x4.h | 4 +++ 7 files changed, 164 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 006765fd204c..422ccd70d5f5 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -292,6 +293,36 @@ static struct resource realview_eb_isp1761_resources[] = { }, }; +static struct resource pmu_resources[] = { + [0] = { + .start = IRQ_EB11MP_PMU_CPU0, + .end = IRQ_EB11MP_PMU_CPU0, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .start = IRQ_EB11MP_PMU_CPU1, + .end = IRQ_EB11MP_PMU_CPU1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_EB11MP_PMU_CPU2, + .end = IRQ_EB11MP_PMU_CPU2, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_EB11MP_PMU_CPU3, + .end = IRQ_EB11MP_PMU_CPU3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .num_resources = ARRAY_SIZE(pmu_resources), + .resource = pmu_resources, +}; + static void __init gic_init_irq(void) { if (core_tile_eb11mp() || core_tile_a9mp()) { @@ -405,6 +436,7 @@ static void __init realview_eb_init(void) * Bits: .... ...0 0111 1001 0000 .... .... .... */ l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff); #endif + platform_device_register(&pmu_device); } realview_flash_register(&realview_eb_flash_resource, 1); diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index 217f7c19551e..96568ebfa2bb 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -261,6 +262,19 @@ static struct resource realview_pb1176_isp1761_resources[] = { }, }; +static struct resource pmu_resource = { + .start = IRQ_DC1176_CORE_PMU, + .end = IRQ_DC1176_CORE_PMU, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .num_resources = 1, + .resource = &pmu_resource, +}; + static void __init gic_init_irq(void) { /* ARM1176 DevChip GIC, primary */ @@ -322,6 +336,7 @@ static void __init realview_pb1176_init(void) realview_eth_register(NULL, realview_pb1176_smsc911x_resources); platform_device_register(&realview_i2c_device); realview_usb_register(realview_pb1176_isp1761_resources); + platform_device_register(&pmu_device); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index 9ef2ecc3c098..7fbefbbebaf0 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -258,6 +259,36 @@ static struct resource realview_pb11mp_isp1761_resources[] = { }, }; +static struct resource pmu_resources[] = { + [0] = { + .start = IRQ_TC11MP_PMU_CPU0, + .end = IRQ_TC11MP_PMU_CPU0, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .start = IRQ_TC11MP_PMU_CPU1, + .end = IRQ_TC11MP_PMU_CPU1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_TC11MP_PMU_CPU2, + .end = IRQ_TC11MP_PMU_CPU2, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_TC11MP_PMU_CPU3, + .end = IRQ_TC11MP_PMU_CPU3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .num_resources = ARRAY_SIZE(pmu_resources), + .resource = pmu_resources, +}; + static void __init gic_init_irq(void) { unsigned int pldctrl; @@ -327,6 +358,7 @@ static void __init realview_pb11mp_init(void) platform_device_register(&realview_i2c_device); platform_device_register(&realview_cf_device); realview_usb_register(realview_pb11mp_isp1761_resources); + platform_device_register(&pmu_device); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index 2fab3a6d566b..d3c113b3dfce 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -248,6 +249,19 @@ static struct resource realview_pba8_isp1761_resources[] = { }, }; +static struct resource pmu_resource = { + .start = IRQ_PBA8_PMU, + .end = IRQ_PBA8_PMU, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .num_resources = 1, + .resource = &pmu_resource, +}; + static void __init gic_init_irq(void) { /* ARM PB-A8 on-board GIC */ @@ -294,6 +308,7 @@ static void __init realview_pba8_init(void) platform_device_register(&realview_i2c_device); platform_device_register(&realview_cf_device); realview_usb_register(realview_pba8_isp1761_resources); + platform_device_register(&pmu_device); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index d94857eb0690..a235ba30996b 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -270,6 +271,36 @@ static struct resource realview_pbx_isp1761_resources[] = { }, }; +static struct resource pmu_resources[] = { + [0] = { + .start = IRQ_PBX_PMU_CPU0, + .end = IRQ_PBX_PMU_CPU0, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .start = IRQ_PBX_PMU_CPU1, + .end = IRQ_PBX_PMU_CPU1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_PBX_PMU_CPU2, + .end = IRQ_PBX_PMU_CPU2, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_PBX_PMU_CPU3, + .end = IRQ_PBX_PMU_CPU3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .num_resources = ARRAY_SIZE(pmu_resources), + .resource = pmu_resources, +}; + static void __init gic_init_irq(void) { /* ARM PBX on-board GIC */ @@ -354,6 +385,7 @@ static void __init realview_pbx_init(void) /* 16KB way size, 8-way associativity, parity disabled * Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */ l2x0_init(l2x0_base, 0x02520000, 0xc0000fff); + platform_device_register(&pmu_device); } #endif diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index 5a0449c6f50d..e6f73030d5f0 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #include @@ -186,6 +188,36 @@ static struct clk_lookup lookups[] = { }, }; +static struct resource pmu_resources[] = { + [0] = { + .start = IRQ_CT_CA9X4_PMU_CPU0, + .end = IRQ_CT_CA9X4_PMU_CPU0, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .start = IRQ_CT_CA9X4_PMU_CPU1, + .end = IRQ_CT_CA9X4_PMU_CPU1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_CT_CA9X4_PMU_CPU2, + .end = IRQ_CT_CA9X4_PMU_CPU2, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_CT_CA9X4_PMU_CPU3, + .end = IRQ_CT_CA9X4_PMU_CPU3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .num_resources = ARRAY_SIZE(pmu_resources), + .resource = pmu_resources, +}; + static void ct_ca9x4_init(void) { int i; @@ -198,6 +230,8 @@ static void ct_ca9x4_init(void) for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++) amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); + + platform_device_register(&pmu_device); } MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4") diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h index 10718e654c6a..8650f04136ef 100644 --- a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h +++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h @@ -39,5 +39,9 @@ #define IRQ_CT_CA9X4_TIMER0 80 #define IRQ_CT_CA9X4_TIMER1 81 #define IRQ_CT_CA9X4_GPIO { 82 } +#define IRQ_CT_CA9X4_PMU_CPU0 92 +#define IRQ_CT_CA9X4_PMU_CPU1 93 +#define IRQ_CT_CA9X4_PMU_CPU2 94 +#define IRQ_CT_CA9X4_PMU_CPU3 95 #endif -- cgit v1.2.3-59-g8ed1b From d94f944e108da21badabd99f527b25e03b677b96 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 25 Mar 2010 17:12:41 +0300 Subject: ARM: cns3xxx: Add basic support for Cavium Networks CNS3xxx processors This patch adds very basic support for ECONA CNS3xxx ARM11 MPcore (ARMv6) dual-core processors. Note that SMP is not yet supported, as well as many peripheral devices. Support for these features will be added later. Signed-off-by: Anton Vorontsov --- MAINTAINERS | 6 + arch/arm/Kconfig | 11 + arch/arm/Makefile | 1 + arch/arm/mach-cns3xxx/Kconfig | 4 + arch/arm/mach-cns3xxx/Makefile | 1 + arch/arm/mach-cns3xxx/Makefile.boot | 3 + arch/arm/mach-cns3xxx/core.c | 249 +++++++++ arch/arm/mach-cns3xxx/core.h | 23 + arch/arm/mach-cns3xxx/include/mach/cns3xxx.h | 635 +++++++++++++++++++++++ arch/arm/mach-cns3xxx/include/mach/debug-macro.S | 21 + arch/arm/mach-cns3xxx/include/mach/entry-macro.S | 82 +++ arch/arm/mach-cns3xxx/include/mach/hardware.h | 22 + arch/arm/mach-cns3xxx/include/mach/io.h | 17 + arch/arm/mach-cns3xxx/include/mach/irqs.h | 24 + arch/arm/mach-cns3xxx/include/mach/memory.h | 26 + arch/arm/mach-cns3xxx/include/mach/system.h | 29 ++ arch/arm/mach-cns3xxx/include/mach/timex.h | 12 + arch/arm/mach-cns3xxx/include/mach/uncompress.h | 55 ++ arch/arm/mach-cns3xxx/include/mach/vmalloc.h | 11 + arch/arm/mach-cns3xxx/pm.c | 86 +++ 20 files changed, 1318 insertions(+) create mode 100644 arch/arm/mach-cns3xxx/Kconfig create mode 100644 arch/arm/mach-cns3xxx/Makefile create mode 100644 arch/arm/mach-cns3xxx/Makefile.boot create mode 100644 arch/arm/mach-cns3xxx/core.c create mode 100644 arch/arm/mach-cns3xxx/core.h create mode 100644 arch/arm/mach-cns3xxx/include/mach/cns3xxx.h create mode 100644 arch/arm/mach-cns3xxx/include/mach/debug-macro.S create mode 100644 arch/arm/mach-cns3xxx/include/mach/entry-macro.S create mode 100644 arch/arm/mach-cns3xxx/include/mach/hardware.h create mode 100644 arch/arm/mach-cns3xxx/include/mach/io.h create mode 100644 arch/arm/mach-cns3xxx/include/mach/irqs.h create mode 100644 arch/arm/mach-cns3xxx/include/mach/memory.h create mode 100644 arch/arm/mach-cns3xxx/include/mach/system.h create mode 100644 arch/arm/mach-cns3xxx/include/mach/timex.h create mode 100644 arch/arm/mach-cns3xxx/include/mach/uncompress.h create mode 100644 arch/arm/mach-cns3xxx/include/mach/vmalloc.h create mode 100644 arch/arm/mach-cns3xxx/pm.c (limited to 'arch') diff --git a/MAINTAINERS b/MAINTAINERS index d5b0b1b6dc52..27299d139478 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -586,6 +586,12 @@ F: drivers/mtd/nand/bcm_umi_bch.c F: drivers/mtd/nand/bcm_umi_hamming.c F: drivers/mtd/nand/nand_bcm_umi.h +ARM/CAVIUM NETWORKS CNS3XXX MACHINE SUPPORT +M: Anton Vorontsov +S: Maintained +F: arch/arm/mach-cns3xxx/ +T: git git://git.infradead.org/users/cbou/linux-cns3xxx.git + ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE M: Hartley Sweeten M: Ryan Mallon diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 92622eb5cc0d..572e6cc2b2f6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -297,6 +297,15 @@ config ARCH_CLPS711X help Support for Cirrus Logic 711x/721x based boards. +config ARCH_CNS3XXX + bool "Cavium Networks CNS3XXX family" + select CPU_V6 + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select ARM_GIC + help + Support for Cavium Networks CNS3XXX platform. + config ARCH_GEMINI bool "Cortina Systems Gemini" select CPU_FA526 @@ -817,6 +826,8 @@ source "arch/arm/mach-bcmring/Kconfig" source "arch/arm/mach-clps711x/Kconfig" +source "arch/arm/mach-cns3xxx/Kconfig" + source "arch/arm/mach-davinci/Kconfig" source "arch/arm/mach-dove/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ed820e737a8a..3e312ec8e624 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -121,6 +121,7 @@ machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 machine-$(CONFIG_ARCH_AT91) := at91 machine-$(CONFIG_ARCH_BCMRING) := bcmring machine-$(CONFIG_ARCH_CLPS711X) := clps711x +machine-$(CONFIG_ARCH_CNS3XXX) := cns3xxx machine-$(CONFIG_ARCH_DAVINCI) := davinci machine-$(CONFIG_ARCH_DOVE) := dove machine-$(CONFIG_ARCH_EBSA110) := ebsa110 diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig new file mode 100644 index 000000000000..20284cdcb18b --- /dev/null +++ b/arch/arm/mach-cns3xxx/Kconfig @@ -0,0 +1,4 @@ +menu "CNS3XXX platform type" + depends on ARCH_CNS3XXX + +endmenu diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile new file mode 100644 index 000000000000..e5e76dd2111a --- /dev/null +++ b/arch/arm/mach-cns3xxx/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_CNS3XXX) += core.o pm.o diff --git a/arch/arm/mach-cns3xxx/Makefile.boot b/arch/arm/mach-cns3xxx/Makefile.boot new file mode 100644 index 000000000000..777012865220 --- /dev/null +++ b/arch/arm/mach-cns3xxx/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00C00000 diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c new file mode 100644 index 000000000000..9ca4d581016f --- /dev/null +++ b/arch/arm/mach-cns3xxx/core.c @@ -0,0 +1,249 @@ +/* + * Copyright 1999 - 2003 ARM Limited + * Copyright 2000 Deep Blue Solutions Ltd + * Copyright 2008 Cavium Networks + * + * This file 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "core.h" + +static struct map_desc cns3xxx_io_desc[] __initdata = { + { + .virtual = CNS3XXX_TC11MP_TWD_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_TIMER1_2_3_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TIMER1_2_3_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_GPIOA_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_GPIOA_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_GPIOB_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_GPIOB_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_MISC_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_MISC_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_PM_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_PM_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +void __init cns3xxx_map_io(void) +{ + iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc)); +} + +/* used by entry-macro.S */ +void __iomem *gic_cpu_base_addr; + +void __init cns3xxx_init_irq(void) +{ + gic_cpu_base_addr = __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT); + gic_dist_init(0, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), 29); + gic_cpu_init(0, gic_cpu_base_addr); +} + +void cns3xxx_power_off(void) +{ + u32 __iomem *pm_base = __io(CNS3XXX_PM_BASE_VIRT); + u32 clkctrl; + + printk(KERN_INFO "powering system down...\n"); + + clkctrl = readl(pm_base + PM_SYS_CLK_CTRL_OFFSET); + clkctrl &= 0xfffff1ff; + clkctrl |= (0x5 << 9); /* Hibernate */ + writel(clkctrl, pm_base + PM_SYS_CLK_CTRL_OFFSET); + +} + +/* + * Timer + */ +static void __iomem *cns3xxx_tmr1; + +static void cns3xxx_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *clk) +{ + unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); + int pclk = cns3xxx_cpu_clock() / 8; + int reload; + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + reload = pclk * 20 / (3 * HZ) * 0x25000; + writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET); + ctrl |= (1 << 0) | (1 << 2) | (1 << 9); + break; + case CLOCK_EVT_MODE_ONESHOT: + /* period set, and timer enabled in 'next_event' hook */ + ctrl |= (1 << 2) | (1 << 9); + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + default: + ctrl = 0; + } + + writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); +} + +static int cns3xxx_timer_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); + + writel(evt, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET); + writel(ctrl | (1 << 0), cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); + + return 0; +} + +static struct clock_event_device cns3xxx_tmr1_clockevent = { + .name = "cns3xxx timer1", + .shift = 8, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_mode = cns3xxx_timer_set_mode, + .set_next_event = cns3xxx_timer_set_next_event, + .rating = 350, + .cpumask = cpu_all_mask, +}; + +static void __init cns3xxx_clockevents_init(unsigned int timer_irq) +{ + cns3xxx_tmr1_clockevent.irq = timer_irq; + cns3xxx_tmr1_clockevent.mult = + div_sc((cns3xxx_cpu_clock() >> 3) * 1000000, NSEC_PER_SEC, + cns3xxx_tmr1_clockevent.shift); + cns3xxx_tmr1_clockevent.max_delta_ns = + clockevent_delta2ns(0xffffffff, &cns3xxx_tmr1_clockevent); + cns3xxx_tmr1_clockevent.min_delta_ns = + clockevent_delta2ns(0xf, &cns3xxx_tmr1_clockevent); + + clockevents_register_device(&cns3xxx_tmr1_clockevent); +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t cns3xxx_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &cns3xxx_tmr1_clockevent; + u32 __iomem *stat = cns3xxx_tmr1 + TIMER1_2_INTERRUPT_STATUS_OFFSET; + u32 val; + + /* Clear the interrupt */ + val = readl(stat); + writel(val & ~(1 << 2), stat); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction cns3xxx_timer_irq = { + .name = "timer", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = cns3xxx_timer_interrupt, +}; + +/* + * Set up the clock source and clock events devices + */ +static void __init __cns3xxx_timer_init(unsigned int timer_irq) +{ + u32 val; + u32 irq_mask; + + /* + * Initialise to a known state (all timers off) + */ + + /* disable timer1 and timer2 */ + writel(0, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); + /* stop free running timer3 */ + writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET); + + /* timer1 */ + writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET); + writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET); + + writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET); + writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET); + + /* mask irq, non-mask timer1 overflow */ + irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET); + irq_mask &= ~(1 << 2); + irq_mask |= 0x03; + writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET); + + /* down counter */ + val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); + val |= (1 << 9); + writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); + + /* timer2 */ + writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET); + writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET); + + /* mask irq */ + irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET); + irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5)); + writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET); + + /* down counter */ + val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); + val |= (1 << 10); + writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); + + /* Make irqs happen for the system timer */ + setup_irq(timer_irq, &cns3xxx_timer_irq); + + cns3xxx_clockevents_init(timer_irq); +} + +static void __init cns3xxx_timer_init(void) +{ + cns3xxx_tmr1 = __io(CNS3XXX_TIMER1_2_3_BASE_VIRT); + + __cns3xxx_timer_init(IRQ_CNS3XXX_TIMER0); +} + +struct sys_timer cns3xxx_timer = { + .init = cns3xxx_timer_init, +}; diff --git a/arch/arm/mach-cns3xxx/core.h b/arch/arm/mach-cns3xxx/core.h new file mode 100644 index 000000000000..6b33ec11346e --- /dev/null +++ b/arch/arm/mach-cns3xxx/core.h @@ -0,0 +1,23 @@ +/* + * Copyright 2000 Deep Blue Solutions Ltd + * Copyright 2004 ARM Limited + * Copyright 2008 Cavium Networks + * + * This file 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. + */ + +#ifndef __CNS3XXX_CORE_H +#define __CNS3XXX_CORE_H + +extern void __iomem *gic_cpu_base_addr; +extern struct sys_timer cns3xxx_timer; + +void __init cns3xxx_map_io(void); +void __init cns3xxx_init_irq(void); +void cns3xxx_power_off(void); +void cns3xxx_pwr_power_up(unsigned int block); +void cns3xxx_pwr_power_down(unsigned int block); + +#endif /* __CNS3XXX_CORE_H */ diff --git a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h new file mode 100644 index 000000000000..8a2f5a21d4ee --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h @@ -0,0 +1,635 @@ +/* + * Copyright 2008 Cavium Networks + * + * This file 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. + */ + +#ifndef __MACH_BOARD_CNS3XXXH +#define __MACH_BOARD_CNS3XXXH + +/* + * Memory map + */ +#define CNS3XXX_FLASH_BASE 0x10000000 /* Flash/SRAM Memory Bank 0 */ +#define CNS3XXX_FLASH_SIZE SZ_256M + +#define CNS3XXX_DDR2SDRAM_BASE 0x20000000 /* DDR2 SDRAM Memory */ + +#define CNS3XXX_SPI_FLASH_BASE 0x60000000 /* SPI Serial Flash Memory */ + +#define CNS3XXX_SWITCH_BASE 0x70000000 /* Switch and HNAT Control */ +#define CNS3XXX_SWITCH_BASE_VIRT 0xFFF00000 + +#define CNS3XXX_PPE_BASE 0x70001000 /* HANT */ +#define CNS3XXX_PPE_BASE_VIRT 0xFFF50000 + +#define CNS3XXX_EMBEDDED_SRAM_BASE 0x70002000 /* HANT Embedded SRAM */ +#define CNS3XXX_EMBEDDED_SRAM_BASE_VIRT 0xFFF60000 + +#define CNS3XXX_SSP_BASE 0x71000000 /* Synchronous Serial Port - SPI/PCM/I2C */ +#define CNS3XXX_SSP_BASE_VIRT 0xFFF01000 + +#define CNS3XXX_DMC_BASE 0x72000000 /* DMC Control (DDR2 SDRAM) */ +#define CNS3XXX_DMC_BASE_VIRT 0xFFF02000 + +#define CNS3XXX_SMC_BASE 0x73000000 /* SMC Control */ +#define CNS3XXX_SMC_BASE_VIRT 0xFFF03000 + +#define SMC_MEMC_STATUS_OFFSET 0x000 +#define SMC_MEMIF_CFG_OFFSET 0x004 +#define SMC_MEMC_CFG_SET_OFFSET 0x008 +#define SMC_MEMC_CFG_CLR_OFFSET 0x00C +#define SMC_DIRECT_CMD_OFFSET 0x010 +#define SMC_SET_CYCLES_OFFSET 0x014 +#define SMC_SET_OPMODE_OFFSET 0x018 +#define SMC_REFRESH_PERIOD_0_OFFSET 0x020 +#define SMC_REFRESH_PERIOD_1_OFFSET 0x024 +#define SMC_SRAM_CYCLES0_0_OFFSET 0x100 +#define SMC_NAND_CYCLES0_0_OFFSET 0x100 +#define SMC_OPMODE0_0_OFFSET 0x104 +#define SMC_SRAM_CYCLES0_1_OFFSET 0x120 +#define SMC_NAND_CYCLES0_1_OFFSET 0x120 +#define SMC_OPMODE0_1_OFFSET 0x124 +#define SMC_USER_STATUS_OFFSET 0x200 +#define SMC_USER_CONFIG_OFFSET 0x204 +#define SMC_ECC_STATUS_OFFSET 0x300 +#define SMC_ECC_MEMCFG_OFFSET 0x304 +#define SMC_ECC_MEMCOMMAND1_OFFSET 0x308 +#define SMC_ECC_MEMCOMMAND2_OFFSET 0x30C +#define SMC_ECC_ADDR0_OFFSET 0x310 +#define SMC_ECC_ADDR1_OFFSET 0x314 +#define SMC_ECC_VALUE0_OFFSET 0x318 +#define SMC_ECC_VALUE1_OFFSET 0x31C +#define SMC_ECC_VALUE2_OFFSET 0x320 +#define SMC_ECC_VALUE3_OFFSET 0x324 +#define SMC_PERIPH_ID_0_OFFSET 0xFE0 +#define SMC_PERIPH_ID_1_OFFSET 0xFE4 +#define SMC_PERIPH_ID_2_OFFSET 0xFE8 +#define SMC_PERIPH_ID_3_OFFSET 0xFEC +#define SMC_PCELL_ID_0_OFFSET 0xFF0 +#define SMC_PCELL_ID_1_OFFSET 0xFF4 +#define SMC_PCELL_ID_2_OFFSET 0xFF8 +#define SMC_PCELL_ID_3_OFFSET 0xFFC + +#define CNS3XXX_GPIOA_BASE 0x74000000 /* GPIO port A */ +#define CNS3XXX_GPIOA_BASE_VIRT 0xFFF04000 + +#define CNS3XXX_GPIOB_BASE 0x74800000 /* GPIO port B */ +#define CNS3XXX_GPIOB_BASE_VIRT 0xFFF05000 + +#define CNS3XXX_RTC_BASE 0x75000000 /* Real Time Clock */ +#define CNS3XXX_RTC_BASE_VIRT 0xFFF06000 + +#define RTC_SEC_OFFSET 0x00 +#define RTC_MIN_OFFSET 0x04 +#define RTC_HOUR_OFFSET 0x08 +#define RTC_DAY_OFFSET 0x0C +#define RTC_SEC_ALM_OFFSET 0x10 +#define RTC_MIN_ALM_OFFSET 0x14 +#define RTC_HOUR_ALM_OFFSET 0x18 +#define RTC_REC_OFFSET 0x1C +#define RTC_CTRL_OFFSET 0x20 +#define RTC_INTR_STS_OFFSET 0x34 + +#define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */ +#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */ + +#define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */ +#define CNS3XXX_PM_BASE_VIRT 0xFFF08000 + +#define PM_CLK_GATE_OFFSET 0x00 +#define PM_SOFT_RST_OFFSET 0x04 +#define PM_HS_CFG_OFFSET 0x08 +#define PM_CACTIVE_STA_OFFSET 0x0C +#define PM_PWR_STA_OFFSET 0x10 +#define PM_SYS_CLK_CTRL_OFFSET 0x14 +#define PM_PLL_LCD_I2S_CTRL_OFFSET 0x18 +#define PM_PLL_HM_PD_OFFSET 0x1C + +#define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */ +#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000 + +#define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */ +#define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000 + +#define CNS3XXX_UART2_BASE 0x78800000 /* UART 2 */ +#define CNS3XXX_UART2_BASE_VIRT 0xFFF0B000 + +#define CNS3XXX_DMAC_BASE 0x79000000 /* Generic DMA Control */ +#define CNS3XXX_DMAC_BASE_VIRT 0xFFF0D000 + +#define CNS3XXX_CORESIGHT_BASE 0x7A000000 /* CoreSight */ +#define CNS3XXX_CORESIGHT_BASE_VIRT 0xFFF0E000 + +#define CNS3XXX_CRYPTO_BASE 0x7B000000 /* Crypto */ +#define CNS3XXX_CRYPTO_BASE_VIRT 0xFFF0F000 + +#define CNS3XXX_I2S_BASE 0x7C000000 /* I2S */ +#define CNS3XXX_I2S_BASE_VIRT 0xFFF10000 + +#define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */ +#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800 + +#define TIMER1_COUNTER_OFFSET 0x00 +#define TIMER1_AUTO_RELOAD_OFFSET 0x04 +#define TIMER1_MATCH_V1_OFFSET 0x08 +#define TIMER1_MATCH_V2_OFFSET 0x0C + +#define TIMER2_COUNTER_OFFSET 0x10 +#define TIMER2_AUTO_RELOAD_OFFSET 0x14 +#define TIMER2_MATCH_V1_OFFSET 0x18 +#define TIMER2_MATCH_V2_OFFSET 0x1C + +#define TIMER1_2_CONTROL_OFFSET 0x30 +#define TIMER1_2_INTERRUPT_STATUS_OFFSET 0x34 +#define TIMER1_2_INTERRUPT_MASK_OFFSET 0x38 + +#define TIMER_FREERUN_OFFSET 0x40 +#define TIMER_FREERUN_CONTROL_OFFSET 0x44 + +#define CNS3XXX_HCIE_BASE 0x7D000000 /* HCIE Control */ +#define CNS3XXX_HCIE_BASE_VIRT 0xFFF30000 + +#define CNS3XXX_RAID_BASE 0x7E000000 /* RAID Control */ +#define CNS3XXX_RAID_BASE_VIRT 0xFFF12000 + +#define CNS3XXX_AXI_IXC_BASE 0x7F000000 /* AXI IXC */ +#define CNS3XXX_AXI_IXC_BASE_VIRT 0xFFF13000 + +#define CNS3XXX_CLCD_BASE 0x80000000 /* LCD Control */ +#define CNS3XXX_CLCD_BASE_VIRT 0xFFF14000 + +#define CNS3XXX_USBOTG_BASE 0x81000000 /* USB OTG Control */ +#define CNS3XXX_USBOTG_BASE_VIRT 0xFFF15000 + +#define CNS3XXX_USB_BASE 0x82000000 /* USB Host Control */ +#define CNS3XXX_USB_BASE_VIRT 0xFFF16000 + +#define CNS3XXX_SATA2_BASE 0x83000000 /* SATA */ +#define CNS3XXX_SATA2_SIZE SZ_16M +#define CNS3XXX_SATA2_BASE_VIRT 0xFFF17000 + +#define CNS3XXX_CAMERA_BASE 0x84000000 /* Camera Interface */ +#define CNS3XXX_CAMERA_BASE_VIRT 0xFFF18000 + +#define CNS3XXX_SDIO_BASE 0x85000000 /* SDIO */ +#define CNS3XXX_SDIO_BASE_VIRT 0xFFF19000 + +#define CNS3XXX_I2S_TDM_BASE 0x86000000 /* I2S TDM */ +#define CNS3XXX_I2S_TDM_BASE_VIRT 0xFFF1A000 + +#define CNS3XXX_2DG_BASE 0x87000000 /* 2D Graphic Control */ +#define CNS3XXX_2DG_BASE_VIRT 0xFFF1B000 + +#define CNS3XXX_USB_OHCI_BASE 0x88000000 /* USB OHCI */ +#define CNS3XXX_USB_OHCI_BASE_VIRT 0xFFF1C000 + +#define CNS3XXX_L2C_BASE 0x92000000 /* L2 Cache Control */ +#define CNS3XXX_L2C_BASE_VIRT 0xFFF27000 + +#define CNS3XXX_PCIE0_MEM_BASE 0xA0000000 /* PCIe Port 0 IO/Memory Space */ +#define CNS3XXX_PCIE0_MEM_BASE_VIRT 0xE0000000 + +#define CNS3XXX_PCIE0_HOST_BASE 0xAB000000 /* PCIe Port 0 RC Base */ +#define CNS3XXX_PCIE0_HOST_BASE_VIRT 0xE1000000 + +#define CNS3XXX_PCIE0_IO_BASE 0xAC000000 /* PCIe Port 0 */ +#define CNS3XXX_PCIE0_IO_BASE_VIRT 0xE2000000 + +#define CNS3XXX_PCIE0_CFG0_BASE 0xAD000000 /* PCIe Port 0 CFG Type 0 */ +#define CNS3XXX_PCIE0_CFG0_BASE_VIRT 0xE3000000 + +#define CNS3XXX_PCIE0_CFG1_BASE 0xAE000000 /* PCIe Port 0 CFG Type 1 */ +#define CNS3XXX_PCIE0_CFG1_BASE_VIRT 0xE4000000 + +#define CNS3XXX_PCIE0_MSG_BASE 0xAF000000 /* PCIe Port 0 Message Space */ +#define CNS3XXX_PCIE0_MSG_BASE_VIRT 0xE5000000 + +#define CNS3XXX_PCIE1_MEM_BASE 0xB0000000 /* PCIe Port 1 IO/Memory Space */ +#define CNS3XXX_PCIE1_MEM_BASE_VIRT 0xE8000000 + +#define CNS3XXX_PCIE1_HOST_BASE 0xBB000000 /* PCIe Port 1 RC Base */ +#define CNS3XXX_PCIE1_HOST_BASE_VIRT 0xE9000000 + +#define CNS3XXX_PCIE1_IO_BASE 0xBC000000 /* PCIe Port 1 */ +#define CNS3XXX_PCIE1_IO_BASE_VIRT 0xEA000000 + +#define CNS3XXX_PCIE1_CFG0_BASE 0xBD000000 /* PCIe Port 1 CFG Type 0 */ +#define CNS3XXX_PCIE1_CFG0_BASE_VIRT 0xEB000000 + +#define CNS3XXX_PCIE1_CFG1_BASE 0xBE000000 /* PCIe Port 1 CFG Type 1 */ +#define CNS3XXX_PCIE1_CFG1_BASE_VIRT 0xEC000000 + +#define CNS3XXX_PCIE1_MSG_BASE 0xBF000000 /* PCIe Port 1 Message Space */ +#define CNS3XXX_PCIE1_MSG_BASE_VIRT 0xED000000 + +/* + * Testchip peripheral and fpga gic regions + */ +#define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */ +#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000 + +#define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */ +#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100 + +#define CNS3XXX_TC11MP_TWD_BASE 0x90000600 +#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600 + +#define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */ +#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000 + +#define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */ +#define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000 + +/* + * Misc block + */ +#define MISC_MEM_MAP(offs) (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + (offs)) +#define MISC_MEM_MAP_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_MISC_BASE_VIRT + (offset)))) + +#define MISC_MEMORY_REMAP_REG MISC_MEM_MAP_VALUE(0x00) +#define MISC_CHIP_CONFIG_REG MISC_MEM_MAP_VALUE(0x04) +#define MISC_DEBUG_PROBE_DATA_REG MISC_MEM_MAP_VALUE(0x08) +#define MISC_DEBUG_PROBE_SELECTION_REG MISC_MEM_MAP_VALUE(0x0C) +#define MISC_IO_PIN_FUNC_SELECTION_REG MISC_MEM_MAP_VALUE(0x10) +#define MISC_GPIOA_PIN_ENABLE_REG MISC_MEM_MAP_VALUE(0x14) +#define MISC_GPIOB_PIN_ENABLE_REG MISC_MEM_MAP_VALUE(0x18) +#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_A MISC_MEM_MAP_VALUE(0x1C) +#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_B MISC_MEM_MAP_VALUE(0x20) +#define MISC_GPIOA_15_0_PULL_CTRL_REG MISC_MEM_MAP_VALUE(0x24) +#define MISC_GPIOA_16_31_PULL_CTRL_REG MISC_MEM_MAP_VALUE(0x28) +#define MISC_GPIOB_15_0_PULL_CTRL_REG MISC_MEM_MAP_VALUE(0x2C) +#define MISC_GPIOB_16_31_PULL_CTRL_REG MISC_MEM_MAP_VALUE(0x30) +#define MISC_IO_PULL_CTRL_REG MISC_MEM_MAP_VALUE(0x34) +#define MISC_E_FUSE_31_0_REG MISC_MEM_MAP_VALUE(0x40) +#define MISC_E_FUSE_63_32_REG MISC_MEM_MAP_VALUE(0x44) +#define MISC_E_FUSE_95_64_REG MISC_MEM_MAP_VALUE(0x48) +#define MISC_E_FUSE_127_96_REG MISC_MEM_MAP_VALUE(0x4C) +#define MISC_SOFTWARE_TEST_1_REG MISC_MEM_MAP_VALUE(0x50) +#define MISC_SOFTWARE_TEST_2_REG MISC_MEM_MAP_VALUE(0x54) + +#define MISC_SATA_POWER_MODE MISC_MEM_MAP_VALUE(0x310) + +#define MISC_USB_CFG_REG MISC_MEM_MAP_VALUE(0x800) +#define MISC_USB_STS_REG MISC_MEM_MAP_VALUE(0x804) +#define MISC_USBPHY00_CFG_REG MISC_MEM_MAP_VALUE(0x808) +#define MISC_USBPHY01_CFG_REG MISC_MEM_MAP_VALUE(0x80c) +#define MISC_USBPHY10_CFG_REG MISC_MEM_MAP_VALUE(0x810) +#define MISC_USBPHY11_CFG_REG MISC_MEM_MAP_VALUE(0x814) + +#define MISC_PCIEPHY_CMCTL(x) MISC_MEM_MAP(0x900 + (x) * 0x004) +#define MISC_PCIEPHY_CTL(x) MISC_MEM_MAP(0x940 + (x) * 0x100) +#define MISC_PCIE_AXIS_AWMISC(x) MISC_MEM_MAP(0x944 + (x) * 0x100) +#define MISC_PCIE_AXIS_ARMISC(x) MISC_MEM_MAP(0x948 + (x) * 0x100) +#define MISC_PCIE_AXIS_RMISC(x) MISC_MEM_MAP(0x94C + (x) * 0x100) +#define MISC_PCIE_AXIS_BMISC(x) MISC_MEM_MAP(0x950 + (x) * 0x100) +#define MISC_PCIE_AXIM_RMISC(x) MISC_MEM_MAP(0x954 + (x) * 0x100) +#define MISC_PCIE_AXIM_BMISC(x) MISC_MEM_MAP(0x958 + (x) * 0x100) +#define MISC_PCIE_CTRL(x) MISC_MEM_MAP(0x95C + (x) * 0x100) +#define MISC_PCIE_PM_DEBUG(x) MISC_MEM_MAP(0x960 + (x) * 0x100) +#define MISC_PCIE_RFC_DEBUG(x) MISC_MEM_MAP(0x964 + (x) * 0x100) +#define MISC_PCIE_CXPL_DEBUGL(x) MISC_MEM_MAP(0x968 + (x) * 0x100) +#define MISC_PCIE_CXPL_DEBUGH(x) MISC_MEM_MAP(0x96C + (x) * 0x100) +#define MISC_PCIE_DIAG_DEBUGH(x) MISC_MEM_MAP(0x970 + (x) * 0x100) +#define MISC_PCIE_W1CLR(x) MISC_MEM_MAP(0x974 + (x) * 0x100) +#define MISC_PCIE_INT_MASK(x) MISC_MEM_MAP(0x978 + (x) * 0x100) +#define MISC_PCIE_INT_STATUS(x) MISC_MEM_MAP(0x97C + (x) * 0x100) + +/* + * Power management and clock control + */ +#define PMU_REG_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_PM_BASE_VIRT + (offset)))) + +#define PM_CLK_GATE_REG PMU_REG_VALUE(0x000) +#define PM_SOFT_RST_REG PMU_REG_VALUE(0x004) +#define PM_HS_CFG_REG PMU_REG_VALUE(0x008) +#define PM_CACTIVE_STA_REG PMU_REG_VALUE(0x00C) +#define PM_PWR_STA_REG PMU_REG_VALUE(0x010) +#define PM_CLK_CTRL_REG PMU_REG_VALUE(0x014) +#define PM_PLL_LCD_I2S_CTRL_REG PMU_REG_VALUE(0x018) +#define PM_PLL_HM_PD_CTRL_REG PMU_REG_VALUE(0x01C) +#define PM_REGULAT_CTRL_REG PMU_REG_VALUE(0x020) +#define PM_WDT_CTRL_REG PMU_REG_VALUE(0x024) +#define PM_WU_CTRL0_REG PMU_REG_VALUE(0x028) +#define PM_WU_CTRL1_REG PMU_REG_VALUE(0x02C) +#define PM_CSR_REG PMU_REG_VALUE(0x030) + +/* PM_CLK_GATE_REG */ +#define PM_CLK_GATE_REG_OFFSET_SDIO (25) +#define PM_CLK_GATE_REG_OFFSET_GPU (24) +#define PM_CLK_GATE_REG_OFFSET_CIM (23) +#define PM_CLK_GATE_REG_OFFSET_LCDC (22) +#define PM_CLK_GATE_REG_OFFSET_I2S (21) +#define PM_CLK_GATE_REG_OFFSET_RAID (20) +#define PM_CLK_GATE_REG_OFFSET_SATA (19) +#define PM_CLK_GATE_REG_OFFSET_PCIE(x) (17 + (x)) +#define PM_CLK_GATE_REG_OFFSET_USB_HOST (16) +#define PM_CLK_GATE_REG_OFFSET_USB_OTG (15) +#define PM_CLK_GATE_REG_OFFSET_TIMER (14) +#define PM_CLK_GATE_REG_OFFSET_CRYPTO (13) +#define PM_CLK_GATE_REG_OFFSET_HCIE (12) +#define PM_CLK_GATE_REG_OFFSET_SWITCH (11) +#define PM_CLK_GATE_REG_OFFSET_GPIO (10) +#define PM_CLK_GATE_REG_OFFSET_UART3 (9) +#define PM_CLK_GATE_REG_OFFSET_UART2 (8) +#define PM_CLK_GATE_REG_OFFSET_UART1 (7) +#define PM_CLK_GATE_REG_OFFSET_RTC (5) +#define PM_CLK_GATE_REG_OFFSET_GDMA (4) +#define PM_CLK_GATE_REG_OFFSET_SPI_PCM_I2C (3) +#define PM_CLK_GATE_REG_OFFSET_SMC_NFI (1) +#define PM_CLK_GATE_REG_MASK (0x03FFFFBA) + +/* PM_SOFT_RST_REG */ +#define PM_SOFT_RST_REG_OFFST_WARM_RST_FLAG (31) +#define PM_SOFT_RST_REG_OFFST_CPU1 (29) +#define PM_SOFT_RST_REG_OFFST_CPU0 (28) +#define PM_SOFT_RST_REG_OFFST_SDIO (25) +#define PM_SOFT_RST_REG_OFFST_GPU (24) +#define PM_SOFT_RST_REG_OFFST_CIM (23) +#define PM_SOFT_RST_REG_OFFST_LCDC (22) +#define PM_SOFT_RST_REG_OFFST_I2S (21) +#define PM_SOFT_RST_REG_OFFST_RAID (20) +#define PM_SOFT_RST_REG_OFFST_SATA (19) +#define PM_SOFT_RST_REG_OFFST_PCIE(x) (17 + (x)) +#define PM_SOFT_RST_REG_OFFST_USB_HOST (16) +#define PM_SOFT_RST_REG_OFFST_USB_OTG (15) +#define PM_SOFT_RST_REG_OFFST_TIMER (14) +#define PM_SOFT_RST_REG_OFFST_CRYPTO (13) +#define PM_SOFT_RST_REG_OFFST_HCIE (12) +#define PM_SOFT_RST_REG_OFFST_SWITCH (11) +#define PM_SOFT_RST_REG_OFFST_GPIO (10) +#define PM_SOFT_RST_REG_OFFST_UART3 (9) +#define PM_SOFT_RST_REG_OFFST_UART2 (8) +#define PM_SOFT_RST_REG_OFFST_UART1 (7) +#define PM_SOFT_RST_REG_OFFST_RTC (5) +#define PM_SOFT_RST_REG_OFFST_GDMA (4) +#define PM_SOFT_RST_REG_OFFST_SPI_PCM_I2C (3) +#define PM_SOFT_RST_REG_OFFST_DMC (2) +#define PM_SOFT_RST_REG_OFFST_SMC_NFI (1) +#define PM_SOFT_RST_REG_OFFST_GLOBAL (0) +#define PM_SOFT_RST_REG_MASK (0xF3FFFFBF) + +/* PMHS_CFG_REG */ +#define PM_HS_CFG_REG_OFFSET_SDIO (25) +#define PM_HS_CFG_REG_OFFSET_GPU (24) +#define PM_HS_CFG_REG_OFFSET_CIM (23) +#define PM_HS_CFG_REG_OFFSET_LCDC (22) +#define PM_HS_CFG_REG_OFFSET_I2S (21) +#define PM_HS_CFG_REG_OFFSET_RAID (20) +#define PM_HS_CFG_REG_OFFSET_SATA (19) +#define PM_HS_CFG_REG_OFFSET_PCIE1 (18) +#define PM_HS_CFG_REG_OFFSET_PCIE0 (17) +#define PM_HS_CFG_REG_OFFSET_USB_HOST (16) +#define PM_HS_CFG_REG_OFFSET_USB_OTG (15) +#define PM_HS_CFG_REG_OFFSET_TIMER (14) +#define PM_HS_CFG_REG_OFFSET_CRYPTO (13) +#define PM_HS_CFG_REG_OFFSET_HCIE (12) +#define PM_HS_CFG_REG_OFFSET_SWITCH (11) +#define PM_HS_CFG_REG_OFFSET_GPIO (10) +#define PM_HS_CFG_REG_OFFSET_UART3 (9) +#define PM_HS_CFG_REG_OFFSET_UART2 (8) +#define PM_HS_CFG_REG_OFFSET_UART1 (7) +#define PM_HS_CFG_REG_OFFSET_RTC (5) +#define PM_HS_CFG_REG_OFFSET_GDMA (4) +#define PM_HS_CFG_REG_OFFSET_SPI_PCM_I2S (3) +#define PM_HS_CFG_REG_OFFSET_DMC (2) +#define PM_HS_CFG_REG_OFFSET_SMC_NFI (1) +#define PM_HS_CFG_REG_MASK (0x03FFFFBE) +#define PM_HS_CFG_REG_MASK_SUPPORT (0x01100806) + +/* PM_CACTIVE_STA_REG */ +#define PM_CACTIVE_STA_REG_OFFSET_SDIO (25) +#define PM_CACTIVE_STA_REG_OFFSET_GPU (24) +#define PM_CACTIVE_STA_REG_OFFSET_CIM (23) +#define PM_CACTIVE_STA_REG_OFFSET_LCDC (22) +#define PM_CACTIVE_STA_REG_OFFSET_I2S (21) +#define PM_CACTIVE_STA_REG_OFFSET_RAID (20) +#define PM_CACTIVE_STA_REG_OFFSET_SATA (19) +#define PM_CACTIVE_STA_REG_OFFSET_PCIE1 (18) +#define PM_CACTIVE_STA_REG_OFFSET_PCIE0 (17) +#define PM_CACTIVE_STA_REG_OFFSET_USB_HOST (16) +#define PM_CACTIVE_STA_REG_OFFSET_USB_OTG (15) +#define PM_CACTIVE_STA_REG_OFFSET_TIMER (14) +#define PM_CACTIVE_STA_REG_OFFSET_CRYPTO (13) +#define PM_CACTIVE_STA_REG_OFFSET_HCIE (12) +#define PM_CACTIVE_STA_REG_OFFSET_SWITCH (11) +#define PM_CACTIVE_STA_REG_OFFSET_GPIO (10) +#define PM_CACTIVE_STA_REG_OFFSET_UART3 (9) +#define PM_CACTIVE_STA_REG_OFFSET_UART2 (8) +#define PM_CACTIVE_STA_REG_OFFSET_UART1 (7) +#define PM_CACTIVE_STA_REG_OFFSET_RTC (5) +#define PM_CACTIVE_STA_REG_OFFSET_GDMA (4) +#define PM_CACTIVE_STA_REG_OFFSET_SPI_PCM_I2S (3) +#define PM_CACTIVE_STA_REG_OFFSET_DMC (2) +#define PM_CACTIVE_STA_REG_OFFSET_SMC_NFI (1) +#define PM_CACTIVE_STA_REG_MASK (0x03FFFFBE) + +/* PM_PWR_STA_REG */ +#define PM_PWR_STA_REG_REG_OFFSET_SDIO (25) +#define PM_PWR_STA_REG_REG_OFFSET_GPU (24) +#define PM_PWR_STA_REG_REG_OFFSET_CIM (23) +#define PM_PWR_STA_REG_REG_OFFSET_LCDC (22) +#define PM_PWR_STA_REG_REG_OFFSET_I2S (21) +#define PM_PWR_STA_REG_REG_OFFSET_RAID (20) +#define PM_PWR_STA_REG_REG_OFFSET_SATA (19) +#define PM_PWR_STA_REG_REG_OFFSET_PCIE1 (18) +#define PM_PWR_STA_REG_REG_OFFSET_PCIE0 (17) +#define PM_PWR_STA_REG_REG_OFFSET_USB_HOST (16) +#define PM_PWR_STA_REG_REG_OFFSET_USB_OTG (15) +#define PM_PWR_STA_REG_REG_OFFSET_TIMER (14) +#define PM_PWR_STA_REG_REG_OFFSET_CRYPTO (13) +#define PM_PWR_STA_REG_REG_OFFSET_HCIE (12) +#define PM_PWR_STA_REG_REG_OFFSET_SWITCH (11) +#define PM_PWR_STA_REG_REG_OFFSET_GPIO (10) +#define PM_PWR_STA_REG_REG_OFFSET_UART3 (9) +#define PM_PWR_STA_REG_REG_OFFSET_UART2 (8) +#define PM_PWR_STA_REG_REG_OFFSET_UART1 (7) +#define PM_PWR_STA_REG_REG_OFFSET_RTC (5) +#define PM_PWR_STA_REG_REG_OFFSET_GDMA (4) +#define PM_PWR_STA_REG_REG_OFFSET_SPI_PCM_I2S (3) +#define PM_PWR_STA_REG_REG_OFFSET_DMC (2) +#define PM_PWR_STA_REG_REG_OFFSET_SMC_NFI (1) +#define PM_PWR_STA_REG_REG_MASK (0x03FFFFBE) + +/* PM_CLK_CTRL_REG */ +#define PM_CLK_CTRL_REG_OFFSET_I2S_MCLK (31) +#define PM_CLK_CTRL_REG_OFFSET_DDR2_CHG_EN (30) +#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF1_EN (29) +#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF0_EN (28) +#define PM_CLK_CTRL_REG_OFFSET_TIMER_SIM_MODE (27) +#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_DIV (24) +#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_SEL (22) +#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_DIV (20) +#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_SEL (16) +#define PM_CLK_CTRL_REG_OFFSET_MDC_DIV (14) +#define PM_CLK_CTRL_REG_OFFSET_CRYPTO_CLK_SEL (12) +#define PM_CLK_CTRL_REG_OFFSET_CPU_PWR_MODE (9) +#define PM_CLK_CTRL_REG_OFFSET_PLL_DDR2_SEL (7) +#define PM_CLK_CTRL_REG_OFFSET_DIV_IMMEDIATE (6) +#define PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV (4) +#define PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL (0) + +#define PM_CPU_CLK_DIV(DIV) { \ + PM_CLK_CTRL_REG &= ~((0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \ + PM_CLK_CTRL_REG |= (((DIV)&0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \ +} + +#define PM_PLL_CPU_SEL(CPU) { \ + PM_CLK_CTRL_REG &= ~((0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \ + PM_CLK_CTRL_REG |= (((CPU)&0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \ +} + +/* PM_PLL_LCD_I2S_CTRL_REG */ +#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_MCLK_SMC_DIV (22) +#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_R_SEL (17) +#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_P (11) +#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_M (3) +#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_S (0) + +/* PM_PLL_HM_PD_CTRL_REG */ +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1 (11) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0 (10) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2SCD (6) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2S (5) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_LCD (4) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB (3) +#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_RGMII (2) +#define PM_PLL_HM_PD_CTRL_REG_MASK (0x00000C7C) + +/* PM_WDT_CTRL_REG */ +#define PM_WDT_CTRL_REG_OFFSET_RESET_CPU_ONLY (0) + +/* PM_CSR_REG - Clock Scaling Register*/ +#define PM_CSR_REG_OFFSET_CSR_EN (30) +#define PM_CSR_REG_OFFSET_CSR_NUM (0) + +#define CNS3XXX_PWR_CLK_EN(BLOCK) (0x1< diff --git a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S new file mode 100644 index 000000000000..5e1c5545680f --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S @@ -0,0 +1,82 @@ +/* + * Low-level IRQ helper macros for Cavium Networks platforms + * + * Copyright 2008 Cavium Networks + * + * This file 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 +#include + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =gic_cpu_base_addr + ldr \base, [\base] + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + /* + * The interrupt numbering scheme is defined in the + * interrupt controller spec. To wit: + * + * Interrupts 0-15 are IPI + * 16-28 are reserved + * 29-31 are local. We allow 30 to be used for the watchdog. + * 32-1020 are global + * 1021-1022 are reserved + * 1023 is "spurious" (no interrupt) + * + * For now, we ignore all local interrupts so only return an interrupt if it's + * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. + * + * A simple read from the controller will tell us the number of the highest + * priority enabled interrupt. We then just need to check whether it is in the + * valid range for an IRQ (30-1020 inclusive). + */ + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */ + + ldr \tmp, =1021 + + bic \irqnr, \irqstat, #0x1c00 + + cmp \irqnr, #29 + cmpcc \irqnr, \irqnr + cmpne \irqnr, \tmp + cmpcs \irqnr, \irqnr + + .endm + + /* We assume that irqstat (the raw value of the IRQ acknowledge + * register) is preserved from the macro above. + * If there is an IPI, we immediately signal end of interrupt on the + * controller, since this requires the original irqstat value which + * we won't easily be able to recreate later. + */ + + .macro test_for_ipi, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #16 + strcc \irqstat, [\base, #GIC_CPU_EOI] + cmpcs \irqnr, \irqnr + .endm + + /* As above, this assumes that irqstat and base are preserved.. */ + + .macro test_for_ltirq, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + mov \tmp, #0 + cmp \irqnr, #29 + moveq \tmp, #1 + streq \irqstat, [\base, #GIC_CPU_EOI] + cmp \tmp, #0 + .endm diff --git a/arch/arm/mach-cns3xxx/include/mach/hardware.h b/arch/arm/mach-cns3xxx/include/mach/hardware.h new file mode 100644 index 000000000000..57e09836f9d7 --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/hardware.h @@ -0,0 +1,22 @@ +/* + * This file contains the hardware definitions of the Cavium Networks boards. + * + * Copyright 2003 ARM Limited. + * Copyright 2008 Cavium Networks + * + * This file 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. + */ + +#ifndef __MACH_HARDWARE_H +#define __MACH_HARDWARE_H + +#include + +/* macro to get at IO space when running virtually */ +#define PCIBIOS_MIN_IO 0x00000000 +#define PCIBIOS_MIN_MEM 0x00000000 +#define pcibios_assign_all_busses() 1 + +#endif diff --git a/arch/arm/mach-cns3xxx/include/mach/io.h b/arch/arm/mach-cns3xxx/include/mach/io.h new file mode 100644 index 000000000000..33b6fc1ece7c --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/io.h @@ -0,0 +1,17 @@ +/* + * Copyright 2008 Cavium Networks + * Copyright 2003 ARM Limited + * + * This file 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. + */ +#ifndef __MACH_IO_H +#define __MACH_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#endif diff --git a/arch/arm/mach-cns3xxx/include/mach/irqs.h b/arch/arm/mach-cns3xxx/include/mach/irqs.h new file mode 100644 index 000000000000..2ab96f8085c8 --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/irqs.h @@ -0,0 +1,24 @@ +/* + * Copyright 2000 Deep Blue Solutions Ltd. + * Copyright 2003 ARM Limited + * Copyright 2008 Cavium Networks + * + * This file 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. + */ + +#ifndef __MACH_IRQS_H +#define __MACH_IRQS_H + +#define IRQ_LOCALTIMER 29 +#define IRQ_LOCALWDOG 30 +#define IRQ_TC11MP_GIC_START 32 + +#include + +#ifndef NR_IRQS +#error "NR_IRQS not defined by the board-specific files" +#endif + +#endif diff --git a/arch/arm/mach-cns3xxx/include/mach/memory.h b/arch/arm/mach-cns3xxx/include/mach/memory.h new file mode 100644 index 000000000000..3b6b769b7a27 --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/memory.h @@ -0,0 +1,26 @@ +/* + * Copyright 2003 ARM Limited + * Copyright 2008 Cavium Networks + * + * This file 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. + */ + +#ifndef __MACH_MEMORY_H +#define __MACH_MEMORY_H + +/* + * Physical DRAM offset. + */ +#define PHYS_OFFSET UL(0x00000000) + +#define __phys_to_bus(x) ((x) + PHYS_OFFSET) +#define __bus_to_phys(x) ((x) - PHYS_OFFSET) + +#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v)) +#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b)) +#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p)) +#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b)) + +#endif diff --git a/arch/arm/mach-cns3xxx/include/mach/system.h b/arch/arm/mach-cns3xxx/include/mach/system.h new file mode 100644 index 000000000000..58bb03ae3cf4 --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/system.h @@ -0,0 +1,29 @@ +/* + * Copyright 2000 Deep Blue Solutions Ltd + * Copyright 2003 ARM Limited + * Copyright 2008 Cavium Networks + * + * This file 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. + */ + +#ifndef __MACH_SYSTEM_H +#define __MACH_SYSTEM_H + +#include +#include +#include + +static inline void arch_idle(void) +{ + /* + * This should do all the clock switching + * and wait for interrupt tricks + */ + cpu_do_idle(); +} + +void arch_reset(char mode, const char *cmd); + +#endif diff --git a/arch/arm/mach-cns3xxx/include/mach/timex.h b/arch/arm/mach-cns3xxx/include/mach/timex.h new file mode 100644 index 000000000000..1fd04217cacb --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/timex.h @@ -0,0 +1,12 @@ +/* + * Cavium Networks architecture timex specifications + * + * Copyright 2003 ARM Limited + * Copyright 2008 Cavium Networks + * + * This file 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. + */ + +#define CLOCK_TICK_RATE (50000000 / 16) diff --git a/arch/arm/mach-cns3xxx/include/mach/uncompress.h b/arch/arm/mach-cns3xxx/include/mach/uncompress.h new file mode 100644 index 000000000000..de8ead9b91f7 --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/uncompress.h @@ -0,0 +1,55 @@ +/* + * Copyright 2003 ARM Limited + * Copyright 2008 Cavium Networks + * + * This file 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 +#include +#include + +#define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00)) +#define AMBA_UART_LCRH(base) (*(volatile unsigned char *)((base) + 0x2c)) +#define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30)) +#define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18)) + +/* + * Return the UART base address + */ +static inline unsigned long get_uart_base(void) +{ + if (machine_is_cns3420vb()) + return CNS3XXX_UART0_BASE; + else + return 0; +} + +/* + * This does not append a newline + */ +static inline void putc(int c) +{ + unsigned long base = get_uart_base(); + + while (AMBA_UART_FR(base) & (1 << 5)) + barrier(); + + AMBA_UART_DR(base) = c; +} + +static inline void flush(void) +{ + unsigned long base = get_uart_base(); + + while (AMBA_UART_FR(base) & (1 << 3)) + barrier(); +} + +/* + * nothing to do + */ +#define arch_decomp_setup() +#define arch_decomp_wdog() diff --git a/arch/arm/mach-cns3xxx/include/mach/vmalloc.h b/arch/arm/mach-cns3xxx/include/mach/vmalloc.h new file mode 100644 index 000000000000..4d381ec05278 --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/vmalloc.h @@ -0,0 +1,11 @@ +/* + * Copyright 2000 Russell King. + * Copyright 2003 ARM Limited + * Copyright 2008 Cavium Networks + * + * This file 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. + */ + +#define VMALLOC_END 0xd8000000 diff --git a/arch/arm/mach-cns3xxx/pm.c b/arch/arm/mach-cns3xxx/pm.c new file mode 100644 index 000000000000..725e1a4fc231 --- /dev/null +++ b/arch/arm/mach-cns3xxx/pm.c @@ -0,0 +1,86 @@ +/* + * Copyright 2008 Cavium Networks + * + * This file 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 +#include +#include + +void cns3xxx_pwr_clk_en(unsigned int block) +{ + PM_CLK_GATE_REG |= (block & PM_CLK_GATE_REG_MASK); +} + +void cns3xxx_pwr_power_up(unsigned int block) +{ + PM_PLL_HM_PD_CTRL_REG &= ~(block & CNS3XXX_PWR_PLL_ALL); + + /* Wait for 300us for the PLL output clock locked. */ + udelay(300); +}; + +void cns3xxx_pwr_power_down(unsigned int block) +{ + /* write '1' to power down */ + PM_PLL_HM_PD_CTRL_REG |= (block & CNS3XXX_PWR_PLL_ALL); +}; + +static void cns3xxx_pwr_soft_rst_force(unsigned int block) +{ + /* + * bit 0, 28, 29 => program low to reset, + * the other else program low and then high + */ + if (block & 0x30000001) { + PM_SOFT_RST_REG &= ~(block & PM_SOFT_RST_REG_MASK); + } else { + PM_SOFT_RST_REG &= ~(block & PM_SOFT_RST_REG_MASK); + PM_SOFT_RST_REG |= (block & PM_SOFT_RST_REG_MASK); + } +} + +void cns3xxx_pwr_soft_rst(unsigned int block) +{ + static unsigned int soft_reset; + + if (soft_reset & block) { + /* SPI/I2C/GPIO use the same block, reset once. */ + return; + } else { + soft_reset |= block; + } + cns3xxx_pwr_soft_rst_force(block); +} + +void arch_reset(char mode, const char *cmd) +{ + /* + * To reset, we hit the on-board reset register + * in the system FPGA. + */ + cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(GLOBAL)); +} + +/* + * cns3xxx_cpu_clock - return CPU/L2 clock + * aclk: cpu clock/2 + * hclk: cpu clock/4 + * pclk: cpu clock/8 + */ +int cns3xxx_cpu_clock(void) +{ + int cpu; + int cpu_sel; + int div_sel; + + cpu_sel = (PM_CLK_CTRL_REG >> PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL) & 0xf; + div_sel = (PM_CLK_CTRL_REG >> PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV) & 0x3; + + cpu = (300 + ((cpu_sel / 3) * 100) + ((cpu_sel % 3) * 33)) >> div_sel; + + return cpu; +} -- cgit v1.2.3-59-g8ed1b From e94cdef039d4b141dffdbf5adde705f8c14dc53f Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 26 Mar 2010 21:19:02 +0300 Subject: ARM: cns3xxx: Add CNS3420 Validation Board support This patch adds support for CNS3420VB rev 1.3 boards. With this patch CNS3420VB boards are able to boot up to the userspace, with a console available on UART0. Signed-off-by: Anton Vorontsov --- arch/arm/mach-cns3xxx/Kconfig | 8 +++ arch/arm/mach-cns3xxx/Makefile | 1 + arch/arm/mach-cns3xxx/cns3420vb.c | 148 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 arch/arm/mach-cns3xxx/cns3420vb.c (limited to 'arch') diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig index 20284cdcb18b..9ebfcc46feb1 100644 --- a/arch/arm/mach-cns3xxx/Kconfig +++ b/arch/arm/mach-cns3xxx/Kconfig @@ -1,4 +1,12 @@ menu "CNS3XXX platform type" depends on ARCH_CNS3XXX +config MACH_CNS3420VB + bool "Support for CNS3420 Validation Board" + help + Include support for the Cavium Networks CNS3420 MPCore Platform + Baseboard. + This is a platform with an on-board ARM11 MPCore and has support + for USB, USB-OTG, MMC/SD/SDIO, SATA, PCI-E, etc. + endmenu diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile index e5e76dd2111a..427507a2d696 100644 --- a/arch/arm/mach-cns3xxx/Makefile +++ b/arch/arm/mach-cns3xxx/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_ARCH_CNS3XXX) += core.o pm.o +obj-$(CONFIG_MACH_CNS3420VB) += cns3420vb.o diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c new file mode 100644 index 000000000000..2e30c8288740 --- /dev/null +++ b/arch/arm/mach-cns3xxx/cns3420vb.c @@ -0,0 +1,148 @@ +/* + * Cavium Networks CNS3420 Validation Board + * + * Copyright 2000 Deep Blue Solutions Ltd + * Copyright 2008 ARM Limited + * Copyright 2008 Cavium Networks + * Scott Shu + * Copyright 2010 MontaVista Software, LLC. + * Anton Vorontsov + * + * This file 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core.h" + +/* + * NOR Flash + */ +static struct mtd_partition cns3420_nor_partitions[] = { + { + .name = "uboot", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", + .size = 0x004C0000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "filesystem", + .size = 0x7000000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "filesystem2", + .size = 0x0AE0000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "ubootenv", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + }, +}; + +static struct physmap_flash_data cns3420_nor_pdata = { + .width = 2, + .parts = cns3420_nor_partitions, + .nr_parts = ARRAY_SIZE(cns3420_nor_partitions), +}; + +static struct resource cns3420_nor_res = { + .start = CNS3XXX_FLASH_BASE, + .end = CNS3XXX_FLASH_BASE + SZ_128M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, +}; + +static struct platform_device cns3420_nor_pdev = { + .name = "physmap-flash", + .id = 0, + .resource = &cns3420_nor_res, + .num_resources = 1, + .dev = { + .platform_data = &cns3420_nor_pdata, + }, +}; + +/* + * UART + */ +static void __init cns3420_early_serial_setup(void) +{ +#ifdef CONFIG_SERIAL_8250_CONSOLE + static struct uart_port cns3420_serial_port = { + .membase = (void __iomem *)CNS3XXX_UART0_BASE_VIRT, + .mapbase = CNS3XXX_UART0_BASE, + .irq = IRQ_CNS3XXX_UART0, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE, + .regshift = 2, + .uartclk = 24000000, + .line = 0, + .type = PORT_16550A, + .fifosize = 16, + }; + + early_serial_setup(&cns3420_serial_port); +#endif +} + +/* + * Initialization + */ +static struct platform_device *cns3420_pdevs[] __initdata = { + &cns3420_nor_pdev, +}; + +static void __init cns3420_init(void) +{ + platform_add_devices(cns3420_pdevs, ARRAY_SIZE(cns3420_pdevs)); + + pm_power_off = cns3xxx_power_off; +} + +static struct map_desc cns3420_io_desc[] __initdata = { + { + .virtual = CNS3XXX_UART0_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_UART0_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static void __init cns3420_map_io(void) +{ + cns3xxx_map_io(); + iotable_init(cns3420_io_desc, ARRAY_SIZE(cns3420_io_desc)); + + cns3420_early_serial_setup(); +} + +MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board") + .phys_io = CNS3XXX_UART0_BASE, + .io_pg_offst = (CNS3XXX_UART0_BASE_VIRT >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = cns3420_map_io, + .init_irq = cns3xxx_init_irq, + .timer = &cns3xxx_timer, + .init_machine = cns3420_init, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 478ea14466fb524b4cd90cdf0b8845f8c5ee6015 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 25 Mar 2010 20:51:49 +0300 Subject: ARM: cns3xxx: Add defconfig for CNS3420 validation board Signed-off-by: Anton Vorontsov --- arch/arm/configs/cns3420vb_defconfig | 831 +++++++++++++++++++++++++++++++++++ 1 file changed, 831 insertions(+) create mode 100644 arch/arm/configs/cns3420vb_defconfig (limited to 'arch') diff --git a/arch/arm/configs/cns3420vb_defconfig b/arch/arm/configs/cns3420vb_defconfig new file mode 100644 index 000000000000..d5c088149e46 --- /dev/null +++ b/arch/arm/configs/cns3420vb_defconfig @@ -0,0 +1,831 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.34-rc6 +# Sun May 2 21:58:08 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_OPROFILE_ARMV6=y +CONFIG_OPROFILE_ARM11_CORE=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_NS is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CPUSETS is not set +# CONFIG_CGROUP_CPUACCT is not set +# CONFIG_RESOURCE_COUNTERS is not set +# CONFIG_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +CONFIG_RELAY=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_LZO=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_SLOW_WORK_DEBUG is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=m +# CONFIG_CFQ_GROUP_IOSCHED is not set +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +CONFIG_ARCH_CNS3XXX=y +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set + +# +# CNS3XXX platform type +# +CONFIG_MACH_CNS3420VB=y + +# +# Processor Type +# +CONFIG_CPU_V6=y +# CONFIG_CPU_32v6K is not set +CONFIG_CPU_32v6=y +CONFIG_CPU_ABRT_EV6=y +CONFIG_CPU_PABRT_V6=y +CONFIG_CPU_CACHE_V6=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V6=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_CPU_HAS_PMU=y +# CONFIG_ARM_ERRATA_411920 is not set +CONFIG_ARM_GIC=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,38400 mem=128M root=/dev/mmcblk0p1 ro rootwait" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=20000 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y +# CONFIG_SATA_PMP is not set +# CONFIG_ATA_SFF is not set +# CONFIG_MD is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set + +# +# Caches +# +CONFIG_FSCACHE=y +# CONFIG_FSCACHE_STATS is not set +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +# CONFIG_CACHEFILES is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_FRAME_POINTER=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_ARM_UNWIND is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +# CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_GENERIC_ATOMIC64=y -- cgit v1.2.3-59-g8ed1b From aec9562f3db8ece218125042e0b2b7ac5b7091e7 Mon Sep 17 00:00:00 2001 From: Anders Larsen Date: Tue, 13 Apr 2010 12:05:32 +0100 Subject: ARM: 6053/1: AT91: Save power by disabling the processor clock when CPU is idle Disable the processor clock when the CPU is idle. This saves much more power than merely entering 'Wait for Interrupt' mode. Since JTAG-debugging doesn't work when the processor clock is switched off, make it conditional on CONFIG_DEBUG_KERNEL. Signed-off-by: Anders Larsen Acked-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/include/mach/system.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h index 5268af3933c2..c80e090b3670 100644 --- a/arch/arm/mach-at91/include/mach/system.h +++ b/arch/arm/mach-at91/include/mach/system.h @@ -24,21 +24,24 @@ #include #include #include +#include static inline void arch_idle(void) { +#ifndef CONFIG_DEBUG_KERNEL /* * Disable the processor clock. The processor will be automatically * re-enabled by an interrupt or by a reset. */ -// at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK); - + at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK); +#else /* * Set the processor (CP15) into 'Wait for Interrupt' mode. * Unlike disabling the processor clock via the PMC (above) * this allows the processor to be woken via JTAG. */ cpu_do_idle(); +#endif } void (*at91_arch_reset)(void); -- cgit v1.2.3-59-g8ed1b From ee5500c45c4860a84bba502c6d9ef5af6395dad6 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Mon, 3 May 2010 11:10:03 +0800 Subject: crypto: omap - Updates omap sham device related platform code - registration with multi OMAP kernels support - clocks Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- arch/arm/mach-omap2/clock2420_data.c | 2 +- arch/arm/mach-omap2/clock2430_data.c | 2 +- arch/arm/mach-omap2/clock3xxx_data.c | 2 +- arch/arm/mach-omap2/devices.c | 58 ++++++++++++++++++++++++------ arch/arm/plat-omap/include/plat/omap34xx.h | 5 +++ 5 files changed, 56 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index f12af95ead45..fc55ab4c32e3 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -1836,7 +1836,7 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "vlynq_ick", &vlynq_ick, CK_242X), CLK(NULL, "vlynq_fck", &vlynq_fck, CK_242X), CLK(NULL, "des_ick", &des_ick, CK_242X), - CLK(NULL, "sha_ick", &sha_ick, CK_242X), + CLK("omap-sham", "ick", &sha_ick, CK_242X), CLK("omap_rng", "ick", &rng_ick, CK_242X), CLK(NULL, "aes_ick", &aes_ick, CK_242X), CLK(NULL, "pka_ick", &pka_ick, CK_242X), diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index 0438b6e4f51a..5884ac681c4a 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -1924,7 +1924,7 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "sdma_ick", &sdma_ick, CK_243X), CLK(NULL, "sdrc_ick", &sdrc_ick, CK_243X), CLK(NULL, "des_ick", &des_ick, CK_243X), - CLK(NULL, "sha_ick", &sha_ick, CK_243X), + CLK("omap-sham", "ick", &sha_ick, CK_243X), CLK("omap_rng", "ick", &rng_ick, CK_243X), CLK(NULL, "aes_ick", &aes_ick, CK_243X), CLK(NULL, "pka_ick", &pka_ick, CK_243X), diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index d5153b6bd6cb..5a974dcbcecc 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3360,7 +3360,7 @@ static struct omap_clk omap3xxx_clks[] = { CLK("mmci-omap-hs.2", "ick", &mmchs3_ick, CK_3430ES2 | CK_AM35XX), CLK(NULL, "icr_ick", &icr_ick, CK_343X), CLK(NULL, "aes2_ick", &aes2_ick, CK_343X), - CLK(NULL, "sha12_ick", &sha12_ick, CK_343X), + CLK("omap-sham", "ick", &sha12_ick, CK_343X), CLK(NULL, "des2_ick", &des2_ick, CK_343X), CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_3XXX), CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_3XXX), diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 23e4d7733610..7e7acc19bed0 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "mux.h" @@ -453,8 +454,10 @@ static void omap_init_mcspi(void) static inline void omap_init_mcspi(void) {} #endif -#ifdef CONFIG_OMAP_SHA1_MD5 -static struct resource sha1_md5_resources[] = { +#if defined(CONFIG_CRYPTO_DEV_OMAP_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP_SHAM_MODULE) + +#ifdef CONFIG_ARCH_OMAP24XX +static struct resource omap2_sham_resources[] = { { .start = OMAP24XX_SEC_SHA1MD5_BASE, .end = OMAP24XX_SEC_SHA1MD5_BASE + 0x64, @@ -465,20 +468,55 @@ static struct resource sha1_md5_resources[] = { .flags = IORESOURCE_IRQ, } }; +static int omap2_sham_resources_sz = ARRAY_SIZE(omap2_sham_resources); +#else +#define omap2_sham_resources NULL +#define omap2_sham_resources_sz 0 +#endif -static struct platform_device sha1_md5_device = { - .name = "OMAP SHA1/MD5", +#ifdef CONFIG_ARCH_OMAP34XX +static struct resource omap3_sham_resources[] = { + { + .start = OMAP34XX_SEC_SHA1MD5_BASE, + .end = OMAP34XX_SEC_SHA1MD5_BASE + 0x64, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_34XX_SHA1MD52_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .start = OMAP34XX_DMA_SHA1MD5_RX, + .flags = IORESOURCE_DMA, + } +}; +static int omap3_sham_resources_sz = ARRAY_SIZE(omap3_sham_resources); +#else +#define omap3_sham_resources NULL +#define omap3_sham_resources_sz 0 +#endif + +static struct platform_device sham_device = { + .name = "omap-sham", .id = -1, - .num_resources = ARRAY_SIZE(sha1_md5_resources), - .resource = sha1_md5_resources, }; -static void omap_init_sha1_md5(void) +static void omap_init_sham(void) { - platform_device_register(&sha1_md5_device); + if (cpu_is_omap24xx()) { + sham_device.resource = omap2_sham_resources; + sham_device.num_resources = omap2_sham_resources_sz; + } else if (cpu_is_omap34xx()) { + sham_device.resource = omap3_sham_resources; + sham_device.num_resources = omap3_sham_resources_sz; + } else { + pr_err("%s: platform not supported\n", __func__); + return; + } + platform_device_register(&sham_device); } #else -static inline void omap_init_sha1_md5(void) { } +static inline void omap_init_sham(void) { } #endif /*-------------------------------------------------------------------------*/ @@ -799,7 +837,7 @@ static int __init omap2_init_devices(void) omap_init_mcspi(); omap_hdq_init(); omap_init_sti(); - omap_init_sha1_md5(); + omap_init_sham(); return 0; } diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h index 2845fdc658b0..98fc8b4a4cc4 100644 --- a/arch/arm/plat-omap/include/plat/omap34xx.h +++ b/arch/arm/plat-omap/include/plat/omap34xx.h @@ -82,5 +82,10 @@ #define OMAP34XX_MAILBOX_BASE (L4_34XX_BASE + 0x94000) +/* Security */ +#define OMAP34XX_SEC_BASE (L4_34XX_BASE + 0xA0000) +#define OMAP34XX_SEC_SHA1MD5_BASE (OMAP34XX_SEC_BASE + 0x23000) +#define OMAP34XX_SEC_AES_BASE (OMAP34XX_SEC_BASE + 0x25000) + #endif /* __ASM_ARCH_OMAP3_H */ -- cgit v1.2.3-59-g8ed1b From 4b53eb4f5d78416456bb969ce30e3bed2731d744 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Fri, 1 Jan 2010 15:11:43 -0800 Subject: arm: msm: allow ARCH_MSM to have v7 cpus ARCH_MSM supports armv7 cpus, so we're pushed the CPU_V6/CPU_V7 selection down into the arch/arm/mach-msm/Kconfig. Also update the description to be a bit more accurate. Signed-off-by: Daniel Walker --- arch/arm/Kconfig | 10 +++++----- arch/arm/mach-msm/Kconfig | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 92622eb5cc0d..9264d0176c3b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -601,14 +601,14 @@ config ARCH_PXA config ARCH_MSM bool "Qualcomm MSM" - select CPU_V6 select GENERIC_TIME select GENERIC_CLOCKEVENTS help - Support for Qualcomm MSM7K based systems. This runs on the ARM11 - apps processor of the MSM7K and depends on a shared memory - interface to the ARM9 modem processor which runs the baseband stack - and controls some vital subsystems (clock and power control, etc). + Support for Qualcomm MSM/QSD based systems. This runs on the + apps processor of the MSM/QSD and depends on a shared memory + interface to the modem processor which runs the baseband + stack and controls some vital subsystems + (clock and power control, etc). config ARCH_SHMOBILE bool "Renesas SH-Mobile" diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index f780086befd7..b9fd5c528e5b 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -29,12 +29,14 @@ endchoice config MACH_HALIBUT depends on ARCH_MSM + select CPU_V6 default y bool "Halibut Board (QCT SURF7201A)" help Support for the Qualcomm SURF7201A eval board. config MACH_TROUT + select CPU_V6 default y bool "HTC Dream (aka trout)" help -- cgit v1.2.3-59-g8ed1b From 4b536b8d909f4e3dfa84fa7a63fbc5896e3490e8 Mon Sep 17 00:00:00 2001 From: Steve Muckle Date: Mon, 29 Dec 2008 16:17:22 -0500 Subject: arm: msm: define HAVE_CLK for ARCH_MSM MSM supports the interface. Acked-by: David Brown Signed-off-by: Steve Muckle --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9264d0176c3b..355bc5e6e6ea 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -601,6 +601,7 @@ config ARCH_PXA config ARCH_MSM bool "Qualcomm MSM" + select HAVE_CLK select GENERIC_TIME select GENERIC_CLOCKEVENTS help -- cgit v1.2.3-59-g8ed1b From ee3c454b8da04815c1884ed85fe89d2d131c0e51 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Fri, 1 Jan 2010 14:52:30 -0800 Subject: arm: msm: add oprofile pmu support add oprofile pmu support for msm. Signed-off-by: Daniel Walker --- arch/arm/kernel/pmu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c index a124312e343f..4f0eb4c2a72c 100644 --- a/arch/arm/kernel/pmu.c +++ b/arch/arm/kernel/pmu.c @@ -44,6 +44,8 @@ static const int irqs[] = { IRQ_IOP33X_CORE_PMU, #elif defined(CONFIG_ARCH_PXA) IRQ_PMU, +#elif defined(CONFIG_ARCH_MSM_ARM11) + INT_ARM11_PMU, #endif }; -- cgit v1.2.3-59-g8ed1b From e220ba60223a9d63e70217e5b112160df8c21cea Mon Sep 17 00:00:00 2001 From: Dave Estes Date: Tue, 11 Aug 2009 17:58:49 -0400 Subject: arm: mm: qsd8x50: Fix incorrect permission faults Handle incorrectly reported permission faults for qsd8650. On permission faults, retry MVA to PA conversion. If retry detects translation fault. Report as translation fault. Cc: Jamie Lokier Signed-off-by: Dave Estes --- arch/arm/mm/Kconfig | 2 ++ arch/arm/mm/abort-ev7.S | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'arch') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 5bd7c89a6045..d3022dabb4aa 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -572,6 +572,8 @@ config CPU_TLB_V6 config CPU_TLB_V7 bool +config VERIFY_PERMISSION_FAULT + bool endif config CPU_HAS_ASID diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S index 2e6dc040c654..ec88b157d3bb 100644 --- a/arch/arm/mm/abort-ev7.S +++ b/arch/arm/mm/abort-ev7.S @@ -29,5 +29,26 @@ ENTRY(v7_early_abort) * V6 code adjusts the returned DFSR. * New designs should not need to patch up faults. */ + +#if defined(CONFIG_VERIFY_PERMISSION_FAULT) + /* + * Detect erroneous permission failures and fix + */ + ldr r3, =0x40d @ On permission fault + and r3, r1, r3 + cmp r3, #0x0d + movne pc, lr + + mcr p15, 0, r0, c7, c8, 0 @ Retranslate FAR + isb + mrc p15, 0, r2, c7, c4, 0 @ Read the PAR + and r3, r2, #0x7b @ On translation fault + cmp r3, #0x0b + movne pc, lr + bic r1, r1, #0xf @ Fix up FSR FS[5:0] + and r2, r2, #0x7e + orr r1, r1, r2, LSR #1 +#endif + mov pc, lr ENDPROC(v7_early_abort) -- cgit v1.2.3-59-g8ed1b From d8f089d2ad35861c432618900fa08ca70c168d76 Mon Sep 17 00:00:00 2001 From: Siddarth Gore Date: Mon, 22 Mar 2010 02:28:20 -0700 Subject: [ARM] Kirkwood: Marvell GuruPlug support GuruPlug Standard: 1 Gb Ethernet, 2 USB 2.0 GuruPlug Plus: 2 Gb Ethernet, 2 USB 2.0, 1 eSATA, 1 uSD slot References: http://www.globalscaletechnologies.com/t-guruplugdetails.aspx http://plugcomputer.org This patch is for GuruPlug Plus, but it supports Standard version as well. Signed-off-by: Siddarth Gore Signed-off-by: Nicolas Pitre --- arch/arm/mach-kirkwood/Kconfig | 6 ++ arch/arm/mach-kirkwood/Makefile | 1 + arch/arm/mach-kirkwood/guruplug-setup.c | 131 ++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 arch/arm/mach-kirkwood/guruplug-setup.c (limited to 'arch') diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 17879a876be6..05a85526d6d5 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -38,6 +38,12 @@ config MACH_ESATA_SHEEVAPLUG Say 'Y' here if you want your kernel to support the Marvell eSATA SheevaPlug Reference Board. +config MACH_GURUPLUG + bool "Marvell GuruPlug Reference Board" + help + Say 'Y' here if you want your kernel to support the + Marvell GuruPlug Reference Board. + config MACH_TS219 bool "QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS" help diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index a5530e36ba3e..85b3a39a6204 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o +obj-$(CONFIG_MACH_GURUPLUG) += guruplug-setup.o obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o diff --git a/arch/arm/mach-kirkwood/guruplug-setup.c b/arch/arm/mach-kirkwood/guruplug-setup.c new file mode 100644 index 000000000000..54d07c89d4ff --- /dev/null +++ b/arch/arm/mach-kirkwood/guruplug-setup.c @@ -0,0 +1,131 @@ +/* + * arch/arm/mach-kirkwood/guruplug-setup.c + * + * Marvell GuruPlug Reference Board Setup + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mtd_partition guruplug_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_4M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data guruplug_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +static struct mv643xx_eth_platform_data guruplug_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(1), +}; + +static struct mv_sata_platform_data guruplug_sata_data = { + .n_ports = 1, +}; + +static struct mvsdio_platform_data guruplug_mvsdio_data = { + /* unfortunately the CD signal has not been connected */ +}; + +static struct gpio_led guruplug_led_pins[] = { + { + .name = "guruplug:red:health", + .gpio = 46, + .active_low = 1, + }, + { + .name = "guruplug:green:health", + .gpio = 47, + .active_low = 1, + }, + { + .name = "guruplug:red:wmode", + .gpio = 48, + .active_low = 1, + }, + { + .name = "guruplug:green:wmode", + .gpio = 49, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data guruplug_led_data = { + .leds = guruplug_led_pins, + .num_leds = ARRAY_SIZE(guruplug_led_pins), +}; + +static struct platform_device guruplug_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &guruplug_led_data, + } +}; + +static unsigned int guruplug_mpp_config[] __initdata = { + MPP46_GPIO, /* M_RLED */ + MPP47_GPIO, /* M_GLED */ + MPP48_GPIO, /* B_RLED */ + MPP49_GPIO, /* B_GLED */ + 0 +}; + +static void __init guruplug_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(guruplug_mpp_config); + + kirkwood_uart0_init(); + kirkwood_nand_init(ARRAY_AND_SIZE(guruplug_nand_parts), 25); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&guruplug_ge00_data); + kirkwood_ge01_init(&guruplug_ge01_data); + kirkwood_sata_init(&guruplug_sata_data); + kirkwood_sdio_init(&guruplug_mvsdio_data); + + platform_device_register(&guruplug_leds); +} + +MACHINE_START(GURUPLUG, "Marvell GuruPlug Reference Board") + /* Maintainer: Siddarth Gore */ + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = guruplug_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &kirkwood_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 5ccc8dab611fcd1d0961b73e22d6c2d108967862 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Sat, 3 Apr 2010 10:31:33 +0200 Subject: [ARM] dns323-setup.c: fix WARN() when booting Since commit b2a731aa5cbca7e0252da75e16de7ae5feb1313a, dns323_init() is setting the power led gpio direction with gpio_direction_output() but doesn't request the gpio before (which is not permitted by the gpio layer afaik). This behaviour is triggering a WARN() at boot time. Tested-by: Christian Samsel Cc: Martin Michlmayr Signed-off-by: Arnaud Patard Signed-off-by: Nicolas Pitre [ Part 2: "Attached Text" ] --- arch/arm/mach-orion5x/dns323-setup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index 421b82f7c63d..685f34a9634b 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c @@ -439,6 +439,7 @@ static void __init dns323_init(void) */ if (dns323_dev_id() == MV88F5181_DEV_ID) { dns323_leds[0].active_low = 1; + gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable"); gpio_direction_output(DNS323_GPIO_LED_POWER1, 0); } -- cgit v1.2.3-59-g8ed1b From 40d2e76315da38993129090dc5d56377e573c312 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Sun, 21 Mar 2010 09:00:43 -0400 Subject: x86-32: Rework cache flush denied handler The cache flush denied error is an erratum on some AMD 486 clones. If an invd instruction is executed in userspace, the processor calls exception 19 (13 hex) instead of #GP (13 decimal). On cpus where XMM is not supported, redirect exception 19 to do_general_protection(). Also, remove die_if_kernel(), since this was the last user. Signed-off-by: Brian Gerst LKML-Reference: <1269176446-2489-2-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin --- arch/x86/Kconfig.cpu | 4 ++++ arch/x86/kernel/entry_32.S | 19 +++++++++++++++++++ arch/x86/kernel/traps.c | 31 +++---------------------------- 3 files changed, 26 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index a19829374e6a..6f6792c56015 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -338,6 +338,10 @@ config X86_F00F_BUG def_bool y depends on M586MMX || M586TSC || M586 || M486 || M386 +config X86_INVD_BUG + def_bool y + depends on M486 || M386 + config X86_WP_WORKS_OK def_bool y depends on !M386 diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 44a8e0dc6737..cd49141cf153 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -53,6 +53,7 @@ #include #include #include +#include /* Avoid __ASSEMBLER__'ifying just for this. */ #include @@ -905,7 +906,25 @@ ENTRY(simd_coprocessor_error) RING0_INT_FRAME pushl $0 CFI_ADJUST_CFA_OFFSET 4 +#ifdef CONFIG_X86_INVD_BUG + /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */ +661: pushl $do_general_protection +662: +.section .altinstructions,"a" + .balign 4 + .long 661b + .long 663f + .byte X86_FEATURE_XMM + .byte 662b-661b + .byte 664f-663f +.previous +.section .altinstr_replacement,"ax" +663: pushl $do_simd_coprocessor_error +664: +.previous +#else pushl $do_simd_coprocessor_error +#endif CFI_ADJUST_CFA_OFFSET 4 jmp error_code CFI_ENDPROC diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 1168e4454188..a16c9dfe6b70 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -108,15 +108,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) dec_preempt_count(); } -#ifdef CONFIG_X86_32 -static inline void -die_if_kernel(const char *str, struct pt_regs *regs, long err) -{ - if (!user_mode_vm(regs)) - die(str, regs, err); -} -#endif - static void __kprobes do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, long error_code, siginfo_t *info) @@ -729,30 +720,14 @@ do_simd_coprocessor_error(struct pt_regs *regs, long error_code) conditional_sti(regs); #ifdef CONFIG_X86_32 - if (cpu_has_xmm) { - /* Handle SIMD FPU exceptions on PIII+ processors. */ - ignore_fpu_irq = 1; - simd_math_error((void __user *)regs->ip); - return; - } - /* - * Handle strange cache flush from user space exception - * in all other cases. This is undocumented behaviour. - */ - if (regs->flags & X86_VM_MASK) { - handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code); - return; - } - current->thread.trap_no = 19; - current->thread.error_code = error_code; - die_if_kernel("cache flush denied", regs, error_code); - force_sig(SIGSEGV, current); + ignore_fpu_irq = 1; #else if (!user_mode(regs) && kernel_math_error(regs, "kernel simd math error", 19)) return; - simd_math_error((void __user *)regs->ip); #endif + + simd_math_error((void __user *)regs->ip); } dotraplinkage void -- cgit v1.2.3-59-g8ed1b From 9b6dba9e0798325dab427b9d60c61630ccc39b28 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Sun, 21 Mar 2010 09:00:44 -0400 Subject: x86: Merge simd_math_error() into math_error() The only difference between FPU and SIMD exceptions is where the status bits are read from (cwd/swd vs. mxcsr). This also fixes the discrepency introduced by commit adf77bac, which fixed FPU but not SIMD. Signed-off-by: Brian Gerst LKML-Reference: <1269176446-2489-3-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/traps.h | 2 +- arch/x86/kernel/irqinit.c | 2 +- arch/x86/kernel/traps.c | 100 ++++++++++++++----------------------------- 3 files changed, 34 insertions(+), 70 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 4da91ad69e0d..f66cda56781d 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h @@ -79,7 +79,7 @@ static inline int get_si_code(unsigned long condition) extern int panic_on_unrecovered_nmi; -void math_error(void __user *); +void math_error(struct pt_regs *, int, int); void math_emulate(struct math_emu_info *); #ifndef CONFIG_X86_32 asmlinkage void smp_thermal_interrupt(void); diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index 0ed2d300cd46..990ae7cfc578 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c @@ -60,7 +60,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id) outb(0, 0xF0); if (ignore_fpu_irq || !boot_cpu_data.hard_math) return IRQ_NONE; - math_error((void __user *)get_irq_regs()->ip); + math_error(get_irq_regs(), 0, 16); return IRQ_HANDLED; } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index a16c9dfe6b70..a472992cecdc 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -595,36 +595,48 @@ static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) * the correct behaviour even in the presence of the asynchronous * IRQ13 behaviour */ -void math_error(void __user *ip) +void math_error(struct pt_regs *regs, int error_code, int trapnr) { struct task_struct *task; siginfo_t info; - unsigned short cwd, swd, err; + unsigned short err; /* * Save the info for the exception handler and clear the error. */ task = current; save_init_fpu(task); - task->thread.trap_no = 16; - task->thread.error_code = 0; + task->thread.trap_no = trapnr; + task->thread.error_code = error_code; info.si_signo = SIGFPE; info.si_errno = 0; - info.si_addr = ip; - /* - * (~cwd & swd) will mask out exceptions that are not set to unmasked - * status. 0x3f is the exception bits in these regs, 0x200 is the - * C1 reg you need in case of a stack fault, 0x040 is the stack - * fault bit. We should only be taking one exception at a time, - * so if this combination doesn't produce any single exception, - * then we have a bad program that isn't synchronizing its FPU usage - * and it will suffer the consequences since we won't be able to - * fully reproduce the context of the exception - */ - cwd = get_fpu_cwd(task); - swd = get_fpu_swd(task); + info.si_addr = (void __user *)regs->ip; + if (trapnr == 16) { + unsigned short cwd, swd; + /* + * (~cwd & swd) will mask out exceptions that are not set to unmasked + * status. 0x3f is the exception bits in these regs, 0x200 is the + * C1 reg you need in case of a stack fault, 0x040 is the stack + * fault bit. We should only be taking one exception at a time, + * so if this combination doesn't produce any single exception, + * then we have a bad program that isn't synchronizing its FPU usage + * and it will suffer the consequences since we won't be able to + * fully reproduce the context of the exception + */ + cwd = get_fpu_cwd(task); + swd = get_fpu_swd(task); - err = swd & ~cwd; + err = swd & ~cwd; + } else { + /* + * The SIMD FPU exceptions are handled a little differently, as there + * is only a single status/control register. Thus, to determine which + * unmasked exception was caught we must mask the exception mask bits + * at 0x1f80, and then use these to mask the exception bits at 0x3f. + */ + unsigned short mxcsr = get_fpu_mxcsr(task); + err = ~(mxcsr >> 7) & mxcsr; + } if (err & 0x001) { /* Invalid op */ /* @@ -663,55 +675,7 @@ dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) return; #endif - math_error((void __user *)regs->ip); -} - -static void simd_math_error(void __user *ip) -{ - struct task_struct *task; - siginfo_t info; - unsigned short mxcsr; - - /* - * Save the info for the exception handler and clear the error. - */ - task = current; - save_init_fpu(task); - task->thread.trap_no = 19; - task->thread.error_code = 0; - info.si_signo = SIGFPE; - info.si_errno = 0; - info.si_code = __SI_FAULT; - info.si_addr = ip; - /* - * The SIMD FPU exceptions are handled a little differently, as there - * is only a single status/control register. Thus, to determine which - * unmasked exception was caught we must mask the exception mask bits - * at 0x1f80, and then use these to mask the exception bits at 0x3f. - */ - mxcsr = get_fpu_mxcsr(task); - switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) { - case 0x000: - default: - break; - case 0x001: /* Invalid Op */ - info.si_code = FPE_FLTINV; - break; - case 0x002: /* Denormalize */ - case 0x010: /* Underflow */ - info.si_code = FPE_FLTUND; - break; - case 0x004: /* Zero Divide */ - info.si_code = FPE_FLTDIV; - break; - case 0x008: /* Overflow */ - info.si_code = FPE_FLTOVF; - break; - case 0x020: /* Precision */ - info.si_code = FPE_FLTRES; - break; - } - force_sig_info(SIGFPE, &info, task); + math_error(regs, error_code, 16); } dotraplinkage void @@ -727,7 +691,7 @@ do_simd_coprocessor_error(struct pt_regs *regs, long error_code) return; #endif - simd_math_error((void __user *)regs->ip); + math_error(regs, error_code, 19); } dotraplinkage void -- cgit v1.2.3-59-g8ed1b From e2e75c915de045f0785387dc32f55e92fab0614c Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Sun, 21 Mar 2010 09:00:45 -0400 Subject: x86: Merge kernel_math_error() into math_error() Clean up the kernel exception handling and make it more similar to the other traps. Signed-off-by: Brian Gerst LKML-Reference: <1269176446-2489-4-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/traps.c | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index a472992cecdc..53ba86fc5dd8 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -576,20 +576,6 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) return; } -#ifdef CONFIG_X86_64 -static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) -{ - if (fixup_exception(regs)) - return 1; - - notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE); - /* Illegal floating point operation in the kernel */ - current->thread.trap_no = trapnr; - die(str, regs, 0); - return 0; -} -#endif - /* * Note that we play around with the 'TS' bit in an attempt to get * the correct behaviour even in the presence of the asynchronous @@ -597,14 +583,28 @@ static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) */ void math_error(struct pt_regs *regs, int error_code, int trapnr) { - struct task_struct *task; + struct task_struct *task = current; siginfo_t info; unsigned short err; + char *str = (trapnr == 16) ? "fpu exception" : "simd exception"; + + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP) + return; + conditional_sti(regs); + + if (!user_mode_vm(regs)) + { + if (!fixup_exception(regs)) { + task->thread.error_code = error_code; + task->thread.trap_no = trapnr; + die(str, regs, error_code); + } + return; + } /* * Save the info for the exception handler and clear the error. */ - task = current; save_init_fpu(task); task->thread.trap_no = trapnr; task->thread.error_code = error_code; @@ -665,14 +665,8 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr) dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) { - conditional_sti(regs); - #ifdef CONFIG_X86_32 ignore_fpu_irq = 1; -#else - if (!user_mode(regs) && - kernel_math_error(regs, "kernel x87 math error", 16)) - return; #endif math_error(regs, error_code, 16); @@ -681,14 +675,8 @@ dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) dotraplinkage void do_simd_coprocessor_error(struct pt_regs *regs, long error_code) { - conditional_sti(regs); - #ifdef CONFIG_X86_32 ignore_fpu_irq = 1; -#else - if (!user_mode(regs) && - kernel_math_error(regs, "kernel simd math error", 19)) - return; #endif math_error(regs, error_code, 19); -- cgit v1.2.3-59-g8ed1b From 250825008f1f94887bc039e9227a8adfb5ba366e Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Sun, 21 Mar 2010 09:00:46 -0400 Subject: x86-32: Don't set ignore_fpu_irq in simd exception Any processor that supports simd will have an internal fpu, and the irq13 handler will not be enabled. Signed-off-by: Brian Gerst LKML-Reference: <1269176446-2489-5-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/traps.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 53ba86fc5dd8..00516e1de55d 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -675,10 +675,6 @@ dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) dotraplinkage void do_simd_coprocessor_error(struct pt_regs *regs, long error_code) { -#ifdef CONFIG_X86_32 - ignore_fpu_irq = 1; -#endif - math_error(regs, error_code, 19); } -- cgit v1.2.3-59-g8ed1b From 2a49456fdae0cc9e4286de38b8fcb85f9c7c7559 Mon Sep 17 00:00:00 2001 From: Simon Guinot Date: Wed, 3 Feb 2010 01:41:09 +0100 Subject: [ARM] Kirkwood: add LaCie 2Big Network v2 support Signed-off-by: Nicolas Pitre --- arch/arm/mach-kirkwood/Kconfig | 6 + arch/arm/mach-kirkwood/Makefile | 1 + arch/arm/mach-kirkwood/net2big_v2-setup.c | 334 ++++++++++++++++++++++++++++++ 3 files changed, 341 insertions(+) create mode 100644 arch/arm/mach-kirkwood/net2big_v2-setup.c (limited to 'arch') diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 05a85526d6d5..953681ae69ea 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -87,6 +87,12 @@ config MACH_INETSPACE_V2 Say 'Y' here if you want your kernel to support the LaCie Internet Space v2 NAS. +config MACH_NET2BIG_V2 + bool "LaCie 2Big Network v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie 2Big Network v2 NAS. + endmenu endif diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index 85b3a39a6204..3697d8e59687 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -12,5 +12,6 @@ obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o +obj-$(CONFIG_MACH_NET2BIG_V2) += net2big_v2-setup.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/arm/mach-kirkwood/net2big_v2-setup.c b/arch/arm/mach-kirkwood/net2big_v2-setup.c new file mode 100644 index 000000000000..359bb19e366c --- /dev/null +++ b/arch/arm/mach-kirkwood/net2big_v2-setup.c @@ -0,0 +1,334 @@ +/* + * arch/arm/mach-kirkwood/net2big_v2-setup.c + * + * LaCie 2Big Network v2 board setup + * + * Copyright (C) 2010 Simon Guinot + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/***************************************************************************** + * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) + ****************************************************************************/ + +static struct mtd_partition net2big_v2_flash_parts[] = { + { + .name = "u-boot", + .size = MTDPART_SIZ_FULL, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, +}; + +static const struct flash_platform_data net2big_v2_flash = { + .type = "mx25l4005a", + .name = "spi_flash", + .parts = net2big_v2_flash_parts, + .nr_parts = ARRAY_SIZE(net2big_v2_flash_parts), +}; + +static struct spi_board_info __initdata net2big_v2_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &net2big_v2_flash, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data net2big_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +/***************************************************************************** + * I2C devices + ****************************************************************************/ + +static struct at24_platform_data at24c04 = { + .byte_len = SZ_4K / 8, + .page_size = 16, +}; + +/* + * i2c addr | chip | description + * 0x50 | HT24LC04 | eeprom (512B) + */ + +static struct i2c_board_info __initdata net2big_v2_i2c_info[] = { + { + I2C_BOARD_INFO("24c04", 0x50), + .platform_data = &at24c04, + } +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data net2big_v2_sata_data = { + .n_ports = 2, +}; + +static int __initdata net2big_v2_gpio_hdd_power[] = { 16, 17 }; + +static void __init net2big_v2_sata_power_init(void) +{ + int i; + int err; + + /* Power up all hard disks. */ + for (i = 0; i < ARRAY_SIZE(net2big_v2_gpio_hdd_power); i++) { + err = gpio_request(net2big_v2_gpio_hdd_power[i], NULL); + if (err == 0) { + err = gpio_direction_output( + net2big_v2_gpio_hdd_power[i], 1); + /* Free the HDD power GPIOs. This allow user-space to + * configure them via the gpiolib sysfs interface. */ + gpio_free(net2big_v2_gpio_hdd_power[i]); + } + if (err) + pr_err("net2big_v2: failed to power-up HDD%d\n", i + 1); + } +} + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define NET2BIG_V2_GPIO_SWITCH_POWER_ON 13 +#define NET2BIG_V2_GPIO_SWITCH_POWER_OFF 15 +#define NET2BIG_V2_GPIO_FUNC_BUTTON 34 + +#define NET2BIG_V2_SWITCH_POWER_ON 0x1 +#define NET2BIG_V2_SWITCH_POWER_OFF 0x2 + +static struct gpio_keys_button net2big_v2_buttons[] = { + [0] = { + .type = EV_SW, + .code = NET2BIG_V2_SWITCH_POWER_ON, + .gpio = NET2BIG_V2_GPIO_SWITCH_POWER_ON, + .desc = "Back power switch (on|auto)", + .active_low = 1, + }, + [1] = { + .type = EV_SW, + .code = NET2BIG_V2_SWITCH_POWER_OFF, + .gpio = NET2BIG_V2_GPIO_SWITCH_POWER_OFF, + .desc = "Back power switch (auto|off)", + .active_low = 1, + }, + [2] = { + .code = KEY_OPTION, + .gpio = NET2BIG_V2_GPIO_FUNC_BUTTON, + .desc = "Function button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data net2big_v2_button_data = { + .buttons = net2big_v2_buttons, + .nbuttons = ARRAY_SIZE(net2big_v2_buttons), +}; + +static struct platform_device net2big_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &net2big_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO LEDs + ****************************************************************************/ + +/* + * The LEDs are controlled by a CPLD and can be configured through a GPIO + * extension bus: + * + * - address register : bit [0-2] -> GPIO [47-49] + * - data register : bit [0-2] -> GPIO [44-46] + * - enable register : GPIO 29 + * + * Address register selection: + * + * addr | register + * ---------------------------- + * 0 | front LED + * 1 | front LED brightness + * 2 | HDD LED brightness + * 3 | HDD1 LED + * 4 | HDD2 LED + * + * Data register configuration: + * + * data | LED brightness + * ------------------------------------------------- + * 0 | min (off) + * - | - + * 7 | max + * + * data | front LED mode + * ------------------------------------------------- + * 0 | fix off + * 1 | fix blue on + * 2 | fix red on + * 3 | blink blue on=1 sec and blue off=1 sec + * 4 | blink red on=1 sec and red off=1 sec + * 5 | blink blue on=2.5 sec and red on=0.5 sec + * 6 | blink blue on=1 sec and red on=1 sec + * 7 | blink blue on=0.5 sec and blue off=2.5 sec + * + * data | HDD LED mode + * ------------------------------------------------- + * 0 | fix blue on + * 1 | SATA activity blink + * 2 | fix red on + * 3 | blink blue on=1 sec and blue off=1 sec + * 4 | blink red on=1 sec and red off=1 sec + * 5 | blink blue on=2.5 sec and red on=0.5 sec + * 6 | blink blue on=1 sec and red on=1 sec + * 7 | blink blue on=0.5 sec and blue off=2.5 sec + */ + +/***************************************************************************** + * Timer + ****************************************************************************/ + +static void net2big_v2_timer_init(void) +{ + kirkwood_tclk = 166666667; + orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); +} + +struct sys_timer net2big_v2_timer = { + .init = net2big_v2_timer_init, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int net2big_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW_SDA, + MPP9_TW_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse alarm */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA HDD1 power */ + MPP17_GPIO, /* SATA HDD2 power */ + MPP20_SATA1_ACTn, + MPP21_SATA0_ACTn, + MPP24_GPIO, /* USB mode select */ + MPP26_GPIO, /* USB device vbus */ + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* GPIO extension ALE */ + MPP34_GPIO, /* Rear Push button */ + MPP35_GPIO, /* Inhibit switch power-off */ + MPP36_GPIO, /* SATA HDD1 presence */ + MPP37_GPIO, /* SATA HDD2 presence */ + MPP40_GPIO, /* eSATA presence */ + MPP44_GPIO, /* GPIO extension (data 0) */ + MPP45_GPIO, /* GPIO extension (data 1) */ + MPP46_GPIO, /* GPIO extension (data 2) */ + MPP47_GPIO, /* GPIO extension (addr 0) */ + MPP48_GPIO, /* GPIO extension (addr 1) */ + MPP49_GPIO, /* GPIO extension (addr 2) */ + 0 +}; + +#define NET2BIG_V2_GPIO_POWER_OFF 7 + +static void net2big_v2_power_off(void) +{ + gpio_set_value(NET2BIG_V2_GPIO_POWER_OFF, 1); +} + +static void __init net2big_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(net2big_v2_mpp_config); + + net2big_v2_sata_power_init(); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&net2big_v2_ge00_data); + kirkwood_sata_init(&net2big_v2_sata_data); + kirkwood_uart0_init(); + spi_register_board_info(net2big_v2_spi_slave_info, + ARRAY_SIZE(net2big_v2_spi_slave_info)); + kirkwood_spi_init(); + kirkwood_i2c_init(); + i2c_register_board_info(0, net2big_v2_i2c_info, + ARRAY_SIZE(net2big_v2_i2c_info)); + + platform_device_register(&net2big_v2_gpio_buttons); + + if (gpio_request(NET2BIG_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(NET2BIG_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = net2big_v2_power_off; + else + pr_err("net2big_v2: failed to configure power-off GPIO\n"); +} + +MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2") + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = net2big_v2_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &net2big_v2_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 3e05ec1b93cd839fa1d1a9961b155b0dbc9a4055 Mon Sep 17 00:00:00 2001 From: Simon Guinot Date: Mon, 4 Jan 2010 20:20:07 +0100 Subject: [ARM] Kirkwood: add LaCie 5Big Network v2 support Signed-off-by: Nicolas Pitre --- arch/arm/mach-kirkwood/Kconfig | 6 + arch/arm/mach-kirkwood/Makefile | 1 + arch/arm/mach-kirkwood/net5big_v2-setup.c | 355 ++++++++++++++++++++++++++++++ 3 files changed, 362 insertions(+) create mode 100644 arch/arm/mach-kirkwood/net5big_v2-setup.c (limited to 'arch') diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 953681ae69ea..29b2163b1fe3 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -93,6 +93,12 @@ config MACH_NET2BIG_V2 Say 'Y' here if you want your kernel to support the LaCie 2Big Network v2 NAS. +config MACH_NET5BIG_V2 + bool "LaCie 5Big Network v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie 5Big Network v2 NAS. + endmenu endif diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index 3697d8e59687..bbb8dd3fa211 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -13,5 +13,6 @@ obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o obj-$(CONFIG_MACH_NET2BIG_V2) += net2big_v2-setup.o +obj-$(CONFIG_MACH_NET5BIG_V2) += net5big_v2-setup.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/arm/mach-kirkwood/net5big_v2-setup.c b/arch/arm/mach-kirkwood/net5big_v2-setup.c new file mode 100644 index 000000000000..f0617ecc8a29 --- /dev/null +++ b/arch/arm/mach-kirkwood/net5big_v2-setup.c @@ -0,0 +1,355 @@ +/* + * arch/arm/mach-kirkwood/net5big_v2-setup.c + * + * LaCie 5Big Network v2 board setup + * + * Copyright (C) 2010 Simon Guinot + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/***************************************************************************** + * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) + ****************************************************************************/ + +static struct mtd_partition net5big_v2_flash_parts[] = { + { + .name = "u-boot", + .size = MTDPART_SIZ_FULL, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, +}; + +static const struct flash_platform_data net5big_v2_flash = { + .type = "mx25l4005a", + .name = "spi_flash", + .parts = net5big_v2_flash_parts, + .nr_parts = ARRAY_SIZE(net5big_v2_flash_parts), +}; + +static struct spi_board_info __initdata net5big_v2_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &net5big_v2_flash, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data net5big_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv643xx_eth_platform_data net5big_v2_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +/***************************************************************************** + * I2C devices + ****************************************************************************/ + +static struct at24_platform_data at24c04 = { + .byte_len = SZ_4K / 8, + .page_size = 16, +}; + +/* + * i2c addr | chip | description + * 0x50 | HT24LC04 | eeprom (512B) + */ + +static struct i2c_board_info __initdata net5big_v2_i2c_info[] = { + { + I2C_BOARD_INFO("24c04", 0x50), + .platform_data = &at24c04, + } +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data net5big_v2_sata_data = { + .n_ports = 2, +}; + +static int __initdata net5big_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 }; + +static void __init net5big_v2_sata_power_init(void) +{ + int i; + int err; + + /* Power up all hard disks. */ + for (i = 0; i < ARRAY_SIZE(net5big_v2_gpio_hdd_power); i++) { + err = gpio_request(net5big_v2_gpio_hdd_power[i], NULL); + if (err == 0) { + err = gpio_direction_output( + net5big_v2_gpio_hdd_power[i], 1); + /* Free the HDD power GPIOs. This allow user-space to + * configure them via the gpiolib sysfs interface. */ + gpio_free(net5big_v2_gpio_hdd_power[i]); + } + if (err) + pr_err("net5big_v2: failed to power up HDD%d\n", i + 1); + } +} + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define NET5BIG_V2_GPIO_SWITCH_POWER_ON 13 +#define NET5BIG_V2_GPIO_SWITCH_POWER_OFF 15 +#define NET5BIG_V2_GPIO_FUNC_BUTTON 34 + +#define NET5BIG_V2_SWITCH_POWER_ON 0x1 +#define NET5BIG_V2_SWITCH_POWER_OFF 0x2 + +static struct gpio_keys_button net5big_v2_buttons[] = { + [0] = { + .type = EV_SW, + .code = NET5BIG_V2_SWITCH_POWER_ON, + .gpio = NET5BIG_V2_GPIO_SWITCH_POWER_ON, + .desc = "Back power switch (on|auto)", + .active_low = 1, + }, + [1] = { + .type = EV_SW, + .code = NET5BIG_V2_SWITCH_POWER_OFF, + .gpio = NET5BIG_V2_GPIO_SWITCH_POWER_OFF, + .desc = "Back power switch (auto|off)", + .active_low = 1, + }, + [2] = { + .code = KEY_OPTION, + .gpio = NET5BIG_V2_GPIO_FUNC_BUTTON, + .desc = "Function button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data net5big_v2_button_data = { + .buttons = net5big_v2_buttons, + .nbuttons = ARRAY_SIZE(net5big_v2_buttons), +}; + +static struct platform_device net5big_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &net5big_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO LEDs + ****************************************************************************/ + +/* + * The LEDs are controlled by a CPLD and can be configured through a GPIO + * extension bus: + * + * - address register : bit [0-2] -> GPIO [47-49] + * - data register : bit [0-2] -> GPIO [44-46] + * - enable register : GPIO 29 + * + * Address register selection: + * + * addr | register + * ---------------------------- + * 0 | front LED + * 1 | front LED brightness + * 2 | HDD LED brightness + * 3 | HDD1 LED + * 4 | HDD2 LED + * 5 | HDD3 LED + * 6 | HDD4 LED + * 7 | HDD5 LED + * + * Data register configuration: + * + * data | LED brightness + * ------------------------------------------------- + * 0 | min (off) + * - | - + * 7 | max + * + * data | front LED mode + * ------------------------------------------------- + * 0 | fix off + * 1 | fix blue on + * 2 | fix red on + * 3 | blink blue on=1 sec and blue off=1 sec + * 4 | blink red on=1 sec and red off=1 sec + * 5 | blink blue on=2.5 sec and red on=0.5 sec + * 6 | blink blue on=1 sec and red on=1 sec + * 7 | blink blue on=0.5 sec and blue off=2.5 sec + * + * data | HDD LED mode + * ------------------------------------------------- + * 0 | fix blue on + * 1 | SATA activity blink + * 2 | fix red on + * 3 | blink blue on=1 sec and blue off=1 sec + * 4 | blink red on=1 sec and red off=1 sec + * 5 | blink blue on=2.5 sec and red on=0.5 sec + * 6 | blink blue on=1 sec and red on=1 sec + * 7 | blink blue on=0.5 sec and blue off=2.5 sec + */ + +/***************************************************************************** + * Timer + ****************************************************************************/ + +static void net5big_v2_timer_init(void) +{ + kirkwood_tclk = 166666667; + orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); +} + +struct sys_timer net5big_v2_timer = { + .init = net5big_v2_timer_init, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int net5big_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW_SDA, + MPP9_TW_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse alarm */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA HDD1 power */ + MPP17_GPIO, /* SATA HDD2 power */ + MPP20_GE1_0, + MPP21_GE1_1, + MPP22_GE1_2, + MPP23_GE1_3, + MPP24_GE1_4, + MPP25_GE1_5, + MPP26_GE1_6, + MPP27_GE1_7, + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* CPLD extension ALE */ + MPP30_GE1_10, + MPP31_GE1_11, + MPP32_GE1_12, + MPP33_GE1_13, + MPP34_GPIO, /* Rear Push button */ + MPP35_GPIO, /* Inhibit switch power-off */ + MPP36_GPIO, /* SATA HDD1 presence */ + MPP37_GPIO, /* SATA HDD2 presence */ + MPP38_GPIO, /* SATA HDD3 presence */ + MPP39_GPIO, /* SATA HDD4 presence */ + MPP40_GPIO, /* SATA HDD5 presence */ + MPP41_GPIO, /* SATA HDD3 power */ + MPP42_GPIO, /* SATA HDD4 power */ + MPP43_GPIO, /* SATA HDD5 power */ + MPP44_GPIO, /* CPLD extension (data 0) */ + MPP45_GPIO, /* CPLD extension (data 1) */ + MPP46_GPIO, /* CPLD extension (data 2) */ + MPP47_GPIO, /* CPLD extension (addr 0) */ + MPP48_GPIO, /* CPLD extension (addr 1) */ + MPP49_GPIO, /* CPLD extension (addr 2) */ + 0 +}; + +#define NET5BIG_V2_GPIO_POWER_OFF 7 + +static void net5big_v2_power_off(void) +{ + gpio_set_value(NET5BIG_V2_GPIO_POWER_OFF, 1); +} + +static void __init net5big_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(net5big_v2_mpp_config); + + net5big_v2_sata_power_init(); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&net5big_v2_ge00_data); + kirkwood_ge01_init(&net5big_v2_ge01_data); + kirkwood_sata_init(&net5big_v2_sata_data); + kirkwood_uart0_init(); + spi_register_board_info(net5big_v2_spi_slave_info, + ARRAY_SIZE(net5big_v2_spi_slave_info)); + kirkwood_spi_init(); + kirkwood_i2c_init(); + i2c_register_board_info(0, net5big_v2_i2c_info, + ARRAY_SIZE(net5big_v2_i2c_info)); + + platform_device_register(&net5big_v2_gpio_buttons); + + if (gpio_request(NET5BIG_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(NET5BIG_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = net5big_v2_power_off; + else + pr_err("net5big_v2: failed to configure power-off GPIO\n"); +} + +MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2") + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = net5big_v2_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &net5big_v2_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 57475b1a47b3e891ce087ca3c6fc93f5a446a244 Mon Sep 17 00:00:00 2001 From: Simon Guinot Date: Mon, 8 Feb 2010 19:08:34 +0100 Subject: [ARM] Kirkwood: merge net2big_v2 and net5big_v2 board setups Signed-off-by: Nicolas Pitre --- arch/arm/mach-kirkwood/Makefile | 4 +- arch/arm/mach-kirkwood/net2big_v2-setup.c | 334 ------------------------ arch/arm/mach-kirkwood/net5big_v2-setup.c | 355 ------------------------- arch/arm/mach-kirkwood/netxbig_v2-setup.c | 415 ++++++++++++++++++++++++++++++ 4 files changed, 417 insertions(+), 691 deletions(-) delete mode 100644 arch/arm/mach-kirkwood/net2big_v2-setup.c delete mode 100644 arch/arm/mach-kirkwood/net5big_v2-setup.c create mode 100644 arch/arm/mach-kirkwood/netxbig_v2-setup.c (limited to 'arch') diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index bbb8dd3fa211..c0cd5d362002 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o -obj-$(CONFIG_MACH_NET2BIG_V2) += net2big_v2-setup.o -obj-$(CONFIG_MACH_NET5BIG_V2) += net5big_v2-setup.o +obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o +obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/arm/mach-kirkwood/net2big_v2-setup.c b/arch/arm/mach-kirkwood/net2big_v2-setup.c deleted file mode 100644 index 359bb19e366c..000000000000 --- a/arch/arm/mach-kirkwood/net2big_v2-setup.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * arch/arm/mach-kirkwood/net2big_v2-setup.c - * - * LaCie 2Big Network v2 board setup - * - * Copyright (C) 2010 Simon Guinot - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "mpp.h" - -/***************************************************************************** - * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) - ****************************************************************************/ - -static struct mtd_partition net2big_v2_flash_parts[] = { - { - .name = "u-boot", - .size = MTDPART_SIZ_FULL, - .offset = 0, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, -}; - -static const struct flash_platform_data net2big_v2_flash = { - .type = "mx25l4005a", - .name = "spi_flash", - .parts = net2big_v2_flash_parts, - .nr_parts = ARRAY_SIZE(net2big_v2_flash_parts), -}; - -static struct spi_board_info __initdata net2big_v2_spi_slave_info[] = { - { - .modalias = "m25p80", - .platform_data = &net2big_v2_flash, - .irq = -1, - .max_speed_hz = 20000000, - .bus_num = 0, - .chip_select = 0, - }, -}; - -/***************************************************************************** - * Ethernet - ****************************************************************************/ - -static struct mv643xx_eth_platform_data net2big_v2_ge00_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(8), -}; - -/***************************************************************************** - * I2C devices - ****************************************************************************/ - -static struct at24_platform_data at24c04 = { - .byte_len = SZ_4K / 8, - .page_size = 16, -}; - -/* - * i2c addr | chip | description - * 0x50 | HT24LC04 | eeprom (512B) - */ - -static struct i2c_board_info __initdata net2big_v2_i2c_info[] = { - { - I2C_BOARD_INFO("24c04", 0x50), - .platform_data = &at24c04, - } -}; - -/***************************************************************************** - * SATA - ****************************************************************************/ - -static struct mv_sata_platform_data net2big_v2_sata_data = { - .n_ports = 2, -}; - -static int __initdata net2big_v2_gpio_hdd_power[] = { 16, 17 }; - -static void __init net2big_v2_sata_power_init(void) -{ - int i; - int err; - - /* Power up all hard disks. */ - for (i = 0; i < ARRAY_SIZE(net2big_v2_gpio_hdd_power); i++) { - err = gpio_request(net2big_v2_gpio_hdd_power[i], NULL); - if (err == 0) { - err = gpio_direction_output( - net2big_v2_gpio_hdd_power[i], 1); - /* Free the HDD power GPIOs. This allow user-space to - * configure them via the gpiolib sysfs interface. */ - gpio_free(net2big_v2_gpio_hdd_power[i]); - } - if (err) - pr_err("net2big_v2: failed to power-up HDD%d\n", i + 1); - } -} - -/***************************************************************************** - * GPIO keys - ****************************************************************************/ - -#define NET2BIG_V2_GPIO_SWITCH_POWER_ON 13 -#define NET2BIG_V2_GPIO_SWITCH_POWER_OFF 15 -#define NET2BIG_V2_GPIO_FUNC_BUTTON 34 - -#define NET2BIG_V2_SWITCH_POWER_ON 0x1 -#define NET2BIG_V2_SWITCH_POWER_OFF 0x2 - -static struct gpio_keys_button net2big_v2_buttons[] = { - [0] = { - .type = EV_SW, - .code = NET2BIG_V2_SWITCH_POWER_ON, - .gpio = NET2BIG_V2_GPIO_SWITCH_POWER_ON, - .desc = "Back power switch (on|auto)", - .active_low = 1, - }, - [1] = { - .type = EV_SW, - .code = NET2BIG_V2_SWITCH_POWER_OFF, - .gpio = NET2BIG_V2_GPIO_SWITCH_POWER_OFF, - .desc = "Back power switch (auto|off)", - .active_low = 1, - }, - [2] = { - .code = KEY_OPTION, - .gpio = NET2BIG_V2_GPIO_FUNC_BUTTON, - .desc = "Function button", - .active_low = 1, - }, -}; - -static struct gpio_keys_platform_data net2big_v2_button_data = { - .buttons = net2big_v2_buttons, - .nbuttons = ARRAY_SIZE(net2big_v2_buttons), -}; - -static struct platform_device net2big_v2_gpio_buttons = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &net2big_v2_button_data, - }, -}; - -/***************************************************************************** - * GPIO LEDs - ****************************************************************************/ - -/* - * The LEDs are controlled by a CPLD and can be configured through a GPIO - * extension bus: - * - * - address register : bit [0-2] -> GPIO [47-49] - * - data register : bit [0-2] -> GPIO [44-46] - * - enable register : GPIO 29 - * - * Address register selection: - * - * addr | register - * ---------------------------- - * 0 | front LED - * 1 | front LED brightness - * 2 | HDD LED brightness - * 3 | HDD1 LED - * 4 | HDD2 LED - * - * Data register configuration: - * - * data | LED brightness - * ------------------------------------------------- - * 0 | min (off) - * - | - - * 7 | max - * - * data | front LED mode - * ------------------------------------------------- - * 0 | fix off - * 1 | fix blue on - * 2 | fix red on - * 3 | blink blue on=1 sec and blue off=1 sec - * 4 | blink red on=1 sec and red off=1 sec - * 5 | blink blue on=2.5 sec and red on=0.5 sec - * 6 | blink blue on=1 sec and red on=1 sec - * 7 | blink blue on=0.5 sec and blue off=2.5 sec - * - * data | HDD LED mode - * ------------------------------------------------- - * 0 | fix blue on - * 1 | SATA activity blink - * 2 | fix red on - * 3 | blink blue on=1 sec and blue off=1 sec - * 4 | blink red on=1 sec and red off=1 sec - * 5 | blink blue on=2.5 sec and red on=0.5 sec - * 6 | blink blue on=1 sec and red on=1 sec - * 7 | blink blue on=0.5 sec and blue off=2.5 sec - */ - -/***************************************************************************** - * Timer - ****************************************************************************/ - -static void net2big_v2_timer_init(void) -{ - kirkwood_tclk = 166666667; - orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); -} - -struct sys_timer net2big_v2_timer = { - .init = net2big_v2_timer_init, -}; - -/***************************************************************************** - * General Setup - ****************************************************************************/ - -static unsigned int net2big_v2_mpp_config[] __initdata = { - MPP0_SPI_SCn, - MPP1_SPI_MOSI, - MPP2_SPI_SCK, - MPP3_SPI_MISO, - MPP6_SYSRST_OUTn, - MPP7_GPO, /* Request power-off */ - MPP8_TW_SDA, - MPP9_TW_SCK, - MPP10_UART0_TXD, - MPP11_UART0_RXD, - MPP13_GPIO, /* Rear power switch (on|auto) */ - MPP14_GPIO, /* USB fuse alarm */ - MPP15_GPIO, /* Rear power switch (auto|off) */ - MPP16_GPIO, /* SATA HDD1 power */ - MPP17_GPIO, /* SATA HDD2 power */ - MPP20_SATA1_ACTn, - MPP21_SATA0_ACTn, - MPP24_GPIO, /* USB mode select */ - MPP26_GPIO, /* USB device vbus */ - MPP28_GPIO, /* USB enable host vbus */ - MPP29_GPIO, /* GPIO extension ALE */ - MPP34_GPIO, /* Rear Push button */ - MPP35_GPIO, /* Inhibit switch power-off */ - MPP36_GPIO, /* SATA HDD1 presence */ - MPP37_GPIO, /* SATA HDD2 presence */ - MPP40_GPIO, /* eSATA presence */ - MPP44_GPIO, /* GPIO extension (data 0) */ - MPP45_GPIO, /* GPIO extension (data 1) */ - MPP46_GPIO, /* GPIO extension (data 2) */ - MPP47_GPIO, /* GPIO extension (addr 0) */ - MPP48_GPIO, /* GPIO extension (addr 1) */ - MPP49_GPIO, /* GPIO extension (addr 2) */ - 0 -}; - -#define NET2BIG_V2_GPIO_POWER_OFF 7 - -static void net2big_v2_power_off(void) -{ - gpio_set_value(NET2BIG_V2_GPIO_POWER_OFF, 1); -} - -static void __init net2big_v2_init(void) -{ - /* - * Basic setup. Needs to be called early. - */ - kirkwood_init(); - kirkwood_mpp_conf(net2big_v2_mpp_config); - - net2big_v2_sata_power_init(); - - kirkwood_ehci_init(); - kirkwood_ge00_init(&net2big_v2_ge00_data); - kirkwood_sata_init(&net2big_v2_sata_data); - kirkwood_uart0_init(); - spi_register_board_info(net2big_v2_spi_slave_info, - ARRAY_SIZE(net2big_v2_spi_slave_info)); - kirkwood_spi_init(); - kirkwood_i2c_init(); - i2c_register_board_info(0, net2big_v2_i2c_info, - ARRAY_SIZE(net2big_v2_i2c_info)); - - platform_device_register(&net2big_v2_gpio_buttons); - - if (gpio_request(NET2BIG_V2_GPIO_POWER_OFF, "power-off") == 0 && - gpio_direction_output(NET2BIG_V2_GPIO_POWER_OFF, 0) == 0) - pm_power_off = net2big_v2_power_off; - else - pr_err("net2big_v2: failed to configure power-off GPIO\n"); -} - -MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2") - .phys_io = KIRKWOOD_REGS_PHYS_BASE, - .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .init_machine = net2big_v2_init, - .map_io = kirkwood_map_io, - .init_irq = kirkwood_init_irq, - .timer = &net2big_v2_timer, -MACHINE_END diff --git a/arch/arm/mach-kirkwood/net5big_v2-setup.c b/arch/arm/mach-kirkwood/net5big_v2-setup.c deleted file mode 100644 index f0617ecc8a29..000000000000 --- a/arch/arm/mach-kirkwood/net5big_v2-setup.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * arch/arm/mach-kirkwood/net5big_v2-setup.c - * - * LaCie 5Big Network v2 board setup - * - * Copyright (C) 2010 Simon Guinot - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "mpp.h" - -/***************************************************************************** - * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) - ****************************************************************************/ - -static struct mtd_partition net5big_v2_flash_parts[] = { - { - .name = "u-boot", - .size = MTDPART_SIZ_FULL, - .offset = 0, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, -}; - -static const struct flash_platform_data net5big_v2_flash = { - .type = "mx25l4005a", - .name = "spi_flash", - .parts = net5big_v2_flash_parts, - .nr_parts = ARRAY_SIZE(net5big_v2_flash_parts), -}; - -static struct spi_board_info __initdata net5big_v2_spi_slave_info[] = { - { - .modalias = "m25p80", - .platform_data = &net5big_v2_flash, - .irq = -1, - .max_speed_hz = 20000000, - .bus_num = 0, - .chip_select = 0, - }, -}; - -/***************************************************************************** - * Ethernet - ****************************************************************************/ - -static struct mv643xx_eth_platform_data net5big_v2_ge00_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(8), -}; - -static struct mv643xx_eth_platform_data net5big_v2_ge01_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(0), -}; - -/***************************************************************************** - * I2C devices - ****************************************************************************/ - -static struct at24_platform_data at24c04 = { - .byte_len = SZ_4K / 8, - .page_size = 16, -}; - -/* - * i2c addr | chip | description - * 0x50 | HT24LC04 | eeprom (512B) - */ - -static struct i2c_board_info __initdata net5big_v2_i2c_info[] = { - { - I2C_BOARD_INFO("24c04", 0x50), - .platform_data = &at24c04, - } -}; - -/***************************************************************************** - * SATA - ****************************************************************************/ - -static struct mv_sata_platform_data net5big_v2_sata_data = { - .n_ports = 2, -}; - -static int __initdata net5big_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 }; - -static void __init net5big_v2_sata_power_init(void) -{ - int i; - int err; - - /* Power up all hard disks. */ - for (i = 0; i < ARRAY_SIZE(net5big_v2_gpio_hdd_power); i++) { - err = gpio_request(net5big_v2_gpio_hdd_power[i], NULL); - if (err == 0) { - err = gpio_direction_output( - net5big_v2_gpio_hdd_power[i], 1); - /* Free the HDD power GPIOs. This allow user-space to - * configure them via the gpiolib sysfs interface. */ - gpio_free(net5big_v2_gpio_hdd_power[i]); - } - if (err) - pr_err("net5big_v2: failed to power up HDD%d\n", i + 1); - } -} - -/***************************************************************************** - * GPIO keys - ****************************************************************************/ - -#define NET5BIG_V2_GPIO_SWITCH_POWER_ON 13 -#define NET5BIG_V2_GPIO_SWITCH_POWER_OFF 15 -#define NET5BIG_V2_GPIO_FUNC_BUTTON 34 - -#define NET5BIG_V2_SWITCH_POWER_ON 0x1 -#define NET5BIG_V2_SWITCH_POWER_OFF 0x2 - -static struct gpio_keys_button net5big_v2_buttons[] = { - [0] = { - .type = EV_SW, - .code = NET5BIG_V2_SWITCH_POWER_ON, - .gpio = NET5BIG_V2_GPIO_SWITCH_POWER_ON, - .desc = "Back power switch (on|auto)", - .active_low = 1, - }, - [1] = { - .type = EV_SW, - .code = NET5BIG_V2_SWITCH_POWER_OFF, - .gpio = NET5BIG_V2_GPIO_SWITCH_POWER_OFF, - .desc = "Back power switch (auto|off)", - .active_low = 1, - }, - [2] = { - .code = KEY_OPTION, - .gpio = NET5BIG_V2_GPIO_FUNC_BUTTON, - .desc = "Function button", - .active_low = 1, - }, -}; - -static struct gpio_keys_platform_data net5big_v2_button_data = { - .buttons = net5big_v2_buttons, - .nbuttons = ARRAY_SIZE(net5big_v2_buttons), -}; - -static struct platform_device net5big_v2_gpio_buttons = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &net5big_v2_button_data, - }, -}; - -/***************************************************************************** - * GPIO LEDs - ****************************************************************************/ - -/* - * The LEDs are controlled by a CPLD and can be configured through a GPIO - * extension bus: - * - * - address register : bit [0-2] -> GPIO [47-49] - * - data register : bit [0-2] -> GPIO [44-46] - * - enable register : GPIO 29 - * - * Address register selection: - * - * addr | register - * ---------------------------- - * 0 | front LED - * 1 | front LED brightness - * 2 | HDD LED brightness - * 3 | HDD1 LED - * 4 | HDD2 LED - * 5 | HDD3 LED - * 6 | HDD4 LED - * 7 | HDD5 LED - * - * Data register configuration: - * - * data | LED brightness - * ------------------------------------------------- - * 0 | min (off) - * - | - - * 7 | max - * - * data | front LED mode - * ------------------------------------------------- - * 0 | fix off - * 1 | fix blue on - * 2 | fix red on - * 3 | blink blue on=1 sec and blue off=1 sec - * 4 | blink red on=1 sec and red off=1 sec - * 5 | blink blue on=2.5 sec and red on=0.5 sec - * 6 | blink blue on=1 sec and red on=1 sec - * 7 | blink blue on=0.5 sec and blue off=2.5 sec - * - * data | HDD LED mode - * ------------------------------------------------- - * 0 | fix blue on - * 1 | SATA activity blink - * 2 | fix red on - * 3 | blink blue on=1 sec and blue off=1 sec - * 4 | blink red on=1 sec and red off=1 sec - * 5 | blink blue on=2.5 sec and red on=0.5 sec - * 6 | blink blue on=1 sec and red on=1 sec - * 7 | blink blue on=0.5 sec and blue off=2.5 sec - */ - -/***************************************************************************** - * Timer - ****************************************************************************/ - -static void net5big_v2_timer_init(void) -{ - kirkwood_tclk = 166666667; - orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); -} - -struct sys_timer net5big_v2_timer = { - .init = net5big_v2_timer_init, -}; - -/***************************************************************************** - * General Setup - ****************************************************************************/ - -static unsigned int net5big_v2_mpp_config[] __initdata = { - MPP0_SPI_SCn, - MPP1_SPI_MOSI, - MPP2_SPI_SCK, - MPP3_SPI_MISO, - MPP6_SYSRST_OUTn, - MPP7_GPO, /* Request power-off */ - MPP8_TW_SDA, - MPP9_TW_SCK, - MPP10_UART0_TXD, - MPP11_UART0_RXD, - MPP13_GPIO, /* Rear power switch (on|auto) */ - MPP14_GPIO, /* USB fuse alarm */ - MPP15_GPIO, /* Rear power switch (auto|off) */ - MPP16_GPIO, /* SATA HDD1 power */ - MPP17_GPIO, /* SATA HDD2 power */ - MPP20_GE1_0, - MPP21_GE1_1, - MPP22_GE1_2, - MPP23_GE1_3, - MPP24_GE1_4, - MPP25_GE1_5, - MPP26_GE1_6, - MPP27_GE1_7, - MPP28_GPIO, /* USB enable host vbus */ - MPP29_GPIO, /* CPLD extension ALE */ - MPP30_GE1_10, - MPP31_GE1_11, - MPP32_GE1_12, - MPP33_GE1_13, - MPP34_GPIO, /* Rear Push button */ - MPP35_GPIO, /* Inhibit switch power-off */ - MPP36_GPIO, /* SATA HDD1 presence */ - MPP37_GPIO, /* SATA HDD2 presence */ - MPP38_GPIO, /* SATA HDD3 presence */ - MPP39_GPIO, /* SATA HDD4 presence */ - MPP40_GPIO, /* SATA HDD5 presence */ - MPP41_GPIO, /* SATA HDD3 power */ - MPP42_GPIO, /* SATA HDD4 power */ - MPP43_GPIO, /* SATA HDD5 power */ - MPP44_GPIO, /* CPLD extension (data 0) */ - MPP45_GPIO, /* CPLD extension (data 1) */ - MPP46_GPIO, /* CPLD extension (data 2) */ - MPP47_GPIO, /* CPLD extension (addr 0) */ - MPP48_GPIO, /* CPLD extension (addr 1) */ - MPP49_GPIO, /* CPLD extension (addr 2) */ - 0 -}; - -#define NET5BIG_V2_GPIO_POWER_OFF 7 - -static void net5big_v2_power_off(void) -{ - gpio_set_value(NET5BIG_V2_GPIO_POWER_OFF, 1); -} - -static void __init net5big_v2_init(void) -{ - /* - * Basic setup. Needs to be called early. - */ - kirkwood_init(); - kirkwood_mpp_conf(net5big_v2_mpp_config); - - net5big_v2_sata_power_init(); - - kirkwood_ehci_init(); - kirkwood_ge00_init(&net5big_v2_ge00_data); - kirkwood_ge01_init(&net5big_v2_ge01_data); - kirkwood_sata_init(&net5big_v2_sata_data); - kirkwood_uart0_init(); - spi_register_board_info(net5big_v2_spi_slave_info, - ARRAY_SIZE(net5big_v2_spi_slave_info)); - kirkwood_spi_init(); - kirkwood_i2c_init(); - i2c_register_board_info(0, net5big_v2_i2c_info, - ARRAY_SIZE(net5big_v2_i2c_info)); - - platform_device_register(&net5big_v2_gpio_buttons); - - if (gpio_request(NET5BIG_V2_GPIO_POWER_OFF, "power-off") == 0 && - gpio_direction_output(NET5BIG_V2_GPIO_POWER_OFF, 0) == 0) - pm_power_off = net5big_v2_power_off; - else - pr_err("net5big_v2: failed to configure power-off GPIO\n"); -} - -MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2") - .phys_io = KIRKWOOD_REGS_PHYS_BASE, - .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .init_machine = net5big_v2_init, - .map_io = kirkwood_map_io, - .init_irq = kirkwood_init_irq, - .timer = &net5big_v2_timer, -MACHINE_END diff --git a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c new file mode 100644 index 000000000000..8a2bb0228e4f --- /dev/null +++ b/arch/arm/mach-kirkwood/netxbig_v2-setup.c @@ -0,0 +1,415 @@ +/* + * arch/arm/mach-kirkwood/netxbig_v2-setup.c + * + * LaCie 2Big and 5Big Network v2 board setup + * + * Copyright (C) 2010 Simon Guinot + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/***************************************************************************** + * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) + ****************************************************************************/ + +static struct mtd_partition netxbig_v2_flash_parts[] = { + { + .name = "u-boot", + .size = MTDPART_SIZ_FULL, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, +}; + +static const struct flash_platform_data netxbig_v2_flash = { + .type = "mx25l4005a", + .name = "spi_flash", + .parts = netxbig_v2_flash_parts, + .nr_parts = ARRAY_SIZE(netxbig_v2_flash_parts), +}; + +static struct spi_board_info __initdata netxbig_v2_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &netxbig_v2_flash, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data netxbig_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +/***************************************************************************** + * I2C devices + ****************************************************************************/ + +static struct at24_platform_data at24c04 = { + .byte_len = SZ_4K / 8, + .page_size = 16, +}; + +/* + * i2c addr | chip | description + * 0x50 | HT24LC04 | eeprom (512B) + */ + +static struct i2c_board_info __initdata netxbig_v2_i2c_info[] = { + { + I2C_BOARD_INFO("24c04", 0x50), + .platform_data = &at24c04, + } +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data netxbig_v2_sata_data = { + .n_ports = 2, +}; + +static int __initdata netxbig_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 }; + +static void __init netxbig_v2_sata_power_init(void) +{ + int i; + int err; + int hdd_nb; + + if (machine_is_net2big_v2()) + hdd_nb = 2; + else + hdd_nb = 5; + + /* Power up all hard disks. */ + for (i = 0; i < hdd_nb; i++) { + err = gpio_request(netxbig_v2_gpio_hdd_power[i], NULL); + if (err == 0) { + err = gpio_direction_output( + netxbig_v2_gpio_hdd_power[i], 1); + /* Free the HDD power GPIOs. This allow user-space to + * configure them via the gpiolib sysfs interface. */ + gpio_free(netxbig_v2_gpio_hdd_power[i]); + } + if (err) + pr_err("netxbig_v2: failed to power up HDD%d\n", i + 1); + } +} + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define NETXBIG_V2_GPIO_SWITCH_POWER_ON 13 +#define NETXBIG_V2_GPIO_SWITCH_POWER_OFF 15 +#define NETXBIG_V2_GPIO_FUNC_BUTTON 34 + +#define NETXBIG_V2_SWITCH_POWER_ON 0x1 +#define NETXBIG_V2_SWITCH_POWER_OFF 0x2 + +static struct gpio_keys_button netxbig_v2_buttons[] = { + [0] = { + .type = EV_SW, + .code = NETXBIG_V2_SWITCH_POWER_ON, + .gpio = NETXBIG_V2_GPIO_SWITCH_POWER_ON, + .desc = "Back power switch (on|auto)", + .active_low = 1, + }, + [1] = { + .type = EV_SW, + .code = NETXBIG_V2_SWITCH_POWER_OFF, + .gpio = NETXBIG_V2_GPIO_SWITCH_POWER_OFF, + .desc = "Back power switch (auto|off)", + .active_low = 1, + }, + [2] = { + .code = KEY_OPTION, + .gpio = NETXBIG_V2_GPIO_FUNC_BUTTON, + .desc = "Function button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data netxbig_v2_button_data = { + .buttons = netxbig_v2_buttons, + .nbuttons = ARRAY_SIZE(netxbig_v2_buttons), +}; + +static struct platform_device netxbig_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &netxbig_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO LEDs + ****************************************************************************/ + +/* + * The LEDs are controlled by a CPLD and can be configured through a GPIO + * extension bus: + * + * - address register : bit [0-2] -> GPIO [47-49] + * - data register : bit [0-2] -> GPIO [44-46] + * - enable register : GPIO 29 + * + * Address register selection: + * + * addr | register + * ---------------------------- + * 0 | front LED + * 1 | front LED brightness + * 2 | HDD LED brightness + * 3 | HDD1 LED + * 4 | HDD2 LED + * 5 | HDD3 LED + * 6 | HDD4 LED + * 7 | HDD5 LED + * + * Data register configuration: + * + * data | LED brightness + * ------------------------------------------------- + * 0 | min (off) + * - | - + * 7 | max + * + * data | front LED mode + * ------------------------------------------------- + * 0 | fix off + * 1 | fix blue on + * 2 | fix red on + * 3 | blink blue on=1 sec and blue off=1 sec + * 4 | blink red on=1 sec and red off=1 sec + * 5 | blink blue on=2.5 sec and red on=0.5 sec + * 6 | blink blue on=1 sec and red on=1 sec + * 7 | blink blue on=0.5 sec and blue off=2.5 sec + * + * data | HDD LED mode + * ------------------------------------------------- + * 0 | fix blue on + * 1 | SATA activity blink + * 2 | fix red on + * 3 | blink blue on=1 sec and blue off=1 sec + * 4 | blink red on=1 sec and red off=1 sec + * 5 | blink blue on=2.5 sec and red on=0.5 sec + * 6 | blink blue on=1 sec and red on=1 sec + * 7 | blink blue on=0.5 sec and blue off=2.5 sec + */ + +/***************************************************************************** + * Timer + ****************************************************************************/ + +static void netxbig_v2_timer_init(void) +{ + kirkwood_tclk = 166666667; + orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); +} + +struct sys_timer netxbig_v2_timer = { + .init = netxbig_v2_timer_init, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int net2big_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW_SDA, + MPP9_TW_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse alarm */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA HDD1 power */ + MPP17_GPIO, /* SATA HDD2 power */ + MPP20_SATA1_ACTn, + MPP21_SATA0_ACTn, + MPP24_GPIO, /* USB mode select */ + MPP26_GPIO, /* USB device vbus */ + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* CPLD extension ALE */ + MPP34_GPIO, /* Rear Push button */ + MPP35_GPIO, /* Inhibit switch power-off */ + MPP36_GPIO, /* SATA HDD1 presence */ + MPP37_GPIO, /* SATA HDD2 presence */ + MPP40_GPIO, /* eSATA presence */ + MPP44_GPIO, /* CPLD extension (data 0) */ + MPP45_GPIO, /* CPLD extension (data 1) */ + MPP46_GPIO, /* CPLD extension (data 2) */ + MPP47_GPIO, /* CPLD extension (addr 0) */ + MPP48_GPIO, /* CPLD extension (addr 1) */ + MPP49_GPIO, /* CPLD extension (addr 2) */ + 0 +}; + +static unsigned int net5big_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW_SDA, + MPP9_TW_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse alarm */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA HDD1 power */ + MPP17_GPIO, /* SATA HDD2 power */ + MPP20_GE1_0, + MPP21_GE1_1, + MPP22_GE1_2, + MPP23_GE1_3, + MPP24_GE1_4, + MPP25_GE1_5, + MPP26_GE1_6, + MPP27_GE1_7, + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* CPLD extension ALE */ + MPP30_GE1_10, + MPP31_GE1_11, + MPP32_GE1_12, + MPP33_GE1_13, + MPP34_GPIO, /* Rear Push button */ + MPP35_GPIO, /* Inhibit switch power-off */ + MPP36_GPIO, /* SATA HDD1 presence */ + MPP37_GPIO, /* SATA HDD2 presence */ + MPP38_GPIO, /* SATA HDD3 presence */ + MPP39_GPIO, /* SATA HDD4 presence */ + MPP40_GPIO, /* SATA HDD5 presence */ + MPP41_GPIO, /* SATA HDD3 power */ + MPP42_GPIO, /* SATA HDD4 power */ + MPP43_GPIO, /* SATA HDD5 power */ + MPP44_GPIO, /* CPLD extension (data 0) */ + MPP45_GPIO, /* CPLD extension (data 1) */ + MPP46_GPIO, /* CPLD extension (data 2) */ + MPP47_GPIO, /* CPLD extension (addr 0) */ + MPP48_GPIO, /* CPLD extension (addr 1) */ + MPP49_GPIO, /* CPLD extension (addr 2) */ + 0 +}; + +#define NETXBIG_V2_GPIO_POWER_OFF 7 + +static void netxbig_v2_power_off(void) +{ + gpio_set_value(NETXBIG_V2_GPIO_POWER_OFF, 1); +} + +static void __init netxbig_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + if (machine_is_net2big_v2()) + kirkwood_mpp_conf(net2big_v2_mpp_config); + else + kirkwood_mpp_conf(net5big_v2_mpp_config); + + netxbig_v2_sata_power_init(); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&netxbig_v2_ge00_data); + if (machine_is_net5big_v2()) + kirkwood_ge01_init(&netxbig_v2_ge01_data); + kirkwood_sata_init(&netxbig_v2_sata_data); + kirkwood_uart0_init(); + spi_register_board_info(netxbig_v2_spi_slave_info, + ARRAY_SIZE(netxbig_v2_spi_slave_info)); + kirkwood_spi_init(); + kirkwood_i2c_init(); + i2c_register_board_info(0, netxbig_v2_i2c_info, + ARRAY_SIZE(netxbig_v2_i2c_info)); + + platform_device_register(&netxbig_v2_gpio_buttons); + + if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(NETXBIG_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = netxbig_v2_power_off; + else + pr_err("netxbig_v2: failed to configure power-off GPIO\n"); +} + +#ifdef CONFIG_MACH_NET2BIG_V2 +MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2") + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = netxbig_v2_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &netxbig_v2_timer, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_NET5BIG_V2 +MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2") + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = netxbig_v2_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &netxbig_v2_timer, +MACHINE_END +#endif -- cgit v1.2.3-59-g8ed1b From d88d95eb1c2a72b6126a550debe0883ff723a948 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sat, 24 Apr 2010 09:56:53 +0200 Subject: x86, k8: Fix build error when K8_NB is disabled K8_NB depends on PCI and when the last is disabled (allnoconfig) we fail at the final linking stage due to missing exported num_k8_northbridges. Add a header stub for that. Signed-off-by: Borislav Petkov LKML-Reference: <20100503183036.GJ26107@aftab> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/k8.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/k8.h b/arch/x86/include/asm/k8.h index f70e60071fe8..af00bd1d2089 100644 --- a/arch/x86/include/asm/k8.h +++ b/arch/x86/include/asm/k8.h @@ -16,11 +16,16 @@ extern int k8_numa_init(unsigned long start_pfn, unsigned long end_pfn); extern int k8_scan_nodes(void); #ifdef CONFIG_K8_NB +extern int num_k8_northbridges; + static inline struct pci_dev *node_to_k8_nb_misc(int node) { return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL; } + #else +#define num_k8_northbridges 0 + static inline struct pci_dev *node_to_k8_nb_misc(int node) { return NULL; -- cgit v1.2.3-59-g8ed1b From 097c1bd5673edaf2a162724636858b71f658fdd2 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 3 May 2010 15:49:31 -0700 Subject: x86, cpu: Make APERF/MPERF a normal table-driven flag APERF/MPERF can be handled via the table like all the other scattered CPU flags. Signed-off-by: H. Peter Anvin Cc: Thomas Renninger Cc: Borislav Petkov LKML-Reference: <1270065406-1814-4-git-send-email-bp@amd64.org> --- arch/x86/kernel/cpu/addon_cpuid_features.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c index fd1fc1902a47..10fa5684a662 100644 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c +++ b/arch/x86/kernel/cpu/addon_cpuid_features.c @@ -30,13 +30,14 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) const struct cpuid_bit *cb; static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { - { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 }, - { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 }, - { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007 }, - { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a }, - { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a }, - { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a }, - { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a }, + { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 }, + { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 }, + { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006 }, + { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007 }, + { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a }, + { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a }, + { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a }, + { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a }, { 0, 0, 0, 0 } }; @@ -54,14 +55,6 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) if (regs[cb->reg] & (1 << cb->bit)) set_cpu_cap(c, cb->feature); } - - /* - * common AMD/Intel features - */ - if (c->cpuid_level >= 6) { - if (cpuid_ecx(6) & 0x1) - set_cpu_cap(c, X86_FEATURE_APERFMPERF); - } } /* leaf 0xb SMT level */ -- cgit v1.2.3-59-g8ed1b From daa494958a59638f32b4334155e4c3e1f664c675 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 12:57:13 -0700 Subject: omap2/3/4: Fix multi.h when omap3 and omap4 are selected without omap2 Otherwise we'll get an error about get_irqnr_and_base being defined twice. Add an entry for omap4, and use ARCH_OMAP3 for omap3 instead of ARCH_OMAP3430. Also fix the check for omap1 to use ARCH_OMAP2PLUS to avoid having to add ARCH_OMAP4 separately there. Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/multi.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/include/plat/multi.h b/arch/arm/plat-omap/include/plat/multi.h index f235d32cd942..ffd909fa5287 100644 --- a/arch/arm/plat-omap/include/plat/multi.h +++ b/arch/arm/plat-omap/include/plat/multi.h @@ -61,9 +61,9 @@ # define OMAP_NAME omap16xx # endif #endif -#if (defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)) +#ifdef CONFIG_ARCH_OMAP2PLUS # if (defined(OMAP_NAME) || defined(MULTI_OMAP1)) -# error "OMAP1 and OMAP2 can't be selected at the same time" +# error "OMAP1 and OMAP2PLUS can't be selected at the same time" # endif #endif #ifdef CONFIG_ARCH_OMAP2420 @@ -82,12 +82,20 @@ # define OMAP_NAME omap2430 # endif #endif -#ifdef CONFIG_ARCH_OMAP3430 +#ifdef CONFIG_ARCH_OMAP3 # ifdef OMAP_NAME # undef MULTI_OMAP2 # define MULTI_OMAP2 # else -# define OMAP_NAME omap3430 +# define OMAP_NAME omap3 +# endif +#endif +#ifdef CONFIG_ARCH_OMAP4 +# ifdef OMAP_NAME +# undef MULTI_OMAP2 +# define MULTI_OMAP2 +# else +# define OMAP_NAME omap4 # endif #endif -- cgit v1.2.3-59-g8ed1b From 96554d70775e936e870f61d9523c9bab3fd54ad6 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 17:39:19 -0700 Subject: omap: Use a memory address for storing the debug port info instead of UART1 scratchpad This removes the dependency to the UART1 being available for storing the debug configuration in uncompress.h. This will simplify the DEBUG_LL UART configuration for boards that may not have UART1, or have an external UART as it requires only one mapping for DEBUG_LL. The patch has a few limitations. Basically now we're assuming that the kernel uncompress code won't overlap with OMAP_UART_INFO. We also assume the printascii is called at least once before paging_init in order for addruart to have a chance to read the UART setup from OMAP_UART_INFO. As suggested by Cyril Chemparathy , Vikram Pandita and Kevin Hilman . Based on an earlier patch posted for Davinci by Cyril Chemparathy . Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/include/mach/debug-macro.S | 21 ++++-------- arch/arm/mach-omap2/include/mach/debug-macro.S | 11 ++++--- arch/arm/plat-omap/include/plat/serial.h | 14 ++++++++ arch/arm/plat-omap/include/plat/uncompress.h | 44 ++++++++++---------------- 4 files changed, 43 insertions(+), 47 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap1/include/mach/debug-macro.S b/arch/arm/mach-omap1/include/mach/debug-macro.S index b6d9584544b4..e8a8cf36b7f0 100644 --- a/arch/arm/mach-omap1/include/mach/debug-macro.S +++ b/arch/arm/mach-omap1/include/mach/debug-macro.S @@ -13,6 +13,8 @@ #include +#include + #include .pushsection .data @@ -37,23 +39,12 @@ omap_uart_virt: .word 0x0 cmp \rx, #0 @ is port configured? bne 99f @ already configured - /* Check 7XX UART1 scratchpad register for uart to use */ + /* Check the debug UART configuration set in uncompress.h */ mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? - moveq \rx, #0xff000000 @ physical base address - movne \rx, #0xfe000000 @ virtual base - orr \rx, \rx, #0x00fb0000 @ OMAP1UART1 - ldrb \rx, [\rx, #(UART_SCR << OMAP7XX_PORT_SHIFT)] - cmp \rx, #0 @ anything in 7XX scratchpad? - bne 10f @ found 7XX uart - - /* Check 15xx/16xx UART1 scratchpad register for uart to use */ - mrc p15, 0, \rx, c1, c0 - tst \rx, #1 @ MMU enabled? - moveq \rx, #0xff000000 @ physical base address - movne \rx, #0xfe000000 @ virtual base - orr \rx, \rx, #0x00fb0000 @ OMAP1UART1 - ldrb \rx, [\rx, #(UART_SCR << OMAP_PORT_SHIFT)] + ldreq \rx, =OMAP_UART_INFO + ldrne \rx, =__phys_to_virt(OMAP_UART_INFO) + ldr \rx, [\rx, #0] /* Select the UART to use based on the UART1 scratchpad value */ 10: cmp \rx, #0 @ no port configured? diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S index 4a63a2ea484d..4976169d9f36 100644 --- a/arch/arm/mach-omap2/include/mach/debug-macro.S +++ b/arch/arm/mach-omap2/include/mach/debug-macro.S @@ -13,6 +13,8 @@ #include +#include + #include #define UART_OFFSET(addr) ((addr) & 0x00ffffff) @@ -40,13 +42,12 @@ omap_uart_lsr: .word 0 cmp \rx, #0 @ is port configured? bne 99f @ already configured - /* Check UART1 scratchpad register for uart to use */ + /* Check the debug UART configuration set in uncompress.h */ mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? - moveq \rx, #0x48000000 @ physical base address - movne \rx, #0xfa000000 @ virtual base - orr \rx, \rx, #0x0006a000 @ uart1 on omap2/3/4 - ldrb \rx, [\rx, #(UART_SCR << OMAP_PORT_SHIFT)] @ scratchpad + ldreq \rx, =OMAP_UART_INFO + ldrne \rx, =__phys_to_virt(OMAP_UART_INFO) + ldr \rx, [\rx, #0] /* Select the UART to use based on the UART1 scratchpad value */ cmp \rx, #0 @ no port configured? diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 83dce4c4f7e6..42a6318dd305 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -15,6 +15,20 @@ #include +/* + * Memory entry used for the DEBUG_LL UART configuration. See also + * uncompress.h and debug-macro.S. + * + * Note that using a memory location for storing the UART configuration + * has at least two limitations: + * + * 1. Kernel uncompress code cannot overlap OMAP_UART_INFO as the + * uncompress code could then partially overwrite itself + * 2. We assume printascii is called at least once before paging_init, + * and addruart has a chance to read OMAP_UART_INFO + */ +#define OMAP_UART_INFO (PHYS_OFFSET + 0x3ffc) + /* OMAP1 serial ports */ #define OMAP1_UART1_BASE 0xfffb0000 #define OMAP1_UART2_BASE 0xfffb0800 diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index 81d9ec540fcf..bbedd71943f6 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -20,27 +20,21 @@ #include #include +#include #include #include -static volatile u8 *uart1_base; -static int uart1_shift; - static volatile u8 *uart_base; static int uart_shift; /* - * Store the DEBUG_LL uart number into UART1 scratchpad register. + * Store the DEBUG_LL uart number into memory. * See also debug-macro.S, and serial.c for related code. - * - * Please note that we currently assume that: - * - UART1 clocks are enabled for register access - * - UART1 scratchpad register can be used */ -static void set_uart1_scratchpad(unsigned char port) +static void set_omap_uart_info(unsigned char port) { - uart1_base[UART_SCR << uart1_shift] = port; + *(volatile u32 *)OMAP_UART_INFO = port; } static void putc(int c) @@ -60,42 +54,38 @@ static inline void flush(void) /* * Macros to configure UART1 and debug UART */ -#define _DEBUG_LL_ENTRY(mach, uart1_phys, uart1_shft, \ - dbg_uart, dbg_shft, dbg_id) \ +#define _DEBUG_LL_ENTRY(mach, dbg_uart, dbg_shft, dbg_id) \ if (machine_is_##mach()) { \ - uart1_base = (volatile u8 *)(uart1_phys); \ - uart1_shift = (uart1_shft); \ uart_base = (volatile u8 *)(dbg_uart); \ uart_shift = (dbg_shft); \ port = (dbg_id); \ - set_uart1_scratchpad(port); \ + set_omap_uart_info(port); \ break; \ } #define DEBUG_LL_OMAP7XX(p, mach) \ - _DEBUG_LL_ENTRY(mach, OMAP1_UART1_BASE, OMAP7XX_PORT_SHIFT, \ - OMAP1_UART##p##_BASE, OMAP7XX_PORT_SHIFT, OMAP1UART##p) + _DEBUG_LL_ENTRY(mach, OMAP1_UART##p##_BASE, OMAP7XX_PORT_SHIFT, \ + OMAP1UART##p) #define DEBUG_LL_OMAP1(p, mach) \ - _DEBUG_LL_ENTRY(mach, OMAP1_UART1_BASE, OMAP_PORT_SHIFT, \ - OMAP1_UART##p##_BASE, OMAP_PORT_SHIFT, OMAP1UART##p) + _DEBUG_LL_ENTRY(mach, OMAP1_UART##p##_BASE, OMAP_PORT_SHIFT, \ + OMAP1UART##p) #define DEBUG_LL_OMAP2(p, mach) \ - _DEBUG_LL_ENTRY(mach, OMAP2_UART1_BASE, OMAP_PORT_SHIFT, \ - OMAP2_UART##p##_BASE, OMAP_PORT_SHIFT, OMAP2UART##p) + _DEBUG_LL_ENTRY(mach, OMAP2_UART##p##_BASE, OMAP_PORT_SHIFT, \ + OMAP2UART##p) #define DEBUG_LL_OMAP3(p, mach) \ - _DEBUG_LL_ENTRY(mach, OMAP3_UART1_BASE, OMAP_PORT_SHIFT, \ - OMAP3_UART##p##_BASE, OMAP_PORT_SHIFT, OMAP3UART##p) + _DEBUG_LL_ENTRY(mach, OMAP3_UART##p##_BASE, OMAP_PORT_SHIFT, \ + OMAP3UART##p) #define DEBUG_LL_OMAP4(p, mach) \ - _DEBUG_LL_ENTRY(mach, OMAP4_UART1_BASE, OMAP_PORT_SHIFT, \ - OMAP4_UART##p##_BASE, OMAP_PORT_SHIFT, OMAP4UART##p) + _DEBUG_LL_ENTRY(mach, OMAP4_UART##p##_BASE, OMAP_PORT_SHIFT, \ + OMAP4UART##p) /* Zoom2/3 shift is different for UART1 and external port */ #define DEBUG_LL_ZOOM(mach) \ - _DEBUG_LL_ENTRY(mach, OMAP2_UART1_BASE, OMAP_PORT_SHIFT, \ - ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART) + _DEBUG_LL_ENTRY(mach, ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART) static inline void __arch_decomp_setup(unsigned long arch_id) { -- cgit v1.2.3-59-g8ed1b From a4f57b81385b7793b83cd5ec9efc24db0bb62404 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 12:57:14 -0700 Subject: omap2/3: Fix DEBUG_LL for omap zoom2/3 Zoom2 and 3 have UARTs only on the external debug board. GPMC needs to be mapped early to use it for DEBUG_LL. Additionally, 0xfb000000 overlaps with other areas, so use 0xfa400000 for the virtual address instead. Note that with the pending serial.c patches you need to set console=ttyS0,115200n8 as it will be the only UART mapped. To use DEBUG_LL, you need to pass also earlyprintk in cmdline. Cc: Allen Pais Acked-by: Vikram Pandita Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-zoom-debugboard.c | 2 +- arch/arm/mach-omap2/board-zoom2.c | 4 ++-- arch/arm/mach-omap2/board-zoom3.c | 4 ++-- arch/arm/mach-omap2/include/mach/debug-macro.S | 4 ++-- arch/arm/mach-omap2/io.c | 9 +++++++++ arch/arm/plat-omap/include/plat/serial.h | 2 +- 6 files changed, 17 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c index e15d2e87cfc1..1d7f827b0408 100644 --- a/arch/arm/mach-omap2/board-zoom-debugboard.c +++ b/arch/arm/mach-omap2/board-zoom-debugboard.c @@ -82,7 +82,7 @@ static inline void __init zoom_init_smsc911x(void) static struct plat_serial8250_port serial_platform_data[] = { { - .mapbase = 0x10000000, + .mapbase = ZOOM_UART_BASE, .irq = OMAP_GPIO_IRQ(102), .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ, .irqflags = IRQF_SHARED | IRQF_TRIGGER_RISING, diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c index 9a26f84b1141..803ef14cbf2d 100644 --- a/arch/arm/mach-omap2/board-zoom2.c +++ b/arch/arm/mach-omap2/board-zoom2.c @@ -91,8 +91,8 @@ static void __init omap_zoom2_map_io(void) } MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board") - .phys_io = 0x48000000, - .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc, + .phys_io = ZOOM_UART_BASE, + .io_pg_offst = (ZOOM_UART_VIRT >> 18) & 0xfffc, .boot_params = 0x80000100, .map_io = omap_zoom2_map_io, .init_irq = omap_zoom2_init_irq, diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c index cd3e40cf3ac1..33147042485f 100644 --- a/arch/arm/mach-omap2/board-zoom3.c +++ b/arch/arm/mach-omap2/board-zoom3.c @@ -73,8 +73,8 @@ static void __init omap_zoom_init(void) } MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board") - .phys_io = 0x48000000, - .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc, + .phys_io = ZOOM_UART_BASE, + .io_pg_offst = (ZOOM_UART_VIRT >> 18) & 0xfffc, .boot_params = 0x80000100, .map_io = omap_zoom_map_io, .init_irq = omap_zoom_init_irq, diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S index 4976169d9f36..35b24409a0c8 100644 --- a/arch/arm/mach-omap2/include/mach/debug-macro.S +++ b/arch/arm/mach-omap2/include/mach/debug-macro.S @@ -88,10 +88,10 @@ omap_uart_lsr: .word 0 b 98f 44: mov \rx, #UART_OFFSET(OMAP4_UART4_BASE) b 98f -95: mov \rx, #ZOOM_UART_BASE +95: ldr \rx, =ZOOM_UART_BASE ldr \tmp, =omap_uart_phys str \rx, [\tmp, #0] - mov \rx, #ZOOM_UART_VIRT + ldr \rx, =ZOOM_UART_VIRT ldr \tmp, =omap_uart_virt str \rx, [\tmp, #0] mov \rx, #(UART_LSR << ZOOM_PORT_SHIFT) diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 87f676acf61d..3cfb425ea67e 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -166,6 +166,15 @@ static struct map_desc omap34xx_io_desc[] __initdata = { .length = L4_EMU_34XX_SIZE, .type = MT_DEVICE }, +#if defined(CONFIG_DEBUG_LL) && \ + (defined(CONFIG_MACH_OMAP_ZOOM2) || defined(CONFIG_MACH_OMAP_ZOOM3)) + { + .virtual = ZOOM_UART_VIRT, + .pfn = __phys_to_pfn(ZOOM_UART_BASE), + .length = SZ_1M, + .type = MT_DEVICE + }, +#endif }; #endif #ifdef CONFIG_ARCH_OMAP4 diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 42a6318dd305..19145f5c32ba 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -53,7 +53,7 @@ /* External port on Zoom2/3 */ #define ZOOM_UART_BASE 0x10000000 -#define ZOOM_UART_VIRT 0xfb000000 +#define ZOOM_UART_VIRT 0xfa400000 #define OMAP_PORT_SHIFT 2 #define OMAP7XX_PORT_SHIFT 0 -- cgit v1.2.3-59-g8ed1b From 8f5a2dd83a1f8e89fdc17eb0f2f07c2e713e635a Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 23 Mar 2010 19:09:51 +0100 Subject: oprofile/x86: rework error handler in nmi_setup() This patch improves the error handler in nmi_setup(). Most parts of the code are moved to allocate_msrs(). In case of an error allocate_msrs() also frees already allocated memory. nmi_setup() becomes easier and better extendable. Signed-off-by: Robert Richter --- arch/x86/oprofile/nmi_int.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 2c505ee71014..c0c21f200faf 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -295,6 +295,7 @@ static void free_msrs(void) kfree(per_cpu(cpu_msrs, i).controls); per_cpu(cpu_msrs, i).controls = NULL; } + nmi_shutdown_mux(); } static int allocate_msrs(void) @@ -307,14 +308,21 @@ static int allocate_msrs(void) per_cpu(cpu_msrs, i).counters = kzalloc(counters_size, GFP_KERNEL); if (!per_cpu(cpu_msrs, i).counters) - return 0; + goto fail; per_cpu(cpu_msrs, i).controls = kzalloc(controls_size, GFP_KERNEL); if (!per_cpu(cpu_msrs, i).controls) - return 0; + goto fail; } + if (!nmi_setup_mux()) + goto fail; + return 1; + +fail: + free_msrs(); + return 0; } static void nmi_cpu_setup(void *dummy) @@ -342,17 +350,7 @@ static int nmi_setup(void) int cpu; if (!allocate_msrs()) - err = -ENOMEM; - else if (!nmi_setup_mux()) - err = -ENOMEM; - else - err = register_die_notifier(&profile_exceptions_nb); - - if (err) { - free_msrs(); - nmi_shutdown_mux(); - return err; - } + return -ENOMEM; /* We need to serialize save and setup for HT because the subset * of msrs are distinct for save and setup operations @@ -374,9 +372,17 @@ static int nmi_setup(void) mux_clone(cpu); } + + err = register_die_notifier(&profile_exceptions_nb); + if (err) + goto fail; + on_each_cpu(nmi_cpu_setup, NULL, 1); nmi_enabled = 1; return 0; +fail: + free_msrs(); + return err; } static void nmi_cpu_restore_registers(struct op_msrs *msrs) @@ -421,7 +427,6 @@ static void nmi_shutdown(void) nmi_enabled = 0; on_each_cpu(nmi_cpu_shutdown, NULL, 1); unregister_die_notifier(&profile_exceptions_nb); - nmi_shutdown_mux(); msrs = &get_cpu_var(cpu_msrs); model->shutdown(msrs); free_msrs(); -- cgit v1.2.3-59-g8ed1b From d0e4120fda6f87eead438eed4d49032e12060e58 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 23 Mar 2010 19:33:21 +0100 Subject: oprofile/x86: reserve counter msrs pairwise For AMD's and Intel's P6 generic performance counters have pairwise counter and control msrs. This patch changes the counter reservation in a way that both msrs must be registered. It joins some counter loops and also removes the unnecessary NUM_CONTROLS macro in the AMD implementation. Signed-off-by: Robert Richter --- arch/x86/oprofile/op_model_amd.c | 43 +++++++++++++++++---------------------- arch/x86/oprofile/op_model_ppro.c | 36 ++++++++++++++++---------------- 2 files changed, 36 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 090cbbec7dbd..2e2bc902b867 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -30,13 +30,10 @@ #include "op_counter.h" #define NUM_COUNTERS 4 -#define NUM_CONTROLS 4 #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX #define NUM_VIRT_COUNTERS 32 -#define NUM_VIRT_CONTROLS 32 #else #define NUM_VIRT_COUNTERS NUM_COUNTERS -#define NUM_VIRT_CONTROLS NUM_CONTROLS #endif #define OP_EVENT_MASK 0x0FFF @@ -134,13 +131,15 @@ static void op_amd_fill_in_addresses(struct op_msrs * const msrs) int i; for (i = 0; i < NUM_COUNTERS; i++) { - if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) - msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; - } - - for (i = 0; i < NUM_CONTROLS; i++) { - if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) - msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; + if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) + continue; + if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) { + release_perfctr_nmi(MSR_K7_PERFCTR0 + i); + continue; + } + /* both registers must be reserved */ + msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; + msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; } } @@ -160,7 +159,7 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, } /* clear all counters */ - for (i = 0; i < NUM_CONTROLS; ++i) { + for (i = 0; i < NUM_COUNTERS; ++i) { if (unlikely(!msrs->controls[i].addr)) { if (counter_config[i].enabled && !smp_processor_id()) /* @@ -175,12 +174,10 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, op_x86_warn_in_use(i); val &= model->reserved; wrmsrl(msrs->controls[i].addr, val); - } - - /* avoid a false detection of ctr overflows in NMI handler */ - for (i = 0; i < NUM_COUNTERS; ++i) { - if (unlikely(!msrs->counters[i].addr)) - continue; + /* + * avoid a false detection of ctr overflows in NMI + * handler + */ wrmsrl(msrs->counters[i].addr, -1LL); } @@ -430,12 +427,10 @@ static void op_amd_shutdown(struct op_msrs const * const msrs) int i; for (i = 0; i < NUM_COUNTERS; ++i) { - if (msrs->counters[i].addr) - release_perfctr_nmi(MSR_K7_PERFCTR0 + i); - } - for (i = 0; i < NUM_CONTROLS; ++i) { - if (msrs->controls[i].addr) - release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); + if (!msrs->counters[i].addr) + continue; + release_perfctr_nmi(MSR_K7_PERFCTR0 + i); + release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); } } @@ -583,7 +578,7 @@ static void op_amd_exit(void) struct op_x86_model_spec op_amd_spec = { .num_counters = NUM_COUNTERS, - .num_controls = NUM_CONTROLS, + .num_controls = NUM_COUNTERS, .num_virt_counters = NUM_VIRT_COUNTERS, .reserved = MSR_AMD_EVENTSEL_RESERVED, .event_mask = OP_EVENT_MASK, diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index 2bf90fafa7b5..f8e268e8e992 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c @@ -35,13 +35,15 @@ static void ppro_fill_in_addresses(struct op_msrs * const msrs) int i; for (i = 0; i < num_counters; i++) { - if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) - msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; - } - - for (i = 0; i < num_counters; i++) { - if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) - msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; + if (!reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) + continue; + if (!reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) { + release_perfctr_nmi(MSR_P6_PERFCTR0 + i); + continue; + } + /* both registers must be reserved */ + msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; + msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; } } @@ -92,12 +94,10 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model, op_x86_warn_in_use(i); val &= model->reserved; wrmsrl(msrs->controls[i].addr, val); - } - - /* avoid a false detection of ctr overflows in NMI handler */ - for (i = 0; i < num_counters; ++i) { - if (unlikely(!msrs->counters[i].addr)) - continue; + /* + * avoid a false detection of ctr overflows in NMI * + * handler + */ wrmsrl(msrs->counters[i].addr, -1LL); } @@ -194,12 +194,10 @@ static void ppro_shutdown(struct op_msrs const * const msrs) int i; for (i = 0; i < num_counters; ++i) { - if (msrs->counters[i].addr) - release_perfctr_nmi(MSR_P6_PERFCTR0 + i); - } - for (i = 0; i < num_counters; ++i) { - if (msrs->controls[i].addr) - release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); + if (!msrs->counters[i].addr) + continue; + release_perfctr_nmi(MSR_P6_PERFCTR0 + i); + release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); } if (reset_value) { kfree(reset_value); -- cgit v1.2.3-59-g8ed1b From 83300ce0df6b72e156b386457aa0f0902b8c0a98 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 23 Mar 2010 20:01:54 +0100 Subject: oprofile/x86: moving shutdown functions Moving some code in preparation of the next patch. Signed-off-by: Robert Richter --- arch/x86/oprofile/op_model_amd.c | 24 ++++++++++++------------ arch/x86/oprofile/op_model_p4.c | 38 ++++++++++++++++++-------------------- arch/x86/oprofile/op_model_ppro.c | 33 ++++++++++++++++----------------- 3 files changed, 46 insertions(+), 49 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 2e2bc902b867..7e5886d54bd5 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -126,6 +126,18 @@ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, /* functions for op_amd_spec */ +static void op_amd_shutdown(struct op_msrs const * const msrs) +{ + int i; + + for (i = 0; i < NUM_COUNTERS; ++i) { + if (!msrs->counters[i].addr) + continue; + release_perfctr_nmi(MSR_K7_PERFCTR0 + i); + release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); + } +} + static void op_amd_fill_in_addresses(struct op_msrs * const msrs) { int i; @@ -422,18 +434,6 @@ static void op_amd_stop(struct op_msrs const * const msrs) op_amd_stop_ibs(); } -static void op_amd_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0; i < NUM_COUNTERS; ++i) { - if (!msrs->counters[i].addr) - continue; - release_perfctr_nmi(MSR_K7_PERFCTR0 + i); - release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); - } -} - static u8 ibs_eilvt_off; static inline void apic_init_ibs_nmi_per_cpu(void *arg) diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index e6a160a4684a..7cc80df330d5 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c @@ -385,6 +385,24 @@ static unsigned int get_stagger(void) static unsigned long reset_value[NUM_COUNTERS_NON_HT]; +static void p4_shutdown(struct op_msrs const * const msrs) +{ + int i; + + for (i = 0; i < num_counters; ++i) { + if (msrs->counters[i].addr) + release_perfctr_nmi(msrs->counters[i].addr); + } + /* + * some of the control registers are specially reserved in + * conjunction with the counter registers (hence the starting offset). + * This saves a few bits. + */ + for (i = num_counters; i < num_controls; ++i) { + if (msrs->controls[i].addr) + release_evntsel_nmi(msrs->controls[i].addr); + } +} static void p4_fill_in_addresses(struct op_msrs * const msrs) { @@ -668,26 +686,6 @@ static void p4_stop(struct op_msrs const * const msrs) } } -static void p4_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0; i < num_counters; ++i) { - if (msrs->counters[i].addr) - release_perfctr_nmi(msrs->counters[i].addr); - } - /* - * some of the control registers are specially reserved in - * conjunction with the counter registers (hence the starting offset). - * This saves a few bits. - */ - for (i = num_counters; i < num_controls; ++i) { - if (msrs->controls[i].addr) - release_evntsel_nmi(msrs->controls[i].addr); - } -} - - #ifdef CONFIG_SMP struct op_x86_model_spec op_p4_ht2_spec = { .num_counters = NUM_COUNTERS_HT2, diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index f8e268e8e992..b07d25a52f02 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c @@ -30,6 +30,22 @@ static int counter_width = 32; static u64 *reset_value; +static void ppro_shutdown(struct op_msrs const * const msrs) +{ + int i; + + for (i = 0; i < num_counters; ++i) { + if (!msrs->counters[i].addr) + continue; + release_perfctr_nmi(MSR_P6_PERFCTR0 + i); + release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); + } + if (reset_value) { + kfree(reset_value); + reset_value = NULL; + } +} + static void ppro_fill_in_addresses(struct op_msrs * const msrs) { int i; @@ -189,23 +205,6 @@ static void ppro_stop(struct op_msrs const * const msrs) } } -static void ppro_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0; i < num_counters; ++i) { - if (!msrs->counters[i].addr) - continue; - release_perfctr_nmi(MSR_P6_PERFCTR0 + i); - release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); - } - if (reset_value) { - kfree(reset_value); - reset_value = NULL; - } -} - - struct op_x86_model_spec op_ppro_spec = { .num_counters = 2, .num_controls = 2, -- cgit v1.2.3-59-g8ed1b From 8617f98c001d00b176422d707e6a67b88bcd7e0d Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Fri, 26 Feb 2010 17:20:55 +0100 Subject: oprofile/x86: return -EBUSY if counters are already reserved In case a counter is already reserved by the watchdog or perf_event subsystem, oprofile ignored this counters silently. This case is handled now and oprofile_setup() now reports an error. Signed-off-by: Robert Richter --- arch/x86/oprofile/nmi_int.c | 5 ++++- arch/x86/oprofile/op_model_amd.c | 24 +++++++++++++----------- arch/x86/oprofile/op_model_p4.c | 14 +++++++++++++- arch/x86/oprofile/op_model_ppro.c | 24 +++++++++++++----------- arch/x86/oprofile/op_x86_model.h | 2 +- 5 files changed, 44 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index c0c21f200faf..9f001d904599 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -357,7 +357,10 @@ static int nmi_setup(void) */ /* Assume saved/restored counters are the same on all CPUs */ - model->fill_in_addresses(&per_cpu(cpu_msrs, 0)); + err = model->fill_in_addresses(&per_cpu(cpu_msrs, 0)); + if (err) + goto fail; + for_each_possible_cpu(cpu) { if (!cpu) continue; diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 7e5886d54bd5..536d0b0b39a5 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -138,21 +138,30 @@ static void op_amd_shutdown(struct op_msrs const * const msrs) } } -static void op_amd_fill_in_addresses(struct op_msrs * const msrs) +static int op_amd_fill_in_addresses(struct op_msrs * const msrs) { int i; for (i = 0; i < NUM_COUNTERS; i++) { if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) - continue; + goto fail; if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) { release_perfctr_nmi(MSR_K7_PERFCTR0 + i); - continue; + goto fail; } /* both registers must be reserved */ msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; + continue; + fail: + if (!counter_config[i].enabled) + continue; + op_x86_warn_reserved(i); + op_amd_shutdown(msrs); + return -EBUSY; } + + return 0; } static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, @@ -172,15 +181,8 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, /* clear all counters */ for (i = 0; i < NUM_COUNTERS; ++i) { - if (unlikely(!msrs->controls[i].addr)) { - if (counter_config[i].enabled && !smp_processor_id()) - /* - * counter is reserved, this is on all - * cpus, so report only for cpu #0 - */ - op_x86_warn_reserved(i); + if (!msrs->controls[i].addr) continue; - } rdmsrl(msrs->controls[i].addr, val); if (val & ARCH_PERFMON_EVENTSEL_ENABLE) op_x86_warn_in_use(i); diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index 7cc80df330d5..182558dd5515 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c @@ -404,7 +404,7 @@ static void p4_shutdown(struct op_msrs const * const msrs) } } -static void p4_fill_in_addresses(struct op_msrs * const msrs) +static int p4_fill_in_addresses(struct op_msrs * const msrs) { unsigned int i; unsigned int addr, cccraddr, stag; @@ -486,6 +486,18 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs) msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; } } + + for (i = 0; i < num_counters; ++i) { + if (!counter_config[i].enabled) + continue; + if (msrs->controls[i].addr) + continue; + op_x86_warn_reserved(i); + p4_shutdown(msrs); + return -EBUSY; + } + + return 0; } diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index b07d25a52f02..1fd17cfb956b 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c @@ -46,21 +46,30 @@ static void ppro_shutdown(struct op_msrs const * const msrs) } } -static void ppro_fill_in_addresses(struct op_msrs * const msrs) +static int ppro_fill_in_addresses(struct op_msrs * const msrs) { int i; for (i = 0; i < num_counters; i++) { if (!reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) - continue; + goto fail; if (!reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) { release_perfctr_nmi(MSR_P6_PERFCTR0 + i); - continue; + goto fail; } /* both registers must be reserved */ msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; + continue; + fail: + if (!counter_config[i].enabled) + continue; + op_x86_warn_reserved(i); + ppro_shutdown(msrs); + return -EBUSY; } + + return 0; } @@ -96,15 +105,8 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model, /* clear all counters */ for (i = 0; i < num_counters; ++i) { - if (unlikely(!msrs->controls[i].addr)) { - if (counter_config[i].enabled && !smp_processor_id()) - /* - * counter is reserved, this is on all - * cpus, so report only for cpu #0 - */ - op_x86_warn_reserved(i); + if (!msrs->controls[i].addr) continue; - } rdmsrl(msrs->controls[i].addr, val); if (val & ARCH_PERFMON_EVENTSEL_ENABLE) op_x86_warn_in_use(i); diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h index ff82a755edd4..551401398fba 100644 --- a/arch/x86/oprofile/op_x86_model.h +++ b/arch/x86/oprofile/op_x86_model.h @@ -41,7 +41,7 @@ struct op_x86_model_spec { u16 event_mask; int (*init)(struct oprofile_operations *ops); void (*exit)(void); - void (*fill_in_addresses)(struct op_msrs * const msrs); + int (*fill_in_addresses)(struct op_msrs * const msrs); void (*setup_ctrs)(struct op_x86_model_spec const *model, struct op_msrs const * const msrs); int (*check_ctrs)(struct pt_regs * const regs, -- cgit v1.2.3-59-g8ed1b From da759fe5be24ec3b236a76c007b460cf6caf2009 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Fri, 26 Feb 2010 10:54:56 +0100 Subject: oprofile/x86: move IBS code Moving code to make future changes easier. This groups all IBS code together. Signed-off-by: Robert Richter --- arch/x86/oprofile/op_model_amd.c | 220 +++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 110 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 536d0b0b39a5..e159254fb7cd 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -102,116 +102,6 @@ static u32 get_ibs_caps(void) return ibs_caps; } -#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX - -static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, - struct op_msrs const * const msrs) -{ - u64 val; - int i; - - /* enable active counters */ - for (i = 0; i < NUM_COUNTERS; ++i) { - int virt = op_x86_phys_to_virt(i); - if (!reset_value[virt]) - continue; - rdmsrl(msrs->controls[i].addr, val); - val &= model->reserved; - val |= op_x86_get_ctrl(model, &counter_config[virt]); - wrmsrl(msrs->controls[i].addr, val); - } -} - -#endif - -/* functions for op_amd_spec */ - -static void op_amd_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0; i < NUM_COUNTERS; ++i) { - if (!msrs->counters[i].addr) - continue; - release_perfctr_nmi(MSR_K7_PERFCTR0 + i); - release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); - } -} - -static int op_amd_fill_in_addresses(struct op_msrs * const msrs) -{ - int i; - - for (i = 0; i < NUM_COUNTERS; i++) { - if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) - goto fail; - if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) { - release_perfctr_nmi(MSR_K7_PERFCTR0 + i); - goto fail; - } - /* both registers must be reserved */ - msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; - msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; - continue; - fail: - if (!counter_config[i].enabled) - continue; - op_x86_warn_reserved(i); - op_amd_shutdown(msrs); - return -EBUSY; - } - - return 0; -} - -static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, - struct op_msrs const * const msrs) -{ - u64 val; - int i; - - /* setup reset_value */ - for (i = 0; i < NUM_VIRT_COUNTERS; ++i) { - if (counter_config[i].enabled - && msrs->counters[op_x86_virt_to_phys(i)].addr) - reset_value[i] = counter_config[i].count; - else - reset_value[i] = 0; - } - - /* clear all counters */ - for (i = 0; i < NUM_COUNTERS; ++i) { - if (!msrs->controls[i].addr) - continue; - rdmsrl(msrs->controls[i].addr, val); - if (val & ARCH_PERFMON_EVENTSEL_ENABLE) - op_x86_warn_in_use(i); - val &= model->reserved; - wrmsrl(msrs->controls[i].addr, val); - /* - * avoid a false detection of ctr overflows in NMI - * handler - */ - wrmsrl(msrs->counters[i].addr, -1LL); - } - - /* enable active counters */ - for (i = 0; i < NUM_COUNTERS; ++i) { - int virt = op_x86_phys_to_virt(i); - if (!reset_value[virt]) - continue; - - /* setup counter registers */ - wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]); - - /* setup control registers */ - rdmsrl(msrs->controls[i].addr, val); - val &= model->reserved; - val |= op_x86_get_ctrl(model, &counter_config[virt]); - wrmsrl(msrs->controls[i].addr, val); - } -} - /* * 16-bit Linear Feedback Shift Register (LFSR) * @@ -376,6 +266,116 @@ static void op_amd_stop_ibs(void) wrmsrl(MSR_AMD64_IBSOPCTL, 0); } +#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX + +static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, + struct op_msrs const * const msrs) +{ + u64 val; + int i; + + /* enable active counters */ + for (i = 0; i < NUM_COUNTERS; ++i) { + int virt = op_x86_phys_to_virt(i); + if (!reset_value[virt]) + continue; + rdmsrl(msrs->controls[i].addr, val); + val &= model->reserved; + val |= op_x86_get_ctrl(model, &counter_config[virt]); + wrmsrl(msrs->controls[i].addr, val); + } +} + +#endif + +/* functions for op_amd_spec */ + +static void op_amd_shutdown(struct op_msrs const * const msrs) +{ + int i; + + for (i = 0; i < NUM_COUNTERS; ++i) { + if (!msrs->counters[i].addr) + continue; + release_perfctr_nmi(MSR_K7_PERFCTR0 + i); + release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); + } +} + +static int op_amd_fill_in_addresses(struct op_msrs * const msrs) +{ + int i; + + for (i = 0; i < NUM_COUNTERS; i++) { + if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) + goto fail; + if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) { + release_perfctr_nmi(MSR_K7_PERFCTR0 + i); + goto fail; + } + /* both registers must be reserved */ + msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; + msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; + continue; + fail: + if (!counter_config[i].enabled) + continue; + op_x86_warn_reserved(i); + op_amd_shutdown(msrs); + return -EBUSY; + } + + return 0; +} + +static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, + struct op_msrs const * const msrs) +{ + u64 val; + int i; + + /* setup reset_value */ + for (i = 0; i < NUM_VIRT_COUNTERS; ++i) { + if (counter_config[i].enabled + && msrs->counters[op_x86_virt_to_phys(i)].addr) + reset_value[i] = counter_config[i].count; + else + reset_value[i] = 0; + } + + /* clear all counters */ + for (i = 0; i < NUM_COUNTERS; ++i) { + if (!msrs->controls[i].addr) + continue; + rdmsrl(msrs->controls[i].addr, val); + if (val & ARCH_PERFMON_EVENTSEL_ENABLE) + op_x86_warn_in_use(i); + val &= model->reserved; + wrmsrl(msrs->controls[i].addr, val); + /* + * avoid a false detection of ctr overflows in NMI + * handler + */ + wrmsrl(msrs->counters[i].addr, -1LL); + } + + /* enable active counters */ + for (i = 0; i < NUM_COUNTERS; ++i) { + int virt = op_x86_phys_to_virt(i); + if (!reset_value[virt]) + continue; + + /* setup counter registers */ + wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]); + + /* setup control registers */ + rdmsrl(msrs->controls[i].addr, val); + val &= model->reserved; + val |= op_x86_get_ctrl(model, &counter_config[virt]); + wrmsrl(msrs->controls[i].addr, val); + } +} + static int op_amd_check_ctrs(struct pt_regs * const regs, struct op_msrs const * const msrs) { -- cgit v1.2.3-59-g8ed1b From 5bdb7934ca4115a12c7d585c5a45312b1c36909b Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 31 Mar 2010 11:58:36 +0200 Subject: oprofile/x86: remove duplicate IBS capability check The check is already done in ibs_exit(). Signed-off-by: Robert Richter --- arch/x86/oprofile/op_model_amd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index e159254fb7cd..384c52410480 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -490,8 +490,7 @@ static int init_ibs_nmi(void) /* uninitialize the APIC for the IBS interrupts if needed */ static void clear_ibs_nmi(void) { - if (ibs_caps) - on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1); + on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1); } /* initialize the APIC for the IBS interrupts if available */ -- cgit v1.2.3-59-g8ed1b From 2623a1d55a6260c855e1f6d1895900b50b40a896 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 3 May 2010 19:44:32 +0200 Subject: oprofile/x86: fix uninitialized counter usage during cpu hotplug This fixes a NULL pointer dereference that is triggered when taking a cpu offline after oprofile was initialized, e.g.: $ opcontrol --init $ opcontrol --start-daemon $ opcontrol --shutdown $ opcontrol --deinit $ echo 0 > /sys/devices/system/cpu/cpu1/online See the crash dump below. Though the counter has been disabled the cpu notifier is still active and trying to use already freed counter data. This fix is for linux-stable. To proper fix this, the hotplug code must be rewritten. Thus I will leave a WARN_ON_ONCE() message with this patch. BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] op_amd_stop+0x2d/0x8e PGD 0 Oops: 0000 [#1] SMP last sysfs file: /sys/devices/system/cpu/cpu1/online CPU 1 Modules linked in: Pid: 0, comm: swapper Not tainted 2.6.34-rc5-oprofile-x86_64-standard-00210-g8c00f06 #16 Anaheim/Anaheim RIP: 0010:[] [] op_amd_stop+0x2d/0x8e RSP: 0018:ffff880001843f28 EFLAGS: 00010006 RAX: 0000000000000000 RBX: 0000000000000000 RCX: dead000000200200 RDX: ffff880001843f68 RSI: dead000000100100 RDI: 0000000000000000 RBP: ffff880001843f48 R08: 0000000000000000 R09: ffff880001843f08 R10: ffffffff8102c9a5 R11: ffff88000184ea80 R12: 0000000000000000 R13: ffff88000184f6c0 R14: 0000000000000000 R15: 0000000000000000 FS: 00007fec6a92e6f0(0000) GS:ffff880001840000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000000 CR3: 000000000163b000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process swapper (pid: 0, threadinfo ffff88042fcd8000, task ffff88042fcd51d0) Stack: ffff880001843f48 0000000000000001 ffff88042e9f7d38 ffff880001843f68 <0> ffff880001843f58 ffffffff8132a602 ffff880001843f98 ffffffff810521b3 <0> ffff880001843f68 ffff880001843f68 ffff880001843f88 ffff88042fcd9fd8 Call Trace: [] nmi_cpu_stop+0x21/0x23 [] generic_smp_call_function_single_interrupt+0xdf/0x11b [] smp_call_function_single_interrupt+0x22/0x31 [] call_function_single_interrupt+0x13/0x20 [] ? wake_up_process+0x10/0x12 [] ? default_idle+0x22/0x37 [] c1e_idle+0xdf/0xe6 [] ? atomic_notifier_call_chain+0x13/0x15 [] cpu_idle+0x4b/0x7e [] start_secondary+0x1ae/0x1b2 Code: 89 e5 41 55 49 89 fd 41 54 45 31 e4 53 31 db 48 83 ec 08 89 df e8 be f8 ff ff 48 98 48 83 3c c5 10 67 7a 81 00 74 1f 49 8b 45 08 <42> 8b 0c 20 0f 32 48 c1 e2 20 25 ff ff bf ff 48 09 d0 48 89 c2 RIP [] op_amd_stop+0x2d/0x8e RSP CR2: 0000000000000000 ---[ end trace 679ac372d674b757 ]--- Kernel panic - not syncing: Fatal exception in interrupt Pid: 0, comm: swapper Tainted: G D 2.6.34-rc5-oprofile-x86_64-standard-00210-g8c00f06 #16 Call Trace: [] panic+0x9e/0x10c [] ? up+0x34/0x39 [] ? kmsg_dump+0x112/0x12c [] oops_end+0x81/0x8e [] no_context+0x1f3/0x202 [] __bad_area_nosemaphore+0x1ba/0x1e0 [] ? enqueue_task_fair+0x16d/0x17a [] ? activate_task+0x42/0x53 [] ? try_to_wake_up+0x272/0x284 [] bad_area_nosemaphore+0xe/0x10 [] do_page_fault+0x1c8/0x37c [] ? enqueue_task_fair+0x16d/0x17a [] page_fault+0x1f/0x30 [] ? wake_up_process+0x10/0x12 [] ? op_amd_stop+0x2d/0x8e [] ? op_amd_stop+0x1c/0x8e [] nmi_cpu_stop+0x21/0x23 [] generic_smp_call_function_single_interrupt+0xdf/0x11b [] smp_call_function_single_interrupt+0x22/0x31 [] call_function_single_interrupt+0x13/0x20 [] ? wake_up_process+0x10/0x12 [] ? default_idle+0x22/0x37 [] c1e_idle+0xdf/0xe6 [] ? atomic_notifier_call_chain+0x13/0x15 [] cpu_idle+0x4b/0x7e [] start_secondary+0x1ae/0x1b2 ------------[ cut here ]------------ WARNING: at /local/rrichter/.source/linux/arch/x86/kernel/smp.c:118 native_smp_send_reschedule+0x27/0x53() Hardware name: Anaheim Modules linked in: Pid: 0, comm: swapper Tainted: G D 2.6.34-rc5-oprofile-x86_64-standard-00210-g8c00f06 #16 Call Trace: [] ? native_smp_send_reschedule+0x27/0x53 [] warn_slowpath_common+0x77/0xa4 [] warn_slowpath_null+0xf/0x11 [] native_smp_send_reschedule+0x27/0x53 [] resched_task+0x60/0x62 [] check_preempt_curr_idle+0x10/0x12 [] try_to_wake_up+0x1f5/0x284 [] default_wake_function+0xd/0xf [] pollwake+0x57/0x5a [] ? default_wake_function+0x0/0xf [] __wake_up_common+0x46/0x75 [] __wake_up+0x38/0x50 [] printk_tick+0x39/0x3b [] update_process_times+0x3f/0x5c [] tick_periodic+0x5d/0x69 [] tick_handle_periodic+0x21/0x71 [] smp_apic_timer_interrupt+0x82/0x95 [] apic_timer_interrupt+0x13/0x20 [] ? panic_blink_one_second+0x0/0x7b [] ? panic+0x10a/0x10c [] ? up+0x34/0x39 [] ? kmsg_dump+0x112/0x12c [] ? oops_end+0x81/0x8e [] ? no_context+0x1f3/0x202 [] ? __bad_area_nosemaphore+0x1ba/0x1e0 [] ? enqueue_task_fair+0x16d/0x17a [] ? activate_task+0x42/0x53 [] ? try_to_wake_up+0x272/0x284 [] ? bad_area_nosemaphore+0xe/0x10 [] ? do_page_fault+0x1c8/0x37c [] ? enqueue_task_fair+0x16d/0x17a [] ? page_fault+0x1f/0x30 [] ? wake_up_process+0x10/0x12 [] ? op_amd_stop+0x2d/0x8e [] ? op_amd_stop+0x1c/0x8e [] ? nmi_cpu_stop+0x21/0x23 [] ? generic_smp_call_function_single_interrupt+0xdf/0x11b [] ? smp_call_function_single_interrupt+0x22/0x31 [] ? call_function_single_interrupt+0x13/0x20 [] ? wake_up_process+0x10/0x12 [] ? default_idle+0x22/0x37 [] ? c1e_idle+0xdf/0xe6 [] ? atomic_notifier_call_chain+0x13/0x15 [] ? cpu_idle+0x4b/0x7e [] ? start_secondary+0x1ae/0x1b2 ---[ end trace 679ac372d674b758 ]--- Cc: Andi Kleen Cc: stable Signed-off-by: Robert Richter --- arch/x86/oprofile/nmi_int.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 9f001d904599..24582040b718 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -95,7 +95,10 @@ static void nmi_cpu_save_registers(struct op_msrs *msrs) static void nmi_cpu_start(void *dummy) { struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs); - model->start(msrs); + if (!msrs->controls) + WARN_ON_ONCE(1); + else + model->start(msrs); } static int nmi_start(void) @@ -107,7 +110,10 @@ static int nmi_start(void) static void nmi_cpu_stop(void *dummy) { struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs); - model->stop(msrs); + if (!msrs->controls) + WARN_ON_ONCE(1); + else + model->stop(msrs); } static void nmi_stop(void) -- cgit v1.2.3-59-g8ed1b From 216f3d9b4e5121feea4b13fae9d4c83e8d7e1c8a Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 3 May 2010 11:58:46 +0200 Subject: oprofile/x86: remove CONFIG_SMP macros CPU notifier register functions also exist if CONFIG_SMP is disabled. This change is part of hotplug code rework and also necessary for later patches. Cc: Andi Kleen Signed-off-by: Robert Richter --- arch/x86/oprofile/nmi_int.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 24582040b718..c5df8ee76ee4 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -471,7 +471,6 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root) return 0; } -#ifdef CONFIG_SMP static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action, void *data) { @@ -491,7 +490,6 @@ static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action, static struct notifier_block oprofile_cpu_nb = { .notifier_call = oprofile_cpu_notifier }; -#endif #ifdef CONFIG_PM @@ -701,9 +699,8 @@ int __init op_nmi_init(struct oprofile_operations *ops) return -ENODEV; } -#ifdef CONFIG_SMP register_cpu_notifier(&oprofile_cpu_nb); -#endif + /* default values, can be overwritten by model */ ops->create_files = nmi_create_files; ops->setup = nmi_setup; @@ -732,9 +729,7 @@ void op_nmi_exit(void) { if (using_nmi) { exit_sysfs(); -#ifdef CONFIG_SMP unregister_cpu_notifier(&oprofile_cpu_nb); -#endif } if (model->exit) model->exit(); -- cgit v1.2.3-59-g8ed1b From 6ae56b55bc364bc2f2342f599b46581627ba22da Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Thu, 29 Apr 2010 14:55:55 +0200 Subject: oprofile/x86: protect cpu hotplug sections This patch reworks oprofile cpu hotplug code as follows: Introduce ctr_running variable to check, if counters are running or not. The state must be known for taking a cpu on or offline and when switching counters during counter multiplexing. Protect on_each_cpu() sections with get_online_cpus()/put_online_cpu() functions. This is necessary if notifiers or states are modified. Within these sections the cpu mask may not change. Switch only between counters in nmi_cpu_switch(), if counters are running. Otherwise the switch may restart a counter though they are disabled. Add nmi_cpu_setup() and nmi_cpu_shutdown() to cpu hotplug code. The function must also be called to avoid uninitialzed counter usage. Cc: Andi Kleen Signed-off-by: Robert Richter --- arch/x86/oprofile/nmi_int.c | 52 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index c5df8ee76ee4..b56601eaf29d 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -31,8 +31,9 @@ static struct op_x86_model_spec *model; static DEFINE_PER_CPU(struct op_msrs, cpu_msrs); static DEFINE_PER_CPU(unsigned long, saved_lvtpc); -/* 0 == registered but off, 1 == registered and on */ -static int nmi_enabled = 0; +/* must be protected with get_online_cpus()/put_online_cpus(): */ +static int nmi_enabled; +static int ctr_running; struct op_counter_config counter_config[OP_MAX_COUNTER]; @@ -103,7 +104,10 @@ static void nmi_cpu_start(void *dummy) static int nmi_start(void) { + get_online_cpus(); on_each_cpu(nmi_cpu_start, NULL, 1); + ctr_running = 1; + put_online_cpus(); return 0; } @@ -118,7 +122,10 @@ static void nmi_cpu_stop(void *dummy) static void nmi_stop(void) { + get_online_cpus(); on_each_cpu(nmi_cpu_stop, NULL, 1); + ctr_running = 0; + put_online_cpus(); } #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX @@ -258,7 +265,10 @@ static int nmi_switch_event(void) if (nmi_multiplex_on() < 0) return -EINVAL; /* not necessary */ - on_each_cpu(nmi_cpu_switch, NULL, 1); + get_online_cpus(); + if (ctr_running) + on_each_cpu(nmi_cpu_switch, NULL, 1); + put_online_cpus(); return 0; } @@ -386,8 +396,11 @@ static int nmi_setup(void) if (err) goto fail; + get_online_cpus(); on_each_cpu(nmi_cpu_setup, NULL, 1); nmi_enabled = 1; + put_online_cpus(); + return 0; fail: free_msrs(); @@ -433,8 +446,11 @@ static void nmi_shutdown(void) { struct op_msrs *msrs; - nmi_enabled = 0; + get_online_cpus(); on_each_cpu(nmi_cpu_shutdown, NULL, 1); + nmi_enabled = 0; + ctr_running = 0; + put_online_cpus(); unregister_die_notifier(&profile_exceptions_nb); msrs = &get_cpu_var(cpu_msrs); model->shutdown(msrs); @@ -442,6 +458,22 @@ static void nmi_shutdown(void) put_cpu_var(cpu_msrs); } +static void nmi_cpu_up(void *dummy) +{ + if (nmi_enabled) + nmi_cpu_setup(dummy); + if (ctr_running) + nmi_cpu_start(dummy); +} + +static void nmi_cpu_down(void *dummy) +{ + if (ctr_running) + nmi_cpu_stop(dummy); + if (nmi_enabled) + nmi_cpu_shutdown(dummy); +} + static int nmi_create_files(struct super_block *sb, struct dentry *root) { unsigned int i; @@ -478,10 +510,10 @@ static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action, switch (action) { case CPU_DOWN_FAILED: case CPU_ONLINE: - smp_call_function_single(cpu, nmi_cpu_start, NULL, 0); + smp_call_function_single(cpu, nmi_cpu_up, NULL, 0); break; case CPU_DOWN_PREPARE: - smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1); + smp_call_function_single(cpu, nmi_cpu_down, NULL, 1); break; } return NOTIFY_DONE; @@ -699,7 +731,11 @@ int __init op_nmi_init(struct oprofile_operations *ops) return -ENODEV; } + get_online_cpus(); register_cpu_notifier(&oprofile_cpu_nb); + nmi_enabled = 0; + ctr_running = 0; + put_online_cpus(); /* default values, can be overwritten by model */ ops->create_files = nmi_create_files; @@ -729,7 +765,11 @@ void op_nmi_exit(void) { if (using_nmi) { exit_sysfs(); + get_online_cpus(); unregister_cpu_notifier(&oprofile_cpu_nb); + nmi_enabled = 0; + ctr_running = 0; + put_online_cpus(); } if (model->exit) model->exit(); -- cgit v1.2.3-59-g8ed1b From de654649737696ecf32873c341b305e30f3dc777 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 3 May 2010 14:41:22 +0200 Subject: oprofile/x86: stop disabled counters in nmi handler This patch adds checks to the nmi handler. Now samples are only generated and counters reenabled, if the counters are running. Otherwise the counters are stopped, if oprofile is using the nmi. In other cases it will ignore the nmi notification. Cc: Andi Kleen Signed-off-by: Robert Richter --- arch/x86/oprofile/nmi_int.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index b56601eaf29d..94b5481bb6c6 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -62,12 +62,16 @@ static int profile_exceptions_notify(struct notifier_block *self, { struct die_args *args = (struct die_args *)data; int ret = NOTIFY_DONE; - int cpu = smp_processor_id(); switch (val) { case DIE_NMI: case DIE_NMI_IPI: - model->check_ctrs(args->regs, &per_cpu(cpu_msrs, cpu)); + if (ctr_running) + model->check_ctrs(args->regs, &__get_cpu_var(cpu_msrs)); + else if (!nmi_enabled) + break; + else + model->stop(&__get_cpu_var(cpu_msrs)); ret = NOTIFY_STOP; break; default: @@ -392,6 +396,9 @@ static int nmi_setup(void) mux_clone(cpu); } + nmi_enabled = 0; + ctr_running = 0; + barrier(); err = register_die_notifier(&profile_exceptions_nb); if (err) goto fail; @@ -451,6 +458,7 @@ static void nmi_shutdown(void) nmi_enabled = 0; ctr_running = 0; put_online_cpus(); + barrier(); unregister_die_notifier(&profile_exceptions_nb); msrs = &get_cpu_var(cpu_msrs); model->shutdown(msrs); -- cgit v1.2.3-59-g8ed1b From d30d64c6da3ec7a0708bfffa7e05752d5b9a1093 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 3 May 2010 15:52:26 +0200 Subject: oprofile/x86: reordering some functions Reordering some functions. Necessary for the next patch. No functional changes. Cc: Andi Kleen Signed-off-by: Robert Richter --- arch/x86/oprofile/nmi_int.c | 134 ++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 67 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 94b5481bb6c6..7de0572b0a5e 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -364,56 +364,6 @@ static struct notifier_block profile_exceptions_nb = { .priority = 2 }; -static int nmi_setup(void) -{ - int err = 0; - int cpu; - - if (!allocate_msrs()) - return -ENOMEM; - - /* We need to serialize save and setup for HT because the subset - * of msrs are distinct for save and setup operations - */ - - /* Assume saved/restored counters are the same on all CPUs */ - err = model->fill_in_addresses(&per_cpu(cpu_msrs, 0)); - if (err) - goto fail; - - for_each_possible_cpu(cpu) { - if (!cpu) - continue; - - memcpy(per_cpu(cpu_msrs, cpu).counters, - per_cpu(cpu_msrs, 0).counters, - sizeof(struct op_msr) * model->num_counters); - - memcpy(per_cpu(cpu_msrs, cpu).controls, - per_cpu(cpu_msrs, 0).controls, - sizeof(struct op_msr) * model->num_controls); - - mux_clone(cpu); - } - - nmi_enabled = 0; - ctr_running = 0; - barrier(); - err = register_die_notifier(&profile_exceptions_nb); - if (err) - goto fail; - - get_online_cpus(); - on_each_cpu(nmi_cpu_setup, NULL, 1); - nmi_enabled = 1; - put_online_cpus(); - - return 0; -fail: - free_msrs(); - return err; -} - static void nmi_cpu_restore_registers(struct op_msrs *msrs) { struct op_msr *counters = msrs->counters; @@ -449,23 +399,6 @@ static void nmi_cpu_shutdown(void *dummy) nmi_cpu_restore_registers(msrs); } -static void nmi_shutdown(void) -{ - struct op_msrs *msrs; - - get_online_cpus(); - on_each_cpu(nmi_cpu_shutdown, NULL, 1); - nmi_enabled = 0; - ctr_running = 0; - put_online_cpus(); - barrier(); - unregister_die_notifier(&profile_exceptions_nb); - msrs = &get_cpu_var(cpu_msrs); - model->shutdown(msrs); - free_msrs(); - put_cpu_var(cpu_msrs); -} - static void nmi_cpu_up(void *dummy) { if (nmi_enabled) @@ -531,6 +464,73 @@ static struct notifier_block oprofile_cpu_nb = { .notifier_call = oprofile_cpu_notifier }; +static int nmi_setup(void) +{ + int err = 0; + int cpu; + + if (!allocate_msrs()) + return -ENOMEM; + + /* We need to serialize save and setup for HT because the subset + * of msrs are distinct for save and setup operations + */ + + /* Assume saved/restored counters are the same on all CPUs */ + err = model->fill_in_addresses(&per_cpu(cpu_msrs, 0)); + if (err) + goto fail; + + for_each_possible_cpu(cpu) { + if (!cpu) + continue; + + memcpy(per_cpu(cpu_msrs, cpu).counters, + per_cpu(cpu_msrs, 0).counters, + sizeof(struct op_msr) * model->num_counters); + + memcpy(per_cpu(cpu_msrs, cpu).controls, + per_cpu(cpu_msrs, 0).controls, + sizeof(struct op_msr) * model->num_controls); + + mux_clone(cpu); + } + + nmi_enabled = 0; + ctr_running = 0; + barrier(); + err = register_die_notifier(&profile_exceptions_nb); + if (err) + goto fail; + + get_online_cpus(); + on_each_cpu(nmi_cpu_setup, NULL, 1); + nmi_enabled = 1; + put_online_cpus(); + + return 0; +fail: + free_msrs(); + return err; +} + +static void nmi_shutdown(void) +{ + struct op_msrs *msrs; + + get_online_cpus(); + on_each_cpu(nmi_cpu_shutdown, NULL, 1); + nmi_enabled = 0; + ctr_running = 0; + put_online_cpus(); + barrier(); + unregister_die_notifier(&profile_exceptions_nb); + msrs = &get_cpu_var(cpu_msrs); + model->shutdown(msrs); + free_msrs(); + put_cpu_var(cpu_msrs); +} + #ifdef CONFIG_PM static int nmi_suspend(struct sys_device *dev, pm_message_t state) -- cgit v1.2.3-59-g8ed1b From 4c18e77f718cdda33363132127db4df795eadbd9 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Mon, 3 May 2010 09:24:30 +0100 Subject: ARM: 6091/1: ST SPEAr: Adding support for shared irq layer Multiple peripherals in SPEAr share common hardware interrupt lines. This patch adds support for a shared irq layer, which registers hardware irqs by itself and exposes virtual irq numbers to peripherals. Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/mach-spear3xx/include/mach/irqs.h | 101 +++++++++++++++-- arch/arm/mach-spear3xx/include/mach/spear300.h | 16 +++ arch/arm/mach-spear3xx/include/mach/spear310.h | 24 ++++ arch/arm/mach-spear3xx/include/mach/spear320.h | 26 +++++ arch/arm/mach-spear3xx/spear300.c | 67 ++++++++++- arch/arm/mach-spear3xx/spear310.c | 148 ++++++++++++++++++++++++ arch/arm/mach-spear3xx/spear320.c | 150 +++++++++++++++++++++++++ arch/arm/mach-spear6xx/include/mach/irqs.h | 1 + arch/arm/plat-spear/Makefile | 2 + arch/arm/plat-spear/include/plat/shirq.h | 73 ++++++++++++ arch/arm/plat-spear/shirq.c | 118 +++++++++++++++++++ 11 files changed, 718 insertions(+), 8 deletions(-) create mode 100644 arch/arm/plat-spear/include/plat/shirq.h create mode 100644 arch/arm/plat-spear/shirq.c (limited to 'arch') diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h index fe980e07b6ab..7f940b818473 100644 --- a/arch/arm/mach-spear3xx/include/mach/irqs.h +++ b/arch/arm/mach-spear3xx/include/mach/irqs.h @@ -14,7 +14,7 @@ #ifndef __MACH_IRQS_H #define __MACH_IRQS_H -/* IRQ definitions */ +/* SPEAr3xx IRQ definitions */ #define IRQ_HW_ACCEL_MOD_0 0 #define IRQ_INTRCOMM_RAS_ARM 1 #define IRQ_CPU_GPT1_1 2 @@ -50,16 +50,103 @@ #define IRQ_HW_ACCEL_MOD_1 31 #define IRQ_VIC_END 32 -#define SPEAR_GPIO_INT_BASE IRQ_VIC_END +#define VIRQ_START IRQ_VIC_END +/* SPEAr300 Virtual irq definitions */ #ifdef CONFIG_MACH_SPEAR300 -#define SPEAR_GPIO1_INT_BASE (SPEAR_GPIO_INT_BASE + 8) -#define SPEAR_GPIO_INT_END (SPEAR_GPIO1_INT_BASE + 8) +/* IRQs sharing IRQ_GEN_RAS_1 */ +#define VIRQ_IT_PERS_S (VIRQ_START + 0) +#define VIRQ_IT_CHANGE_S (VIRQ_START + 1) +#define VIRQ_I2S (VIRQ_START + 2) +#define VIRQ_TDM (VIRQ_START + 3) +#define VIRQ_CAMERA_L (VIRQ_START + 4) +#define VIRQ_CAMERA_F (VIRQ_START + 5) +#define VIRQ_CAMERA_V (VIRQ_START + 6) +#define VIRQ_KEYBOARD (VIRQ_START + 7) +#define VIRQ_GPIO1 (VIRQ_START + 8) + +/* IRQs sharing IRQ_GEN_RAS_3 */ +#define IRQ_CLCD IRQ_GEN_RAS_3 + +/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */ +#define IRQ_SDIO IRQ_INTRCOMM_RAS_ARM + +/* GPIO pins virtual irqs */ +#define SPEAR_GPIO_INT_BASE (VIRQ_START + 9) +#define SPEAR_GPIO1_INT_BASE (SPEAR_GPIO_INT_BASE + 8) +#define SPEAR_GPIO_INT_END (SPEAR_GPIO1_INT_BASE + 8) + +/* SPEAr310 Virtual irq definitions */ +#elif defined(CONFIG_MACH_SPEAR310) +/* IRQs sharing IRQ_GEN_RAS_1 */ +#define VIRQ_SMII0 (VIRQ_START + 0) +#define VIRQ_SMII1 (VIRQ_START + 1) +#define VIRQ_SMII2 (VIRQ_START + 2) +#define VIRQ_SMII3 (VIRQ_START + 3) +#define VIRQ_WAKEUP_SMII0 (VIRQ_START + 4) +#define VIRQ_WAKEUP_SMII1 (VIRQ_START + 5) +#define VIRQ_WAKEUP_SMII2 (VIRQ_START + 6) +#define VIRQ_WAKEUP_SMII3 (VIRQ_START + 7) + +/* IRQs sharing IRQ_GEN_RAS_2 */ +#define VIRQ_UART1 (VIRQ_START + 8) +#define VIRQ_UART2 (VIRQ_START + 9) +#define VIRQ_UART3 (VIRQ_START + 10) +#define VIRQ_UART4 (VIRQ_START + 11) +#define VIRQ_UART5 (VIRQ_START + 12) + +/* IRQs sharing IRQ_GEN_RAS_3 */ +#define VIRQ_EMI (VIRQ_START + 13) +#define VIRQ_PLGPIO (VIRQ_START + 14) + +/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */ +#define VIRQ_TDM_HDLC (VIRQ_START + 15) +#define VIRQ_RS485_0 (VIRQ_START + 16) +#define VIRQ_RS485_1 (VIRQ_START + 17) + +/* GPIO pins virtual irqs */ +#define SPEAR_GPIO_INT_BASE (VIRQ_START + 18) + +/* SPEAr320 Virtual irq definitions */ #else -#define SPEAR_GPIO_INT_END (SPEAR_GPIO_INT_BASE + 8) +/* IRQs sharing IRQ_GEN_RAS_1 */ +#define VIRQ_EMI (VIRQ_START + 0) +#define VIRQ_CLCD (VIRQ_START + 1) +#define VIRQ_SPP (VIRQ_START + 2) + +/* IRQs sharing IRQ_GEN_RAS_2 */ +#define IRQ_SDIO IRQ_GEN_RAS_2 + +/* IRQs sharing IRQ_GEN_RAS_3 */ +#define VIRQ_PLGPIO (VIRQ_START + 3) +#define VIRQ_I2S_PLAY (VIRQ_START + 4) +#define VIRQ_I2S_REC (VIRQ_START + 5) + +/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */ +#define VIRQ_CANU (VIRQ_START + 6) +#define VIRQ_CANL (VIRQ_START + 7) +#define VIRQ_UART1 (VIRQ_START + 8) +#define VIRQ_UART2 (VIRQ_START + 9) +#define VIRQ_SSP1 (VIRQ_START + 10) +#define VIRQ_SSP2 (VIRQ_START + 11) +#define VIRQ_SMII0 (VIRQ_START + 12) +#define VIRQ_MII1_SMII1 (VIRQ_START + 13) +#define VIRQ_WAKEUP_SMII0 (VIRQ_START + 14) +#define VIRQ_WAKEUP_MII1_SMII1 (VIRQ_START + 15) +#define VIRQ_I2C (VIRQ_START + 16) + +/* GPIO pins virtual irqs */ +#define SPEAR_GPIO_INT_BASE (VIRQ_START + 17) + +#endif + +/* PLGPIO Virtual IRQs */ +#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320) +#define SPEAR_PLGPIO_INT_BASE (SPEAR_GPIO_INT_BASE + 8) +#define SPEAR_GPIO_INT_END (SPEAR_PLGPIO_INT_BASE + 102) #endif -#define VIRTUAL_IRQS (SPEAR_GPIO_INT_END - IRQ_VIC_END) -#define NR_IRQS (IRQ_VIC_END + VIRTUAL_IRQS) +#define VIRQ_END SPEAR_GPIO_INT_END +#define NR_IRQS VIRQ_END #endif /* __MACH_IRQS_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h index 40c16f385cfa..ccaa76522ee2 100644 --- a/arch/arm/mach-spear3xx/include/mach/spear300.h +++ b/arch/arm/mach-spear3xx/include/mach/spear300.h @@ -20,6 +20,22 @@ #define SPEAR300_TELECOM_BASE 0x50000000 #define SPEAR300_TELECOM_SIZE 0x10000000 +/* Interrupt registers offsets and masks */ +#define SPEAR300_TELECOM_REG_SIZE 0x00010000 +#define INT_ENB_MASK_REG 0x54 +#define INT_STS_MASK_REG 0x58 +#define IT_PERS_S_IRQ_MASK (1 << 0) +#define IT_CHANGE_S_IRQ_MASK (1 << 1) +#define I2S_IRQ_MASK (1 << 2) +#define TDM_IRQ_MASK (1 << 3) +#define CAMERA_L_IRQ_MASK (1 << 4) +#define CAMERA_F_IRQ_MASK (1 << 5) +#define CAMERA_V_IRQ_MASK (1 << 6) +#define KEYBOARD_IRQ_MASK (1 << 7) +#define GPIO1_IRQ_MASK (1 << 8) + +#define SHIRQ_RAS1_MASK 0x1FF + #define SPEAR300_CLCD_BASE 0x60000000 #define SPEAR300_CLCD_SIZE 0x10000000 diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h index d4f58d6469d9..b27bb8af3309 100644 --- a/arch/arm/mach-spear3xx/include/mach/spear310.h +++ b/arch/arm/mach-spear3xx/include/mach/spear310.h @@ -40,6 +40,30 @@ #define SPEAR310_SOC_CONFIG_BASE 0xB4000000 #define SPEAR310_SOC_CONFIG_SIZE 0x00000070 +/* Interrupt registers offsets and masks */ +#define INT_STS_MASK_REG 0x04 +#define SMII0_IRQ_MASK (1 << 0) +#define SMII1_IRQ_MASK (1 << 1) +#define SMII2_IRQ_MASK (1 << 2) +#define SMII3_IRQ_MASK (1 << 3) +#define WAKEUP_SMII0_IRQ_MASK (1 << 4) +#define WAKEUP_SMII1_IRQ_MASK (1 << 5) +#define WAKEUP_SMII2_IRQ_MASK (1 << 6) +#define WAKEUP_SMII3_IRQ_MASK (1 << 7) +#define UART1_IRQ_MASK (1 << 8) +#define UART2_IRQ_MASK (1 << 9) +#define UART3_IRQ_MASK (1 << 10) +#define UART4_IRQ_MASK (1 << 11) +#define UART5_IRQ_MASK (1 << 12) +#define EMI_IRQ_MASK (1 << 13) +#define TDM_HDLC_IRQ_MASK (1 << 14) +#define RS485_0_IRQ_MASK (1 << 15) +#define RS485_1_IRQ_MASK (1 << 16) + +#define SHIRQ_RAS1_MASK 0x000FF +#define SHIRQ_RAS2_MASK 0x01F00 +#define SHIRQ_RAS3_MASK 0x02000 +#define SHIRQ_INTRCOMM_RAS_MASK 0x1C000 #endif /* __MACH_SPEAR310_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h index e8ad2ed82e24..cacf17a958cd 100644 --- a/arch/arm/mach-spear3xx/include/mach/spear320.h +++ b/arch/arm/mach-spear3xx/include/mach/spear320.h @@ -64,6 +64,32 @@ #define SPEAR320_SOC_CONFIG_BASE 0xB4000000 #define SPEAR320_SOC_CONFIG_SIZE 0x00000070 +/* Interrupt registers offsets and masks */ +#define INT_STS_MASK_REG 0x04 +#define INT_CLR_MASK_REG 0x04 +#define INT_ENB_MASK_REG 0x08 +#define GPIO_IRQ_MASK (1 << 0) +#define I2S_PLAY_IRQ_MASK (1 << 1) +#define I2S_REC_IRQ_MASK (1 << 2) +#define EMI_IRQ_MASK (1 << 7) +#define CLCD_IRQ_MASK (1 << 8) +#define SPP_IRQ_MASK (1 << 9) +#define SDIO_IRQ_MASK (1 << 10) +#define CAN_U_IRQ_MASK (1 << 11) +#define CAN_L_IRQ_MASK (1 << 12) +#define UART1_IRQ_MASK (1 << 13) +#define UART2_IRQ_MASK (1 << 14) +#define SSP1_IRQ_MASK (1 << 15) +#define SSP2_IRQ_MASK (1 << 16) +#define SMII0_IRQ_MASK (1 << 17) +#define MII1_SMII1_IRQ_MASK (1 << 18) +#define WAKEUP_SMII0_IRQ_MASK (1 << 19) +#define WAKEUP_MII1_SMII1_IRQ_MASK (1 << 20) +#define I2C1_IRQ_MASK (1 << 21) + +#define SHIRQ_RAS1_MASK 0x000380 +#define SHIRQ_RAS3_MASK 0x000007 +#define SHIRQ_INTRCOMM_RAS_MASK 0x3FF800 #endif /* __MACH_SPEAR320_H */ diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index 66e7fcd8baf8..3560f8c1e723 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c @@ -17,6 +17,7 @@ #include #include #include +#include /* pad multiplexing support */ /* muxing registers */ @@ -386,14 +387,78 @@ struct amba_device gpio1_device = { .end = SPEAR300_GPIO_BASE + SPEAR300_GPIO_SIZE - 1, .flags = IORESOURCE_MEM, }, - .irq = {IRQ_GEN_RAS_1, NO_IRQ}, + .irq = {VIRQ_GPIO1, NO_IRQ}, +}; + +/* spear3xx shared irq */ +struct shirq_dev_config shirq_ras1_config[] = { + { + .virq = VIRQ_IT_PERS_S, + .enb_mask = IT_PERS_S_IRQ_MASK, + .status_mask = IT_PERS_S_IRQ_MASK, + }, { + .virq = VIRQ_IT_CHANGE_S, + .enb_mask = IT_CHANGE_S_IRQ_MASK, + .status_mask = IT_CHANGE_S_IRQ_MASK, + }, { + .virq = VIRQ_I2S, + .enb_mask = I2S_IRQ_MASK, + .status_mask = I2S_IRQ_MASK, + }, { + .virq = VIRQ_TDM, + .enb_mask = TDM_IRQ_MASK, + .status_mask = TDM_IRQ_MASK, + }, { + .virq = VIRQ_CAMERA_L, + .enb_mask = CAMERA_L_IRQ_MASK, + .status_mask = CAMERA_L_IRQ_MASK, + }, { + .virq = VIRQ_CAMERA_F, + .enb_mask = CAMERA_F_IRQ_MASK, + .status_mask = CAMERA_F_IRQ_MASK, + }, { + .virq = VIRQ_CAMERA_V, + .enb_mask = CAMERA_V_IRQ_MASK, + .status_mask = CAMERA_V_IRQ_MASK, + }, { + .virq = VIRQ_KEYBOARD, + .enb_mask = KEYBOARD_IRQ_MASK, + .status_mask = KEYBOARD_IRQ_MASK, + }, { + .virq = VIRQ_GPIO1, + .enb_mask = GPIO1_IRQ_MASK, + .status_mask = GPIO1_IRQ_MASK, + }, +}; + +struct spear_shirq shirq_ras1 = { + .irq = IRQ_GEN_RAS_1, + .dev_config = shirq_ras1_config, + .dev_count = ARRAY_SIZE(shirq_ras1_config), + .regs = { + .enb_reg = INT_ENB_MASK_REG, + .status_reg = INT_STS_MASK_REG, + .status_reg_mask = SHIRQ_RAS1_MASK, + .clear_reg = -1, + }, }; /* spear300 routines */ void __init spear300_init(void) { + int ret = 0; + /* call spear3xx family common init function */ spear3xx_init(); + + /* shared irq registeration */ + shirq_ras1.regs.base = + ioremap(SPEAR300_TELECOM_BASE, SPEAR300_TELECOM_REG_SIZE); + if (shirq_ras1.regs.base) { + ret = spear_shirq_register(&shirq_ras1); + if (ret) + printk(KERN_ERR "Error registering Shared IRQ\n"); + } } void spear300_pmx_init(void) diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index dd5a57282711..96a1ab824bac 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c @@ -15,6 +15,7 @@ #include #include #include +#include /* pad multiplexing support */ /* muxing registers */ @@ -140,11 +141,158 @@ struct pmx_driver pmx_driver = { /* Add spear310 specific devices here */ +/* spear3xx shared irq */ +struct shirq_dev_config shirq_ras1_config[] = { + { + .virq = VIRQ_SMII0, + .status_mask = SMII0_IRQ_MASK, + }, { + .virq = VIRQ_SMII1, + .status_mask = SMII1_IRQ_MASK, + }, { + .virq = VIRQ_SMII2, + .status_mask = SMII2_IRQ_MASK, + }, { + .virq = VIRQ_SMII3, + .status_mask = SMII3_IRQ_MASK, + }, { + .virq = VIRQ_WAKEUP_SMII0, + .status_mask = WAKEUP_SMII0_IRQ_MASK, + }, { + .virq = VIRQ_WAKEUP_SMII1, + .status_mask = WAKEUP_SMII1_IRQ_MASK, + }, { + .virq = VIRQ_WAKEUP_SMII2, + .status_mask = WAKEUP_SMII2_IRQ_MASK, + }, { + .virq = VIRQ_WAKEUP_SMII3, + .status_mask = WAKEUP_SMII3_IRQ_MASK, + }, +}; + +struct spear_shirq shirq_ras1 = { + .irq = IRQ_GEN_RAS_1, + .dev_config = shirq_ras1_config, + .dev_count = ARRAY_SIZE(shirq_ras1_config), + .regs = { + .enb_reg = -1, + .status_reg = INT_STS_MASK_REG, + .status_reg_mask = SHIRQ_RAS1_MASK, + .clear_reg = -1, + }, +}; + +struct shirq_dev_config shirq_ras2_config[] = { + { + .virq = VIRQ_UART1, + .status_mask = UART1_IRQ_MASK, + }, { + .virq = VIRQ_UART2, + .status_mask = UART2_IRQ_MASK, + }, { + .virq = VIRQ_UART3, + .status_mask = UART3_IRQ_MASK, + }, { + .virq = VIRQ_UART4, + .status_mask = UART4_IRQ_MASK, + }, { + .virq = VIRQ_UART5, + .status_mask = UART5_IRQ_MASK, + }, +}; + +struct spear_shirq shirq_ras2 = { + .irq = IRQ_GEN_RAS_2, + .dev_config = shirq_ras2_config, + .dev_count = ARRAY_SIZE(shirq_ras2_config), + .regs = { + .enb_reg = -1, + .status_reg = INT_STS_MASK_REG, + .status_reg_mask = SHIRQ_RAS2_MASK, + .clear_reg = -1, + }, +}; + +struct shirq_dev_config shirq_ras3_config[] = { + { + .virq = VIRQ_EMI, + .status_mask = EMI_IRQ_MASK, + }, +}; + +struct spear_shirq shirq_ras3 = { + .irq = IRQ_GEN_RAS_3, + .dev_config = shirq_ras3_config, + .dev_count = ARRAY_SIZE(shirq_ras3_config), + .regs = { + .enb_reg = -1, + .status_reg = INT_STS_MASK_REG, + .status_reg_mask = SHIRQ_RAS3_MASK, + .clear_reg = -1, + }, +}; + +struct shirq_dev_config shirq_intrcomm_ras_config[] = { + { + .virq = VIRQ_TDM_HDLC, + .status_mask = TDM_HDLC_IRQ_MASK, + }, { + .virq = VIRQ_RS485_0, + .status_mask = RS485_0_IRQ_MASK, + }, { + .virq = VIRQ_RS485_1, + .status_mask = RS485_1_IRQ_MASK, + }, +}; + +struct spear_shirq shirq_intrcomm_ras = { + .irq = IRQ_INTRCOMM_RAS_ARM, + .dev_config = shirq_intrcomm_ras_config, + .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config), + .regs = { + .enb_reg = -1, + .status_reg = INT_STS_MASK_REG, + .status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK, + .clear_reg = -1, + }, +}; + /* spear310 routines */ void __init spear310_init(void) { + void __iomem *base; + int ret = 0; + /* call spear3xx family common init function */ spear3xx_init(); + + /* shared irq registeration */ + base = ioremap(SPEAR310_SOC_CONFIG_BASE, SPEAR310_SOC_CONFIG_SIZE); + if (base) { + /* shirq 1 */ + shirq_ras1.regs.base = base; + ret = spear_shirq_register(&shirq_ras1); + if (ret) + printk(KERN_ERR "Error registering Shared IRQ 1\n"); + + /* shirq 2 */ + shirq_ras2.regs.base = base; + ret = spear_shirq_register(&shirq_ras2); + if (ret) + printk(KERN_ERR "Error registering Shared IRQ 2\n"); + + /* shirq 3 */ + shirq_ras3.regs.base = base; + ret = spear_shirq_register(&shirq_ras3); + if (ret) + printk(KERN_ERR "Error registering Shared IRQ 3\n"); + + /* shirq 4 */ + shirq_intrcomm_ras.regs.base = base; + ret = spear_shirq_register(&shirq_intrcomm_ras); + if (ret) + printk(KERN_ERR "Error registering Shared IRQ 4\n"); + } } void spear310_pmx_init(void) diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index 2cedf5eb9ec9..6a1219549369 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c @@ -15,6 +15,7 @@ #include #include #include +#include /* pad multiplexing support */ /* muxing registers */ @@ -385,11 +386,160 @@ struct pmx_driver pmx_driver = { /* Add spear320 specific devices here */ +/* spear3xx shared irq */ +struct shirq_dev_config shirq_ras1_config[] = { + { + .virq = VIRQ_EMI, + .status_mask = EMI_IRQ_MASK, + .clear_mask = EMI_IRQ_MASK, + }, { + .virq = VIRQ_CLCD, + .status_mask = CLCD_IRQ_MASK, + .clear_mask = CLCD_IRQ_MASK, + }, { + .virq = VIRQ_SPP, + .status_mask = SPP_IRQ_MASK, + .clear_mask = SPP_IRQ_MASK, + }, +}; + +struct spear_shirq shirq_ras1 = { + .irq = IRQ_GEN_RAS_1, + .dev_config = shirq_ras1_config, + .dev_count = ARRAY_SIZE(shirq_ras1_config), + .regs = { + .enb_reg = -1, + .status_reg = INT_STS_MASK_REG, + .status_reg_mask = SHIRQ_RAS1_MASK, + .clear_reg = INT_CLR_MASK_REG, + .reset_to_clear = 1, + }, +}; + +struct shirq_dev_config shirq_ras3_config[] = { + { + .virq = VIRQ_PLGPIO, + .enb_mask = GPIO_IRQ_MASK, + .status_mask = GPIO_IRQ_MASK, + .clear_mask = GPIO_IRQ_MASK, + }, { + .virq = VIRQ_I2S_PLAY, + .enb_mask = I2S_PLAY_IRQ_MASK, + .status_mask = I2S_PLAY_IRQ_MASK, + .clear_mask = I2S_PLAY_IRQ_MASK, + }, { + .virq = VIRQ_I2S_REC, + .enb_mask = I2S_REC_IRQ_MASK, + .status_mask = I2S_REC_IRQ_MASK, + .clear_mask = I2S_REC_IRQ_MASK, + }, +}; + +struct spear_shirq shirq_ras3 = { + .irq = IRQ_GEN_RAS_3, + .dev_config = shirq_ras3_config, + .dev_count = ARRAY_SIZE(shirq_ras3_config), + .regs = { + .enb_reg = INT_ENB_MASK_REG, + .reset_to_enb = 1, + .status_reg = INT_STS_MASK_REG, + .status_reg_mask = SHIRQ_RAS3_MASK, + .clear_reg = INT_CLR_MASK_REG, + .reset_to_clear = 1, + }, +}; + +struct shirq_dev_config shirq_intrcomm_ras_config[] = { + { + .virq = VIRQ_CANU, + .status_mask = CAN_U_IRQ_MASK, + .clear_mask = CAN_U_IRQ_MASK, + }, { + .virq = VIRQ_CANL, + .status_mask = CAN_L_IRQ_MASK, + .clear_mask = CAN_L_IRQ_MASK, + }, { + .virq = VIRQ_UART1, + .status_mask = UART1_IRQ_MASK, + .clear_mask = UART1_IRQ_MASK, + }, { + .virq = VIRQ_UART2, + .status_mask = UART2_IRQ_MASK, + .clear_mask = UART2_IRQ_MASK, + }, { + .virq = VIRQ_SSP1, + .status_mask = SSP1_IRQ_MASK, + .clear_mask = SSP1_IRQ_MASK, + }, { + .virq = VIRQ_SSP2, + .status_mask = SSP2_IRQ_MASK, + .clear_mask = SSP2_IRQ_MASK, + }, { + .virq = VIRQ_SMII0, + .status_mask = SMII0_IRQ_MASK, + .clear_mask = SMII0_IRQ_MASK, + }, { + .virq = VIRQ_MII1_SMII1, + .status_mask = MII1_SMII1_IRQ_MASK, + .clear_mask = MII1_SMII1_IRQ_MASK, + }, { + .virq = VIRQ_WAKEUP_SMII0, + .status_mask = WAKEUP_SMII0_IRQ_MASK, + .clear_mask = WAKEUP_SMII0_IRQ_MASK, + }, { + .virq = VIRQ_WAKEUP_MII1_SMII1, + .status_mask = WAKEUP_MII1_SMII1_IRQ_MASK, + .clear_mask = WAKEUP_MII1_SMII1_IRQ_MASK, + }, { + .virq = VIRQ_I2C, + .status_mask = I2C1_IRQ_MASK, + .clear_mask = I2C1_IRQ_MASK, + }, +}; + +struct spear_shirq shirq_intrcomm_ras = { + .irq = IRQ_INTRCOMM_RAS_ARM, + .dev_config = shirq_intrcomm_ras_config, + .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config), + .regs = { + .enb_reg = -1, + .status_reg = INT_STS_MASK_REG, + .status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK, + .clear_reg = INT_CLR_MASK_REG, + .reset_to_clear = 1, + }, +}; + /* spear320 routines */ void __init spear320_init(void) { + void __iomem *base; + int ret = 0; + /* call spear3xx family common init function */ spear3xx_init(); + + /* shared irq registeration */ + base = ioremap(SPEAR320_SOC_CONFIG_BASE, SPEAR320_SOC_CONFIG_SIZE); + if (base) { + /* shirq 1 */ + shirq_ras1.regs.base = base; + ret = spear_shirq_register(&shirq_ras1); + if (ret) + printk(KERN_ERR "Error registering Shared IRQ 1\n"); + + /* shirq 3 */ + shirq_ras3.regs.base = base; + ret = spear_shirq_register(&shirq_ras3); + if (ret) + printk(KERN_ERR "Error registering Shared IRQ 3\n"); + + /* shirq 4 */ + shirq_intrcomm_ras.regs.base = base; + ret = spear_shirq_register(&shirq_intrcomm_ras); + if (ret) + printk(KERN_ERR "Error registering Shared IRQ 4\n"); + } } void spear320_pmx_init(void) diff --git a/arch/arm/mach-spear6xx/include/mach/irqs.h b/arch/arm/mach-spear6xx/include/mach/irqs.h index 08a3abced750..8f214b03d75d 100644 --- a/arch/arm/mach-spear6xx/include/mach/irqs.h +++ b/arch/arm/mach-spear6xx/include/mach/irqs.h @@ -85,6 +85,7 @@ #define IRQ_VIC_END 64 +/* GPIO pins virtual irqs */ #define SPEAR_GPIO_INT_BASE IRQ_VIC_END #define SPEAR_GPIO0_INT_BASE SPEAR_GPIO_INT_BASE #define SPEAR_GPIO1_INT_BASE (SPEAR_GPIO0_INT_BASE + 8) diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile index 6f4ad5e9462e..eb89540aeda9 100644 --- a/arch/arm/plat-spear/Makefile +++ b/arch/arm/plat-spear/Makefile @@ -4,3 +4,5 @@ # Common support obj-y := clock.o padmux.o time.o + +obj-$(CONFIG_ARCH_SPEAR3XX) += shirq.o diff --git a/arch/arm/plat-spear/include/plat/shirq.h b/arch/arm/plat-spear/include/plat/shirq.h new file mode 100644 index 000000000000..03ed8b585dcf --- /dev/null +++ b/arch/arm/plat-spear/include/plat/shirq.h @@ -0,0 +1,73 @@ +/* + * arch/arm/plat-spear/include/plat/shirq.h + * + * SPEAr platform shared irq layer header file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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. + */ + +#ifndef __PLAT_SHIRQ_H +#define __PLAT_SHIRQ_H + +#include +#include + +/* + * struct shirq_dev_config: shared irq device configuration + * + * virq: virtual irq number of device + * enb_mask: enable mask of device + * status_mask: status mask of device + * clear_mask: clear mask of device + */ +struct shirq_dev_config { + u32 virq; + u32 enb_mask; + u32 status_mask; + u32 clear_mask; +}; + +/* + * struct shirq_regs: shared irq register configuration + * + * base: base address of shared irq register + * enb_reg: enable register offset + * reset_to_enb: val 1 indicates, we need to clear bit for enabling interrupt + * status_reg: status register offset + * status_reg_mask: status register valid mask + * clear_reg: clear register offset + * reset_to_clear: val 1 indicates, we need to clear bit for clearing interrupt + */ +struct shirq_regs { + void __iomem *base; + u32 enb_reg; + u32 reset_to_enb; + u32 status_reg; + u32 status_reg_mask; + u32 clear_reg; + u32 reset_to_clear; +}; + +/* + * struct spear_shirq: shared irq structure + * + * irq: hardware irq number + * dev_config: array of device config structures which are using "irq" line + * dev_count: size of dev_config array + * regs: register configuration for shared irq block + */ +struct spear_shirq { + u32 irq; + struct shirq_dev_config *dev_config; + u32 dev_count; + struct shirq_regs regs; +}; + +int spear_shirq_register(struct spear_shirq *shirq); + +#endif /* __PLAT_SHIRQ_H */ diff --git a/arch/arm/plat-spear/shirq.c b/arch/arm/plat-spear/shirq.c new file mode 100644 index 000000000000..2172d6946aea --- /dev/null +++ b/arch/arm/plat-spear/shirq.c @@ -0,0 +1,118 @@ +/* + * arch/arm/plat-spear/shirq.c + * + * SPEAr platform shared irq layer source file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * 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 +#include +#include +#include +#include + +struct spear_shirq *shirq; +static DEFINE_SPINLOCK(lock); + +static void shirq_irq_mask(unsigned irq) +{ + struct spear_shirq *shirq = get_irq_chip_data(irq); + u32 val, id = irq - shirq->dev_config[0].virq; + unsigned long flags; + + if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1) + return; + + spin_lock_irqsave(&lock, flags); + val = readl(shirq->regs.base + shirq->regs.enb_reg); + if (shirq->regs.reset_to_enb) + val |= shirq->dev_config[id].enb_mask; + else + val &= ~(shirq->dev_config[id].enb_mask); + writel(val, shirq->regs.base + shirq->regs.enb_reg); + spin_unlock_irqrestore(&lock, flags); +} + +static void shirq_irq_unmask(unsigned irq) +{ + struct spear_shirq *shirq = get_irq_chip_data(irq); + u32 val, id = irq - shirq->dev_config[0].virq; + unsigned long flags; + + if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1) + return; + + spin_lock_irqsave(&lock, flags); + val = readl(shirq->regs.base + shirq->regs.enb_reg); + if (shirq->regs.reset_to_enb) + val &= ~(shirq->dev_config[id].enb_mask); + else + val |= shirq->dev_config[id].enb_mask; + writel(val, shirq->regs.base + shirq->regs.enb_reg); + spin_unlock_irqrestore(&lock, flags); +} + +static struct irq_chip shirq_chip = { + .name = "spear_shirq", + .ack = shirq_irq_mask, + .mask = shirq_irq_mask, + .unmask = shirq_irq_unmask, +}; + +static void shirq_handler(unsigned irq, struct irq_desc *desc) +{ + u32 i, val, mask; + struct spear_shirq *shirq = get_irq_data(irq); + + desc->chip->ack(irq); + while ((val = readl(shirq->regs.base + shirq->regs.status_reg) & + shirq->regs.status_reg_mask)) { + for (i = 0; (i < shirq->dev_count) && val; i++) { + if (!(shirq->dev_config[i].status_mask & val)) + continue; + + generic_handle_irq(shirq->dev_config[i].virq); + + /* clear interrupt */ + val &= ~shirq->dev_config[i].status_mask; + if ((shirq->regs.clear_reg == -1) || + shirq->dev_config[i].clear_mask == -1) + continue; + mask = readl(shirq->regs.base + shirq->regs.clear_reg); + if (shirq->regs.reset_to_clear) + mask &= ~shirq->dev_config[i].clear_mask; + else + mask |= shirq->dev_config[i].clear_mask; + writel(mask, shirq->regs.base + shirq->regs.clear_reg); + } + } + desc->chip->unmask(irq); +} + +int spear_shirq_register(struct spear_shirq *shirq) +{ + int i; + + if (!shirq || !shirq->dev_config || !shirq->regs.base) + return -EFAULT; + + if (!shirq->dev_count) + return -EINVAL; + + set_irq_chained_handler(shirq->irq, shirq_handler); + for (i = 0; i < shirq->dev_count; i++) { + set_irq_chip(shirq->dev_config[i].virq, &shirq_chip); + set_irq_handler(shirq->dev_config[i].virq, handle_simple_irq); + set_irq_flags(shirq->dev_config[i].virq, IRQF_VALID); + set_irq_chip_data(shirq->dev_config[i].virq, shirq); + } + + set_irq_data(shirq->irq, shirq); + return 0; +} -- cgit v1.2.3-59-g8ed1b From e8faff7330a3501eafc9bfe5f4f15af444be29f5 Mon Sep 17 00:00:00 2001 From: Claudio Scordino Date: Mon, 3 May 2010 13:31:28 +0100 Subject: ARM: 6092/1: atmel_serial: support for RS485 communications Final version of the patch that adds support for RS485 communications to the atmel_serial driver. The patch has been already sent and discussed on both linux-kernel and linux-arm-kernel mailing lists several times. Many people collaborated to improve and test the code: Tested-by: Sebastian Heutling Tested-by: Bernhard Roth Reviewed-by: Ryan Mallon Signed-off-by: Claudio Scordino Signed-off-by: Michael Trimarchi Signed-off-by: Rick Bronson Signed-off-by: Sebastian Heutling Signed-off-by: Russell King --- arch/arm/include/asm/ioctls.h | 3 + arch/arm/mach-at91/include/mach/board.h | 8 +- drivers/serial/atmel_serial.c | 207 ++++++++++++++++++++++++++------ 3 files changed, 181 insertions(+), 37 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/asm/ioctls.h index a91d8a1523cf..7f0b6d13296a 100644 --- a/arch/arm/include/asm/ioctls.h +++ b/arch/arm/include/asm/ioctls.h @@ -53,6 +53,9 @@ #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCGRS485 0x542E +#define TIOCSRS485 0x542F + #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 #define FIOASYNC 0x5452 diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index ceaec6c16eb2..df2ed848c9f8 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -39,6 +39,7 @@ #include #include #include +#include /* USB Device */ struct at91_udc_data { @@ -143,9 +144,10 @@ extern struct platform_device *atmel_default_console_device; extern void __init __deprecated at91_init_serial(struct at91_uart_config *config); struct atmel_uart_data { - short use_dma_tx; /* use transmit DMA? */ - short use_dma_rx; /* use receive DMA? */ - void __iomem *regs; /* virtual base address, if any */ + short use_dma_tx; /* use transmit DMA? */ + short use_dma_rx; /* use receive DMA? */ + void __iomem *regs; /* virt. base address, if any */ + struct serial_rs485 rs485; /* rs485 settings */ }; extern void __init at91_add_device_serial(void); diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 2c9bf9b68327..eed3c2d8dd1c 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -59,6 +60,9 @@ #include +static void atmel_start_rx(struct uart_port *port); +static void atmel_stop_rx(struct uart_port *port); + #ifdef CONFIG_SERIAL_ATMEL_TTYAT /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we @@ -93,6 +97,7 @@ #define UART_GET_BRGR(port) __raw_readl((port)->membase + ATMEL_US_BRGR) #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR) #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) +#define UART_PUT_TTGR(port, v) __raw_writel(v, (port)->membase + ATMEL_US_TTGR) /* PDC registers */ #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) @@ -147,6 +152,9 @@ struct atmel_uart_port { unsigned int irq_status_prev; struct circ_buf rx_ring; + + struct serial_rs485 rs485; /* rs485 settings */ + unsigned int tx_done_mask; }; static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; @@ -187,6 +195,46 @@ static bool atmel_use_dma_tx(struct uart_port *port) } #endif +/* Enable or disable the rs485 support */ +void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) +{ + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + unsigned int mode; + + spin_lock(&port->lock); + + /* Disable interrupts */ + UART_PUT_IDR(port, atmel_port->tx_done_mask); + + mode = UART_GET_MR(port); + + /* Resetting serial mode to RS232 (0x0) */ + mode &= ~ATMEL_US_USMODE; + + atmel_port->rs485 = *rs485conf; + + if (rs485conf->flags & SER_RS485_ENABLED) { + dev_dbg(port->dev, "Setting UART to RS485\n"); + atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; + UART_PUT_TTGR(port, rs485conf->delay_rts_before_send); + mode |= ATMEL_US_USMODE_RS485; + } else { + dev_dbg(port->dev, "Setting UART to RS232\n"); + if (atmel_use_dma_tx(port)) + atmel_port->tx_done_mask = ATMEL_US_ENDTX | + ATMEL_US_TXBUFE; + else + atmel_port->tx_done_mask = ATMEL_US_TXRDY; + } + UART_PUT_MR(port, mode); + + /* Enable interrupts */ + UART_PUT_IER(port, atmel_port->tx_done_mask); + + spin_unlock(&port->lock); + +} + /* * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty. */ @@ -202,6 +250,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) { unsigned int control = 0; unsigned int mode; + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); #ifdef CONFIG_ARCH_AT91RM9200 if (cpu_is_at91rm9200()) { @@ -236,6 +285,17 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) mode |= ATMEL_US_CHMODE_LOC_LOOP; else mode |= ATMEL_US_CHMODE_NORMAL; + + /* Resetting serial mode to RS232 (0x0) */ + mode &= ~ATMEL_US_USMODE; + + if (atmel_port->rs485.flags & SER_RS485_ENABLED) { + dev_dbg(port->dev, "Setting UART to RS485\n"); + UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); + mode |= ATMEL_US_USMODE_RS485; + } else { + dev_dbg(port->dev, "Setting UART to RS232\n"); + } UART_PUT_MR(port, mode); } @@ -268,12 +328,17 @@ static u_int atmel_get_mctrl(struct uart_port *port) */ static void atmel_stop_tx(struct uart_port *port) { + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + if (atmel_use_dma_tx(port)) { /* disable PDC transmit */ UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); - UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); - } else - UART_PUT_IDR(port, ATMEL_US_TXRDY); + } + /* Disable interrupts */ + UART_PUT_IDR(port, atmel_port->tx_done_mask); + + if (atmel_port->rs485.flags & SER_RS485_ENABLED) + atmel_start_rx(port); } /* @@ -281,17 +346,39 @@ static void atmel_stop_tx(struct uart_port *port) */ static void atmel_start_tx(struct uart_port *port) { + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + if (atmel_use_dma_tx(port)) { if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN) /* The transmitter is already running. Yes, we really need this.*/ return; - UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); + if (atmel_port->rs485.flags & SER_RS485_ENABLED) + atmel_stop_rx(port); + /* re-enable PDC transmit */ UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); - } else - UART_PUT_IER(port, ATMEL_US_TXRDY); + } + /* Enable interrupts */ + UART_PUT_IER(port, atmel_port->tx_done_mask); +} + +/* + * start receiving - port is in process of being opened. + */ +static void atmel_start_rx(struct uart_port *port) +{ + UART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */ + + if (atmel_use_dma_rx(port)) { + /* enable PDC controller */ + UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | + port->read_status_mask); + UART_PUT_PTCR(port, ATMEL_PDC_RXTEN); + } else { + UART_PUT_IER(port, ATMEL_US_RXRDY); + } } /* @@ -302,9 +389,11 @@ static void atmel_stop_rx(struct uart_port *port) if (atmel_use_dma_rx(port)) { /* disable PDC receive */ UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); - UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); - } else + UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | + port->read_status_mask); + } else { UART_PUT_IDR(port, ATMEL_US_RXRDY); + } } /* @@ -428,8 +517,9 @@ static void atmel_rx_chars(struct uart_port *port) static void atmel_tx_chars(struct uart_port *port) { struct circ_buf *xmit = &port->state->xmit; + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) { + if (port->x_char && UART_GET_CSR(port) & atmel_port->tx_done_mask) { UART_PUT_CHAR(port, port->x_char); port->icount.tx++; port->x_char = 0; @@ -437,7 +527,7 @@ static void atmel_tx_chars(struct uart_port *port) if (uart_circ_empty(xmit) || uart_tx_stopped(port)) return; - while (UART_GET_CSR(port) & ATMEL_US_TXRDY) { + while (UART_GET_CSR(port) & atmel_port->tx_done_mask) { UART_PUT_CHAR(port, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; @@ -449,7 +539,8 @@ static void atmel_tx_chars(struct uart_port *port) uart_write_wakeup(port); if (!uart_circ_empty(xmit)) - UART_PUT_IER(port, ATMEL_US_TXRDY); + /* Enable interrupts */ + UART_PUT_IER(port, atmel_port->tx_done_mask); } /* @@ -501,18 +592,10 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - if (atmel_use_dma_tx(port)) { - /* PDC transmit */ - if (pending & (ATMEL_US_ENDTX | ATMEL_US_TXBUFE)) { - UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); - tasklet_schedule(&atmel_port->tasklet); - } - } else { - /* Interrupt transmit */ - if (pending & ATMEL_US_TXRDY) { - UART_PUT_IDR(port, ATMEL_US_TXRDY); - tasklet_schedule(&atmel_port->tasklet); - } + if (pending & atmel_port->tx_done_mask) { + /* Either PDC or interrupt transmission */ + UART_PUT_IDR(port, atmel_port->tx_done_mask); + tasklet_schedule(&atmel_port->tasklet); } } @@ -590,9 +673,15 @@ static void atmel_tx_dma(struct uart_port *port) UART_PUT_TPR(port, pdc->dma_addr + xmit->tail); UART_PUT_TCR(port, count); - /* re-enable PDC transmit and interrupts */ + /* re-enable PDC transmit */ UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); - UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); + /* Enable interrupts */ + UART_PUT_IER(port, atmel_port->tx_done_mask); + } else { + if (atmel_port->rs485.flags & SER_RS485_ENABLED) { + /* DMA done, stop TX, start RX for RS485 */ + atmel_start_rx(port); + } } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) @@ -1017,6 +1106,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, { unsigned long flags; unsigned int mode, imr, quot, baud; + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); /* Get current mode register */ mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL @@ -1115,6 +1205,17 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, /* disable receiver and transmitter */ UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); + /* Resetting serial mode to RS232 (0x0) */ + mode &= ~ATMEL_US_USMODE; + + if (atmel_port->rs485.flags & SER_RS485_ENABLED) { + dev_dbg(port->dev, "Setting UART to RS485\n"); + UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); + mode |= ATMEL_US_USMODE_RS485; + } else { + dev_dbg(port->dev, "Setting UART to RS232\n"); + } + /* set the parity, stop bits and data size */ UART_PUT_MR(port, mode); @@ -1231,6 +1332,35 @@ static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) } #endif +static int +atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) +{ + struct serial_rs485 rs485conf; + + switch (cmd) { + case TIOCSRS485: + if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg, + sizeof(rs485conf))) + return -EFAULT; + + atmel_config_rs485(port, &rs485conf); + break; + + case TIOCGRS485: + if (copy_to_user((struct serial_rs485 *) arg, + &(to_atmel_uart_port(port)->rs485), + sizeof(rs485conf))) + return -EFAULT; + break; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + + + static struct uart_ops atmel_pops = { .tx_empty = atmel_tx_empty, .set_mctrl = atmel_set_mctrl, @@ -1250,6 +1380,7 @@ static struct uart_ops atmel_pops = { .config_port = atmel_config_port, .verify_port = atmel_verify_port, .pm = atmel_serial_pm, + .ioctl = atmel_ioctl, #ifdef CONFIG_CONSOLE_POLL .poll_get_char = atmel_poll_get_char, .poll_put_char = atmel_poll_put_char, @@ -1265,13 +1396,12 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, struct uart_port *port = &atmel_port->uart; struct atmel_uart_data *data = pdev->dev.platform_data; - port->iotype = UPIO_MEM; - port->flags = UPF_BOOT_AUTOCONF; - port->ops = &atmel_pops; - port->fifosize = 1; - port->line = pdev->id; - port->dev = &pdev->dev; - + port->iotype = UPIO_MEM; + port->flags = UPF_BOOT_AUTOCONF; + port->ops = &atmel_pops; + port->fifosize = 1; + port->line = pdev->id; + port->dev = &pdev->dev; port->mapbase = pdev->resource[0].start; port->irq = pdev->resource[1].start; @@ -1299,8 +1429,16 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, atmel_port->use_dma_rx = data->use_dma_rx; atmel_port->use_dma_tx = data->use_dma_tx; - if (atmel_use_dma_tx(port)) + atmel_port->rs485 = data->rs485; + /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ + if (atmel_port->rs485.flags & SER_RS485_ENABLED) + atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; + else if (atmel_use_dma_tx(port)) { port->fifosize = PDC_BUFFER_SIZE; + atmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE; + } else { + atmel_port->tx_done_mask = ATMEL_US_TXRDY; + } } /* @@ -1334,6 +1472,7 @@ static void atmel_console_putchar(struct uart_port *port, int ch) static void atmel_console_write(struct console *co, const char *s, u_int count) { struct uart_port *port = &atmel_ports[co->index].uart; + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); unsigned int status, imr; unsigned int pdc_tx; @@ -1341,7 +1480,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count) * First, save IMR and then disable interrupts */ imr = UART_GET_IMR(port); - UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY); + UART_PUT_IDR(port, ATMEL_US_RXRDY | atmel_port->tx_done_mask); /* Store PDC transmit status and disable it */ pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN; -- cgit v1.2.3-59-g8ed1b From f38406bbfc5e1d4bd9726454ecb60ba52aa9da11 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 07:27:31 +0100 Subject: ARM: 6077/1: ux500: add SOC Kconfig variables This adds the different config options for SoCs DB8500 and DB5500 and refines the SoC/CPU detection code to support the DB5500 as well via these. The selection between DB5500 and DB8500 is currently a simple compile-time choice. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/Kconfig | 22 ++++++++++++++++++---- arch/arm/mach-ux500/include/mach/hardware.h | 13 +++++++++++-- 2 files changed, 29 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index cd412a3e0ab8..699588f7da87 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -1,16 +1,30 @@ +if ARCH_U8500 + +config UX500_SOC_COMMON + bool + default y + select ARM_GIC + select HAS_MTU + select NOMADIK_GPIO + +config UX500_SOC_DB8500 + bool + +config UX500_SOC_DB5500 + bool + menu "ST-Ericsson platform type" - depends on ARCH_U8500 comment "ST-Ericsson Multicore Mobile Platforms" config MACH_U8500_MOP bool "U8500 Early Development platform" default y - select ARM_GIC - select HAS_MTU - select NOMADIK_GPIO + select UX500_SOC_DB8500 help Include support for mop500 development platform based on U8500 architecture. The platform is based on early drop silicon version of 8500. endmenu + +endif diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 99ca89fe9b30..d86b3543dd23 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h @@ -147,14 +147,23 @@ #include +static inline bool cpu_is_u8500(void) +{ +#ifdef CONFIG_UX500_SOC_DB8500 + return 1; +#else + return 0; +#endif +} + static inline bool cpu_is_u8500ed(void) { - return (read_cpuid_id() & 15) == 0; + return cpu_is_u8500() && (read_cpuid_id() & 15) == 0; } static inline bool cpu_is_u8500v1(void) { - return (read_cpuid_id() & 15) == 1; + return cpu_is_u8500() && (read_cpuid_id() & 15) == 1; } #endif -- cgit v1.2.3-59-g8ed1b From c9c0957286e73d01e98503f714d32180e6963757 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 07:34:53 +0100 Subject: ARM: 6078/1: ux500: add per-SoC register definitions Split up all the hardware register definitions previously found in hardware.h into per-SoC files db8500-regs.h and db5500-regs.h. Rename a couple of macros to prepare for sharing code between the variants. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/cpu-u8500.c | 6 +- arch/arm/mach-ux500/include/mach/db5500-regs.h | 103 +++++++++++++++ arch/arm/mach-ux500/include/mach/db8500-regs.h | 135 +++++++++++++++++++ arch/arm/mach-ux500/include/mach/hardware.h | 174 +++++++++---------------- 4 files changed, 302 insertions(+), 116 deletions(-) create mode 100644 arch/arm/mach-ux500/include/mach/db5500-regs.h create mode 100644 arch/arm/mach-ux500/include/mach/db8500-regs.h (limited to 'arch') diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index 979f1c32ad09..8919af4eeeb5 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -124,10 +124,10 @@ static struct map_desc u8500_io_desc[] __initdata = { __IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K), __IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K), __IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), - __IO_DEV_DESC(U8500_GPIO5_BASE, SZ_4K), __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K), }; @@ -137,7 +137,7 @@ static struct map_desc u8500ed_io_desc[] __initdata = { }; static struct map_desc u8500v1_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_MTU0_BASE_V1, SZ_4K), + __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), }; void __init u8500_map_io(void) @@ -177,7 +177,7 @@ static void __init u8500_timer_init(void) if (cpu_is_u8500ed()) mtu_base = __io_address(U8500_MTU0_BASE_ED); else - mtu_base = __io_address(U8500_MTU0_BASE_V1); + mtu_base = __io_address(U8500_MTU0_BASE); nmdk_timer_init(); } diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h new file mode 100644 index 000000000000..545c80fc8024 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __MACH_DB5500_REGS_H +#define __MACH_DB5500_REGS_H + +#define U5500_PER1_BASE 0xA0020000 +#define U5500_PER2_BASE 0xA0010000 +#define U5500_PER3_BASE 0x80140000 +#define U5500_PER4_BASE 0x80150000 +#define U5500_PER5_BASE 0x80100000 +#define U5500_PER6_BASE 0x80120000 + +#define U5500_GIC_DIST_BASE 0xA0411000 +#define U5500_GIC_CPU_BASE 0xA0410100 +#define U5500_DMA_BASE 0x90030000 +#define U5500_MCDE_BASE 0xA0400000 +#define U5500_MODEM_BASE 0xB0000000 +#define U5500_L2CC_BASE 0xA0412000 +#define U5500_SCU_BASE 0xA0410000 +#define U5500_DSI1_BASE 0xA0401000 +#define U5500_DSI2_BASE 0xA0402000 +#define U5500_SIA_BASE 0xA0100000 +#define U5500_SVA_BASE 0x80200000 +#define U5500_HSEM_BASE 0xA0000000 +#define U5500_NAND0_BASE 0x60000000 +#define U5500_NAND1_BASE 0x70000000 +#define U5500_TWD_BASE 0xa0410600 +#define U5500_B2R2_BASE 0xa0200000 + +#define U5500_FSMC_BASE (U5500_PER1_BASE + 0x0000) +#define U5500_SDI0_BASE (U5500_PER1_BASE + 0x1000) +#define U5500_SDI2_BASE (U5500_PER1_BASE + 0x2000) +#define U5500_UART0_BASE (U5500_PER1_BASE + 0x3000) +#define U5500_I2C1_BASE (U5500_PER1_BASE + 0x4000) +#define U5500_MSP0_BASE (U5500_PER1_BASE + 0x5000) +#define U5500_GPIO0_BASE (U5500_PER1_BASE + 0xE000) +#define U5500_CLKRST1_BASE (U5500_PER1_BASE + 0xF000) + +#define U5500_USBOTG_BASE (U5500_PER2_BASE + 0x0000) +#define U5500_GPIO1_BASE (U5500_PER2_BASE + 0xE000) +#define U5500_CLKRST2_BASE (U5500_PER2_BASE + 0xF000) + +#define U5500_KEYPAD_BASE (U5500_PER3_BASE + 0x0000) +#define U5500_PWM_BASE (U5500_PER3_BASE + 0x1000) +#define U5500_GPIO3_BASE (U5500_PER3_BASE + 0xE000) +#define U5500_CLKRST3_BASE (U5500_PER3_BASE + 0xF000) + +#define U5500_BACKUPRAM0_BASE (U5500_PER4_BASE + 0x0000) +#define U5500_BACKUPRAM1_BASE (U5500_PER4_BASE + 0x1000) +#define U5500_RTT0_BASE (U5500_PER4_BASE + 0x2000) +#define U5500_RTT1_BASE (U5500_PER4_BASE + 0x3000) +#define U5500_RTC_BASE (U5500_PER4_BASE + 0x4000) +#define U5500_SCR_BASE (U5500_PER4_BASE + 0x5000) +#define U5500_DMC_BASE (U5500_PER4_BASE + 0x6000) +#define U5500_PRCMU_BASE (U5500_PER4_BASE + 0x7000) +#define U5500_MSP1_BASE (U5500_PER4_BASE + 0x9000) +#define U5500_GPIO2_BASE (U5500_PER4_BASE + 0xA000) +#define U5500_CDETECT_BASE (U5500_PER4_BASE + 0xF000) + +#define U5500_SPI0_BASE (U5500_PER5_BASE + 0x0000) +#define U5500_SPI1_BASE (U5500_PER5_BASE + 0x1000) +#define U5500_SPI2_BASE (U5500_PER5_BASE + 0x2000) +#define U5500_SPI3_BASE (U5500_PER5_BASE + 0x3000) +#define U5500_UART1_BASE (U5500_PER5_BASE + 0x4000) +#define U5500_UART2_BASE (U5500_PER5_BASE + 0x5000) +#define U5500_UART3_BASE (U5500_PER5_BASE + 0x6000) +#define U5500_SDI1_BASE (U5500_PER5_BASE + 0x7000) +#define U5500_SDI3_BASE (U5500_PER5_BASE + 0x8000) +#define U5500_SDI4_BASE (U5500_PER5_BASE + 0x9000) +#define U5500_I2C2_BASE (U5500_PER5_BASE + 0xA000) +#define U5500_I2C3_BASE (U5500_PER5_BASE + 0xB000) +#define U5500_MSP2_BASE (U5500_PER5_BASE + 0xC000) +#define U5500_IRDA_BASE (U5500_PER5_BASE + 0xD000) +#define U5500_IRRC_BASE (U5500_PER5_BASE + 0x10000) +#define U5500_GPIO4_BASE (U5500_PER5_BASE + 0x1E000) +#define U5500_CLKRST5_BASE (U5500_PER5_BASE + 0x1F000) + +#define U5500_RNG_BASE (U5500_PER6_BASE + 0x0000) +#define U5500_HASH0_BASE (U5500_PER6_BASE + 0x1000) +#define U5500_HASH1_BASE (U5500_PER6_BASE + 0x2000) +#define U5500_PKA_BASE (U5500_PER6_BASE + 0x4000) +#define U5500_PKAM_BASE (U5500_PER6_BASE + 0x5000) +#define U5500_MTU0_BASE (U5500_PER6_BASE + 0x6000) +#define U5500_MTU1_BASE (U5500_PER6_BASE + 0x7000) +#define U5500_CR_BASE (U5500_PER6_BASE + 0x8000) +#define U5500_CRYP0_BASE (U5500_PER6_BASE + 0xA000) +#define U5500_CRYP1_BASE (U5500_PER6_BASE + 0xB000) +#define U5500_CLKRST6_BASE (U5500_PER6_BASE + 0xF000) + +#define U5500_GPIOBANK0_BASE U5500_GPIO0_BASE +#define U5500_GPIOBANK1_BASE (U5500_GPIO0_BASE + 0x80) +#define U5500_GPIOBANK2_BASE U5500_GPIO1_BASE +#define U5500_GPIOBANK3_BASE U5500_GPIO2_BASE +#define U5500_GPIOBANK4_BASE U5500_GPIO3_BASE +#define U5500_GPIOBANK5_BASE U5500_GPIO4_BASE +#define U5500_GPIOBANK6_BASE (U5500_GPIO4_BASE + 0x80) +#define U5500_GPIOBANK7_BASE (U5500_GPIO4_BASE + 0x100) + +#endif diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h new file mode 100644 index 000000000000..9169e1e382a3 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __MACH_DB8500_REGS_H +#define __MACH_DB8500_REGS_H + +#define U8500_PER3_BASE 0x80000000 +#define U8500_STM_BASE 0x80100000 +#define U8500_STM_REG_BASE (U8500_STM_BASE + 0xF000) +#define U8500_PER2_BASE 0x80110000 +#define U8500_PER1_BASE 0x80120000 +#define U8500_B2R2_BASE 0x80130000 +#define U8500_HSEM_BASE 0x80140000 +#define U8500_PER4_BASE 0x80150000 +#define U8500_ICN_BASE 0x81000000 + +#define U8500_BOOT_ROM_BASE 0x90000000 +/* ASIC ID is at 0xff4 offset within this region */ +#define U8500_ASIC_ID_BASE 0x9001F000 + +#define U8500_PER6_BASE 0xa03c0000 +#define U8500_PER5_BASE 0xa03e0000 +#define U8500_PER7_BASE_ED 0xa03d0000 + +#define U8500_SVA_BASE 0xa0100000 +#define U8500_SIA_BASE 0xa0200000 + +#define U8500_SGA_BASE 0xa0300000 +#define U8500_MCDE_BASE 0xa0350000 +#define U8500_DMA_BASE_ED 0xa0362000 +#define U8500_DMA_BASE 0x801C0000 /* v1 */ + +#define U8500_SBAG_BASE 0xa0390000 + +#define U8500_SCU_BASE 0xa0410000 +#define U8500_GIC_CPU_BASE 0xa0410100 +#define U8500_TWD_BASE 0xa0410600 +#define U8500_GIC_DIST_BASE 0xa0411000 +#define U8500_L2CC_BASE 0xa0412000 + +#define U8500_MODEM_I2C 0xb7e02000 + +#define U8500_GPIO0_BASE (U8500_PER1_BASE + 0xE000) +#define U8500_GPIO1_BASE (U8500_PER3_BASE + 0xE000) +#define U8500_GPIO2_BASE (U8500_PER2_BASE + 0xE000) +#define U8500_GPIO3_BASE (U8500_PER5_BASE + 0x1E000) + +/* per7 base addressess */ +#define U8500_CR_BASE_ED (U8500_PER7_BASE_ED + 0x8000) +#define U8500_MTU0_BASE_ED (U8500_PER7_BASE_ED + 0xa000) +#define U8500_MTU1_BASE_ED (U8500_PER7_BASE_ED + 0xb000) +#define U8500_TZPC0_BASE_ED (U8500_PER7_BASE_ED + 0xc000) +#define U8500_CLKRST7_BASE_ED (U8500_PER7_BASE_ED + 0xf000) + +#define U8500_UART0_BASE (U8500_PER1_BASE + 0x0000) +#define U8500_UART1_BASE (U8500_PER1_BASE + 0x1000) + +/* per6 base addressess */ +#define U8500_RNG_BASE (U8500_PER6_BASE + 0x0000) +#define U8500_PKA_BASE (U8500_PER6_BASE + 0x1000) +#define U8500_PKAM_BASE (U8500_PER6_BASE + 0x2000) +#define U8500_MTU0_BASE (U8500_PER6_BASE + 0x6000) /* v1 */ +#define U8500_MTU1_BASE (U8500_PER6_BASE + 0x7000) /* v1 */ +#define U8500_CR_BASE (U8500_PER6_BASE + 0x8000) /* v1 */ +#define U8500_CRYPTO0_BASE (U8500_PER6_BASE + 0xa000) +#define U8500_CRYPTO1_BASE (U8500_PER6_BASE + 0xb000) +#define U8500_CLKRST6_BASE (U8500_PER6_BASE + 0xf000) + +/* per5 base addressess */ +#define U8500_USBOTG_BASE (U8500_PER5_BASE + 0x00000) +#define U8500_CLKRST5_BASE (U8500_PER5_BASE + 0x1f000) + +/* per4 base addressess */ +#define U8500_BACKUPRAM0_BASE (U8500_PER4_BASE + 0x00000) +#define U8500_BACKUPRAM1_BASE (U8500_PER4_BASE + 0x01000) +#define U8500_RTT0_BASE (U8500_PER4_BASE + 0x02000) +#define U8500_RTT1_BASE (U8500_PER4_BASE + 0x03000) +#define U8500_RTC_BASE (U8500_PER4_BASE + 0x04000) +#define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000) +#define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000) +#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000) +#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x0f000) + +/* per3 base addresses */ +#define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000) +#define U8500_SSP0_BASE (U8500_PER3_BASE + 0x2000) +#define U8500_SSP1_BASE (U8500_PER3_BASE + 0x3000) +#define U8500_I2C0_BASE (U8500_PER3_BASE + 0x4000) +#define U8500_SDI2_BASE (U8500_PER3_BASE + 0x5000) +#define U8500_SKE_BASE (U8500_PER3_BASE + 0x6000) +#define U8500_UART2_BASE (U8500_PER3_BASE + 0x7000) +#define U8500_SDI5_BASE (U8500_PER3_BASE + 0x8000) +#define U8500_CLKRST3_BASE (U8500_PER3_BASE + 0xf000) + +/* per2 base addressess */ +#define U8500_I2C3_BASE (U8500_PER2_BASE + 0x0000) +#define U8500_SPI2_BASE (U8500_PER2_BASE + 0x1000) +#define U8500_SPI1_BASE (U8500_PER2_BASE + 0x2000) +#define U8500_PWL_BASE (U8500_PER2_BASE + 0x3000) +#define U8500_SDI4_BASE (U8500_PER2_BASE + 0x4000) +#define U8500_MSP2_BASE (U8500_PER2_BASE + 0x7000) +#define U8500_SDI1_BASE (U8500_PER2_BASE + 0x8000) +#define U8500_SDI3_BASE (U8500_PER2_BASE + 0x9000) +#define U8500_SPI0_BASE (U8500_PER2_BASE + 0xa000) +#define U8500_HSIR_BASE (U8500_PER2_BASE + 0xb000) +#define U8500_HSIT_BASE (U8500_PER2_BASE + 0xc000) +#define U8500_CLKRST2_BASE (U8500_PER2_BASE + 0xf000) + +/* per1 base addresses */ +#define U8500_I2C1_BASE (U8500_PER1_BASE + 0x2000) +#define U8500_MSP0_BASE (U8500_PER1_BASE + 0x3000) +#define U8500_MSP1_BASE (U8500_PER1_BASE + 0x4000) +#define U8500_SDI0_BASE (U8500_PER1_BASE + 0x6000) +#define U8500_I2C2_BASE (U8500_PER1_BASE + 0x8000) +#define U8500_SPI3_BASE (U8500_PER1_BASE + 0x9000) +#define U8500_I2C4_BASE (U8500_PER1_BASE + 0xa000) +#define U8500_SLIM0_BASE (U8500_PER1_BASE + 0xb000) +#define U8500_CLKRST1_BASE (U8500_PER1_BASE + 0xf000) + +#define U8500_SHRM_GOP_INTERRUPT_BASE 0xB7C00040 + +#define U8500_GPIOBANK0_BASE U8500_GPIO0_BASE +#define U8500_GPIOBANK1_BASE (U8500_GPIO0_BASE + 0x80) +#define U8500_GPIOBANK2_BASE U8500_GPIO1_BASE +#define U8500_GPIOBANK3_BASE (U8500_GPIO1_BASE + 0x80) +#define U8500_GPIOBANK4_BASE (U8500_GPIO1_BASE + 0x100) +#define U8500_GPIOBANK5_BASE (U8500_GPIO1_BASE + 0x180) +#define U8500_GPIOBANK6_BASE U8500_GPIO2_BASE +#define U8500_GPIOBANK7_BASE (U8500_GPIO2_BASE + 0x80) +#define U8500_GPIOBANK8_BASE U8500_GPIO3_BASE + +#endif diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index d86b3543dd23..1353f1757057 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h @@ -26,119 +26,67 @@ /* used by some plat-nomadik code */ #define io_p2v(n) __io_address(n) -/* - * Base address definitions for U8500 Onchip IPs. All the - * peripherals are contained in a single 1 Mbyte region, with - * AHB peripherals at the bottom and APB peripherals at the - * top of the region. PER stands for PERIPHERAL region which - * itself divided into sub regions. - */ -#define U8500_PER3_BASE 0x80000000 -#define U8500_PER2_BASE 0x80110000 -#define U8500_PER1_BASE 0x80120000 -#define U8500_PER4_BASE 0x80150000 - -#define U8500_PER6_BASE 0xa03c0000 -#define U8500_PER5_BASE 0xa03e0000 -#define U8500_PER7_BASE 0xa03d0000 - -#define U8500_SVA_BASE 0xa0100000 -#define U8500_SIA_BASE 0xa0200000 - -#define U8500_SGA_BASE 0xa0300000 -#define U8500_MCDE_BASE 0xa0350000 -#define U8500_DMA_BASE 0xa0362000 - -#define U8500_SCU_BASE 0xa0410000 -#define U8500_GIC_CPU_BASE 0xa0410100 -#define U8500_TWD_BASE 0xa0410600 -#define U8500_GIC_DIST_BASE 0xa0411000 -#define U8500_L2CC_BASE 0xa0412000 - -#define U8500_TWD_SIZE 0x100 - -/* per7 base addressess */ -#define U8500_CR_BASE_ED (U8500_PER7_BASE + 0x8000) -#define U8500_MTU0_BASE_ED (U8500_PER7_BASE + 0xa000) -#define U8500_MTU1_BASE_ED (U8500_PER7_BASE + 0xb000) -#define U8500_TZPC0_BASE_ED (U8500_PER7_BASE + 0xc000) -#define U8500_CLKRST7_BASE_ED (U8500_PER7_BASE + 0xf000) - -/* per6 base addressess */ -#define U8500_RNG_BASE (U8500_PER6_BASE + 0x0000) -#define U8500_PKA_BASE (U8500_PER6_BASE + 0x1000) -#define U8500_PKAM_BASE (U8500_PER6_BASE + 0x2000) -#define U8500_MTU0_BASE_V1 (U8500_PER6_BASE + 0x6000) -#define U8500_MTU1_BASE_V1 (U8500_PER6_BASE + 0x7000) -#define U8500_CR_BASE_V1 (U8500_PER6_BASE + 0x8000) -#define U8500_CRYPTO0_BASE (U8500_PER6_BASE + 0xa000) -#define U8500_CRYPTO1_BASE (U8500_PER6_BASE + 0xb000) -#define U8500_CLKRST6_BASE (U8500_PER6_BASE + 0xf000) - -/* per5 base addressess */ -#define U8500_USBOTG_BASE (U8500_PER5_BASE + 0x00000) -#define U8500_GPIO5_BASE (U8500_PER5_BASE + 0x1e000) -#define U8500_CLKRST5_BASE (U8500_PER5_BASE + 0x1f000) - -/* per4 base addressess */ -#define U8500_BACKUPRAM0_BASE (U8500_PER4_BASE + 0x0000) -#define U8500_BACKUPRAM1_BASE (U8500_PER4_BASE + 0x1000) -#define U8500_RTT0_BASE (U8500_PER4_BASE + 0x2000) -#define U8500_RTT1_BASE (U8500_PER4_BASE + 0x3000) -#define U8500_RTC_BASE (U8500_PER4_BASE + 0x4000) -#define U8500_SCR_BASE (U8500_PER4_BASE + 0x5000) -#define U8500_DMC_BASE (U8500_PER4_BASE + 0x6000) -#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x7000) - -/* per3 base addressess */ -#define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000) -#define U8500_SSP0_BASE (U8500_PER3_BASE + 0x2000) -#define U8500_SSP1_BASE (U8500_PER3_BASE + 0x3000) -#define U8500_I2C0_BASE (U8500_PER3_BASE + 0x4000) -#define U8500_SDI2_BASE (U8500_PER3_BASE + 0x5000) -#define U8500_SKE_BASE (U8500_PER3_BASE + 0x6000) -#define U8500_UART2_BASE (U8500_PER3_BASE + 0x7000) -#define U8500_SDI5_BASE (U8500_PER3_BASE + 0x8000) -#define U8500_GPIO3_BASE (U8500_PER3_BASE + 0xe000) -#define U8500_CLKRST3_BASE (U8500_PER3_BASE + 0xf000) - -/* per2 base addressess */ -#define U8500_I2C3_BASE (U8500_PER2_BASE + 0x0000) -#define U8500_SPI2_BASE (U8500_PER2_BASE + 0x1000) -#define U8500_SPI1_BASE (U8500_PER2_BASE + 0x2000) -#define U8500_PWL_BASE (U8500_PER2_BASE + 0x3000) -#define U8500_SDI4_BASE (U8500_PER2_BASE + 0x4000) -#define U8500_MSP2_BASE (U8500_PER2_BASE + 0x7000) -#define U8500_SDI1_BASE (U8500_PER2_BASE + 0x8000) -#define U8500_SDI3_BASE (U8500_PER2_BASE + 0x9000) -#define U8500_SPI0_BASE (U8500_PER2_BASE + 0xa000) -#define U8500_HSIR_BASE (U8500_PER2_BASE + 0xb000) -#define U8500_HSIT_BASE (U8500_PER2_BASE + 0xc000) -#define U8500_GPIO2_BASE (U8500_PER2_BASE + 0xe000) -#define U8500_CLKRST2_BASE (U8500_PER2_BASE + 0xf000) - -/* per1 base addresses */ -#define U8500_UART0_BASE (U8500_PER1_BASE + 0x0000) -#define U8500_UART1_BASE (U8500_PER1_BASE + 0x1000) -#define U8500_I2C1_BASE (U8500_PER1_BASE + 0x2000) -#define U8500_MSP0_BASE (U8500_PER1_BASE + 0x3000) -#define U8500_MSP1_BASE (U8500_PER1_BASE + 0x4000) -#define U8500_SDI0_BASE (U8500_PER1_BASE + 0x6000) -#define U8500_I2C2_BASE (U8500_PER1_BASE + 0x8000) -#define U8500_SPI3_BASE (U8500_PER1_BASE + 0x9000) -#define U8500_SLIM0_BASE (U8500_PER1_BASE + 0xa000) -#define U8500_GPIO1_BASE (U8500_PER1_BASE + 0xe000) -#define U8500_CLKRST1_BASE (U8500_PER1_BASE + 0xf000) - -#define U8500_GPIOBANK0_BASE U8500_GPIO1_BASE -#define U8500_GPIOBANK1_BASE (U8500_GPIO1_BASE + 0x80) -#define U8500_GPIOBANK2_BASE U8500_GPIO3_BASE -#define U8500_GPIOBANK3_BASE (U8500_GPIO3_BASE + 0x80) -#define U8500_GPIOBANK4_BASE (U8500_GPIO3_BASE + 0x100) -#define U8500_GPIOBANK5_BASE (U8500_GPIO3_BASE + 0x180) -#define U8500_GPIOBANK6_BASE U8500_GPIO2_BASE -#define U8500_GPIOBANK7_BASE (U8500_GPIO2_BASE + 0x80) -#define U8500_GPIOBANK8_BASE U8500_GPIO5_BASE +#include +#include + +#ifdef CONFIG_UX500_SOC_DB8500 +#define UX500(periph) U8500_##periph##_BASE +#elif defined(CONFIG_UX500_SOC_DB5500) +#define UX500(periph) U5500_##periph##_BASE +#endif + +#define UX500_BACKUPRAM0_BASE UX500(BACKUPRAM0) +#define UX500_BACKUPRAM1_BASE UX500(BACKUPRAM1) +#define UX500_B2R2_BASE UX500(B2R2) + +#define UX500_CLKRST1_BASE UX500(CLKRST1) +#define UX500_CLKRST2_BASE UX500(CLKRST2) +#define UX500_CLKRST3_BASE UX500(CLKRST3) +#define UX500_CLKRST5_BASE UX500(CLKRST5) +#define UX500_CLKRST6_BASE UX500(CLKRST6) + +#define UX500_DMA_BASE UX500(DMA) +#define UX500_FSMC_BASE UX500(FSMC) + +#define UX500_GIC_CPU_BASE UX500(GIC_CPU) +#define UX500_GIC_DIST_BASE UX500(GIC_DIST) + +#define UX500_I2C1_BASE UX500(I2C1) +#define UX500_I2C2_BASE UX500(I2C2) +#define UX500_I2C3_BASE UX500(I2C3) + +#define UX500_L2CC_BASE UX500(L2CC) +#define UX500_MCDE_BASE UX500(MCDE) +#define UX500_MTU0_BASE UX500(MTU0) +#define UX500_MTU1_BASE UX500(MTU1) +#define UX500_PRCMU_BASE UX500(PRCMU) + +#define UX500_RNG_BASE UX500(RNG) +#define UX500_RTC_BASE UX500(RTC) + +#define UX500_SCU_BASE UX500(SCU) + +#define UX500_SDI0_BASE UX500(SDI0) +#define UX500_SDI1_BASE UX500(SDI1) +#define UX500_SDI2_BASE UX500(SDI2) +#define UX500_SDI3_BASE UX500(SDI3) +#define UX500_SDI4_BASE UX500(SDI4) + +#define UX500_SPI0_BASE UX500(SPI0) +#define UX500_SPI1_BASE UX500(SPI1) +#define UX500_SPI2_BASE UX500(SPI2) +#define UX500_SPI3_BASE UX500(SPI3) + +#define UX500_SIA_BASE UX500(SIA) +#define UX500_SVA_BASE UX500(SVA) + +#define UX500_TWD_BASE UX500(TWD) + +#define UX500_UART0_BASE UX500(UART0) +#define UX500_UART1_BASE UX500(UART1) +#define UX500_UART2_BASE UX500(UART2) + +#define UX500_USBOTG_BASE UX500(USBOTG) /* ST-Ericsson modified pl022 id */ #define SSP_PER_ID 0x01080022 -- cgit v1.2.3-59-g8ed1b From 39a982b4cda1b9c129094a411962348827412d50 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 07:38:06 +0100 Subject: ARM: 6079/1: ux500: allow choice of the DEBUG_LL UART Allow the UART used for DEBUG_LL to be selected. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/Kconfig | 7 +++++++ arch/arm/mach-ux500/include/mach/debug-macro.S | 12 ++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 699588f7da87..8ad5ee8107ae 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -27,4 +27,11 @@ config MACH_U8500_MOP on early drop silicon version of 8500. endmenu +config UX500_DEBUG_UART + int "Ux500 UART to use for low-level debug" + default 2 + help + Choose the UART on which kernel low-level debug messages should be + output. + endif diff --git a/arch/arm/mach-ux500/include/mach/debug-macro.S b/arch/arm/mach-ux500/include/mach/debug-macro.S index 09cbfda8aee5..c5203b7ea552 100644 --- a/arch/arm/mach-ux500/include/mach/debug-macro.S +++ b/arch/arm/mach-ux500/include/mach/debug-macro.S @@ -10,11 +10,19 @@ */ #include +#if CONFIG_UX500_DEBUG_UART > 2 +#error Invalid Ux500 debug UART +#endif + +#define __UX500_UART(n) UX500_UART##n##_BASE +#define UX500_UART(n) __UX500_UART(n) +#define UART_BASE UX500_UART(CONFIG_UX500_DEBUG_UART) + .macro addruart, rx, tmp mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? - ldreq \rx, =U8500_UART2_BASE @ no, physical address - ldrne \rx, =IO_ADDRESS(U8500_UART2_BASE) @ yes, virtual address + ldreq \rx, =UART_BASE @ no, physical address + ldrne \rx, =IO_ADDRESS(UART_BASE) @ yes, virtual address .endm #include -- cgit v1.2.3-59-g8ed1b From 178980f98eef58607647eb66e178bf984bf81f4c Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 07:39:02 +0100 Subject: ARM: 6080/1: ux500: move irq and common maps to cpu.c Move IRQ initialization and common io mapping setup code to cpu.c, renaming U8500* to UX500* along the way. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/Makefile | 2 +- arch/arm/mach-ux500/board-mop500.c | 2 +- arch/arm/mach-ux500/cpu-u8500.c | 44 +-------------------- arch/arm/mach-ux500/cpu.c | 68 ++++++++++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/setup.h | 13 +++++- 5 files changed, 83 insertions(+), 46 deletions(-) create mode 100644 arch/arm/mach-ux500/cpu.c (limited to 'arch') diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 95e6e24c0042..6deee85dfbe0 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel, U8500 machine. # -obj-y := clock.o +obj-y := clock.o cpu.o obj-$(CONFIG_ARCH_U8500) += cpu-u8500.o obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 4335186135e4..9ca47095db76 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -221,7 +221,7 @@ MACHINE_START(U8500, "ST-Ericsson MOP500 platform") .io_pg_offst = (IO_ADDRESS(U8500_UART2_BASE) >> 18) & 0xfffc, .boot_params = 0x100, .map_io = u8500_map_io, - .init_irq = u8500_init_irq, + .init_irq = ux500_init_irq, /* we re-use nomadik timer here */ .timer = &u8500_timer, .init_machine = u8500_init_machine, diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index 8919af4eeeb5..2c8aa93dca6e 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -18,9 +18,7 @@ #include #include -#include #include -#include #include #include #include @@ -103,32 +101,13 @@ static struct platform_device *platform_devs[] __initdata = { &u8500_gpio_devs[8], }; -#define __IO_DEV_DESC(x, sz) { \ - .virtual = IO_ADDRESS(x), \ - .pfn = __phys_to_pfn(x), \ - .length = sz, \ - .type = MT_DEVICE, \ -} - /* minimum static i/o mapping required to boot U8500 platforms */ static struct map_desc u8500_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_UART2_BASE, SZ_4K), - __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K), - __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K), - __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K), - __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), - __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), - __IO_DEV_DESC(U8500_CLKRST1_BASE, SZ_4K), - __IO_DEV_DESC(U8500_CLKRST2_BASE, SZ_4K), - __IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K), - __IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K), - __IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), - __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K), }; static struct map_desc u8500ed_io_desc[] __initdata = { @@ -142,6 +121,8 @@ static struct map_desc u8500v1_io_desc[] __initdata = { void __init u8500_map_io(void) { + ux500_map_io(); + iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); if (cpu_is_u8500ed()) @@ -150,12 +131,6 @@ void __init u8500_map_io(void) iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); } -void __init u8500_init_irq(void) -{ - gic_dist_init(0, __io_address(U8500_GIC_DIST_BASE), 29); - gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE)); -} - /* * This function is called from the board init */ @@ -185,18 +160,3 @@ static void __init u8500_timer_init(void) struct sys_timer u8500_timer = { .init = u8500_timer_init, }; - -#ifdef CONFIG_CACHE_L2X0 -static int u8500_l2x0_init(void) -{ - void __iomem *l2x0_base; - - l2x0_base = __io_address(U8500_L2CC_BASE); - - /* 64KB way size, 8 way associativity, force WA */ - l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); - - return 0; -} -early_initcall(u8500_l2x0_init); -#endif diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c new file mode 100644 index 000000000000..e6a8058cd735 --- /dev/null +++ b/arch/arm/mach-ux500/cpu.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "clock.h" + +static struct map_desc ux500_io_desc[] __initdata = { + __IO_DEV_DESC(UX500_UART0_BASE, SZ_4K), + __IO_DEV_DESC(UX500_UART2_BASE, SZ_4K), + + __IO_DEV_DESC(UX500_GIC_CPU_BASE, SZ_4K), + __IO_DEV_DESC(UX500_GIC_DIST_BASE, SZ_4K), + __IO_DEV_DESC(UX500_L2CC_BASE, SZ_4K), + __IO_DEV_DESC(UX500_TWD_BASE, SZ_4K), + __IO_DEV_DESC(UX500_SCU_BASE, SZ_4K), + + __IO_DEV_DESC(UX500_CLKRST1_BASE, SZ_4K), + __IO_DEV_DESC(UX500_CLKRST2_BASE, SZ_4K), + __IO_DEV_DESC(UX500_CLKRST3_BASE, SZ_4K), + __IO_DEV_DESC(UX500_CLKRST5_BASE, SZ_4K), + __IO_DEV_DESC(UX500_CLKRST6_BASE, SZ_4K), + + __IO_DEV_DESC(UX500_MTU0_BASE, SZ_4K), + __IO_DEV_DESC(UX500_MTU1_BASE, SZ_4K), + + __IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K), +}; + +void __init ux500_map_io(void) +{ + iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc)); +} + +void __init ux500_init_irq(void) +{ + gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); + gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE)); +} + +#ifdef CONFIG_CACHE_L2X0 +static int ux500_l2x0_init(void) +{ + void __iomem *l2x0_base; + + l2x0_base = __io_address(UX500_L2CC_BASE); + + /* 64KB way size, 8 way associativity, force WA */ + l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); + + return 0; +} +early_initcall(ux500_l2x0_init); +#endif diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index 65112bfd7a0c..6c4c348fbdbb 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -14,13 +14,22 @@ #include #include -extern void u8500_map_io(void); +extern void __init ux500_map_io(void); +extern void __init u8500_map_io(void); + extern void u8500_init_devices(void); -extern void u8500_init_irq(void); +extern void __init ux500_init_irq(void); /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); struct sys_timer; extern struct sys_timer u8500_timer; +#define __IO_DEV_DESC(x, sz) { \ + .virtual = IO_ADDRESS(x), \ + .pfn = __phys_to_pfn(x), \ + .length = sz, \ + .type = MT_DEVICE, \ +} + #endif /* __ASM_ARCH_SETUP_H */ -- cgit v1.2.3-59-g8ed1b From d67d1127a625cc5ebc3802180b19cc74f35b5578 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 07:43:48 +0100 Subject: ARM: 6081/1: ux500: move gpio macros to common header Move GPIO macros to a common header, and allow them to use the correct macros for the appropriate SoC, and be named accordingly. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/cpu-u8500.c | 30 -------------------------- arch/arm/mach-ux500/include/mach/gpio.h | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index 2c8aa93dca6e..c80beca0f977 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -23,36 +23,6 @@ #include #include -#define GPIO_RESOURCE(block) \ - { \ - .start = U8500_GPIOBANK##block##_BASE, \ - .end = U8500_GPIOBANK##block##_BASE + 127, \ - .flags = IORESOURCE_MEM, \ - }, \ - { \ - .start = IRQ_GPIO##block, \ - .end = IRQ_GPIO##block, \ - .flags = IORESOURCE_IRQ, \ - } - -#define GPIO_DEVICE(block) \ - { \ - .name = "gpio", \ - .id = block, \ - .num_resources = 2, \ - .resource = &u8500_gpio_resources[block * 2], \ - .dev = { \ - .platform_data = &u8500_gpio_data[block], \ - }, \ - } - -#define GPIO_DATA(_name, first) \ - { \ - .name = _name, \ - .first_gpio = first, \ - .first_irq = NOMADIK_GPIO_TO_IRQ(first), \ - } - static struct nmk_gpio_platform_data u8500_gpio_data[] = { GPIO_DATA("GPIO-0-31", 0), GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */ diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h index 3c4cd31ad9f7..d548a622e7d2 100644 --- a/arch/arm/mach-ux500/include/mach/gpio.h +++ b/arch/arm/mach-ux500/include/mach/gpio.h @@ -9,4 +9,42 @@ #include +#define __GPIO_RESOURCE(soc, block) \ + { \ + .start = soc##_GPIOBANK##block##_BASE, \ + .end = soc##_GPIOBANK##block##_BASE + 127, \ + .flags = IORESOURCE_MEM, \ + }, \ + { \ + .start = IRQ_GPIO##block, \ + .end = IRQ_GPIO##block, \ + .flags = IORESOURCE_IRQ, \ + } + +#define __GPIO_DEVICE(soc, block) \ + { \ + .name = "gpio", \ + .id = block, \ + .num_resources = 2, \ + .resource = &soc##_gpio_resources[block * 2], \ + .dev = { \ + .platform_data = &soc##_gpio_data[block], \ + }, \ + } + +#define GPIO_DATA(_name, first) \ + { \ + .name = _name, \ + .first_gpio = first, \ + .first_irq = NOMADIK_GPIO_TO_IRQ(first), \ + } + +#ifdef CONFIG_UX500_SOC_DB8500 +#define GPIO_RESOURCE(block) __GPIO_RESOURCE(U8500, block) +#define GPIO_DEVICE(block) __GPIO_DEVICE(u8500, block) +#elif defined(CONFIG_UX500_SOC_DB5500) +#define GPIO_RESOURCE(block) __GPIO_RESOURCE(U5500, block) +#define GPIO_DEVICE(block) __GPIO_DEVICE(u5500, block) +#endif + #endif /* __ASM_ARCH_GPIO_H */ -- cgit v1.2.3-59-g8ed1b From d48fd006e6d9394e9abd14f4747034f73bb6a386 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 07:46:56 +0100 Subject: ARM: 6082/1: ux500: put common devices into devices.c Introduce devices.c, for placing devices common among Ux500 SoCs. Start with the PL031 device. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/Makefile | 2 +- arch/arm/mach-ux500/board-mop500.c | 13 ----------- arch/arm/mach-ux500/cpu-u8500.c | 2 ++ arch/arm/mach-ux500/cpu.c | 10 ++++++++ arch/arm/mach-ux500/devices.c | 37 ++++++++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/devices.h | 15 ++++++++++++ arch/arm/mach-ux500/include/mach/setup.h | 6 ++++- 7 files changed, 70 insertions(+), 15 deletions(-) create mode 100644 arch/arm/mach-ux500/devices.c create mode 100644 arch/arm/mach-ux500/include/mach/devices.h (limited to 'arch') diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 6deee85dfbe0..e5b9f742a0c9 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel, U8500 machine. # -obj-y := clock.o cpu.o +obj-y := clock.o cpu.o devices.o obj-$(CONFIG_ARCH_U8500) += cpu-u8500.o obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 9ca47095db76..cc52d53d7727 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -107,18 +107,6 @@ static struct amba_device pl022_device = { .periphid = SSP_PER_ID, }; -static struct amba_device pl031_device = { - .dev = { - .init_name = "pl031", - }, - .res = { - .start = U8500_RTC_BASE, - .end = U8500_RTC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_RTC_RTT, NO_IRQ}, -}; - #define U8500_I2C_RESOURCES(id, size) \ static struct resource u8500_i2c_resources_##id[] = { \ [0] = { \ @@ -188,7 +176,6 @@ static struct amba_device *amba_devs[] __initdata = { &uart1_device, &uart2_device, &pl022_device, - &pl031_device, }; /* add any platform devices here - TODO */ diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index c80beca0f977..730d020f0f99 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -106,6 +106,8 @@ void __init u8500_map_io(void) */ void __init u8500_init_devices(void) { + ux500_init_devices(); + /* Register the platform devices */ platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index e6a8058cd735..05615c094493 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -16,6 +16,7 @@ #include #include +#include #include "clock.h" @@ -41,11 +42,20 @@ static struct map_desc ux500_io_desc[] __initdata = { __IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K), }; +static struct amba_device *ux500_amba_devs[] __initdata = { + &ux500_pl031_device, +}; + void __init ux500_map_io(void) { iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc)); } +void __init ux500_init_devices(void) +{ + amba_add_devices(ux500_amba_devs, ARRAY_SIZE(ux500_amba_devs)); +} + void __init ux500_init_irq(void) { gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); diff --git a/arch/arm/mach-ux500/devices.c b/arch/arm/mach-ux500/devices.c new file mode 100644 index 000000000000..eef686a4802f --- /dev/null +++ b/arch/arm/mach-ux500/devices.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include +#include + +#include +#include + +struct amba_device ux500_pl031_device = { + .dev = { + .init_name = "pl031", + }, + .res = { + .start = UX500_RTC_BASE, + .end = UX500_RTC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_RTC_RTT, NO_IRQ}, +}; + +void __init amba_add_devices(struct amba_device *devs[], int num) +{ + int i; + + for (i = 0; i < num; i++) { + struct amba_device *d = devs[i]; + amba_device_register(d, &iomem_resource); + } +} diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h new file mode 100644 index 000000000000..5bca7c605cd6 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/devices.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __ASM_ARCH_DEVICES_H__ +#define __ASM_ARCH_DEVICES_H__ + +struct platform_device; +struct amba_device; + +extern struct amba_device ux500_pl031_device; + +#endif diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index 6c4c348fbdbb..6187effe92db 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -17,11 +17,15 @@ extern void __init ux500_map_io(void); extern void __init u8500_map_io(void); -extern void u8500_init_devices(void); +extern void __init ux500_init_devices(void); +extern void __init u8500_init_devices(void); + extern void __init ux500_init_irq(void); /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); +extern void __init amba_add_devices(struct amba_device *devs[], int num); + struct sys_timer; extern struct sys_timer u8500_timer; -- cgit v1.2.3-59-g8ed1b From 9e4e7fe1a97191e373257ab59e3d6bbcce9a9f1e Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 08:03:52 +0100 Subject: ARM: 6083/1: ux500: put DB8500-specific devices in devices-db8500.c Add devices-db8500.c for DB8500-specific devices, starting with SSP0. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/Makefile | 2 +- arch/arm/mach-ux500/board-mop500.c | 21 ++++----------------- arch/arm/mach-ux500/devices-db8500.c | 30 ++++++++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/devices.h | 1 + 4 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 arch/arm/mach-ux500/devices-db8500.c (limited to 'arch') diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index e5b9f742a0c9..55651e04ab43 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -3,6 +3,6 @@ # obj-y := clock.o cpu.o devices.o -obj-$(CONFIG_ARCH_U8500) += cpu-u8500.o +obj-$(CONFIG_ARCH_U8500) += cpu-u8500.o devices-db8500.o obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index cc52d53d7727..6bb9a3d3f51e 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -24,6 +24,7 @@ #include #include +#include #define __MEM_4K_RESOURCE(x) \ .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} @@ -91,22 +92,6 @@ static struct pl022_ssp_controller ssp0_platform_data = { .num_chipselect = 5, }; -static struct amba_device pl022_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "ssp0", - .platform_data = &ssp0_platform_data, - }, - .res = { - .start = U8500_SSP0_BASE, - .end = U8500_SSP0_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_SSP0, NO_IRQ }, - /* ST-Ericsson modified id */ - .periphid = SSP_PER_ID, -}; - #define U8500_I2C_RESOURCES(id, size) \ static struct resource u8500_i2c_resources_##id[] = { \ [0] = { \ @@ -175,7 +160,7 @@ static struct amba_device *amba_devs[] __initdata = { &uart0_device, &uart1_device, &uart2_device, - &pl022_device, + &u8500_ssp0_device, }; /* add any platform devices here - TODO */ @@ -190,6 +175,8 @@ static void __init u8500_init_machine(void) { int i; + u8500_ssp0_device.dev.platform_data = &ssp0_platform_data; + /* Register the active AMBA devices on this board */ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) amba_device_register(amba_devs[i], &iomem_resource); diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c new file mode 100644 index 000000000000..f4a2dda4d0ac --- /dev/null +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include +#include + +#include +#include + +struct amba_device u8500_ssp0_device = { + .dev = { + .coherent_dma_mask = ~0, + .init_name = "ssp0", + }, + .res = { + .start = U8500_SSP0_BASE, + .end = U8500_SSP0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_SSP0, NO_IRQ }, + /* ST-Ericsson modified id */ + .periphid = SSP_PER_ID, +}; diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h index 5bca7c605cd6..90229b168959 100644 --- a/arch/arm/mach-ux500/include/mach/devices.h +++ b/arch/arm/mach-ux500/include/mach/devices.h @@ -11,5 +11,6 @@ struct platform_device; struct amba_device; extern struct amba_device ux500_pl031_device; +extern struct amba_device u8500_ssp0_device; #endif -- cgit v1.2.3-59-g8ed1b From 4b27aa4140c20380a67ecefaa48cf3714cc0b8ea Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 08:18:38 +0100 Subject: ARM: 6084/1: ux500: move UART devices to devices.c The three PL011 UARTs are common among Ux500 SoCs, so move them to devices.c. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/board-mop500.c | 28 +++------------------------- arch/arm/mach-ux500/devices.c | 21 +++++++++++++++++++++ arch/arm/mach-ux500/include/mach/devices.h | 3 +++ 3 files changed, 27 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 6bb9a3d3f51e..0e595bf3366e 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -26,28 +26,6 @@ #include #include -#define __MEM_4K_RESOURCE(x) \ - .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} - -/* These are active devices on this board */ -static struct amba_device uart0_device = { - .dev = { .init_name = "uart0" }, - __MEM_4K_RESOURCE(U8500_UART0_BASE), - .irq = {IRQ_UART0, NO_IRQ}, -}; - -static struct amba_device uart1_device = { - .dev = { .init_name = "uart1" }, - __MEM_4K_RESOURCE(U8500_UART1_BASE), - .irq = {IRQ_UART1, NO_IRQ}, -}; - -static struct amba_device uart2_device = { - .dev = { .init_name = "uart2" }, - __MEM_4K_RESOURCE(U8500_UART2_BASE), - .irq = {IRQ_UART2, NO_IRQ}, -}; - static void ab4500_spi_cs_control(u32 command) { /* set the FRM signal, which is CS - TODO */ @@ -157,9 +135,9 @@ U8500_I2C_PDEVICE(2); U8500_I2C_PDEVICE(3); static struct amba_device *amba_devs[] __initdata = { - &uart0_device, - &uart1_device, - &uart2_device, + &ux500_uart0_device, + &ux500_uart1_device, + &ux500_uart2_device, &u8500_ssp0_device, }; diff --git a/arch/arm/mach-ux500/devices.c b/arch/arm/mach-ux500/devices.c index eef686a4802f..374fcceb10a9 100644 --- a/arch/arm/mach-ux500/devices.c +++ b/arch/arm/mach-ux500/devices.c @@ -14,6 +14,9 @@ #include #include +#define __MEM_4K_RESOURCE(x) \ + .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} + struct amba_device ux500_pl031_device = { .dev = { .init_name = "pl031", @@ -26,6 +29,24 @@ struct amba_device ux500_pl031_device = { .irq = {IRQ_RTC_RTT, NO_IRQ}, }; +struct amba_device ux500_uart0_device = { + .dev = { .init_name = "uart0" }, + __MEM_4K_RESOURCE(UX500_UART0_BASE), + .irq = {IRQ_UART0, NO_IRQ}, +}; + +struct amba_device ux500_uart1_device = { + .dev = { .init_name = "uart1" }, + __MEM_4K_RESOURCE(UX500_UART1_BASE), + .irq = {IRQ_UART1, NO_IRQ}, +}; + +struct amba_device ux500_uart2_device = { + .dev = { .init_name = "uart2" }, + __MEM_4K_RESOURCE(UX500_UART2_BASE), + .irq = {IRQ_UART2, NO_IRQ}, +}; + void __init amba_add_devices(struct amba_device *devs[], int num) { int i; diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h index 90229b168959..7cc4983c0f48 100644 --- a/arch/arm/mach-ux500/include/mach/devices.h +++ b/arch/arm/mach-ux500/include/mach/devices.h @@ -12,5 +12,8 @@ struct amba_device; extern struct amba_device ux500_pl031_device; extern struct amba_device u8500_ssp0_device; +extern struct amba_device ux500_uart0_device; +extern struct amba_device ux500_uart1_device; +extern struct amba_device ux500_uart2_device; #endif -- cgit v1.2.3-59-g8ed1b From f9faf23799d0726afb56ee6c6c53fbea00ec7de3 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 08:24:37 +0100 Subject: ARM: 6085/1: ux500: reorganize i2c devices Move common i2c devices to devices.c and DB8500-specific I2C devices to devices-db8500.c. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/board-mop500.c | 50 ++++++------------------------ arch/arm/mach-ux500/devices-db8500.c | 40 ++++++++++++++++++++++++ arch/arm/mach-ux500/devices.c | 30 ++++++++++++++++++ arch/arm/mach-ux500/include/mach/devices.h | 7 +++++ arch/arm/mach-ux500/include/mach/irqs.h | 1 + 5 files changed, 88 insertions(+), 40 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 0e595bf3366e..cd0bd36221b9 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -70,27 +70,8 @@ static struct pl022_ssp_controller ssp0_platform_data = { .num_chipselect = 5, }; -#define U8500_I2C_RESOURCES(id, size) \ -static struct resource u8500_i2c_resources_##id[] = { \ - [0] = { \ - .start = U8500_I2C##id##_BASE, \ - .end = U8500_I2C##id##_BASE + size - 1, \ - .flags = IORESOURCE_MEM, \ - }, \ - [1] = { \ - .start = IRQ_I2C##id, \ - .end = IRQ_I2C##id, \ - .flags = IORESOURCE_IRQ \ - } \ -} - -U8500_I2C_RESOURCES(0, SZ_4K); -U8500_I2C_RESOURCES(1, SZ_4K); -U8500_I2C_RESOURCES(2, SZ_4K); -U8500_I2C_RESOURCES(3, SZ_4K); - #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ -static struct nmk_i2c_controller u8500_i2c_##id = { \ +static struct nmk_i2c_controller u8500_i2c##id##_data = { \ /* \ * slave data setup time, which is \ * 250 ns,100ns,10ns which is 14,6,2 \ @@ -118,22 +99,6 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); U8500_I2C_CONTROLLER(2, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); U8500_I2C_CONTROLLER(3, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); -#define U8500_I2C_PDEVICE(cid) \ -static struct platform_device i2c_controller##cid = { \ - .name = "nmk-i2c", \ - .id = cid, \ - .num_resources = 2, \ - .resource = u8500_i2c_resources_##cid, \ - .dev = { \ - .platform_data = &u8500_i2c_##cid \ - } \ -} - -U8500_I2C_PDEVICE(0); -U8500_I2C_PDEVICE(1); -U8500_I2C_PDEVICE(2); -U8500_I2C_PDEVICE(3); - static struct amba_device *amba_devs[] __initdata = { &ux500_uart0_device, &ux500_uart1_device, @@ -143,16 +108,21 @@ static struct amba_device *amba_devs[] __initdata = { /* add any platform devices here - TODO */ static struct platform_device *platform_devs[] __initdata = { - &i2c_controller0, - &i2c_controller1, - &i2c_controller2, - &i2c_controller3, + &u8500_i2c0_device, + &ux500_i2c1_device, + &ux500_i2c2_device, + &ux500_i2c3_device, }; static void __init u8500_init_machine(void) { int i; + u8500_i2c0_device.dev.platform_data = &u8500_i2c0_data; + ux500_i2c1_device.dev.platform_data = &u8500_i2c1_data; + ux500_i2c2_device.dev.platform_data = &u8500_i2c2_data; + ux500_i2c3_device.dev.platform_data = &u8500_i2c3_data; + u8500_ssp0_device.dev.platform_data = &ssp0_platform_data; /* Register the active AMBA devices on this board */ diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index f4a2dda4d0ac..397f862c9ef4 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -28,3 +28,43 @@ struct amba_device u8500_ssp0_device = { /* ST-Ericsson modified id */ .periphid = SSP_PER_ID, }; + +static struct resource u8500_i2c0_resources[] = { + [0] = { + .start = U8500_I2C0_BASE, + .end = U8500_I2C0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_I2C0, + .end = IRQ_I2C0, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device u8500_i2c0_device = { + .name = "nmk-i2c", + .id = 0, + .resource = u8500_i2c0_resources, + .num_resources = ARRAY_SIZE(u8500_i2c0_resources), +}; + +static struct resource u8500_i2c4_resources[] = { + [0] = { + .start = U8500_I2C4_BASE, + .end = U8500_I2C4_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_I2C4, + .end = IRQ_I2C4, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device u8500_i2c4_device = { + .name = "nmk-i2c", + .id = 4, + .resource = u8500_i2c4_resources, + .num_resources = ARRAY_SIZE(u8500_i2c4_resources), +}; diff --git a/arch/arm/mach-ux500/devices.c b/arch/arm/mach-ux500/devices.c index 374fcceb10a9..8a268893cb7f 100644 --- a/arch/arm/mach-ux500/devices.c +++ b/arch/arm/mach-ux500/devices.c @@ -47,6 +47,36 @@ struct amba_device ux500_uart2_device = { .irq = {IRQ_UART2, NO_IRQ}, }; +#define UX500_I2C_RESOURCES(id, size) \ +static struct resource ux500_i2c##id##_resources[] = { \ + [0] = { \ + .start = UX500_I2C##id##_BASE, \ + .end = UX500_I2C##id##_BASE + size - 1, \ + .flags = IORESOURCE_MEM, \ + }, \ + [1] = { \ + .start = IRQ_I2C##id, \ + .end = IRQ_I2C##id, \ + .flags = IORESOURCE_IRQ \ + } \ +} + +UX500_I2C_RESOURCES(1, SZ_4K); +UX500_I2C_RESOURCES(2, SZ_4K); +UX500_I2C_RESOURCES(3, SZ_4K); + +#define UX500_I2C_PDEVICE(cid) \ +struct platform_device ux500_i2c##cid##_device = { \ + .name = "nmk-i2c", \ + .id = cid, \ + .num_resources = 2, \ + .resource = ux500_i2c##cid##_resources, \ +} + +UX500_I2C_PDEVICE(1); +UX500_I2C_PDEVICE(2); +UX500_I2C_PDEVICE(3); + void __init amba_add_devices(struct amba_device *devs[], int num) { int i; diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h index 7cc4983c0f48..251b4eb8694a 100644 --- a/arch/arm/mach-ux500/include/mach/devices.h +++ b/arch/arm/mach-ux500/include/mach/devices.h @@ -16,4 +16,11 @@ extern struct amba_device ux500_uart0_device; extern struct amba_device ux500_uart1_device; extern struct amba_device ux500_uart2_device; +extern struct platform_device ux500_i2c1_device; +extern struct platform_device ux500_i2c2_device; +extern struct platform_device ux500_i2c3_device; + +extern struct platform_device u8500_i2c0_device; +extern struct platform_device u8500_i2c4_device; + #endif diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h index 8a1f6976c245..7970684b1d09 100644 --- a/arch/arm/mach-ux500/include/mach/irqs.h +++ b/arch/arm/mach-ux500/include/mach/irqs.h @@ -42,6 +42,7 @@ #define IRQ_AB4500 (IRQ_SHPI_START + 40) #define IRQ_DISP (IRQ_SHPI_START + 48) #define IRQ_SiPI3 (IRQ_SHPI_START + 49) +#define IRQ_I2C4 (IRQ_SHPI_START + 51) #define IRQ_SSP1 (IRQ_SHPI_START + 52) #define IRQ_I2C2 (IRQ_SHPI_START + 55) #define IRQ_SDMMC0 (IRQ_SHPI_START + 60) -- cgit v1.2.3-59-g8ed1b From 5b1f7ddf18b75adeb433ef9d91a2e4bd7580facc Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 08:25:52 +0100 Subject: ARM: 6086/1: ux500: move gpio devices to devices-db8500.c The GPIO layout is different on DB5500, so move the current one to devices-db8500.c. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/cpu-u8500.c | 37 +----------------------------- arch/arm/mach-ux500/devices-db8500.c | 37 ++++++++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/devices.h | 2 ++ 3 files changed, 40 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index 730d020f0f99..51e9bf2d71e2 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -22,42 +22,7 @@ #include #include #include - -static struct nmk_gpio_platform_data u8500_gpio_data[] = { - GPIO_DATA("GPIO-0-31", 0), - GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */ - GPIO_DATA("GPIO-64-95", 64), - GPIO_DATA("GPIO-96-127", 96), /* 97..127 not routed to pin */ - GPIO_DATA("GPIO-128-159", 128), - GPIO_DATA("GPIO-160-191", 160), /* 172..191 not routed to pin */ - GPIO_DATA("GPIO-192-223", 192), - GPIO_DATA("GPIO-224-255", 224), /* 231..255 not routed to pin */ - GPIO_DATA("GPIO-256-288", 256), /* 258..288 not routed to pin */ -}; - -static struct resource u8500_gpio_resources[] = { - GPIO_RESOURCE(0), - GPIO_RESOURCE(1), - GPIO_RESOURCE(2), - GPIO_RESOURCE(3), - GPIO_RESOURCE(4), - GPIO_RESOURCE(5), - GPIO_RESOURCE(6), - GPIO_RESOURCE(7), - GPIO_RESOURCE(8), -}; - -static struct platform_device u8500_gpio_devs[] = { - GPIO_DEVICE(0), - GPIO_DEVICE(1), - GPIO_DEVICE(2), - GPIO_DEVICE(3), - GPIO_DEVICE(4), - GPIO_DEVICE(5), - GPIO_DEVICE(6), - GPIO_DEVICE(7), - GPIO_DEVICE(8), -}; +#include static struct platform_device *platform_devs[] __initdata = { &u8500_gpio_devs[0], diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 397f862c9ef4..20334236afce 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -9,11 +9,48 @@ #include #include #include +#include #include #include #include +static struct nmk_gpio_platform_data u8500_gpio_data[] = { + GPIO_DATA("GPIO-0-31", 0), + GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */ + GPIO_DATA("GPIO-64-95", 64), + GPIO_DATA("GPIO-96-127", 96), /* 98..127 not routed to pin */ + GPIO_DATA("GPIO-128-159", 128), + GPIO_DATA("GPIO-160-191", 160), /* 172..191 not routed to pin */ + GPIO_DATA("GPIO-192-223", 192), + GPIO_DATA("GPIO-224-255", 224), /* 231..255 not routed to pin */ + GPIO_DATA("GPIO-256-288", 256), /* 268..288 not routed to pin */ +}; + +static struct resource u8500_gpio_resources[] = { + GPIO_RESOURCE(0), + GPIO_RESOURCE(1), + GPIO_RESOURCE(2), + GPIO_RESOURCE(3), + GPIO_RESOURCE(4), + GPIO_RESOURCE(5), + GPIO_RESOURCE(6), + GPIO_RESOURCE(7), + GPIO_RESOURCE(8), +}; + +struct platform_device u8500_gpio_devs[] = { + GPIO_DEVICE(0), + GPIO_DEVICE(1), + GPIO_DEVICE(2), + GPIO_DEVICE(3), + GPIO_DEVICE(4), + GPIO_DEVICE(5), + GPIO_DEVICE(6), + GPIO_DEVICE(7), + GPIO_DEVICE(8), +}; + struct amba_device u8500_ssp0_device = { .dev = { .coherent_dma_mask = ~0, diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h index 251b4eb8694a..76b3569f055e 100644 --- a/arch/arm/mach-ux500/include/mach/devices.h +++ b/arch/arm/mach-ux500/include/mach/devices.h @@ -10,6 +10,8 @@ struct platform_device; struct amba_device; +extern struct platform_device u8500_gpio_devs[]; + extern struct amba_device ux500_pl031_device; extern struct amba_device u8500_ssp0_device; extern struct amba_device ux500_uart0_device; -- cgit v1.2.3-59-g8ed1b From 41ac329f607add059ae8b063375c5d9d6e7471cf Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 08:28:05 +0100 Subject: ARM: 6087/1: ux500: move sys_timer to cpu.c Move the common system timer setup code to cpu.c. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/board-mop500.c | 2 +- arch/arm/mach-ux500/cpu-u8500.c | 21 --------------------- arch/arm/mach-ux500/cpu.c | 21 +++++++++++++++++++++ arch/arm/mach-ux500/include/mach/setup.h | 2 +- 4 files changed, 23 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index cd0bd36221b9..072196c57263 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -145,6 +145,6 @@ MACHINE_START(U8500, "ST-Ericsson MOP500 platform") .map_io = u8500_map_io, .init_irq = ux500_init_irq, /* we re-use nomadik timer here */ - .timer = &u8500_timer, + .timer = &ux500_timer, .init_machine = u8500_init_machine, MACHINE_END diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index 51e9bf2d71e2..d04299f3b6b5 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -17,9 +17,7 @@ #include #include -#include #include -#include #include #include #include @@ -78,22 +76,3 @@ void __init u8500_init_devices(void) return ; } - -static void __init u8500_timer_init(void) -{ -#ifdef CONFIG_LOCAL_TIMERS - /* Setup the local timer base */ - twd_base = __io_address(U8500_TWD_BASE); -#endif - /* Setup the MTU base */ - if (cpu_is_u8500ed()) - mtu_base = __io_address(U8500_MTU0_BASE_ED); - else - mtu_base = __io_address(U8500_MTU0_BASE); - - nmdk_timer_init(); -} - -struct sys_timer u8500_timer = { - .init = u8500_timer_init, -}; diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 05615c094493..d81ad023963c 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -13,7 +13,9 @@ #include #include #include +#include +#include #include #include #include @@ -76,3 +78,22 @@ static int ux500_l2x0_init(void) } early_initcall(ux500_l2x0_init); #endif + +static void __init ux500_timer_init(void) +{ +#ifdef CONFIG_LOCAL_TIMERS + /* Setup the local timer base */ + twd_base = __io_address(UX500_TWD_BASE); +#endif + /* Setup the MTU base */ + if (cpu_is_u8500ed()) + mtu_base = __io_address(U8500_MTU0_BASE_ED); + else + mtu_base = __io_address(UX500_MTU0_BASE); + + nmdk_timer_init(); +} + +struct sys_timer ux500_timer = { + .init = ux500_timer_init, +}; diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index 6187effe92db..c730d078f9ab 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -27,7 +27,7 @@ extern void nmdk_timer_init(void); extern void __init amba_add_devices(struct amba_device *devs[], int num); struct sys_timer; -extern struct sys_timer u8500_timer; +extern struct sys_timer ux500_timer; #define __IO_DEV_DESC(x, sz) { \ .virtual = IO_ADDRESS(x), \ -- cgit v1.2.3-59-g8ed1b From 817412d3a1391d4667494f16cd49455c62453c78 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 08:31:35 +0100 Subject: ARM: 6088/1: ux500: use UX500_* macros instead of U8500_* So that the correct addresses get used on U5500. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/include/mach/entry-macro.S | 2 +- arch/arm/mach-ux500/platsmp.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ux500/include/mach/entry-macro.S b/arch/arm/mach-ux500/include/mach/entry-macro.S index eece3301fef7..60ea88db8283 100644 --- a/arch/arm/mach-ux500/include/mach/entry-macro.S +++ b/arch/arm/mach-ux500/include/mach/entry-macro.S @@ -17,7 +17,7 @@ .endm .macro get_irqnr_preamble, base, tmp - ldr \base, =IO_ADDRESS(U8500_GIC_CPU_BASE) + ldr \base, =IO_ADDRESS(UX500_GIC_CPU_BASE) .endm .macro arch_ret_to_user, tmp1, tmp2 diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 76dd9354bd18..438ef16aec90 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -30,7 +30,7 @@ volatile int __cpuinitdata pen_release = -1; static unsigned int __init get_core_count(void) { - return scu_get_core_count(__io_address(U8500_SCU_BASE)); + return scu_get_core_count(__io_address(UX500_SCU_BASE)); } static DEFINE_SPINLOCK(boot_lock); @@ -44,7 +44,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) * core (e.g. timer irq), then they will not have been enabled * for us: do so */ - gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE)); + gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE)); /* * let the primary processor know we're out of the @@ -106,12 +106,12 @@ static void __init wakeup_secondary(void) */ #define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4 __raw_writel(virt_to_phys(u8500_secondary_startup), - (void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) + + __io_address(UX500_BACKUPRAM0_BASE) + U8500_CPU1_JUMPADDR_OFFSET); #define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0 __raw_writel(0xA1FEED01, - (void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) + + __io_address(UX500_BACKUPRAM0_BASE) + U8500_CPU1_WAKEMAGIC_OFFSET); /* make sure write buffer is drained */ @@ -172,7 +172,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) * boot CPU, but only if we have more than one CPU. */ percpu_timer_setup(); - scu_enable(__io_address(U8500_SCU_BASE)); + scu_enable(__io_address(UX500_SCU_BASE)); wakeup_secondary(); } } -- cgit v1.2.3-59-g8ed1b From cb165c52561fd5947747fdbdb0c7ad22c6138175 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 08:42:07 +0100 Subject: ARM: 6089/1: ux500: rename cpu-u8500.c to cpu-db8500.c Move the DB8500-specific file to a more appropriate name. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/Makefile | 2 +- arch/arm/mach-ux500/cpu-db8500.c | 78 ++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-ux500/cpu-u8500.c | 78 ---------------------------------------- 3 files changed, 79 insertions(+), 79 deletions(-) create mode 100644 arch/arm/mach-ux500/cpu-db8500.c delete mode 100644 arch/arm/mach-ux500/cpu-u8500.c (limited to 'arch') diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 55651e04ab43..2eb768583e21 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -3,6 +3,6 @@ # obj-y := clock.o cpu.o devices.o -obj-$(CONFIG_ARCH_U8500) += cpu-u8500.o devices-db8500.o +obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c new file mode 100644 index 000000000000..d04299f3b6b5 --- /dev/null +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2008-2009 ST-Ericsson + * + * Author: Srinidhi KASAGAR + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static struct platform_device *platform_devs[] __initdata = { + &u8500_gpio_devs[0], + &u8500_gpio_devs[1], + &u8500_gpio_devs[2], + &u8500_gpio_devs[3], + &u8500_gpio_devs[4], + &u8500_gpio_devs[5], + &u8500_gpio_devs[6], + &u8500_gpio_devs[7], + &u8500_gpio_devs[8], +}; + +/* minimum static i/o mapping required to boot U8500 platforms */ +static struct map_desc u8500_io_desc[] __initdata = { + __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), +}; + +static struct map_desc u8500ed_io_desc[] __initdata = { + __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K), + __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K), +}; + +static struct map_desc u8500v1_io_desc[] __initdata = { + __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), +}; + +void __init u8500_map_io(void) +{ + ux500_map_io(); + + iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); + + if (cpu_is_u8500ed()) + iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc)); + else + iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); +} + +/* + * This function is called from the board init + */ +void __init u8500_init_devices(void) +{ + ux500_init_devices(); + + /* Register the platform devices */ + platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); + + return ; +} diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c deleted file mode 100644 index d04299f3b6b5..000000000000 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2008-2009 ST-Ericsson - * - * Author: Srinidhi KASAGAR - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static struct platform_device *platform_devs[] __initdata = { - &u8500_gpio_devs[0], - &u8500_gpio_devs[1], - &u8500_gpio_devs[2], - &u8500_gpio_devs[3], - &u8500_gpio_devs[4], - &u8500_gpio_devs[5], - &u8500_gpio_devs[6], - &u8500_gpio_devs[7], - &u8500_gpio_devs[8], -}; - -/* minimum static i/o mapping required to boot U8500 platforms */ -static struct map_desc u8500_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), - __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), - __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), - __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), - __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), -}; - -static struct map_desc u8500ed_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K), - __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K), -}; - -static struct map_desc u8500v1_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), -}; - -void __init u8500_map_io(void) -{ - ux500_map_io(); - - iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); - - if (cpu_is_u8500ed()) - iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc)); - else - iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); -} - -/* - * This function is called from the board init - */ -void __init u8500_init_devices(void) -{ - ux500_init_devices(); - - /* Register the platform devices */ - platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - - return ; -} -- cgit v1.2.3-59-g8ed1b From 591d8dd71cc265465ac706ac11e5f613c6181a43 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 3 May 2010 08:46:51 +0100 Subject: ARM: 6090/1: ux500: add U5500 support Add basic support for the U5500 platform. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-ux500/Kconfig | 17 ++++++---- arch/arm/mach-ux500/Makefile | 2 ++ arch/arm/mach-ux500/board-u5500.c | 41 +++++++++++++++++++++++ arch/arm/mach-ux500/clock.c | 4 +++ arch/arm/mach-ux500/cpu-db5500.c | 50 +++++++++++++++++++++++++++++ arch/arm/mach-ux500/devices-db5500.c | 46 ++++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/devices.h | 1 + arch/arm/mach-ux500/include/mach/hardware.h | 9 ++++++ arch/arm/mach-ux500/include/mach/setup.h | 2 ++ 9 files changed, 166 insertions(+), 6 deletions(-) create mode 100644 arch/arm/mach-ux500/board-u5500.c create mode 100644 arch/arm/mach-ux500/cpu-db5500.c create mode 100644 arch/arm/mach-ux500/devices-db5500.c (limited to 'arch') diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 8ad5ee8107ae..6625e5bbf4d6 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -13,19 +13,24 @@ config UX500_SOC_DB8500 config UX500_SOC_DB5500 bool -menu "ST-Ericsson platform type" - -comment "ST-Ericsson Multicore Mobile Platforms" +choice + prompt "Ux500 target platform" + default MACH_U8500_MOP config MACH_U8500_MOP - bool "U8500 Early Development platform" - default y + bool "U8500 Development platform" select UX500_SOC_DB8500 help Include support for mop500 development platform based on U8500 architecture. The platform is based on early drop silicon version of 8500. -endmenu + +config MACH_U5500 + bool "U5500 Development platform" + select UX500_SOC_DB5500 + help + Include support for the U5500 development platform. +endchoice config UX500_DEBUG_UART int "Ux500 UART to use for low-level debug" diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 2eb768583e21..c7bc4199e3a8 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -3,6 +3,8 @@ # obj-y := clock.o cpu.o devices.o +obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o +obj-$(CONFIG_MACH_U5500) += board-u5500.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c new file mode 100644 index 000000000000..4430e69cf538 --- /dev/null +++ b/arch/arm/mach-ux500/board-u5500.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +static struct amba_device *amba_board_devs[] __initdata = { + &ux500_uart0_device, + &ux500_uart1_device, + &ux500_uart2_device, +}; + +static void __init u5500_init_machine(void) +{ + u5500_init_devices(); + + amba_add_devices(amba_board_devs, ARRAY_SIZE(amba_board_devs)); +} + +MACHINE_START(U8500, "ST-Ericsson U5500 Platform") + .phys_io = UX500_UART0_BASE, + .io_pg_offst = (IO_ADDRESS(UX500_UART0_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = u5500_map_io, + .init_irq = ux500_init_irq, + .timer = &ux500_timer, + .init_machine = u5500_init_machine, +MACHINE_END diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index d16b8b5ca8c7..c325dad1679c 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -502,6 +502,10 @@ static int __init clk_init(void) if (cpu_is_u8500ed()) { clk_prcmu_ops.enable = clk_prcmu_ed_enable; clk_prcmu_ops.disable = clk_prcmu_ed_disable; + } else if (cpu_is_u5500()) { + /* Clock tree for U5500 not implemented yet */ + clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; + clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; } clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c new file mode 100644 index 000000000000..6a3ac4539f16 --- /dev/null +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include + +#include + +#include +#include +#include + +static struct map_desc u5500_io_desc[] __initdata = { + __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GPIO3_BASE, SZ_4K), + __IO_DEV_DESC(U5500_GPIO4_BASE, SZ_4K), +}; + +static struct platform_device *u5500_platform_devs[] __initdata = { + &u5500_gpio_devs[0], + &u5500_gpio_devs[1], + &u5500_gpio_devs[2], + &u5500_gpio_devs[3], + &u5500_gpio_devs[4], + &u5500_gpio_devs[5], + &u5500_gpio_devs[6], + &u5500_gpio_devs[7], +}; + +void __init u5500_map_io(void) +{ + ux500_map_io(); + + iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc)); +} + +void __init u5500_init_devices(void) +{ + ux500_init_devices(); + + platform_add_devices(u5500_platform_devs, + ARRAY_SIZE(u5500_platform_devs)); +} diff --git a/arch/arm/mach-ux500/devices-db5500.c b/arch/arm/mach-ux500/devices-db5500.c new file mode 100644 index 000000000000..33e5b56bebb6 --- /dev/null +++ b/arch/arm/mach-ux500/devices-db5500.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include + +#include +#include + +static struct nmk_gpio_platform_data u5500_gpio_data[] = { + GPIO_DATA("GPIO-0-31", 0), + GPIO_DATA("GPIO-32-63", 32), /* 36..63 not routed to pin */ + GPIO_DATA("GPIO-64-95", 64), /* 83..95 not routed to pin */ + GPIO_DATA("GPIO-96-127", 96), /* 102..127 not routed to pin */ + GPIO_DATA("GPIO-128-159", 128), /* 149..159 not routed to pin */ + GPIO_DATA("GPIO-160-191", 160), + GPIO_DATA("GPIO-192-223", 192), + GPIO_DATA("GPIO-224-255", 224), /* 228..255 not routed to pin */ +}; + +static struct resource u5500_gpio_resources[] = { + GPIO_RESOURCE(0), + GPIO_RESOURCE(1), + GPIO_RESOURCE(2), + GPIO_RESOURCE(3), + GPIO_RESOURCE(4), + GPIO_RESOURCE(5), + GPIO_RESOURCE(6), + GPIO_RESOURCE(7), +}; + +struct platform_device u5500_gpio_devs[] = { + GPIO_DEVICE(0), + GPIO_DEVICE(1), + GPIO_DEVICE(2), + GPIO_DEVICE(3), + GPIO_DEVICE(4), + GPIO_DEVICE(5), + GPIO_DEVICE(6), + GPIO_DEVICE(7), +}; diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h index 76b3569f055e..0422af00a56e 100644 --- a/arch/arm/mach-ux500/include/mach/devices.h +++ b/arch/arm/mach-ux500/include/mach/devices.h @@ -10,6 +10,7 @@ struct platform_device; struct amba_device; +extern struct platform_device u5500_gpio_devs[]; extern struct platform_device u8500_gpio_devs[]; extern struct amba_device ux500_pl031_device; diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 1353f1757057..8656379a8309 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h @@ -114,6 +114,15 @@ static inline bool cpu_is_u8500v1(void) return cpu_is_u8500() && (read_cpuid_id() & 15) == 1; } +static inline bool cpu_is_u5500(void) +{ +#ifdef CONFIG_UX500_SOC_DB5500 + return 1; +#else + return 0; +#endif +} + #endif #endif /* __MACH_HARDWARE_H */ diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index c730d078f9ab..e978dbd9e210 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -15,9 +15,11 @@ #include extern void __init ux500_map_io(void); +extern void __init u5500_map_io(void); extern void __init u8500_map_io(void); extern void __init ux500_init_devices(void); +extern void __init u5500_init_devices(void); extern void __init u8500_init_devices(void); extern void __init ux500_init_irq(void); -- cgit v1.2.3-59-g8ed1b From 609c9ba29742f65b83f062dc57e5326d620de7bb Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 12:57:14 -0700 Subject: omap3: Fix compile for board-cm-t35 Otherwise we can get the following error: error: variable 'tdo24m_mcspi_config' has initializer but incomplete type ... Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-cm-t35.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 2de4f79f03a0..e679a2cc86c3 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -45,6 +45,7 @@ #include #include #include +#include #include -- cgit v1.2.3-59-g8ed1b From dee5f8285e6300f34054afd39c9406fc2f709362 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 12:57:14 -0700 Subject: omap3: Remove non-muxable ball entries for 3630 These are currently non-muxable, so let's save some memory and remove them. Otherwise we get the following warnings: mux: Unknown ball offset 0x5e mux: Unknown ball offset 0x60 mux: Unknown ball offset 0x62 ... Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/mux34xx.c | 86 ------------------------------------------- 1 file changed, 86 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c index 07aa7b3c95f7..2ff4dce95ee8 100644 --- a/arch/arm/mach-omap2/mux34xx.c +++ b/arch/arm/mach-omap2/mux34xx.c @@ -1901,26 +1901,15 @@ struct omap_ball __initdata omap36xx_cbp_ball[] = { _OMAP3_BALLENTRY(GPMC_A8, "m3", "ab18"), _OMAP3_BALLENTRY(GPMC_A9, "l3", "ac19"), _OMAP3_BALLENTRY(GPMC_CLK, "t4", "w2"), - _OMAP3_BALLENTRY(GPMC_D0, "k1", "m2"), - _OMAP3_BALLENTRY(GPMC_D1, "l1", "m1"), _OMAP3_BALLENTRY(GPMC_D10, "p1", "ab4"), _OMAP3_BALLENTRY(GPMC_D11, "r1", "ac4"), _OMAP3_BALLENTRY(GPMC_D12, "r2", "ab6"), _OMAP3_BALLENTRY(GPMC_D13, "t2", "ac6"), _OMAP3_BALLENTRY(GPMC_D14, "w1", "ab7"), _OMAP3_BALLENTRY(GPMC_D15, "y1", "ac7"), - _OMAP3_BALLENTRY(GPMC_D2, "l2", "n2"), - _OMAP3_BALLENTRY(GPMC_D3, "p2", "n1"), - _OMAP3_BALLENTRY(GPMC_D4, "t1", "r2"), - _OMAP3_BALLENTRY(GPMC_D5, "v1", "r1"), - _OMAP3_BALLENTRY(GPMC_D6, "v2", "t2"), - _OMAP3_BALLENTRY(GPMC_D7, "w2", "t1"), - _OMAP3_BALLENTRY(GPMC_D8, "h2", "ab3"), _OMAP3_BALLENTRY(GPMC_D9, "k2", "ac3"), - _OMAP3_BALLENTRY(GPMC_NADV_ALE, "f3", "w1"), _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "g3", "ac12"), _OMAP3_BALLENTRY(GPMC_NBE1, "u3", NULL), - _OMAP3_BALLENTRY(GPMC_NCS0, "g4", "y2"), _OMAP3_BALLENTRY(GPMC_NCS1, "h3", "y1"), _OMAP3_BALLENTRY(GPMC_NCS2, "v8", NULL), _OMAP3_BALLENTRY(GPMC_NCS3, "u8", NULL), @@ -1928,10 +1917,7 @@ struct omap_ball __initdata omap36xx_cbp_ball[] = { _OMAP3_BALLENTRY(GPMC_NCS5, "r8", NULL), _OMAP3_BALLENTRY(GPMC_NCS6, "p8", NULL), _OMAP3_BALLENTRY(GPMC_NCS7, "n8", NULL), - _OMAP3_BALLENTRY(GPMC_NOE, "g2", "v2"), - _OMAP3_BALLENTRY(GPMC_NWE, "f4", "v1"), _OMAP3_BALLENTRY(GPMC_NWP, "h1", "ab10"), - _OMAP3_BALLENTRY(GPMC_WAIT0, "m8", "ab12"), _OMAP3_BALLENTRY(GPMC_WAIT1, "l8", "ac10"), _OMAP3_BALLENTRY(GPMC_WAIT2, "k8", NULL), _OMAP3_BALLENTRY(GPMC_WAIT3, "j8", NULL), @@ -1948,8 +1934,6 @@ struct omap_ball __initdata omap36xx_cbp_ball[] = { _OMAP3_BALLENTRY(HSUSB0_DIR, "r28", NULL), _OMAP3_BALLENTRY(HSUSB0_NXT, "t26", NULL), _OMAP3_BALLENTRY(HSUSB0_STP, "t25", NULL), - _OMAP3_BALLENTRY(I2C1_SCL, "k21", NULL), - _OMAP3_BALLENTRY(I2C1_SDA, "j21", NULL), _OMAP3_BALLENTRY(I2C2_SCL, "af15", NULL), _OMAP3_BALLENTRY(I2C2_SDA, "ae15", NULL), _OMAP3_BALLENTRY(I2C3_SCL, "af14", NULL), @@ -1958,11 +1942,6 @@ struct omap_ball __initdata omap36xx_cbp_ball[] = { _OMAP3_BALLENTRY(I2C4_SDA, "ae26", NULL), _OMAP3_BALLENTRY(JTAG_EMU0, "aa11", NULL), _OMAP3_BALLENTRY(JTAG_EMU1, "aa10", NULL), - _OMAP3_BALLENTRY(JTAG_RTCK, "aa12", NULL), - _OMAP3_BALLENTRY(JTAG_TCK, "aa13", NULL), - _OMAP3_BALLENTRY(JTAG_TDI, "aa20", NULL), - _OMAP3_BALLENTRY(JTAG_TDO, "aa19", NULL), - _OMAP3_BALLENTRY(JTAG_TMS_TMSC, "aa18", NULL), _OMAP3_BALLENTRY(MCBSP1_CLKR, "y21", NULL), _OMAP3_BALLENTRY(MCBSP1_CLKX, "w21", NULL), _OMAP3_BALLENTRY(MCBSP1_DR, "u21", NULL), @@ -2010,77 +1989,12 @@ struct omap_ball __initdata omap36xx_cbp_ball[] = { _OMAP3_BALLENTRY(SDMMC2_DAT5, "ah3", NULL), _OMAP3_BALLENTRY(SDMMC2_DAT6, "af3", NULL), _OMAP3_BALLENTRY(SDMMC2_DAT7, "ae3", NULL), - _OMAP3_BALLENTRY(SDRC_A0, NULL, "n22"), - _OMAP3_BALLENTRY(SDRC_A1, NULL, "n23"), - _OMAP3_BALLENTRY(SDRC_A10, NULL, "v22"), - _OMAP3_BALLENTRY(SDRC_A11, NULL, "v23"), - _OMAP3_BALLENTRY(SDRC_A12, NULL, "w22"), - _OMAP3_BALLENTRY(SDRC_A13, NULL, "w23"), - _OMAP3_BALLENTRY(SDRC_A14, NULL, "y22"), - _OMAP3_BALLENTRY(SDRC_A2, NULL, "p22"), - _OMAP3_BALLENTRY(SDRC_A3, NULL, "p23"), - _OMAP3_BALLENTRY(SDRC_A4, NULL, "r22"), - _OMAP3_BALLENTRY(SDRC_A5, NULL, "r23"), - _OMAP3_BALLENTRY(SDRC_A6, NULL, "t22"), - _OMAP3_BALLENTRY(SDRC_A7, NULL, "t23"), - _OMAP3_BALLENTRY(SDRC_A8, NULL, "u22"), - _OMAP3_BALLENTRY(SDRC_A9, NULL, "u23"), - _OMAP3_BALLENTRY(SDRC_BA0, "h9", "ab21"), - _OMAP3_BALLENTRY(SDRC_BA1, "h10", "ac21"), _OMAP3_BALLENTRY(SDRC_CKE0, "h16", "j22"), _OMAP3_BALLENTRY(SDRC_CKE1, "h17", "j23"), - _OMAP3_BALLENTRY(SDRC_CLK, "a13", "a11"), - _OMAP3_BALLENTRY(SDRC_D0, NULL, "j2"), - _OMAP3_BALLENTRY(SDRC_D1, NULL, "j1"), - _OMAP3_BALLENTRY(SDRC_D10, "c15", "b14"), - _OMAP3_BALLENTRY(SDRC_D11, "b16", "a14"), - _OMAP3_BALLENTRY(SDRC_D12, "d17", "b16"), - _OMAP3_BALLENTRY(SDRC_D13, "c17", "a16"), - _OMAP3_BALLENTRY(SDRC_D14, "b17", "b19"), - _OMAP3_BALLENTRY(SDRC_D15, "d18", "a19"), - _OMAP3_BALLENTRY(SDRC_D16, NULL, "b3"), - _OMAP3_BALLENTRY(SDRC_D17, NULL, "a3"), - _OMAP3_BALLENTRY(SDRC_D18, NULL, "b5"), - _OMAP3_BALLENTRY(SDRC_D19, NULL, "a5"), - _OMAP3_BALLENTRY(SDRC_D2, NULL, "g2"), - _OMAP3_BALLENTRY(SDRC_D20, NULL, "b8"), - _OMAP3_BALLENTRY(SDRC_D21, NULL, "a8"), - _OMAP3_BALLENTRY(SDRC_D22, NULL, "b9"), - _OMAP3_BALLENTRY(SDRC_D23, NULL, "a9"), - _OMAP3_BALLENTRY(SDRC_D24, NULL, "b21"), - _OMAP3_BALLENTRY(SDRC_D25, NULL, "a21"), - _OMAP3_BALLENTRY(SDRC_D26, NULL, "d22"), - _OMAP3_BALLENTRY(SDRC_D27, NULL, "d23"), - _OMAP3_BALLENTRY(SDRC_D28, NULL, "e22"), - _OMAP3_BALLENTRY(SDRC_D29, NULL, "e23"), - _OMAP3_BALLENTRY(SDRC_D3, NULL, "g1"), - _OMAP3_BALLENTRY(SDRC_D30, NULL, "g22"), - _OMAP3_BALLENTRY(SDRC_D31, NULL, "g23"), - _OMAP3_BALLENTRY(SDRC_D4, NULL, "f2"), - _OMAP3_BALLENTRY(SDRC_D5, NULL, "f1"), - _OMAP3_BALLENTRY(SDRC_D6, NULL, "d2"), - _OMAP3_BALLENTRY(SDRC_D7, NULL, "d1"), - _OMAP3_BALLENTRY(SDRC_D8, "c14", "b13"), - _OMAP3_BALLENTRY(SDRC_D9, "b14", "a13"), - _OMAP3_BALLENTRY(SDRC_DM0, NULL, "c1"), - _OMAP3_BALLENTRY(SDRC_DM1, "a16", "a17"), - _OMAP3_BALLENTRY(SDRC_DM2, NULL, "a6"), - _OMAP3_BALLENTRY(SDRC_DM3, NULL, "a20"), - _OMAP3_BALLENTRY(SDRC_DQS0, NULL, "c2"), - _OMAP3_BALLENTRY(SDRC_DQS1, "a17", "b17"), - _OMAP3_BALLENTRY(SDRC_DQS2, NULL, "b6"), - _OMAP3_BALLENTRY(SDRC_DQS3, NULL, "b20"), - _OMAP3_BALLENTRY(SDRC_NCAS, "h13", "l22"), - _OMAP3_BALLENTRY(SDRC_NCLK, "a14", "b11"), - _OMAP3_BALLENTRY(SDRC_NCS0, "h11", "m22"), - _OMAP3_BALLENTRY(SDRC_NCS1, "h12", "m23"), - _OMAP3_BALLENTRY(SDRC_NRAS, "h14", "l23"), - _OMAP3_BALLENTRY(SDRC_NWE, "h15", "k23"), _OMAP3_BALLENTRY(SIM_CLK, "p26", NULL), _OMAP3_BALLENTRY(SIM_IO, "p27", NULL), _OMAP3_BALLENTRY(SIM_PWRCTRL, "r27", NULL), _OMAP3_BALLENTRY(SIM_RST, "r25", NULL), - _OMAP3_BALLENTRY(SYS_32K, "ae25", NULL), _OMAP3_BALLENTRY(SYS_BOOT0, "ah26", NULL), _OMAP3_BALLENTRY(SYS_BOOT1, "ag26", NULL), _OMAP3_BALLENTRY(SYS_BOOT2, "ae14", NULL), -- cgit v1.2.3-59-g8ed1b From 82cd4adefe5a67870f2113498bdfe9350edd2078 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 12:57:15 -0700 Subject: omap4: Fix multiboot with CONFIG_PM and CONFIG_ARCH_OMAP3 selected We cannot use the omap34xx_sram_init(). It needs to be implemented for omap4. Otherwise we get an error and the system won't boot: Unhandled fault: imprecise external abort (0x1406) at 0xea963e94 ... Fix this by adding a dummy omap44xx_sram_init(). Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/sram.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 51f4dfb82e2b..226b2e858d6c 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -437,6 +437,20 @@ static inline int omap34xx_sram_init(void) } #endif +#ifdef CONFIG_ARCH_OMAP4 +int __init omap44xx_sram_init(void) +{ + printk(KERN_ERR "FIXME: %s not implemented\n", __func__); + + return -ENODEV; +} +#else +static inline int omap44xx_sram_init(void) +{ + return 0; +} +#endif + int __init omap_sram_init(void) { omap_detect_sram(); @@ -451,7 +465,7 @@ int __init omap_sram_init(void) else if (cpu_is_omap34xx()) omap34xx_sram_init(); else if (cpu_is_omap44xx()) - omap34xx_sram_init(); /* FIXME: */ + omap44xx_sram_init(); return 0; } -- cgit v1.2.3-59-g8ed1b From 7327d6374c3a6b610c0370d0dd26545efbdc3115 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 12:57:16 -0700 Subject: omap2/3/4: Add new boards to omap3_defconfig Enable 2430 omaps and the missing boards. Signed-off-by: Tony Lindgren --- arch/arm/configs/omap3_defconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap3_defconfig index d6ad92177324..01e5986bb48e 100644 --- a/arch/arm/configs/omap3_defconfig +++ b/arch/arm/configs/omap3_defconfig @@ -264,7 +264,7 @@ CONFIG_MACH_OMAP_GENERIC=y # OMAP Core Type # CONFIG_ARCH_OMAP2420=y -# CONFIG_ARCH_OMAP2430 is not set +CONFIG_ARCH_OMAP2430=y CONFIG_ARCH_OMAP3430=y CONFIG_OMAP_PACKAGE_CBB=y CONFIG_OMAP_PACKAGE_CUS=y @@ -276,8 +276,9 @@ CONFIG_OMAP_PACKAGE_CBP=y CONFIG_MACH_OMAP2_TUSB6010=y CONFIG_MACH_OMAP_H4=y CONFIG_MACH_OMAP_APOLLON=y -# CONFIG_MACH_OMAP_2430SDP is not set +CONFIG_MACH_OMAP_2430SDP=y CONFIG_MACH_OMAP3_BEAGLE=y +CONFIG_MACH_DEVKIT8000=y CONFIG_MACH_OMAP_LDP=y CONFIG_MACH_OVERO=y CONFIG_MACH_OMAP3EVM=y -- cgit v1.2.3-59-g8ed1b From 75eaf1eaa8184eaddd54cb1d1e489f5d66007960 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 12:57:16 -0700 Subject: omap2/3/4: Make omap3_defconfig usable on Nokia boards The bootloader on Nokia boards does not support updating the kernel cmdline. For the other boards, the bootloader provided cmdline will be used instead. To mount root on n8x0, compile in also the MMC_OMAP. It seems that the best way to mount root with the new kernels on Nokia boards is to mount root on mmcblk0p2. Note that n8x0 current has several issues booting with omap3_defconfig: The bootloader has a 2MB limit for loading kernels, so you may want to use kexec. Also ARMv6 does not currently work with ARMv7 for VFP and TLS. Signed-off-by: Tony Lindgren --- arch/arm/configs/omap3_defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap3_defconfig index 01e5986bb48e..d2ab4928db57 100644 --- a/arch/arm/configs/omap3_defconfig +++ b/arch/arm/configs/omap3_defconfig @@ -391,7 +391,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8" +CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyS2,115200" # CONFIG_XIP_KERNEL is not set CONFIG_KEXEC=y CONFIG_ATAGS_PROC=y @@ -1687,7 +1687,7 @@ CONFIG_SDIO_UART=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_OMAP is not set +CONFIG_MMC_OMAP=y CONFIG_MMC_OMAP_HS=y # CONFIG_MMC_AT91 is not set # CONFIG_MMC_ATMELMCI is not set -- cgit v1.2.3-59-g8ed1b From 0c463d09f4b973a8c12f6177138f4dc67b4df705 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 12:57:16 -0700 Subject: omap2/3/4: Update PMIC options for TWL and Menelaus chips These are needed for mounting root on MMC on many boards. Also disable CONFIG_WATCHDOG_NOWAYOUT, that can keep the system from running with external watchdogs. Signed-off-by: Tony Lindgren --- arch/arm/configs/omap3_defconfig | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap3_defconfig index d2ab4928db57..a8468365b49d 100644 --- a/arch/arm/configs/omap3_defconfig +++ b/arch/arm/configs/omap3_defconfig @@ -1263,7 +1263,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_THERMAL is not set CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y +# CONFIG_WATCHDOG_NOWAYOUT is not set # # Watchdog Device Drivers @@ -1292,9 +1292,9 @@ CONFIG_MFD_CORE=y # CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set -# CONFIG_MENELAUS is not set +CONFIG_MENELAUS=y CONFIG_TWL4030_CORE=y -# CONFIG_TWL4030_POWER is not set +CONFIG_TWL4030_POWER=y CONFIG_TWL4030_CODEC=y # CONFIG_MFD_TMIO is not set # CONFIG_MFD_T7L66XB is not set @@ -1313,7 +1313,7 @@ CONFIG_TWL4030_CODEC=y # CONFIG_AB4500_CORE is not set CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set -CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set # CONFIG_REGULATOR_BQ24022 is not set @@ -1321,8 +1321,8 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_REGULATOR_MAX8660 is not set CONFIG_REGULATOR_TWL4030=y # CONFIG_REGULATOR_LP3971 is not set -# CONFIG_REGULATOR_TPS65023 is not set -# CONFIG_REGULATOR_TPS6507X is not set +CONFIG_REGULATOR_TPS65023=y +CONFIG_REGULATOR_TPS6507X=y # CONFIG_MEDIA_SUPPORT is not set # @@ -1752,6 +1752,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_BQ32K is not set +CONFIG_RTC_DRV_TWL92330=y CONFIG_RTC_DRV_TWL4030=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set -- cgit v1.2.3-59-g8ed1b From df5d9411f999a0d943bbaa932850db708d5579ff Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 12:57:17 -0700 Subject: omap2/3/4: Disable CONFIG_PM_VERBOSE in omap3_defconfig It's too noisy. Signed-off-by: Tony Lindgren --- arch/arm/configs/omap3_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap3_defconfig index a8468365b49d..7855edb9ff24 100644 --- a/arch/arm/configs/omap3_defconfig +++ b/arch/arm/configs/omap3_defconfig @@ -444,7 +444,7 @@ CONFIG_BINFMT_MISC=y # CONFIG_PM=y CONFIG_PM_DEBUG=y -CONFIG_PM_VERBOSE=y +# CONFIG_PM_VERBOSE is not set CONFIG_CAN_PM_TRACE=y CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y -- cgit v1.2.3-59-g8ed1b From 2c2df8418ac7908eec4558407b83f16739006c54 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:02 -0700 Subject: x86, acpi/irq: Introduce apci_isa_irq_to_gsi There are a number of cases where the current code makes the assumption that isa irqs identity map to the first 16 acpi global system intereupts. In most instances that assumption is correct as that is the required behaviour in dual i8259 mode and the default behavior in ioapic mode. However there are some systems out there that take advantage of acpis interrupt remapping for the isa irqs to have a completely different mapping of isa_irq to gsi. Introduce acpi_isa_irq_to_gsi to perform this mapping explicitly in the code that needs it. Initially this will be just the current assumed identity mapping to ensure it's introduction does not cause regressions. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-1-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/ia64/kernel/acpi.c | 8 ++++++++ arch/x86/kernel/acpi/boot.c | 8 ++++++++ include/linux/acpi.h | 1 + 3 files changed, 17 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 4d1a7e9314cf..c6c90f39f4d9 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -785,6 +785,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) return 0; } +int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi) +{ + if (isa_irq >= 16) + return -1; + *gsi = isa_irq; + return 0; +} + /* * ACPI based hotplug CPU support */ diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index cd40aba6aa95..da718d672596 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -458,6 +458,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) return 0; } +int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi) +{ + if (isa_irq >= 16) + return -1; + *gsi = isa_irq; + return 0; +} + /* * success: return IRQ number (>=0) * failure: return < 0 diff --git a/include/linux/acpi.h b/include/linux/acpi.h index b926afe8c03e..7a937dabcc4a 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -116,6 +116,7 @@ extern unsigned long acpi_realmode_flags; int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity); int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); +int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi); #ifdef CONFIG_X86_IO_APIC extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity); -- cgit v1.2.3-59-g8ed1b From 9a0a91bb56d2915cdb8585717de38376ad20fef9 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:03 -0700 Subject: x86, acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq In perverse acpi implementations the isa irqs are not identity mapped to the first 16 gsi. Furthermore at least the extended interrupt resource capability may return gsi's and not isa irqs. So since what we get from acpi is a gsi teach acpi_get_overrride_irq to operate on a gsi instead of an isa_irq. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-2-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/apic/io_apic.c | 23 ++++++++++++++--------- include/linux/acpi.h | 4 ++-- 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 127b8718abfb..73ec92838d83 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -4082,22 +4082,27 @@ int __init io_apic_get_version(int ioapic) return reg_01.bits.version; } -int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) +int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity) { - int i; + int ioapic, pin, idx; if (skip_ioapic_setup) return -1; - for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].irqtype == mp_INT && - mp_irqs[i].srcbusirq == bus_irq) - break; - if (i >= mp_irq_entries) + ioapic = mp_find_ioapic(gsi); + if (ioapic < 0) + return -1; + + pin = mp_find_ioapic_pin(ioapic, gsi); + if (pin < 0) + return -1; + + idx = find_irq_entry(ioapic, pin, mp_INT); + if (idx < 0) return -1; - *trigger = irq_trigger(i); - *polarity = irq_polarity(i); + *trigger = irq_trigger(idx); + *polarity = irq_polarity(idx); return 0; } diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 7a937dabcc4a..3da73f5f0ae9 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -119,9 +119,9 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi); #ifdef CONFIG_X86_IO_APIC -extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity); +extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity); #else -#define acpi_get_override_irq(bus, trigger, polarity) (-1) +#define acpi_get_override_irq(gsi, trigger, polarity) (-1) #endif /* * This function undoes the effect of one call to acpi_register_gsi(). -- cgit v1.2.3-59-g8ed1b From 9d2062b879495649bb525cf7979126da2e45d288 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:05 -0700 Subject: x86, acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Currently acpi_sci_ioapic_setup calls mp_override_legacy_irq with bus_irq == gsi, which is wrong if we are comming from an override Instead pass the bus_irq into acpi_sci_ioapic_setup. This fix was inspired by a similar fix from: Yinghai Lu Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-4-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/acpi/boot.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index da718d672596..0a036dc6f9ff 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -313,7 +313,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end) /* * Parse Interrupt Source Override for the ACPI SCI */ -static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) +static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi) { if (trigger == 0) /* compatible SCI trigger is level */ trigger = 3; @@ -333,7 +333,7 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) * If GSI is < 16, this will update its flags, * else it will create a new mp_irqs[] entry. */ - mp_override_legacy_irq(gsi, polarity, trigger, gsi); + mp_override_legacy_irq(bus_irq, polarity, trigger, gsi); /* * stash over-ride to indicate we've been here @@ -357,9 +357,10 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header, acpi_table_print_madt_entry(header); if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) { - acpi_sci_ioapic_setup(intsrc->global_irq, + acpi_sci_ioapic_setup(intsrc->source_irq, intsrc->inti_flags & ACPI_MADT_POLARITY_MASK, - (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2); + (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2, + intsrc->global_irq); return 0; } @@ -1162,7 +1163,8 @@ static int __init acpi_parse_madt_ioapic_entries(void) * pretend we got one so we can set the SCI flags. */ if (!acpi_sci_override_gsi) - acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0); + acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0, + acpi_gbl_FADT.sci_interrupt); /* Fill in identity legacy mappings where no override */ mp_config_acpi_legacy_irqs(); -- cgit v1.2.3-59-g8ed1b From 0fd52670fb6400be0996ac492b5ed77f3d83d69a Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:06 -0700 Subject: x86, acpi/irq: Generalize mp_config_acpi_legacy_irqs Remove the assumption that there is not an override for isa irq 0. Instead lookup the gsi and from that lookup the ioapic and pin of each isa irq indivdually. In general this should not have any behavioural affect but in perverse cases this gets all of the details correct, instead of doing something weird. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-5-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/acpi/boot.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 0a036dc6f9ff..3ee92f28a4b2 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -961,8 +961,6 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) void __init mp_config_acpi_legacy_irqs(void) { int i; - int ioapic; - unsigned int dstapic; struct mpc_intsrc mp_irq; #if defined (CONFIG_MCA) || defined (CONFIG_EISA) @@ -982,20 +980,28 @@ void __init mp_config_acpi_legacy_irqs(void) return; #endif - /* - * Locate the IOAPIC that manages the ISA IRQs (0-15). - */ - ioapic = mp_find_ioapic(0); - if (ioapic < 0) - return; - dstapic = mp_ioapics[ioapic].apicid; - /* * Use the default configuration for the IRQs 0-15. Unless * overridden by (MADT) interrupt source override entries. */ for (i = 0; i < 16; i++) { + int ioapic, pin; + unsigned int dstapic; int idx; + u32 gsi; + + /* Locate the gsi that irq i maps to. */ + if (acpi_isa_irq_to_gsi(i, &gsi)) + continue; + + /* + * Locate the IOAPIC that manages the ISA IRQ. + */ + ioapic = mp_find_ioapic(gsi); + if (ioapic < 0) + continue; + pin = mp_find_ioapic_pin(ioapic, gsi); + dstapic = mp_ioapics[ioapic].apicid; for (idx = 0; idx < mp_irq_entries; idx++) { struct mpc_intsrc *irq = mp_irqs + idx; @@ -1005,7 +1011,7 @@ void __init mp_config_acpi_legacy_irqs(void) break; /* Do we already have a mapping for this IOAPIC pin */ - if (irq->dstapic == dstapic && irq->dstirq == i) + if (irq->dstapic == dstapic && irq->dstirq == pin) break; } @@ -1020,7 +1026,7 @@ void __init mp_config_acpi_legacy_irqs(void) mp_irq.dstapic = dstapic; mp_irq.irqtype = mp_INT; mp_irq.srcbusirq = i; /* Identity mapped */ - mp_irq.dstirq = i; + mp_irq.dstirq = pin; save_mp_irq(&mp_irq); } -- cgit v1.2.3-59-g8ed1b From 9638fa521e42c9281c874c6b5a382b1ced4ee496 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:07 -0700 Subject: x86, ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Multiple declarations of the same function in different headers is a pain to maintain. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-6-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/mpspec.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index d8bf23a88d05..29994f06c7e2 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h @@ -106,10 +106,6 @@ struct device; extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level, int active_high_low); extern int acpi_probe_gsi(void); -#ifdef CONFIG_X86_IO_APIC -extern int mp_find_ioapic(int gsi); -extern int mp_find_ioapic_pin(int ioapic, int gsi); -#endif #else /* !CONFIG_ACPI: */ static inline int acpi_probe_gsi(void) { -- cgit v1.2.3-59-g8ed1b From 4b6b19a1c7302477653d799a53d48063dd53d555 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:08 -0700 Subject: x86, ioapic: Fix io_apic_redir_entries to return the number of entries. io_apic_redir_entries has a huge conceptual bug. It returns the maximum redirection entry not the number of redirection entries. Which simply does not match what the name of the function. This just caught me and it caught Feng Tang, and Len Brown when they wrote sfi_parse_ioapic. Modify io_apic_redir_entries to actually return the number of redirection entries, and fix the callers so that they properly handle receiving the number of the number of redirection table entries, instead of the number of redirection table entries less one. While the usage in sfi.c does not show up in this patch it is fixed by virtue of the fact that io_apic_redir_entries now has the semantics sfi_parse_ioapic most reasonably expects. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-7-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/apic/io_apic.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 73ec92838d83..0a053e61b3ea 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -3855,7 +3855,11 @@ int __init io_apic_get_redir_entries (int ioapic) reg_01.raw = io_apic_read(ioapic, 1); raw_spin_unlock_irqrestore(&ioapic_lock, flags); - return reg_01.bits.entries; + /* The register returns the maximum index redir index + * supported, which is one less than the total number of redir + * entries. + */ + return reg_01.bits.entries + 1; } void __init probe_nr_irqs_gsi(void) @@ -3871,7 +3875,7 @@ void __init probe_nr_irqs_gsi(void) nr = 0; for (idx = 0; idx < nr_ioapics; idx++) - nr += io_apic_get_redir_entries(idx) + 1; + nr += io_apic_get_redir_entries(idx); if (nr > nr_irqs_gsi) nr_irqs_gsi = nr; @@ -4306,7 +4310,7 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) */ mp_gsi_routing[idx].gsi_base = gsi_base; mp_gsi_routing[idx].gsi_end = gsi_base + - io_apic_get_redir_entries(idx); + io_apic_get_redir_entries(idx) - 1; printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, -- cgit v1.2.3-59-g8ed1b From eddb0c55a14074d6bac8c2ef169aefd7e2c6f139 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:09 -0700 Subject: x86, ioapic: Fix the types of gsi values This patches fixes the types of gsi_base and gsi_end values in struct mp_ioapic_gsi, and the gsi parameter of mp_find_ioapic and mp_find_ioapic_pin A gsi is cannonically a u32, not an int. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-8-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/io_apic.h | 10 +++++----- arch/x86/kernel/apic/io_apic.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 35832a03a515..feeaf0d92460 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -180,12 +180,12 @@ extern void ioapic_write_entry(int apic, int pin, extern void setup_ioapic_ids_from_mpc(void); struct mp_ioapic_gsi{ - int gsi_base; - int gsi_end; + u32 gsi_base; + u32 gsi_end; }; extern struct mp_ioapic_gsi mp_gsi_routing[]; -int mp_find_ioapic(int gsi); -int mp_find_ioapic_pin(int ioapic, int gsi); +int mp_find_ioapic(u32 gsi); +int mp_find_ioapic_pin(int ioapic, u32 gsi); void __init mp_register_ioapic(int id, u32 address, u32 gsi_base); extern void __init pre_init_apic_IRQ0(void); @@ -197,7 +197,7 @@ static const int timer_through_8259 = 0; static inline void ioapic_init_mappings(void) { } static inline void ioapic_insert_resources(void) { } static inline void probe_nr_irqs_gsi(void) { } -static inline int mp_find_ioapic(int gsi) { return 0; } +static inline int mp_find_ioapic(u32 gsi) { return 0; } struct io_apic_irq_attr; static inline int io_apic_set_pci_routing(struct device *dev, int irq, diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 0a053e61b3ea..9ab97622b8e6 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -4247,7 +4247,7 @@ void __init ioapic_insert_resources(void) } } -int mp_find_ioapic(int gsi) +int mp_find_ioapic(u32 gsi) { int i = 0; @@ -4262,7 +4262,7 @@ int mp_find_ioapic(int gsi) return -1; } -int mp_find_ioapic_pin(int ioapic, int gsi) +int mp_find_ioapic_pin(int ioapic, u32 gsi) { if (WARN_ON(ioapic == -1)) return -1; -- cgit v1.2.3-59-g8ed1b From 5777372af5c929b8f3c706ed7b295b7279537c88 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:10 -0700 Subject: x86, ioapic: Teach mp_register_ioapic to compute a global gsi_end Add the global variable gsi_end and teach mp_register_ioapic to keep it uptodate as we add more ioapics into the system. ioapics can only be added early in boot so the code that runs later can treat gsi_end as a constant. Remove the have hacks in sfi.c to second guess mp_register_ioapic by keeping t's own running total of how many gsi's have been seen, and instead use the gsi_end. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-9-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/io_apic.h | 1 + arch/x86/kernel/apic/io_apic.c | 6 ++++++ arch/x86/kernel/sfi.c | 4 +--- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index feeaf0d92460..37b0f2bb5034 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -184,6 +184,7 @@ struct mp_ioapic_gsi{ u32 gsi_end; }; extern struct mp_ioapic_gsi mp_gsi_routing[]; +extern u32 gsi_end; int mp_find_ioapic(u32 gsi); int mp_find_ioapic_pin(int ioapic, u32 gsi); void __init mp_register_ioapic(int id, u32 address, u32 gsi_base); diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 9ab97622b8e6..f80725571577 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -89,6 +89,9 @@ int nr_ioapics; /* IO APIC gsi routing info */ struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS]; +/* The last gsi number used */ +u32 gsi_end; + /* MP IRQ source entries */ struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; @@ -4312,6 +4315,9 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) mp_gsi_routing[idx].gsi_end = gsi_base + io_apic_get_redir_entries(idx) - 1; + if (mp_gsi_routing[idx].gsi_end > gsi_end) + gsi_end = mp_gsi_routing[idx].gsi_end; + printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr, diff --git a/arch/x86/kernel/sfi.c b/arch/x86/kernel/sfi.c index 34e099382651..7ded57896c0a 100644 --- a/arch/x86/kernel/sfi.c +++ b/arch/x86/kernel/sfi.c @@ -81,7 +81,6 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table) #endif /* CONFIG_X86_LOCAL_APIC */ #ifdef CONFIG_X86_IO_APIC -static u32 gsi_base; static int __init sfi_parse_ioapic(struct sfi_table_header *table) { @@ -94,8 +93,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table) pentry = (struct sfi_apic_table_entry *)sb->pentry; for (i = 0; i < num; i++) { - mp_register_ioapic(i, pentry->phys_addr, gsi_base); - gsi_base += io_apic_get_redir_entries(i); + mp_register_ioapic(i, pentry->phys_addr, gsi_end + 1); pentry++; } -- cgit v1.2.3-59-g8ed1b From cf7500c0ea133d66f8449d86392d83f840102632 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:11 -0700 Subject: x86, ioapic: In mpparse use mp_register_ioapic Long ago MP_ioapic_info was the primary way of setting up our ioapic data structures and mp_register_ioapic was a compatibility shim for acpi code. Now the situation is reversed and and mp_register_ioapic is the primary way of setting up our ioapic data structures. Keep the setting up of ioapic data structures uniform by having mp_register_ioapic call mp_register_ioapic. This changes a few fields: - type: is now hardset to MP_IOAPIC but type had to bey MP_IOAPIC or MP_ioapic_info would not have been called. - flags: is now hard coded to MPC_APIC_USABLE. We require flags to contain at least MPC_APIC_USEBLE in MP_ioapic_info and we don't ever examine flags so dropping a few flags that might possibly exist that we have never used is harmless. - apicaddr: Unchanged - apicver: Read from the ioapic instead of using the cached hardware value in the MP table. The real hardware value will be more accurate. - apicid: Now verified to be unique and changed if it is not. If the BIOS got this right this is a noop. If the BIOS did not fixing things appears to be the better solution. This adds gsi_base and gsi_end values to our ioapics defined with the mpatable, which will make our lives simpler later since we can always assume gsi_base and gsi_end are valid. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-10-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/mpparse.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index e81030f71a8f..5ae5d2426edf 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -115,21 +115,6 @@ static void __init MP_bus_info(struct mpc_bus *m) printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); } -static int bad_ioapic(unsigned long address) -{ - if (nr_ioapics >= MAX_IO_APICS) { - printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " - "(found %d)\n", MAX_IO_APICS, nr_ioapics); - panic("Recompile kernel with bigger MAX_IO_APICS!\n"); - } - if (!address) { - printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" - " found in table, skipping!\n"); - return 1; - } - return 0; -} - static void __init MP_ioapic_info(struct mpc_ioapic *m) { if (!(m->flags & MPC_APIC_USABLE)) @@ -138,15 +123,7 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m) printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n", m->apicid, m->apicver, m->apicaddr); - if (bad_ioapic(m->apicaddr)) - return; - - mp_ioapics[nr_ioapics].apicaddr = m->apicaddr; - mp_ioapics[nr_ioapics].apicid = m->apicid; - mp_ioapics[nr_ioapics].type = m->type; - mp_ioapics[nr_ioapics].apicver = m->apicver; - mp_ioapics[nr_ioapics].flags = m->flags; - nr_ioapics++; + mp_register_ioapic(m->apicid, m->apicaddr, gsi_end + 1); } static void print_MP_intsrc_info(struct mpc_intsrc *m) -- cgit v1.2.3-59-g8ed1b From 7716a5c4ff5f1f3dc5e9edcab125cbf7fceef0af Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:12 -0700 Subject: x86, ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic. Now that all ioapic registration happens in mp_register_ioapic we can move the calculation of nr_ioapic_registers there from enable_IO_APIC. The number of ioapic registers is already calucated in mp_register_ioapic so all that really needs to be done is to save the caluclated value in nr_ioapic_registers. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-11-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/apic/io_apic.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index f80725571577..dae9240bd287 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1953,20 +1953,8 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; void __init enable_IO_APIC(void) { - union IO_APIC_reg_01 reg_01; int i8259_apic, i8259_pin; int apic; - unsigned long flags; - - /* - * The number of IO-APIC IRQ registers (== #pins): - */ - for (apic = 0; apic < nr_ioapics; apic++) { - raw_spin_lock_irqsave(&ioapic_lock, flags); - reg_01.raw = io_apic_read(apic, 1); - raw_spin_unlock_irqrestore(&ioapic_lock, flags); - nr_ioapic_registers[apic] = reg_01.bits.entries+1; - } if (!legacy_pic->nr_legacy_irqs) return; @@ -4293,6 +4281,7 @@ static int bad_ioapic(unsigned long address) void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) { int idx = 0; + int entries; if (bad_ioapic(address)) return; @@ -4311,9 +4300,14 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) * Build basic GSI lookup table to facilitate gsi->io_apic lookups * and to prevent reprogramming of IOAPIC pins (PCI GSIs). */ + entries = io_apic_get_redir_entries(idx); mp_gsi_routing[idx].gsi_base = gsi_base; - mp_gsi_routing[idx].gsi_end = gsi_base + - io_apic_get_redir_entries(idx) - 1; + mp_gsi_routing[idx].gsi_end = gsi_base + entries - 1; + + /* + * The number of IO-APIC IRQ registers (== #pins): + */ + nr_ioapic_registers[idx] = entries; if (mp_gsi_routing[idx].gsi_end > gsi_end) gsi_end = mp_gsi_routing[idx].gsi_end; -- cgit v1.2.3-59-g8ed1b From d464207c4fdd70c2a0febd4f9c58206fa915bb36 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:13 -0700 Subject: x86, ioapic: Optimize pin_2_irq Now that all ioapics have valid gsi_base values use this to accellerate pin_2_irq. In the case of acpi this also ensures that pin_2_irq will compute the same irq value for an ioapic pin as acpi will. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-12-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/apic/io_apic.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index dae9240bd287..0d35f46929d1 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1019,7 +1019,7 @@ static inline int irq_trigger(int idx) int (*ioapic_renumber_irq)(int ioapic, int irq); static int pin_2_irq(int idx, int apic, int pin) { - int irq, i; + int irq; int bus = mp_irqs[idx].srcbus; /* @@ -1031,18 +1031,13 @@ static int pin_2_irq(int idx, int apic, int pin) if (test_bit(bus, mp_bus_not_pci)) { irq = mp_irqs[idx].srcbusirq; } else { - /* - * PCI IRQs are mapped in order - */ - i = irq = 0; - while (i < apic) - irq += nr_ioapic_registers[i++]; - irq += pin; + u32 gsi = mp_gsi_routing[apic].gsi_base + pin; /* * For MPS mode, so far only needed by ES7000 platform */ if (ioapic_renumber_irq) - irq = ioapic_renumber_irq(apic, irq); + gsi = ioapic_renumber_irq(apic, gsi); + irq = gsi; } #ifdef CONFIG_X86_32 -- cgit v1.2.3-59-g8ed1b From 4afc51a835d3aeba11c35090f524e05c84586d27 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:14 -0700 Subject: x86, ioapic: Simplify probe_nr_irqs_gsi. Use the global gsi_end value now that all ioapics have valid gsi numbers instead of a combination of acpi_probe_gsi and walking all of the ioapics and couting their number of entries by hand if acpi_probe_gsi gave us an answer we did not like. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-13-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/mpspec.h | 6 ------ arch/x86/kernel/acpi/boot.c | 23 ----------------------- arch/x86/kernel/apic/io_apic.c | 17 +++-------------- 3 files changed, 3 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index 29994f06c7e2..c82868e9f905 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void); struct device; extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level, int active_high_low); -extern int acpi_probe_gsi(void); -#else /* !CONFIG_ACPI: */ -static inline int acpi_probe_gsi(void) -{ - return 0; -} #endif /* CONFIG_ACPI */ #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 3ee92f28a4b2..07a63ce5811a 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -876,29 +876,6 @@ static int __init acpi_parse_madt_lapic_entries(void) extern int es7000_plat; #endif -int __init acpi_probe_gsi(void) -{ - int idx; - int gsi; - int max_gsi = 0; - - if (acpi_disabled) - return 0; - - if (!acpi_ioapic) - return 0; - - max_gsi = 0; - for (idx = 0; idx < nr_ioapics; idx++) { - gsi = mp_gsi_routing[idx].gsi_end; - - if (gsi > max_gsi) - max_gsi = gsi; - } - - return max_gsi + 1; -} - static void assign_to_mp_irq(struct mpc_intsrc *m, struct mpc_intsrc *mp_irq) { diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 0d35f46929d1..9f3f6ca86dac 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -3850,22 +3850,11 @@ int __init io_apic_get_redir_entries (int ioapic) void __init probe_nr_irqs_gsi(void) { - int nr = 0; + int nr; - nr = acpi_probe_gsi(); - if (nr > nr_irqs_gsi) { + nr = gsi_end + 1; + if (nr > nr_irqs_gsi) nr_irqs_gsi = nr; - } else { - /* for acpi=off or acpi is not compiled in */ - int idx; - - nr = 0; - for (idx = 0; idx < nr_ioapics; idx++) - nr += io_apic_get_redir_entries(idx); - - if (nr > nr_irqs_gsi) - nr_irqs_gsi = nr; - } printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); } -- cgit v1.2.3-59-g8ed1b From 988856ee1623bd37e384105f7bb2b7fe44c009f6 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:15 -0700 Subject: x86, acpi/irq: Handle isa irqs that are not identity mapped to gsi's. ACPI irq source overrides are allowed for the 16 isa irqs and are allowed to map any gsi to any isa irq. A few motherboards have been seen to take advantage of this and put the isa irqs on the 2nd or 3rd ioapic. This causes some problems, most notably the fact that we can not use any gsi < 16. To correct this move the gsis that are not isa irqs and have a gsi number < 16 into the linux irq space just past gsi_end. This is what the es7000 platform is doing today. Moving only the low 16 gsis above the rest of the gsi's only penalizes weird platforms, leaving sane acpi implementations with a 1-1 mapping of gsis and irqs. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-14-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/acpi/boot.c | 57 +++++++++++++++++++++++++++++++++++++++--- arch/x86/kernel/apic/io_apic.c | 8 ++++-- 2 files changed, 59 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 07a63ce5811a..325fbbab7f89 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -93,6 +93,53 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; +/* + * ISA irqs by default are the first 16 gsis but can be + * any gsi as specified by an interrupt source override. + */ +static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +}; + +static unsigned int gsi_to_irq(unsigned int gsi) +{ + unsigned int irq = gsi + NR_IRQS_LEGACY; + unsigned int i; + + for (i = 0; i < NR_IRQS_LEGACY; i++) { + if (isa_irq_to_gsi[i] == gsi) { + return i; + } + } + + /* Provide an identity mapping of gsi == irq + * except on truly weird platforms that have + * non isa irqs in the first 16 gsis. + */ + if (gsi >= NR_IRQS_LEGACY) + irq = gsi; + else + irq = gsi_end + 1 + gsi; + + return irq; +} + +static u32 irq_to_gsi(int irq) +{ + unsigned int gsi; + + if (irq < NR_IRQS_LEGACY) + gsi = isa_irq_to_gsi[irq]; + else if (irq <= gsi_end) + gsi = irq; + else if (irq <= (gsi_end + NR_IRQS_LEGACY)) + gsi = irq - gsi_end; + else + gsi = 0xffffffff; + + return gsi; +} + /* * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, * to map the target physical address. The problem is that set_fixmap() @@ -449,7 +496,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) { - *irq = gsi; + *irq = gsi_to_irq(gsi); #ifdef CONFIG_X86_IO_APIC if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) @@ -463,7 +510,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi) { if (isa_irq >= 16) return -1; - *gsi = isa_irq; + *gsi = irq_to_gsi(isa_irq); return 0; } @@ -491,7 +538,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity); } #endif - irq = plat_gsi; + irq = gsi_to_irq(plat_gsi); return irq; } @@ -933,6 +980,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) mp_irq.dstirq = pin; /* INTIN# */ save_mp_irq(&mp_irq); + + isa_irq_to_gsi[bus_irq] = gsi; } void __init mp_config_acpi_legacy_irqs(void) @@ -1086,7 +1135,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, polarity == ACPI_ACTIVE_HIGH ? 0 : 1); - io_apic_set_pci_routing(dev, gsi, &irq_attr); + io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); return gsi; } diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 9f3f6ca86dac..594827c3c615 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1037,7 +1037,11 @@ static int pin_2_irq(int idx, int apic, int pin) */ if (ioapic_renumber_irq) gsi = ioapic_renumber_irq(apic, gsi); - irq = gsi; + + if (gsi >= NR_IRQS_LEGACY) + irq = gsi; + else + irq = gsi_end + 1 + gsi; } #ifdef CONFIG_X86_32 @@ -3852,7 +3856,7 @@ void __init probe_nr_irqs_gsi(void) { int nr; - nr = gsi_end + 1; + nr = gsi_end + 1 + NR_IRQS_LEGACY; if (nr > nr_irqs_gsi) nr_irqs_gsi = nr; -- cgit v1.2.3-59-g8ed1b From 7b20bd5fb902088579af4e70f7f802b93181a628 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 30 Mar 2010 01:07:16 -0700 Subject: x86, irq: Kill io_apic_renumber_irq Now that the generic irq layer is performing the exact same remapping as io_apic_renumber_irq we can kill this weird es7000 specific function. Signed-off-by: Eric W. Biederman LKML-Reference: <1269936436-7039-15-git-send-email-ebiederm@xmission.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/io_apic.h | 1 - arch/x86/kernel/acpi/boot.c | 5 ----- arch/x86/kernel/apic/es7000_32.c | 19 ------------------- arch/x86/kernel/apic/io_apic.c | 6 ------ 4 files changed, 31 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 37b0f2bb5034..9da192a17f0f 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -159,7 +159,6 @@ struct io_apic_irq_attr; extern int io_apic_set_pci_routing(struct device *dev, int irq, struct io_apic_irq_attr *irq_attr); void setup_IO_APIC_irq_extra(u32 gsi); -extern int (*ioapic_renumber_irq)(int ioapic, int irq); extern void ioapic_init_mappings(void); extern void ioapic_insert_resources(void); diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 325fbbab7f89..9a5ed58f09dc 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1117,11 +1117,6 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) ioapic_pin = mp_find_ioapic_pin(ioapic, gsi); -#ifdef CONFIG_X86_32 - if (ioapic_renumber_irq) - gsi = ioapic_renumber_irq(ioapic, gsi); -#endif - if (ioapic_pin > MP_MAX_IOAPIC_PIN) { printk(KERN_ERR "Invalid reference to IOAPIC pin " "%d-%d\n", mp_ioapics[ioapic].apicid, diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 03ba1b895f5e..425e53a87feb 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -131,24 +131,6 @@ int es7000_plat; static unsigned int base; -static int -es7000_rename_gsi(int ioapic, int gsi) -{ - if (es7000_plat == ES7000_ZORRO) - return gsi; - - if (!base) { - int i; - for (i = 0; i < nr_ioapics; i++) - base += nr_ioapic_registers[i]; - } - - if (!ioapic && (gsi < 16)) - gsi += base; - - return gsi; -} - static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) { unsigned long vect = 0, psaival = 0; @@ -190,7 +172,6 @@ static void setup_unisys(void) es7000_plat = ES7000_ZORRO; else es7000_plat = ES7000_CLASSIC; - ioapic_renumber_irq = es7000_rename_gsi; } /* diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 594827c3c615..d174d8866547 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1016,7 +1016,6 @@ static inline int irq_trigger(int idx) return MPBIOS_trigger(idx); } -int (*ioapic_renumber_irq)(int ioapic, int irq); static int pin_2_irq(int idx, int apic, int pin) { int irq; @@ -1032,11 +1031,6 @@ static int pin_2_irq(int idx, int apic, int pin) irq = mp_irqs[idx].srcbusirq; } else { u32 gsi = mp_gsi_routing[apic].gsi_base + pin; - /* - * For MPS mode, so far only needed by ES7000 platform - */ - if (ioapic_renumber_irq) - gsi = ioapic_renumber_irq(apic, gsi); if (gsi >= NR_IRQS_LEGACY) irq = gsi; -- cgit v1.2.3-59-g8ed1b From 471c70ff39809af783c7718defe574a9ba81dd26 Mon Sep 17 00:00:00 2001 From: Torez Smith Date: Fri, 5 Mar 2010 10:43:01 +0000 Subject: powerpc/booke: Add Stack Marking support to Booke Exception Prolog This patch adds a marker to the exception stack frame to aid in debugging. It's already inserted on other platforms and xmon recognizes it and identifies exception frames when showing stack traces. Signed-off-by: Torez Smith Signed-off-by: Dave Kleikamp Signed-off-by: Josh Boyer --- arch/powerpc/kernel/head_booke.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 50504ae39cb7..a0bf158c8b47 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -1,6 +1,7 @@ #ifndef __HEAD_BOOKE_H__ #define __HEAD_BOOKE_H__ +#include /* for STACK_FRAME_REGS_MARKER */ /* * Macros used for common Book-e exception handling */ @@ -48,6 +49,9 @@ stw r10,0(r11); \ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ stw r0,GPR0(r11); \ + lis r10, STACK_FRAME_REGS_MARKER@ha;/* exception frame marker */ \ + addi r10, r10, STACK_FRAME_REGS_MARKER@l; \ + stw r10, 8(r11); \ SAVE_4GPRS(3, r11); \ SAVE_2GPRS(7, r11) -- cgit v1.2.3-59-g8ed1b From 795033c344d88dc6aa5106d0cc358656f29bd722 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Fri, 5 Mar 2010 10:43:07 +0000 Subject: powerpc/44x: break out cpu init code into stand-alone function The 47x platform supports multiple cores and shares code with 44x. Break out code that is common for initializing the primary and secondary cpus into a function which can be called for both. Signed-off-by: Dave Kleikamp Signed-off-by: Josh Boyer --- arch/powerpc/kernel/head_44x.S | 330 +++++++++++++++++++++-------------------- 1 file changed, 171 insertions(+), 159 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 711368b993f2..39be049a7850 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -69,165 +69,7 @@ _ENTRY(_start); mr r27,r7 li r24,0 /* CPU number */ -/* - * In case the firmware didn't do it, we apply some workarounds - * that are good for all 440 core variants here - */ - mfspr r3,SPRN_CCR0 - rlwinm r3,r3,0,0,27 /* disable icache prefetch */ - isync - mtspr SPRN_CCR0,r3 - isync - sync - -/* - * Set up the initial MMU state - * - * We are still executing code at the virtual address - * mappings set by the firmware for the base of RAM. - * - * We first invalidate all TLB entries but the one - * we are running from. We then load the KERNELBASE - * mappings so we can begin to use kernel addresses - * natively and so the interrupt vector locations are - * permanently pinned (necessary since Book E - * implementations always have translation enabled). - * - * TODO: Use the known TLB entry we are running from to - * determine which physical region we are located - * in. This can be used to determine where in RAM - * (on a shared CPU system) or PCI memory space - * (on a DRAMless system) we are located. - * For now, we assume a perfect world which means - * we are located at the base of DRAM (physical 0). - */ - -/* - * Search TLB for entry that we are currently using. - * Invalidate all entries but the one we are using. - */ - /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */ - mfspr r3,SPRN_PID /* Get PID */ - mfmsr r4 /* Get MSR */ - andi. r4,r4,MSR_IS@l /* TS=1? */ - beq wmmucr /* If not, leave STS=0 */ - oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */ -wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */ - sync - - bl invstr /* Find our address */ -invstr: mflr r5 /* Make it accessible */ - tlbsx r23,0,r5 /* Find entry we are in */ - li r4,0 /* Start at TLB entry 0 */ - li r3,0 /* Set PAGEID inval value */ -1: cmpw r23,r4 /* Is this our entry? */ - beq skpinv /* If so, skip the inval */ - tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ -skpinv: addi r4,r4,1 /* Increment */ - cmpwi r4,64 /* Are we done? */ - bne 1b /* If not, repeat */ - isync /* If so, context change */ - -/* - * Configure and load pinned entry into TLB slot 63. - */ - - lis r3,PAGE_OFFSET@h - ori r3,r3,PAGE_OFFSET@l - - /* Kernel is at the base of RAM */ - li r4, 0 /* Load the kernel physical address */ - - /* Load the kernel PID = 0 */ - li r0,0 - mtspr SPRN_PID,r0 - sync - - /* Initialize MMUCR */ - li r5,0 - mtspr SPRN_MMUCR,r5 - sync - - /* pageid fields */ - clrrwi r3,r3,10 /* Mask off the effective page number */ - ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M - - /* xlat fields */ - clrrwi r4,r4,10 /* Mask off the real page number */ - /* ERPN is 0 for first 4GB page */ - - /* attrib fields */ - /* Added guarded bit to protect against speculative loads/stores */ - li r5,0 - ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) - - li r0,63 /* TLB slot 63 */ - - tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ - tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ - tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ - - /* Force context change */ - mfmsr r0 - mtspr SPRN_SRR1, r0 - lis r0,3f@h - ori r0,r0,3f@l - mtspr SPRN_SRR0,r0 - sync - rfi - - /* If necessary, invalidate original entry we used */ -3: cmpwi r23,63 - beq 4f - li r6,0 - tlbwe r6,r23,PPC44x_TLB_PAGEID - isync - -4: -#ifdef CONFIG_PPC_EARLY_DEBUG_44x - /* Add UART mapping for early debug. */ - - /* pageid fields */ - lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h - ori r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K - - /* xlat fields */ - lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h - ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH - - /* attrib fields */ - li r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G) - li r0,62 /* TLB slot 0 */ - - tlbwe r3,r0,PPC44x_TLB_PAGEID - tlbwe r4,r0,PPC44x_TLB_XLAT - tlbwe r5,r0,PPC44x_TLB_ATTRIB - - /* Force context change */ - isync -#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ - - /* Establish the interrupt vector offsets */ - SET_IVOR(0, CriticalInput); - SET_IVOR(1, MachineCheck); - SET_IVOR(2, DataStorage); - SET_IVOR(3, InstructionStorage); - SET_IVOR(4, ExternalInput); - SET_IVOR(5, Alignment); - SET_IVOR(6, Program); - SET_IVOR(7, FloatingPointUnavailable); - SET_IVOR(8, SystemCall); - SET_IVOR(9, AuxillaryProcessorUnavailable); - SET_IVOR(10, Decrementer); - SET_IVOR(11, FixedIntervalTimer); - SET_IVOR(12, WatchdogTimer); - SET_IVOR(13, DataTLBError); - SET_IVOR(14, InstructionTLBError); - SET_IVOR(15, DebugCrit); - - /* Establish the interrupt vector base */ - lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ - mtspr SPRN_IVPR,r4 + bl init_cpu_state /* * This is where the main kernel code starts. @@ -646,6 +488,176 @@ _GLOBAL(set_context) isync /* Force context change */ blr +/* + * Init CPU state. This is called at boot time or for secondary CPUs + * to setup initial TLB entries, setup IVORs, etc... + */ +_GLOBAL(init_cpu_state) + mflr r22 +/* + * In case the firmware didn't do it, we apply some workarounds + * that are good for all 440 core variants here + */ + mfspr r3,SPRN_CCR0 + rlwinm r3,r3,0,0,27 /* disable icache prefetch */ + isync + mtspr SPRN_CCR0,r3 + isync + sync + +/* + * Set up the initial MMU state + * + * We are still executing code at the virtual address + * mappings set by the firmware for the base of RAM. + * + * We first invalidate all TLB entries but the one + * we are running from. We then load the KERNELBASE + * mappings so we can begin to use kernel addresses + * natively and so the interrupt vector locations are + * permanently pinned (necessary since Book E + * implementations always have translation enabled). + * + * TODO: Use the known TLB entry we are running from to + * determine which physical region we are located + * in. This can be used to determine where in RAM + * (on a shared CPU system) or PCI memory space + * (on a DRAMless system) we are located. + * For now, we assume a perfect world which means + * we are located at the base of DRAM (physical 0). + */ + +/* + * Search TLB for entry that we are currently using. + * Invalidate all entries but the one we are using. + */ + /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */ + mfspr r3,SPRN_PID /* Get PID */ + mfmsr r4 /* Get MSR */ + andi. r4,r4,MSR_IS@l /* TS=1? */ + beq wmmucr /* If not, leave STS=0 */ + oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */ +wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */ + sync + + bl invstr /* Find our address */ +invstr: mflr r5 /* Make it accessible */ + tlbsx r23,0,r5 /* Find entry we are in */ + li r4,0 /* Start at TLB entry 0 */ + li r3,0 /* Set PAGEID inval value */ +1: cmpw r23,r4 /* Is this our entry? */ + beq skpinv /* If so, skip the inval */ + tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ +skpinv: addi r4,r4,1 /* Increment */ + cmpwi r4,64 /* Are we done? */ + bne 1b /* If not, repeat */ + isync /* If so, context change */ + +/* + * Configure and load pinned entry into TLB slot 63. + */ + + lis r3,PAGE_OFFSET@h + ori r3,r3,PAGE_OFFSET@l + + /* Kernel is at the base of RAM */ + li r4, 0 /* Load the kernel physical address */ + + /* Load the kernel PID = 0 */ + li r0,0 + mtspr SPRN_PID,r0 + sync + + /* Initialize MMUCR */ + li r5,0 + mtspr SPRN_MMUCR,r5 + sync + + /* pageid fields */ + clrrwi r3,r3,10 /* Mask off the effective page number */ + ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M + + /* xlat fields */ + clrrwi r4,r4,10 /* Mask off the real page number */ + /* ERPN is 0 for first 4GB page */ + + /* attrib fields */ + /* Added guarded bit to protect against speculative loads/stores */ + li r5,0 + ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) + + li r0,63 /* TLB slot 63 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ + + /* Force context change */ + mfmsr r0 + mtspr SPRN_SRR1, r0 + lis r0,3f@h + ori r0,r0,3f@l + mtspr SPRN_SRR0,r0 + sync + rfi + + /* If necessary, invalidate original entry we used */ +3: cmpwi r23,63 + beq 4f + li r6,0 + tlbwe r6,r23,PPC44x_TLB_PAGEID + isync + +4: +#ifdef CONFIG_PPC_EARLY_DEBUG_44x + /* Add UART mapping for early debug. */ + + /* pageid fields */ + lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h + ori r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K + + /* xlat fields */ + lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h + ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH + + /* attrib fields */ + li r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G) + li r0,62 /* TLB slot 0 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID + tlbwe r4,r0,PPC44x_TLB_XLAT + tlbwe r5,r0,PPC44x_TLB_ATTRIB + + /* Force context change */ + isync +#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ + + /* Establish the interrupt vector offsets */ + SET_IVOR(0, CriticalInput); + SET_IVOR(1, MachineCheck); + SET_IVOR(2, DataStorage); + SET_IVOR(3, InstructionStorage); + SET_IVOR(4, ExternalInput); + SET_IVOR(5, Alignment); + SET_IVOR(6, Program); + SET_IVOR(7, FloatingPointUnavailable); + SET_IVOR(8, SystemCall); + SET_IVOR(9, AuxillaryProcessorUnavailable); + SET_IVOR(10, Decrementer); + SET_IVOR(11, FixedIntervalTimer); + SET_IVOR(12, WatchdogTimer); + SET_IVOR(13, DataTLBError); + SET_IVOR(14, InstructionTLBError); + SET_IVOR(15, DebugCrit); + + /* Establish the interrupt vector base */ + lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ + mtspr SPRN_IVPR,r4 + + addis r22,r22,KERNELBASE@h + mtlr r22 + blr + /* * We put a few things here that have to be page-aligned. This stuff * goes at the beginning of the data segment, which is page-aligned. -- cgit v1.2.3-59-g8ed1b From e7f75ad01d590243904c2d95ab47e6b2e9ef6dad Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Fri, 5 Mar 2010 10:43:12 +0000 Subject: powerpc/47x: Base ppc476 support This patch adds the base support for the 476 processor. The code was primarily written by Ben Herrenschmidt and Torez Smith, but I've been maintaining it for a while. The goal is to have a single binary that will run on 44x and 47x, but we still have some details to work out. The biggest is that the L1 cache line size differs on the two platforms, but it's currently a compile-time option. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Torez Smith Signed-off-by: Dave Kleikamp Signed-off-by: Josh Boyer --- arch/powerpc/include/asm/cache.h | 6 +- arch/powerpc/include/asm/cputable.h | 4 + arch/powerpc/include/asm/mmu-44x.h | 51 +++- arch/powerpc/include/asm/mmu.h | 1 + arch/powerpc/include/asm/reg.h | 1 + arch/powerpc/include/asm/reg_booke.h | 24 ++ arch/powerpc/kernel/cputable.c | 13 + arch/powerpc/kernel/entry_32.S | 5 + arch/powerpc/kernel/head_44x.S | 502 +++++++++++++++++++++++++++++++-- arch/powerpc/kernel/misc_32.S | 9 +- arch/powerpc/kernel/smp.c | 8 + arch/powerpc/mm/44x_mmu.c | 144 +++++++++- arch/powerpc/mm/mmu_context_nohash.c | 8 + arch/powerpc/mm/mmu_decl.h | 7 +- arch/powerpc/mm/tlb_nohash_low.S | 118 +++++++- arch/powerpc/platforms/44x/Kconfig | 9 + arch/powerpc/platforms/Kconfig.cputype | 5 +- 17 files changed, 871 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 81de6eb3455d..725634fc18c6 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -12,8 +12,12 @@ #define L1_CACHE_SHIFT 6 #define MAX_COPY_PREFETCH 4 #elif defined(CONFIG_PPC32) -#define L1_CACHE_SHIFT 5 #define MAX_COPY_PREFETCH 4 +#if defined(CONFIG_PPC_47x) +#define L1_CACHE_SHIFT 7 +#else +#define L1_CACHE_SHIFT 5 +#endif #else /* CONFIG_PPC64 */ #define L1_CACHE_SHIFT 7 #endif diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index abb833b0e58f..97ab5089df67 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -365,6 +365,7 @@ extern const char *powerpc_base_platform; #define CPU_FTRS_44X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE) #define CPU_FTRS_440x6 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE | \ CPU_FTR_INDEXED_DCR) +#define CPU_FTRS_47X (CPU_FTRS_440x6) #define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \ CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \ CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE) @@ -453,6 +454,9 @@ enum { #ifdef CONFIG_44x CPU_FTRS_44X | CPU_FTRS_440x6 | #endif +#ifdef CONFIG_PPC_47x + CPU_FTRS_47X | +#endif #ifdef CONFIG_E200 CPU_FTRS_E200 | #endif diff --git a/arch/powerpc/include/asm/mmu-44x.h b/arch/powerpc/include/asm/mmu-44x.h index 0372669383a8..bf52d704fc47 100644 --- a/arch/powerpc/include/asm/mmu-44x.h +++ b/arch/powerpc/include/asm/mmu-44x.h @@ -40,7 +40,7 @@ #define PPC44x_TLB_I 0x00000400 /* Caching is inhibited */ #define PPC44x_TLB_M 0x00000200 /* Memory is coherent */ #define PPC44x_TLB_G 0x00000100 /* Memory is guarded */ -#define PPC44x_TLB_E 0x00000080 /* Memory is guarded */ +#define PPC44x_TLB_E 0x00000080 /* Memory is little endian */ #define PPC44x_TLB_PERM_MASK 0x0000003f #define PPC44x_TLB_UX 0x00000020 /* User execution */ @@ -53,6 +53,52 @@ /* Number of TLB entries */ #define PPC44x_TLB_SIZE 64 +/* 47x bits */ +#define PPC47x_MMUCR_TID 0x0000ffff +#define PPC47x_MMUCR_STS 0x00010000 + +/* Page identification fields */ +#define PPC47x_TLB0_EPN_MASK 0xfffff000 /* Effective Page Number */ +#define PPC47x_TLB0_VALID 0x00000800 /* Valid flag */ +#define PPC47x_TLB0_TS 0x00000400 /* Translation address space */ +#define PPC47x_TLB0_4K 0x00000000 +#define PPC47x_TLB0_16K 0x00000010 +#define PPC47x_TLB0_64K 0x00000030 +#define PPC47x_TLB0_1M 0x00000070 +#define PPC47x_TLB0_16M 0x000000f0 +#define PPC47x_TLB0_256M 0x000001f0 +#define PPC47x_TLB0_1G 0x000003f0 +#define PPC47x_TLB0_BOLTED_R 0x00000008 /* tlbre only */ + +/* Translation fields */ +#define PPC47x_TLB1_RPN_MASK 0xfffff000 /* Real Page Number */ +#define PPC47x_TLB1_ERPN_MASK 0x000003ff + +/* Storage attribute and access control fields */ +#define PPC47x_TLB2_ATTR_MASK 0x0003ff80 +#define PPC47x_TLB2_IL1I 0x00020000 /* Memory is guarded */ +#define PPC47x_TLB2_IL1D 0x00010000 /* Memory is guarded */ +#define PPC47x_TLB2_U0 0x00008000 /* User 0 */ +#define PPC47x_TLB2_U1 0x00004000 /* User 1 */ +#define PPC47x_TLB2_U2 0x00002000 /* User 2 */ +#define PPC47x_TLB2_U3 0x00001000 /* User 3 */ +#define PPC47x_TLB2_W 0x00000800 /* Caching is write-through */ +#define PPC47x_TLB2_I 0x00000400 /* Caching is inhibited */ +#define PPC47x_TLB2_M 0x00000200 /* Memory is coherent */ +#define PPC47x_TLB2_G 0x00000100 /* Memory is guarded */ +#define PPC47x_TLB2_E 0x00000080 /* Memory is little endian */ +#define PPC47x_TLB2_PERM_MASK 0x0000003f +#define PPC47x_TLB2_UX 0x00000020 /* User execution */ +#define PPC47x_TLB2_UW 0x00000010 /* User write */ +#define PPC47x_TLB2_UR 0x00000008 /* User read */ +#define PPC47x_TLB2_SX 0x00000004 /* Super execution */ +#define PPC47x_TLB2_SW 0x00000002 /* Super write */ +#define PPC47x_TLB2_SR 0x00000001 /* Super read */ +#define PPC47x_TLB2_U_RWX (PPC47x_TLB2_UX|PPC47x_TLB2_UW|PPC47x_TLB2_UR) +#define PPC47x_TLB2_S_RWX (PPC47x_TLB2_SX|PPC47x_TLB2_SW|PPC47x_TLB2_SR) +#define PPC47x_TLB2_S_RW (PPC47x_TLB2_SW | PPC47x_TLB2_SR) +#define PPC47x_TLB2_IMG (PPC47x_TLB2_I | PPC47x_TLB2_M | PPC47x_TLB2_G) + #ifndef __ASSEMBLY__ extern unsigned int tlb_44x_hwater; @@ -79,12 +125,15 @@ typedef struct { #if (PAGE_SHIFT == 12) #define PPC44x_TLBE_SIZE PPC44x_TLB_4K +#define PPC47x_TLBE_SIZE PPC47x_TLB0_4K #define mmu_virtual_psize MMU_PAGE_4K #elif (PAGE_SHIFT == 14) #define PPC44x_TLBE_SIZE PPC44x_TLB_16K +#define PPC47x_TLBE_SIZE PPC47x_TLB0_16K #define mmu_virtual_psize MMU_PAGE_16K #elif (PAGE_SHIFT == 16) #define PPC44x_TLBE_SIZE PPC44x_TLB_64K +#define PPC47x_TLBE_SIZE PPC47x_TLB0_64K #define mmu_virtual_psize MMU_PAGE_64K #elif (PAGE_SHIFT == 18) #define PPC44x_TLBE_SIZE PPC44x_TLB_256K diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 7ffbb65ff7a9..7ebf42ed84a2 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -18,6 +18,7 @@ #define MMU_FTR_TYPE_44x ASM_CONST(0x00000008) #define MMU_FTR_TYPE_FSL_E ASM_CONST(0x00000010) #define MMU_FTR_TYPE_3E ASM_CONST(0x00000020) +#define MMU_FTR_TYPE_47x ASM_CONST(0x00000040) /* * This is individual features diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 5572e86223f4..b2d1ac635f22 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -817,6 +817,7 @@ #define PVR_403GC 0x00200200 #define PVR_403GCX 0x00201400 #define PVR_405GP 0x40110000 +#define PVR_476 0x11a52000 #define PVR_STB03XXX 0x40310000 #define PVR_NP405H 0x41410000 #define PVR_NP405L 0x41610000 diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 414d434a66d0..5304a37ba425 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -191,6 +191,10 @@ #define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */ #define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */ +#define PPC47x_MCSR_GPR 0x01000000 /* GPR parity error */ +#define PPC47x_MCSR_FPR 0x00800000 /* FPR parity error */ +#define PPC47x_MCSR_IPR 0x00400000 /* Imprecise Machine Check Exception */ + #ifdef CONFIG_E500 #define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ #define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */ @@ -604,5 +608,25 @@ #define DBCR_JOI 0x00000002 /* JTAG Serial Outbound Int. Enable */ #define DBCR_JII 0x00000001 /* JTAG Serial Inbound Int. Enable */ #endif /* 403GCX */ + +/* Some 476 specific registers */ +#define SPRN_SSPCR 830 +#define SPRN_USPCR 831 +#define SPRN_ISPCR 829 +#define SPRN_MMUBE0 820 +#define MMUBE0_IBE0_SHIFT 24 +#define MMUBE0_IBE1_SHIFT 16 +#define MMUBE0_IBE2_SHIFT 8 +#define MMUBE0_VBE0 0x00000004 +#define MMUBE0_VBE1 0x00000002 +#define MMUBE0_VBE2 0x00000001 +#define SPRN_MMUBE1 821 +#define MMUBE1_IBE3_SHIFT 24 +#define MMUBE1_IBE4_SHIFT 16 +#define MMUBE1_IBE5_SHIFT 8 +#define MMUBE1_VBE3 0x00000004 +#define MMUBE1_VBE4 0x00000002 +#define MMUBE1_VBE5 0x00000001 + #endif /* __ASM_POWERPC_REG_BOOKE_H__ */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 8af4949434b2..a1d845839727 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1701,6 +1701,19 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_440A, .platform = "ppc440", }, + { /* 476 core */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x11a50000, + .cpu_name = "476", + .cpu_features = CPU_FTRS_47X, + .cpu_user_features = COMMON_USER_BOOKE | + PPC_FEATURE_HAS_FPU, + .mmu_features = MMU_FTR_TYPE_47x | + MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, + .icache_bsize = 32, + .dcache_bsize = 128, + .platform = "ppc470", + }, { /* default match */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 1175a8539e6c..ed4aeb96398b 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -373,11 +373,13 @@ syscall_exit_cont: bnel- load_dbcr0 #endif #ifdef CONFIG_44x +BEGIN_MMU_FTR_SECTION lis r4,icache_44x_need_flush@ha lwz r5,icache_44x_need_flush@l(r4) cmplwi cr0,r5,0 bne- 2f 1: +END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_47x) #endif /* CONFIG_44x */ BEGIN_FTR_SECTION lwarx r7,0,r1 @@ -848,6 +850,9 @@ resume_kernel: /* interrupts are hard-disabled at this point */ restore: #ifdef CONFIG_44x +BEGIN_MMU_FTR_SECTION + b 1f +END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) lis r4,icache_44x_need_flush@ha lwz r5,icache_44x_need_flush@l(r4) cmplwi cr0,r5,0 diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 39be049a7850..1acd175428c4 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -37,6 +37,7 @@ #include #include #include +#include #include "head_booke.h" @@ -191,7 +192,7 @@ interrupt_base: #endif /* Data TLB Error Interrupt */ - START_EXCEPTION(DataTLBError) + START_EXCEPTION(DataTLBError44x) mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */ mtspr SPRN_SPRG_WSCRATCH1, r11 mtspr SPRN_SPRG_WSCRATCH2, r12 @@ -282,7 +283,7 @@ tlb_44x_patch_hwater_D: mfspr r10,SPRN_DEAR /* Jump to common tlb load */ - b finish_tlb_load + b finish_tlb_load_44x 2: /* The bailout. Restore registers to pre-exception conditions @@ -302,7 +303,7 @@ tlb_44x_patch_hwater_D: * information from different registers and bailout * to a different point. */ - START_EXCEPTION(InstructionTLBError) + START_EXCEPTION(InstructionTLBError44x) mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */ mtspr SPRN_SPRG_WSCRATCH1, r11 mtspr SPRN_SPRG_WSCRATCH2, r12 @@ -378,7 +379,7 @@ tlb_44x_patch_hwater_I: mfspr r10,SPRN_SRR0 /* Jump to common TLB load point */ - b finish_tlb_load + b finish_tlb_load_44x 2: /* The bailout. Restore registers to pre-exception conditions @@ -392,15 +393,7 @@ tlb_44x_patch_hwater_I: mfspr r10, SPRN_SPRG_RSCRATCH0 b InstructionStorage - /* Debug Interrupt */ - DEBUG_CRIT_EXCEPTION - -/* - * Local functions - */ - /* - * Both the instruction and data TLB miss get to this * point to load the TLB. * r10 - EA of fault @@ -410,7 +403,7 @@ tlb_44x_patch_hwater_I: * MMUCR - loaded with proper value when we get here * Upon exit, we reload everything and RFI. */ -finish_tlb_load: +finish_tlb_load_44x: /* Combine RPN & ERPN an write WS 0 */ rlwimi r11,r12,0,0,31-PAGE_SHIFT tlbwe r11,r13,PPC44x_TLB_XLAT @@ -443,6 +436,227 @@ finish_tlb_load: mfspr r10, SPRN_SPRG_RSCRATCH0 rfi /* Force context change */ +/* TLB error interrupts for 476 + */ +#ifdef CONFIG_PPC_47x + START_EXCEPTION(DataTLBError47x) + mtspr SPRN_SPRG_WSCRATCH0,r10 /* Save some working registers */ + mtspr SPRN_SPRG_WSCRATCH1,r11 + mtspr SPRN_SPRG_WSCRATCH2,r12 + mtspr SPRN_SPRG_WSCRATCH3,r13 + mfcr r11 + mtspr SPRN_SPRG_WSCRATCH4,r11 + mfspr r10,SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11,PAGE_OFFSET@h + cmplw cr0,r10,r11 + blt+ 3f + lis r11,swapper_pg_dir@h + ori r11,r11, swapper_pg_dir@l + li r12,0 /* MMUCR = 0 */ + b 4f + + /* Get the PGD for the current thread and setup MMUCR */ +3: mfspr r11,SPRN_SPRG3 + lwz r11,PGDIR(r11) + mfspr r12,SPRN_PID /* Get PID */ +4: mtspr SPRN_MMUCR,r12 /* Set MMUCR */ + + /* Mask of required permission bits. Note that while we + * do copy ESR:ST to _PAGE_RW position as trying to write + * to an RO page is pretty common, we don't do it with + * _PAGE_DIRTY. We could do it, but it's a fairly rare + * event so I'd rather take the overhead when it happens + * rather than adding an instruction here. We should measure + * whether the whole thing is worth it in the first place + * as we could avoid loading SPRN_ESR completely in the first + * place... + * + * TODO: Is it worth doing that mfspr & rlwimi in the first + * place or can we save a couple of instructions here ? + */ + mfspr r12,SPRN_ESR + li r13,_PAGE_PRESENT|_PAGE_ACCESSED + rlwimi r13,r12,10,30,30 + + /* Load the PTE */ + /* Compute pgdir/pmd offset */ + rlwinm r12,r10,PPC44x_PGD_OFF_SHIFT,PPC44x_PGD_OFF_MASK_BIT,29 + lwzx r11,r12,r11 /* Get pgd/pmd entry */ + + /* Word 0 is EPN,V,TS,DSIZ */ + li r12,PPC47x_TLB0_VALID | PPC47x_TLBE_SIZE + rlwimi r10,r12,0,32-PAGE_SHIFT,31 /* Insert valid and page size*/ + li r12,0 + tlbwe r10,r12,0 + + /* XXX can we do better ? Need to make sure tlbwe has established + * latch V bit in MMUCR0 before the PTE is loaded further down */ +#ifdef CONFIG_SMP + isync +#endif + + rlwinm. r12,r11,0,0,20 /* Extract pt base address */ + /* Compute pte address */ + rlwimi r12,r10,PPC44x_PTE_ADD_SHIFT,PPC44x_PTE_ADD_MASK_BIT,28 + beq 2f /* Bail if no table */ + lwz r11,0(r12) /* Get high word of pte entry */ + + /* XXX can we do better ? maybe insert a known 0 bit from r11 into the + * bottom of r12 to create a data dependency... We can also use r10 + * as destination nowadays + */ +#ifdef CONFIG_SMP + lwsync +#endif + lwz r12,4(r12) /* Get low word of pte entry */ + + andc. r13,r13,r12 /* Check permission */ + + /* Jump to common tlb load */ + beq finish_tlb_load_47x + +2: /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11,SPRN_SPRG_RSCRATCH4 + mtcr r11 + mfspr r13,SPRN_SPRG_RSCRATCH3 + mfspr r12,SPRN_SPRG_RSCRATCH2 + mfspr r11,SPRN_SPRG_RSCRATCH1 + mfspr r10,SPRN_SPRG_RSCRATCH0 + b DataStorage + + /* Instruction TLB Error Interrupt */ + /* + * Nearly the same as above, except we get our + * information from different registers and bailout + * to a different point. + */ + START_EXCEPTION(InstructionTLBError47x) + mtspr SPRN_SPRG_WSCRATCH0,r10 /* Save some working registers */ + mtspr SPRN_SPRG_WSCRATCH1,r11 + mtspr SPRN_SPRG_WSCRATCH2,r12 + mtspr SPRN_SPRG_WSCRATCH3,r13 + mfcr r11 + mtspr SPRN_SPRG_WSCRATCH4,r11 + mfspr r10,SPRN_SRR0 /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + lis r11,PAGE_OFFSET@h + cmplw cr0,r10,r11 + blt+ 3f + lis r11,swapper_pg_dir@h + ori r11,r11, swapper_pg_dir@l + li r12,0 /* MMUCR = 0 */ + b 4f + + /* Get the PGD for the current thread and setup MMUCR */ +3: mfspr r11,SPRN_SPRG_THREAD + lwz r11,PGDIR(r11) + mfspr r12,SPRN_PID /* Get PID */ +4: mtspr SPRN_MMUCR,r12 /* Set MMUCR */ + + /* Make up the required permissions */ + li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC + + /* Load PTE */ + /* Compute pgdir/pmd offset */ + rlwinm r12,r10,PPC44x_PGD_OFF_SHIFT,PPC44x_PGD_OFF_MASK_BIT,29 + lwzx r11,r12,r11 /* Get pgd/pmd entry */ + + /* Word 0 is EPN,V,TS,DSIZ */ + li r12,PPC47x_TLB0_VALID | PPC47x_TLBE_SIZE + rlwimi r10,r12,0,32-PAGE_SHIFT,31 /* Insert valid and page size*/ + li r12,0 + tlbwe r10,r12,0 + + /* XXX can we do better ? Need to make sure tlbwe has established + * latch V bit in MMUCR0 before the PTE is loaded further down */ +#ifdef CONFIG_SMP + isync +#endif + + rlwinm. r12,r11,0,0,20 /* Extract pt base address */ + /* Compute pte address */ + rlwimi r12,r10,PPC44x_PTE_ADD_SHIFT,PPC44x_PTE_ADD_MASK_BIT,28 + beq 2f /* Bail if no table */ + + lwz r11,0(r12) /* Get high word of pte entry */ + /* XXX can we do better ? maybe insert a known 0 bit from r11 into the + * bottom of r12 to create a data dependency... We can also use r10 + * as destination nowadays + */ +#ifdef CONFIG_SMP + lwsync +#endif + lwz r12,4(r12) /* Get low word of pte entry */ + + andc. r13,r13,r12 /* Check permission */ + + /* Jump to common TLB load point */ + beq finish_tlb_load_47x + +2: /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRN_SPRG_RSCRATCH4 + mtcr r11 + mfspr r13, SPRN_SPRG_RSCRATCH3 + mfspr r12, SPRN_SPRG_RSCRATCH2 + mfspr r11, SPRN_SPRG_RSCRATCH1 + mfspr r10, SPRN_SPRG_RSCRATCH0 + b InstructionStorage + +/* + * Both the instruction and data TLB miss get to this + * point to load the TLB. + * r10 - free to use + * r11 - PTE high word value + * r12 - PTE low word value + * r13 - free to use + * MMUCR - loaded with proper value when we get here + * Upon exit, we reload everything and RFI. + */ +finish_tlb_load_47x: + /* Combine RPN & ERPN an write WS 1 */ + rlwimi r11,r12,0,0,31-PAGE_SHIFT + tlbwe r11,r13,1 + + /* And make up word 2 */ + li r10,0xf85 /* Mask to apply from PTE */ + rlwimi r10,r12,29,30,30 /* DIRTY -> SW position */ + and r11,r12,r10 /* Mask PTE bits to keep */ + andi. r10,r12,_PAGE_USER /* User page ? */ + beq 1f /* nope, leave U bits empty */ + rlwimi r11,r11,3,26,28 /* yes, copy S bits to U */ +1: tlbwe r11,r13,2 + + /* Done...restore registers and get out of here. + */ + mfspr r11, SPRN_SPRG_RSCRATCH4 + mtcr r11 + mfspr r13, SPRN_SPRG_RSCRATCH3 + mfspr r12, SPRN_SPRG_RSCRATCH2 + mfspr r11, SPRN_SPRG_RSCRATCH1 + mfspr r10, SPRN_SPRG_RSCRATCH0 + rfi + +#endif /* CONFIG_PPC_47x */ + + /* Debug Interrupt */ + /* + * This statement needs to exist at the end of the IVPR + * definition just in case you end up taking a debug + * exception within another exception. + */ + DEBUG_CRIT_EXCEPTION + /* * Global functions */ @@ -491,9 +705,18 @@ _GLOBAL(set_context) /* * Init CPU state. This is called at boot time or for secondary CPUs * to setup initial TLB entries, setup IVORs, etc... + * */ _GLOBAL(init_cpu_state) mflr r22 +#ifdef CONFIG_PPC_47x + /* We use the PVR to differenciate 44x cores from 476 */ + mfspr r3,SPRN_PVR + srwi r3,r3,16 + cmplwi cr0,r3,PVR_476@h + beq head_start_47x +#endif /* CONFIG_PPC_47x */ + /* * In case the firmware didn't do it, we apply some workarounds * that are good for all 440 core variants here @@ -506,7 +729,7 @@ _GLOBAL(init_cpu_state) sync /* - * Set up the initial MMU state + * Set up the initial MMU state for 44x * * We are still executing code at the virtual address * mappings set by the firmware for the base of RAM. @@ -646,16 +869,257 @@ skpinv: addi r4,r4,1 /* Increment */ SET_IVOR(10, Decrementer); SET_IVOR(11, FixedIntervalTimer); SET_IVOR(12, WatchdogTimer); - SET_IVOR(13, DataTLBError); - SET_IVOR(14, InstructionTLBError); + SET_IVOR(13, DataTLBError44x); + SET_IVOR(14, InstructionTLBError44x); SET_IVOR(15, DebugCrit); + b head_start_common + + +#ifdef CONFIG_PPC_47x + +#ifdef CONFIG_SMP + +/* Entry point for secondary 47x processors */ +_GLOBAL(start_secondary_47x) + mr r24,r3 /* CPU number */ + + bl init_cpu_state + + /* Now we need to bolt the rest of kernel memory which + * is done in C code. We must be careful because our task + * struct or our stack can (and will probably) be out + * of reach of the initial 256M TLB entry, so we use a + * small temporary stack in .bss for that. This works + * because only one CPU at a time can be in this code + */ + lis r1,temp_boot_stack@h + ori r1,r1,temp_boot_stack@l + addi r1,r1,1024-STACK_FRAME_OVERHEAD + li r0,0 + stw r0,0(r1) + bl mmu_init_secondary + + /* Now we can get our task struct and real stack pointer */ + + /* Get current_thread_info and current */ + lis r1,secondary_ti@ha + lwz r1,secondary_ti@l(r1) + lwz r2,TI_TASK(r1) + + /* Current stack pointer */ + addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD + li r0,0 + stw r0,0(r1) + + /* Kernel stack for exception entry in SPRG3 */ + addi r4,r2,THREAD /* init task's THREAD */ + mtspr SPRN_SPRG3,r4 + + b start_secondary + +#endif /* CONFIG_SMP */ + +/* + * Set up the initial MMU state for 44x + * + * We are still executing code at the virtual address + * mappings set by the firmware for the base of RAM. + */ + +head_start_47x: + /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */ + mfspr r3,SPRN_PID /* Get PID */ + mfmsr r4 /* Get MSR */ + andi. r4,r4,MSR_IS@l /* TS=1? */ + beq 1f /* If not, leave STS=0 */ + oris r3,r3,PPC47x_MMUCR_STS@h /* Set STS=1 */ +1: mtspr SPRN_MMUCR,r3 /* Put MMUCR */ + sync + + /* Find the entry we are running from */ + bl 1f +1: mflr r23 + tlbsx r23,0,r23 + tlbre r24,r23,0 + tlbre r25,r23,1 + tlbre r26,r23,2 + +/* + * Cleanup time + */ + + /* Initialize MMUCR */ + li r5,0 + mtspr SPRN_MMUCR,r5 + sync + +clear_all_utlb_entries: + + #; Set initial values. + + addis r3,0,0x8000 + addi r4,0,0 + addi r5,0,0 + b clear_utlb_entry + + #; Align the loop to speed things up. + + .align 6 + +clear_utlb_entry: + + tlbwe r4,r3,0 + tlbwe r5,r3,1 + tlbwe r5,r3,2 + addis r3,r3,0x2000 + cmpwi r3,0 + bne clear_utlb_entry + addis r3,0,0x8000 + addis r4,r4,0x100 + cmpwi r4,0 + bne clear_utlb_entry + + #; Restore original entry. + + oris r23,r23,0x8000 /* specify the way */ + tlbwe r24,r23,0 + tlbwe r25,r23,1 + tlbwe r26,r23,2 + +/* + * Configure and load pinned entry into TLB for the kernel core + */ + + lis r3,PAGE_OFFSET@h + ori r3,r3,PAGE_OFFSET@l + + /* Kernel is at the base of RAM */ + li r4, 0 /* Load the kernel physical address */ + + /* Load the kernel PID = 0 */ + li r0,0 + mtspr SPRN_PID,r0 + sync + + /* Word 0 */ + clrrwi r3,r3,12 /* Mask off the effective page number */ + ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_256M + + /* Word 1 */ + clrrwi r4,r4,12 /* Mask off the real page number */ + /* ERPN is 0 for first 4GB page */ + /* Word 2 */ + li r5,0 + ori r5,r5,PPC47x_TLB2_S_RWX +#ifdef CONFIG_SMP + ori r5,r5,PPC47x_TLB2_M +#endif + + /* We write to way 0 and bolted 0 */ + lis r0,0x8800 + tlbwe r3,r0,0 + tlbwe r4,r0,1 + tlbwe r5,r0,2 + +/* + * Configure SSPCR, ISPCR and USPCR for now to search everything, we can fix + * them up later + */ + LOAD_REG_IMMEDIATE(r3, 0x9abcdef0) + mtspr SPRN_SSPCR,r3 + mtspr SPRN_USPCR,r3 + LOAD_REG_IMMEDIATE(r3, 0x12345670) + mtspr SPRN_ISPCR,r3 + + /* Force context change */ + mfmsr r0 + mtspr SPRN_SRR1, r0 + lis r0,3f@h + ori r0,r0,3f@l + mtspr SPRN_SRR0,r0 + sync + rfi + + /* Invalidate original entry we used */ +3: + rlwinm r24,r24,0,21,19 /* clear the "valid" bit */ + tlbwe r24,r23,0 + addi r24,0,0 + tlbwe r24,r23,1 + tlbwe r24,r23,2 + isync /* Clear out the shadow TLB entries */ + +#ifdef CONFIG_PPC_EARLY_DEBUG_44x + /* Add UART mapping for early debug. */ + + /* Word 0 */ + lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h + ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_TS | PPC47x_TLB0_1M + + /* Word 1 */ + lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h + ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH + + /* Word 2 */ + li r5,(PPC47x_TLB2_S_RW | PPC47x_TLB2_IMG) + + /* Bolted in way 0, bolt slot 5, we -hope- we don't hit the same + * congruence class as the kernel, we need to make sure of it at + * some point + */ + lis r0,0x8d00 + tlbwe r3,r0,0 + tlbwe r4,r0,1 + tlbwe r5,r0,2 + + /* Force context change */ + isync +#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ + + /* Establish the interrupt vector offsets */ + SET_IVOR(0, CriticalInput); + SET_IVOR(1, MachineCheckA); + SET_IVOR(2, DataStorage); + SET_IVOR(3, InstructionStorage); + SET_IVOR(4, ExternalInput); + SET_IVOR(5, Alignment); + SET_IVOR(6, Program); + SET_IVOR(7, FloatingPointUnavailable); + SET_IVOR(8, SystemCall); + SET_IVOR(9, AuxillaryProcessorUnavailable); + SET_IVOR(10, Decrementer); + SET_IVOR(11, FixedIntervalTimer); + SET_IVOR(12, WatchdogTimer); + SET_IVOR(13, DataTLBError47x); + SET_IVOR(14, InstructionTLBError47x); + SET_IVOR(15, DebugCrit); + + /* We configure icbi to invalidate 128 bytes at a time since the + * current 32-bit kernel code isn't too happy with icache != dcache + * block size + */ + mfspr r3,SPRN_CCR0 + oris r3,r3,0x0020 + mtspr SPRN_CCR0,r3 + isync + +#endif /* CONFIG_PPC_47x */ + +/* + * Here we are back to code that is common between 44x and 47x + * + * We proceed to further kernel initialization and return to the + * main kernel entry + */ +head_start_common: /* Establish the interrupt vector base */ lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ mtspr SPRN_IVPR,r4 addis r22,r22,KERNELBASE@h mtlr r22 + isync blr /* @@ -683,3 +1147,9 @@ swapper_pg_dir: */ abatron_pteptrs: .space 8 + +#ifdef CONFIG_SMP + .align 12 +temp_boot_stack: + .space 1024 +#endif /* CONFIG_SMP */ diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 8649f536f8df..8043d1b73cf0 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -441,7 +441,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) addi r3,r3,L1_CACHE_BYTES bdnz 0b sync -#ifndef CONFIG_44x +#ifdef CONFIG_44x /* We don't flush the icache on 44x. Those have a virtual icache * and we don't have access to the virtual address here (it's * not the page vaddr but where it's mapped in user space). The @@ -449,15 +449,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) * a change in the address space occurs, before returning to * user space */ +BEGIN_MMU_FTR_SECTION + blr +END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x) +#endif /* CONFIG_44x */ mtctr r4 1: icbi 0,r6 addi r6,r6,L1_CACHE_BYTES bdnz 1b sync isync -#endif /* CONFIG_44x */ blr +#ifndef CONFIG_BOOKE /* * Flush a particular page from the data cache to RAM, identified * by its physical address. We turn off the MMU so we can just use @@ -490,6 +494,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) mtmsr r10 /* restore DR */ isync blr +#endif /* CONFIG_BOOKE */ /* * Clear pages using the dcbz instruction, which doesn't cause any diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index e36f94f7411a..3fe4de2b685e 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -495,6 +495,14 @@ int __devinit start_secondary(void *unused) current->active_mm = &init_mm; smp_store_cpu_info(cpu); + +#if defined(CONFIG_BOOKE) || defined(CONFIG_40x) + /* Clear any pending timer interrupts */ + mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); + + /* Enable decrementer interrupt */ + mtspr(SPRN_TCR, TCR_DIE); +#endif set_dec(tb_ticks_per_jiffy); preempt_disable(); cpu_callin_map[cpu] = 1; diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c index 3986264b0993..d8c6efb32bc6 100644 --- a/arch/powerpc/mm/44x_mmu.c +++ b/arch/powerpc/mm/44x_mmu.c @@ -38,7 +38,9 @@ unsigned int tlb_44x_index; /* = 0 */ unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS; int icache_44x_need_flush; -static void __init ppc44x_update_tlb_hwater(void) +unsigned long tlb_47x_boltmap[1024/8]; + +static void __cpuinit ppc44x_update_tlb_hwater(void) { extern unsigned int tlb_44x_patch_hwater_D[]; extern unsigned int tlb_44x_patch_hwater_I[]; @@ -59,7 +61,7 @@ static void __init ppc44x_update_tlb_hwater(void) } /* - * "Pins" a 256MB TLB entry in AS0 for kernel lowmem + * "Pins" a 256MB TLB entry in AS0 for kernel lowmem for 44x type MMU */ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys) { @@ -67,12 +69,18 @@ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys) ppc44x_update_tlb_hwater(); + mtspr(SPRN_MMUCR, 0); + __asm__ __volatile__( "tlbwe %2,%3,%4\n" "tlbwe %1,%3,%5\n" "tlbwe %0,%3,%6\n" : +#ifdef CONFIG_PPC47x + : "r" (PPC47x_TLB2_S_RWX), +#else : "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), +#endif "r" (phys), "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M), "r" (entry), @@ -81,8 +89,93 @@ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys) "i" (PPC44x_TLB_ATTRIB)); } +static int __init ppc47x_find_free_bolted(void) +{ + unsigned int mmube0 = mfspr(SPRN_MMUBE0); + unsigned int mmube1 = mfspr(SPRN_MMUBE1); + + if (!(mmube0 & MMUBE0_VBE0)) + return 0; + if (!(mmube0 & MMUBE0_VBE1)) + return 1; + if (!(mmube0 & MMUBE0_VBE2)) + return 2; + if (!(mmube1 & MMUBE1_VBE3)) + return 3; + if (!(mmube1 & MMUBE1_VBE4)) + return 4; + if (!(mmube1 & MMUBE1_VBE5)) + return 5; + return -1; +} + +static void __init ppc47x_update_boltmap(void) +{ + unsigned int mmube0 = mfspr(SPRN_MMUBE0); + unsigned int mmube1 = mfspr(SPRN_MMUBE1); + + if (mmube0 & MMUBE0_VBE0) + __set_bit((mmube0 >> MMUBE0_IBE0_SHIFT) & 0xff, + tlb_47x_boltmap); + if (mmube0 & MMUBE0_VBE1) + __set_bit((mmube0 >> MMUBE0_IBE1_SHIFT) & 0xff, + tlb_47x_boltmap); + if (mmube0 & MMUBE0_VBE2) + __set_bit((mmube0 >> MMUBE0_IBE2_SHIFT) & 0xff, + tlb_47x_boltmap); + if (mmube1 & MMUBE1_VBE3) + __set_bit((mmube1 >> MMUBE1_IBE3_SHIFT) & 0xff, + tlb_47x_boltmap); + if (mmube1 & MMUBE1_VBE4) + __set_bit((mmube1 >> MMUBE1_IBE4_SHIFT) & 0xff, + tlb_47x_boltmap); + if (mmube1 & MMUBE1_VBE5) + __set_bit((mmube1 >> MMUBE1_IBE5_SHIFT) & 0xff, + tlb_47x_boltmap); +} + +/* + * "Pins" a 256MB TLB entry in AS0 for kernel lowmem for 47x type MMU + */ +static void __cpuinit ppc47x_pin_tlb(unsigned int virt, unsigned int phys) +{ + unsigned int rA; + int bolted; + + /* Base rA is HW way select, way 0, bolted bit set */ + rA = 0x88000000; + + /* Look for a bolted entry slot */ + bolted = ppc47x_find_free_bolted(); + BUG_ON(bolted < 0); + + /* Insert bolted slot number */ + rA |= bolted << 24; + + pr_debug("256M TLB entry for 0x%08x->0x%08x in bolt slot %d\n", + virt, phys, bolted); + + mtspr(SPRN_MMUCR, 0); + + __asm__ __volatile__( + "tlbwe %2,%3,0\n" + "tlbwe %1,%3,1\n" + "tlbwe %0,%3,2\n" + : + : "r" (PPC47x_TLB2_SW | PPC47x_TLB2_SR | + PPC47x_TLB2_SX +#ifdef CONFIG_SMP + | PPC47x_TLB2_M +#endif + ), + "r" (phys), + "r" (virt | PPC47x_TLB0_VALID | PPC47x_TLB0_256M), + "r" (rA)); +} + void __init MMU_init_hw(void) { + /* This is not useful on 47x but won't hurt either */ ppc44x_update_tlb_hwater(); flush_instruction_cache(); @@ -95,8 +188,51 @@ unsigned long __init mmu_mapin_ram(unsigned long top) /* Pin in enough TLBs to cover any lowmem not covered by the * initial 256M mapping established in head_44x.S */ for (addr = PPC_PIN_SIZE; addr < lowmem_end_addr; - addr += PPC_PIN_SIZE) - ppc44x_pin_tlb(addr + PAGE_OFFSET, addr); + addr += PPC_PIN_SIZE) { + if (mmu_has_feature(MMU_FTR_TYPE_47x)) + ppc47x_pin_tlb(addr + PAGE_OFFSET, addr); + else + ppc44x_pin_tlb(addr + PAGE_OFFSET, addr); + } + if (mmu_has_feature(MMU_FTR_TYPE_47x)) { + ppc47x_update_boltmap(); +#ifdef DEBUG + { + int i; + + printk(KERN_DEBUG "bolted entries: "); + for (i = 0; i < 255; i++) { + if (test_bit(i, tlb_47x_boltmap)) + printk("%d ", i); + } + printk("\n"); + } +#endif /* DEBUG */ + } return total_lowmem; } + +#ifdef CONFIG_SMP +void __cpuinit mmu_init_secondary(int cpu) +{ + unsigned long addr; + + /* Pin in enough TLBs to cover any lowmem not covered by the + * initial 256M mapping established in head_44x.S + * + * WARNING: This is called with only the first 256M of the + * linear mapping in the TLB and we can't take faults yet + * so beware of what this code uses. It runs off a temporary + * stack. current (r2) isn't initialized, smp_processor_id() + * will not work, current thread info isn't accessible, ... + */ + for (addr = PPC_PIN_SIZE; addr < lowmem_end_addr; + addr += PPC_PIN_SIZE) { + if (mmu_has_feature(MMU_FTR_TYPE_47x)) + ppc47x_pin_tlb(addr + PAGE_OFFSET, addr); + else + ppc44x_pin_tlb(addr + PAGE_OFFSET, addr); + } +} +#endif /* CONFIG_SMP */ diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index 1f2d9ff09895..ddfd7ad4e1d6 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c @@ -395,10 +395,18 @@ void __init mmu_context_init(void) * the PID/TID comparison is disabled, so we can use a TID of zero * to represent all kernel pages as shared among all contexts. * -- Dan + * + * The IBM 47x core supports 16-bit PIDs, thus 65535 contexts. We + * should normally never have to steal though the facility is + * present if needed. + * -- BenH */ if (mmu_has_feature(MMU_FTR_TYPE_8xx)) { first_context = 0; last_context = 15; + } else if (mmu_has_feature(MMU_FTR_TYPE_47x)) { + first_context = 1; + last_context = 65535; } else { first_context = 1; last_context = 255; diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index d49a77503e19..eb11d5d2aa94 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -69,12 +69,7 @@ static inline void _tlbil_va(unsigned long address, unsigned int pid, } #endif /* CONIFG_8xx */ -/* - * As of today, we don't support tlbivax broadcast on any - * implementation. When that becomes the case, this will be - * an extern. - */ -#ifdef CONFIG_PPC_BOOK3E +#if defined(CONFIG_PPC_BOOK3E) || defined(CONFIG_PPC_47x) extern void _tlbivax_bcast(unsigned long address, unsigned int pid, unsigned int tsize, unsigned int ind); #else diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index bbdc5b577b85..e925cb58afd9 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S @@ -10,7 +10,7 @@ * - tlbil_va * - tlbil_pid * - tlbil_all - * - tlbivax_bcast (not yet) + * - tlbivax_bcast * * Code mostly moved over from misc_32.S * @@ -33,6 +33,7 @@ #include #include #include +#include #if defined(CONFIG_40x) @@ -65,7 +66,7 @@ _GLOBAL(__tlbil_va) * Nothing to do for 8xx, everything is inline */ -#elif defined(CONFIG_44x) +#elif defined(CONFIG_44x) /* Includes 47x */ /* * 440 implementation uses tlbsx/we for tlbil_va and a full sweep @@ -73,7 +74,13 @@ _GLOBAL(__tlbil_va) */ _GLOBAL(__tlbil_va) mfspr r5,SPRN_MMUCR - rlwimi r5,r4,0,24,31 /* Set TID */ + mfmsr r10 + + /* + * We write 16 bits of STID since 47x supports that much, we + * will never be passed out of bounds values on 440 (hopefully) + */ + rlwimi r5,r4,0,16,31 /* We have to run the search with interrupts disabled, otherwise * an interrupt which causes a TLB miss can clobber the MMUCR @@ -83,24 +90,41 @@ _GLOBAL(__tlbil_va) * and restoring MMUCR, so only normal interrupts have to be * taken care of. */ - mfmsr r4 wrteei 0 mtspr SPRN_MMUCR,r5 - tlbsx. r3, 0, r3 - wrtee r4 - bne 1f + tlbsx. r6,0,r3 + bne 10f sync - /* There are only 64 TLB entries, so r3 < 64, - * which means bit 22, is clear. Since 22 is - * the V bit in the TLB_PAGEID, loading this +BEGIN_MMU_FTR_SECTION + b 2f +END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) + /* On 440 There are only 64 TLB entries, so r3 < 64, which means bit + * 22, is clear. Since 22 is the V bit in the TLB_PAGEID, loading this * value will invalidate the TLB entry. */ - tlbwe r3, r3, PPC44x_TLB_PAGEID + tlbwe r6,r6,PPC44x_TLB_PAGEID isync -1: blr +10: wrtee r10 + blr +2: +#ifdef CONFIG_PPC_47x + oris r7,r6,0x8000 /* specify way explicitely */ + clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */ + ori r4,r4,PPC47x_TLBE_SIZE + tlbwe r4,r7,0 /* write it */ + isync + wrtee r10 + blr +#else /* CONFIG_PPC_47x */ +1: trap + EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0; +#endif /* !CONFIG_PPC_47x */ _GLOBAL(_tlbil_all) _GLOBAL(_tlbil_pid) +BEGIN_MMU_FTR_SECTION + b 2f +END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) li r3,0 sync @@ -115,6 +139,76 @@ _GLOBAL(_tlbil_pid) isync blr +2: +#ifdef CONFIG_PPC_47x + /* 476 variant. There's not simple way to do this, hopefully we'll + * try to limit the amount of such full invalidates + */ + mfmsr r11 /* Interrupts off */ + wrteei 0 + li r3,-1 /* Current set */ + lis r10,tlb_47x_boltmap@h + ori r10,r10,tlb_47x_boltmap@l + lis r7,0x8000 /* Specify way explicitely */ + + b 9f /* For each set */ + +1: li r9,4 /* Number of ways */ + li r4,0 /* Current way */ + li r6,0 /* Default entry value 0 */ + andi. r0,r8,1 /* Check if way 0 is bolted */ + mtctr r9 /* Load way counter */ + bne- 3f /* Bolted, skip loading it */ + +2: /* For each way */ + or r5,r3,r4 /* Make way|index for tlbre */ + rlwimi r5,r5,16,8,15 /* Copy index into position */ + tlbre r6,r5,0 /* Read entry */ +3: addis r4,r4,0x2000 /* Next way */ + andi. r0,r6,PPC47x_TLB0_VALID /* Valid entry ? */ + beq 4f /* Nope, skip it */ + rlwimi r7,r5,0,1,2 /* Insert way number */ + rlwinm r6,r6,0,21,19 /* Clear V */ + tlbwe r6,r7,0 /* Write it */ +4: bdnz 2b /* Loop for each way */ + srwi r8,r8,1 /* Next boltmap bit */ +9: cmpwi cr1,r3,255 /* Last set done ? */ + addi r3,r3,1 /* Next set */ + beq cr1,1f /* End of loop */ + andi. r0,r3,0x1f /* Need to load a new boltmap word ? */ + bne 1b /* No, loop */ + lwz r8,0(r10) /* Load boltmap entry */ + addi r10,r10,4 /* Next word */ + b 1b /* Then loop */ +1: isync /* Sync shadows */ + wrtee r11 +#else /* CONFIG_PPC_47x */ +1: trap + EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0; +#endif /* !CONFIG_PPC_47x */ + blr + +#ifdef CONFIG_PPC_47x +/* + * _tlbivax_bcast is only on 47x. We don't bother doing a runtime + * check though, it will blow up soon enough if we mistakenly try + * to use it on a 440. + */ +_GLOBAL(_tlbivax_bcast) + mfspr r5,SPRN_MMUCR + mfmsr r10 + rlwimi r5,r4,0,16,31 + wrteei 0 + mtspr SPRN_MMUCR,r5 +/* tlbivax 0,r3 - use .long to avoid binutils deps */ + .long 0x7c000624 | (r3 << 11) + isync + eieio + tlbsync + sync + wrtee r10 + blr +#endif /* CONFIG_PPC_47x */ #elif defined(CONFIG_FSL_BOOKE) /* diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 7486bffd3ebb..9365e530ac5a 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -1,3 +1,12 @@ +config PPC_47x + bool "Support for 47x variant" + depends on 44x + default n + select MPIC + help + This option enables support for the 47x family of processors and is + not currently compatible with other 44x or 46x varients + config BAMBOO bool "Bamboo" depends on 44x diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index a8aae0b54579..d361f8119b1e 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -43,7 +43,7 @@ config 40x select PPC_PCI_CHOICE config 44x - bool "AMCC 44x" + bool "AMCC 44x, 46x or 47x" select PPC_DCR_NATIVE select PPC_UDBG_16550 select 4xx_SOC @@ -294,7 +294,7 @@ config PPC_PERF_CTRS This enables the powerpc-specific perf_event back-end. config SMP - depends on PPC_BOOK3S || PPC_BOOK3E || FSL_BOOKE + depends on PPC_BOOK3S || PPC_BOOK3E || FSL_BOOKE || PPC_47x bool "Symmetric multi-processing support" ---help--- This enables support for systems with more than one CPU. If you have @@ -322,6 +322,7 @@ config NR_CPUS config NOT_COHERENT_CACHE bool depends on 4xx || 8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON + default n if PPC_47x default y config CHECK_CACHE_COHERENCY -- cgit v1.2.3-59-g8ed1b From fc5e709731429bc2db27897630e7c0089f297680 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Fri, 5 Mar 2010 03:43:18 +0000 Subject: powerpc/476: add machine check handler for 47x core The 47x core's MCSR varies from 44x, so it needs it's own machine check handler. Signed-off-by: Dave Kleikamp Signed-off-by: Josh Boyer --- arch/powerpc/include/asm/cputable.h | 1 + arch/powerpc/kernel/cputable.c | 1 + arch/powerpc/kernel/traps.c | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 97ab5089df67..e3cba4e1eb34 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -72,6 +72,7 @@ extern int machine_check_4xx(struct pt_regs *regs); extern int machine_check_440A(struct pt_regs *regs); extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs); +extern int machine_check_47x(struct pt_regs *regs); /* NOTE WELL: Update identify_cpu() if fields are added or removed! */ struct cpu_spec { diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index a1d845839727..ad6baf834a76 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1712,6 +1712,7 @@ static struct cpu_spec __initdata cpu_specs[] = { MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, .icache_bsize = 32, .dcache_bsize = 128, + .machine_check = machine_check_47x, .platform = "ppc470", }, { /* default match */ diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 29d128eb6c43..ca7ce85ebc2e 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -380,6 +380,46 @@ int machine_check_440A(struct pt_regs *regs) } return 0; } + +int machine_check_47x(struct pt_regs *regs) +{ + unsigned long reason = get_mc_reason(regs); + u32 mcsr; + + printk(KERN_ERR "Machine check in kernel mode.\n"); + if (reason & ESR_IMCP) { + printk(KERN_ERR + "Instruction Synchronous Machine Check exception\n"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + return 0; + } + mcsr = mfspr(SPRN_MCSR); + if (mcsr & MCSR_IB) + printk(KERN_ERR "Instruction Read PLB Error\n"); + if (mcsr & MCSR_DRB) + printk(KERN_ERR "Data Read PLB Error\n"); + if (mcsr & MCSR_DWB) + printk(KERN_ERR "Data Write PLB Error\n"); + if (mcsr & MCSR_TLBP) + printk(KERN_ERR "TLB Parity Error\n"); + if (mcsr & MCSR_ICP) { + flush_instruction_cache(); + printk(KERN_ERR "I-Cache Parity Error\n"); + } + if (mcsr & MCSR_DCSP) + printk(KERN_ERR "D-Cache Search Parity Error\n"); + if (mcsr & PPC47x_MCSR_GPR) + printk(KERN_ERR "GPR Parity Error\n"); + if (mcsr & PPC47x_MCSR_FPR) + printk(KERN_ERR "FPR Parity Error\n"); + if (mcsr & PPC47x_MCSR_IPR) + printk(KERN_ERR "Machine Check exception is imprecise\n"); + + /* Clear MCSR */ + mtspr(SPRN_MCSR, mcsr); + + return 0; +} #elif defined(CONFIG_E500) int machine_check_e500(struct pt_regs *regs) { -- cgit v1.2.3-59-g8ed1b From d07e7ce9b6fd1a4ff0a6b40c74fbecdc584a135b Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 27 Apr 2010 15:55:21 +0900 Subject: ASoC: S3C: I2Sv2: Move defines closer to driver The header for I2Sv2 linux/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h contains only controller specific definitions and nothing SoC specific. So, it could be moved to sound/soc/s3c24xx/ Signed-off-by: Jassi Brar Acked-by: Ben Dooks Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- .../plat-samsung/include/plat/regs-s3c2412-iis.h | 82 ---------------------- sound/soc/s3c24xx/regs-i2s-v2.h | 82 ++++++++++++++++++++++ sound/soc/s3c24xx/s3c-i2s-v2.c | 3 +- sound/soc/s3c24xx/s3c2412-i2s.c | 3 +- sound/soc/s3c24xx/s3c64xx-i2s.c | 2 +- 5 files changed, 85 insertions(+), 87 deletions(-) delete mode 100644 arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h create mode 100644 sound/soc/s3c24xx/regs-i2s-v2.h (limited to 'arch') diff --git a/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h b/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h deleted file mode 100644 index abf2fbc2eb2f..000000000000 --- a/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h +++ /dev/null @@ -1,82 +0,0 @@ -/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h - * - * Copyright 2007 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * - * 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. - * - * S3C2412 IIS register definition -*/ - -#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H -#define __ASM_ARCH_REGS_S3C2412_IIS_H - -#define S3C2412_IISCON (0x00) -#define S3C2412_IISMOD (0x04) -#define S3C2412_IISFIC (0x08) -#define S3C2412_IISPSR (0x0C) -#define S3C2412_IISTXD (0x10) -#define S3C2412_IISRXD (0x14) - -#define S3C2412_IISCON_LRINDEX (1 << 11) -#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10) -#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9) -#define S3C2412_IISCON_TXFIFO_FULL (1 << 8) -#define S3C2412_IISCON_RXFIFO_FULL (1 << 7) -#define S3C2412_IISCON_TXDMA_PAUSE (1 << 6) -#define S3C2412_IISCON_RXDMA_PAUSE (1 << 5) -#define S3C2412_IISCON_TXCH_PAUSE (1 << 4) -#define S3C2412_IISCON_RXCH_PAUSE (1 << 3) -#define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2) -#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) -#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) - -#define S3C64XX_IISMOD_BLC_16BIT (0 << 13) -#define S3C64XX_IISMOD_BLC_8BIT (1 << 13) -#define S3C64XX_IISMOD_BLC_24BIT (2 << 13) -#define S3C64XX_IISMOD_BLC_MASK (3 << 13) - -#define S3C64XX_IISMOD_IMS_PCLK (0 << 10) -#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10) - -#define S3C2412_IISMOD_MASTER_INTERNAL (0 << 10) -#define S3C2412_IISMOD_MASTER_EXTERNAL (1 << 10) -#define S3C2412_IISMOD_SLAVE (2 << 10) -#define S3C2412_IISMOD_MASTER_MASK (3 << 10) -#define S3C2412_IISMOD_MODE_TXONLY (0 << 8) -#define S3C2412_IISMOD_MODE_RXONLY (1 << 8) -#define S3C2412_IISMOD_MODE_TXRX (2 << 8) -#define S3C2412_IISMOD_MODE_MASK (3 << 8) -#define S3C2412_IISMOD_LR_LLOW (0 << 7) -#define S3C2412_IISMOD_LR_RLOW (1 << 7) -#define S3C2412_IISMOD_SDF_IIS (0 << 5) -#define S3C2412_IISMOD_SDF_MSB (1 << 5) -#define S3C2412_IISMOD_SDF_LSB (2 << 5) -#define S3C2412_IISMOD_SDF_MASK (3 << 5) -#define S3C2412_IISMOD_RCLK_256FS (0 << 3) -#define S3C2412_IISMOD_RCLK_512FS (1 << 3) -#define S3C2412_IISMOD_RCLK_384FS (2 << 3) -#define S3C2412_IISMOD_RCLK_768FS (3 << 3) -#define S3C2412_IISMOD_RCLK_MASK (3 << 3) -#define S3C2412_IISMOD_BCLK_32FS (0 << 1) -#define S3C2412_IISMOD_BCLK_48FS (1 << 1) -#define S3C2412_IISMOD_BCLK_16FS (2 << 1) -#define S3C2412_IISMOD_BCLK_24FS (3 << 1) -#define S3C2412_IISMOD_BCLK_MASK (3 << 1) -#define S3C2412_IISMOD_8BIT (1 << 0) - -#define S3C64XX_IISMOD_CDCLKCON (1 << 12) - -#define S3C2412_IISPSR_PSREN (1 << 15) - -#define S3C2412_IISFIC_TXFLUSH (1 << 15) -#define S3C2412_IISFIC_RXFLUSH (1 << 7) -#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf) -#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf) - - - -#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */ - diff --git a/sound/soc/s3c24xx/regs-i2s-v2.h b/sound/soc/s3c24xx/regs-i2s-v2.h new file mode 100644 index 000000000000..abf2fbc2eb2f --- /dev/null +++ b/sound/soc/s3c24xx/regs-i2s-v2.h @@ -0,0 +1,82 @@ +/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h + * + * Copyright 2007 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * + * 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. + * + * S3C2412 IIS register definition +*/ + +#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H +#define __ASM_ARCH_REGS_S3C2412_IIS_H + +#define S3C2412_IISCON (0x00) +#define S3C2412_IISMOD (0x04) +#define S3C2412_IISFIC (0x08) +#define S3C2412_IISPSR (0x0C) +#define S3C2412_IISTXD (0x10) +#define S3C2412_IISRXD (0x14) + +#define S3C2412_IISCON_LRINDEX (1 << 11) +#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10) +#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9) +#define S3C2412_IISCON_TXFIFO_FULL (1 << 8) +#define S3C2412_IISCON_RXFIFO_FULL (1 << 7) +#define S3C2412_IISCON_TXDMA_PAUSE (1 << 6) +#define S3C2412_IISCON_RXDMA_PAUSE (1 << 5) +#define S3C2412_IISCON_TXCH_PAUSE (1 << 4) +#define S3C2412_IISCON_RXCH_PAUSE (1 << 3) +#define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2) +#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) +#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) + +#define S3C64XX_IISMOD_BLC_16BIT (0 << 13) +#define S3C64XX_IISMOD_BLC_8BIT (1 << 13) +#define S3C64XX_IISMOD_BLC_24BIT (2 << 13) +#define S3C64XX_IISMOD_BLC_MASK (3 << 13) + +#define S3C64XX_IISMOD_IMS_PCLK (0 << 10) +#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10) + +#define S3C2412_IISMOD_MASTER_INTERNAL (0 << 10) +#define S3C2412_IISMOD_MASTER_EXTERNAL (1 << 10) +#define S3C2412_IISMOD_SLAVE (2 << 10) +#define S3C2412_IISMOD_MASTER_MASK (3 << 10) +#define S3C2412_IISMOD_MODE_TXONLY (0 << 8) +#define S3C2412_IISMOD_MODE_RXONLY (1 << 8) +#define S3C2412_IISMOD_MODE_TXRX (2 << 8) +#define S3C2412_IISMOD_MODE_MASK (3 << 8) +#define S3C2412_IISMOD_LR_LLOW (0 << 7) +#define S3C2412_IISMOD_LR_RLOW (1 << 7) +#define S3C2412_IISMOD_SDF_IIS (0 << 5) +#define S3C2412_IISMOD_SDF_MSB (1 << 5) +#define S3C2412_IISMOD_SDF_LSB (2 << 5) +#define S3C2412_IISMOD_SDF_MASK (3 << 5) +#define S3C2412_IISMOD_RCLK_256FS (0 << 3) +#define S3C2412_IISMOD_RCLK_512FS (1 << 3) +#define S3C2412_IISMOD_RCLK_384FS (2 << 3) +#define S3C2412_IISMOD_RCLK_768FS (3 << 3) +#define S3C2412_IISMOD_RCLK_MASK (3 << 3) +#define S3C2412_IISMOD_BCLK_32FS (0 << 1) +#define S3C2412_IISMOD_BCLK_48FS (1 << 1) +#define S3C2412_IISMOD_BCLK_16FS (2 << 1) +#define S3C2412_IISMOD_BCLK_24FS (3 << 1) +#define S3C2412_IISMOD_BCLK_MASK (3 << 1) +#define S3C2412_IISMOD_8BIT (1 << 0) + +#define S3C64XX_IISMOD_CDCLKCON (1 << 12) + +#define S3C2412_IISPSR_PSREN (1 << 15) + +#define S3C2412_IISFIC_TXFLUSH (1 << 15) +#define S3C2412_IISFIC_RXFLUSH (1 << 7) +#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf) +#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf) + + + +#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */ + diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index 865f93143bf1..cb3652ed057d 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -24,10 +24,9 @@ #include #include -#include - #include +#include "regs-i2s-v2.h" #include "s3c-i2s-v2.h" #include "s3c-dma.h" diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c index f3148f98b419..7134465693e3 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/sound/soc/s3c24xx/s3c2412-i2s.c @@ -32,12 +32,11 @@ #include #include -#include - #include #include #include "s3c-dma.h" +#include "regs-i2s-v2.h" #include "s3c2412-i2s.h" #define S3C2412_I2S_DEBUG 0 diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index ab1fa159d3ae..b7e951fe30a6 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -18,7 +18,6 @@ #include -#include #include #include #include @@ -27,6 +26,7 @@ #include #include "s3c-dma.h" +#include "regs-i2s-v2.h" #include "s3c64xx-i2s.h" /* The value should be set to maximum of the total number -- cgit v1.2.3-59-g8ed1b From 221c185d4e11b4061409da5d592779ced484614c Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Fri, 5 Mar 2010 10:43:24 +0000 Subject: powerpc/476: Add isync after loading mmu and debug spr's 476 requires an isync after loading MMU and debug related SPR's. Some of these are in performance-critical paths and may need to be optimized, but initially, we're playing it safe. Signed-off-by: Torez Smith Signed-off-by: Dave Kleikamp Signed-off-by: Josh Boyer --- arch/powerpc/kernel/kprobes.c | 3 +++ arch/powerpc/kernel/process.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index b36f074524ad..c533525ca56a 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -114,6 +114,9 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) #ifdef CONFIG_PPC_ADV_DEBUG_REGS regs->msr &= ~MSR_CE; mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM); +#ifdef CONFIG_PPC_47x + isync(); +#endif #endif /* diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index e4d71ced97ef..9d255b4f0a0e 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -371,6 +371,9 @@ int set_dabr(unsigned long dabr) /* XXX should we have a CPU_FTR_HAS_DABR ? */ #ifdef CONFIG_PPC_ADV_DEBUG_REGS mtspr(SPRN_DAC1, dabr); +#ifdef CONFIG_PPC_47x + isync(); +#endif #elif defined(CONFIG_PPC_BOOK3S) mtspr(SPRN_DABR, dabr); #endif -- cgit v1.2.3-59-g8ed1b From 17dcd13a3793d434c030dcf9c52ad0d43493b2a0 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 22 Apr 2010 10:47:43 +0200 Subject: ARM: h1940: fix touchscreen support The touchscreen is using the adc device so it needs to be in the device list Signed-off-by: Arnaud Patard Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-h1940.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index fbedd0760941..bd4ced59c9ad 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -271,7 +271,6 @@ static struct platform_device h1940_lcd_powerdev = { }; static struct platform_device *h1940_devices[] __initdata = { - &s3c_device_ts, &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, @@ -285,6 +284,8 @@ static struct platform_device *h1940_devices[] __initdata = { &s3c_device_timer[0], &h1940_backlight, &h1940_lcd_powerdev, + &s3c_device_adc, + &s3c_device_ts, }; static void __init h1940_map_io(void) -- cgit v1.2.3-59-g8ed1b From f44c67cdc3182dd59cae299488687c6280027410 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 22 Apr 2010 10:47:44 +0200 Subject: ARM: S3C24XX: fix s3c2410fb platdata passing Setting s3c2410fb_mach_info displays field with a struct marked as __initdata means it won't be available later for ioctls like FBIOPUT_VSCREENINFO and they will fail. Copying in s3c24xx_fb_set_platdata() is fixing this issue. Signed-off-by: Arnaud Patard Signed-off-by: Ben Dooks --- arch/arm/plat-s3c24xx/devs.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 9265f09bfa58..429e45321384 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -149,10 +150,14 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd) { struct s3c2410fb_mach_info *npd; - npd = kmalloc(sizeof(*npd), GFP_KERNEL); + npd = kmemdup(pd, sizeof(*npd), GFP_KERNEL); if (npd) { - memcpy(npd, pd, sizeof(*npd)); s3c_device_lcd.dev.platform_data = npd; + npd->displays = kmemdup(pd->displays, + sizeof(struct s3c2410fb_display) * npd->num_displays, + GFP_KERNEL); + if (!npd->displays) + printk(KERN_ERR "no memory for LCD display data\n"); } else { printk(KERN_ERR "no memory for LCD platform data\n"); } -- cgit v1.2.3-59-g8ed1b From 1f138f13890afc824443a9cfcebe9ecae7727666 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 22 Apr 2010 10:47:45 +0200 Subject: ARM: S3C24XX: s3c24xx_mci_set_platdata should be marked __init The s3c24xx_mci_set_platdata() is init time only, so should be marked as __init Signed-off-by: Arnaud Patard [ben-linux@fluff.org: update description] Signed-off-by: Ben Dooks --- arch/arm/plat-s3c24xx/devs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 429e45321384..b9565c1eb410 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -376,7 +376,7 @@ struct platform_device s3c_device_sdi = { EXPORT_SYMBOL(s3c_device_sdi); -void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata) +void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata) { struct s3c24xx_mci_pdata *npd; -- cgit v1.2.3-59-g8ed1b From b4e8c8dd8456c1d3685fb5b715c9795d250f500e Mon Sep 17 00:00:00 2001 From: Torez Smith Date: Fri, 5 Mar 2010 10:45:54 +0000 Subject: powerpc/4xx: Simple platform for the ISS 4xx simulator This is a trivial 4xx plaform that uses the new simple bsp from Josh and is handy to use in simulators such as ISS or even Mambo who don't properly implement most of the actual devices in the SoC but really only the core. Signed-off-by: Torez Smith Signed-off-by: Dave Kleikamp Signed-off-by: Josh Boyer --- arch/powerpc/boot/Makefile | 5 +- arch/powerpc/boot/dts/iss4xx-mpic.dts | 155 +++++++++++++++++++++++++++++++ arch/powerpc/boot/dts/iss4xx.dts | 116 +++++++++++++++++++++++ arch/powerpc/boot/treeboot-iss4xx.c | 56 ++++++++++++ arch/powerpc/boot/wrapper | 3 + arch/powerpc/include/asm/reg.h | 3 + arch/powerpc/kernel/cputable.c | 15 +++ arch/powerpc/kernel/head_44x.S | 2 + arch/powerpc/platforms/44x/Kconfig | 11 +++ arch/powerpc/platforms/44x/Makefile | 1 + arch/powerpc/platforms/44x/iss4xx.c | 167 ++++++++++++++++++++++++++++++++++ 11 files changed, 533 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/boot/dts/iss4xx-mpic.dts create mode 100644 arch/powerpc/boot/dts/iss4xx.dts create mode 100644 arch/powerpc/boot/treeboot-iss4xx.c create mode 100644 arch/powerpc/platforms/44x/iss4xx.c (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 25e889c0c06e..ad0df7d0a643 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -44,6 +44,7 @@ $(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405 $(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405 $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405 $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 +$(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405 $(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405 @@ -77,7 +78,7 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \ virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \ cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c \ - gamecube-head.S gamecube.c wii-head.S wii.c + gamecube-head.S gamecube.c wii-head.S wii.c treeboot-iss4xx.c src-boot := $(src-wlib) $(src-plat) empty.c src-boot := $(addprefix $(obj)/, $(src-boot)) @@ -206,6 +207,8 @@ image-$(CONFIG_TAISHAN) += cuImage.taishan image-$(CONFIG_KATMAI) += cuImage.katmai image-$(CONFIG_WARP) += cuImage.warp image-$(CONFIG_YOSEMITE) += cuImage.yosemite +image-$(CONFIG_ISS4xx) += treeImage.iss4xx \ + treeImage.iss4xx-mpic # Board ports in arch/powerpc/platform/8xx/Kconfig image-$(CONFIG_MPC86XADS) += cuImage.mpc866ads diff --git a/arch/powerpc/boot/dts/iss4xx-mpic.dts b/arch/powerpc/boot/dts/iss4xx-mpic.dts new file mode 100644 index 000000000000..23e9d9b7e400 --- /dev/null +++ b/arch/powerpc/boot/dts/iss4xx-mpic.dts @@ -0,0 +1,155 @@ +/* + * Device Tree Source for IBM Embedded PPC 476 Platform + * + * Copyright 2010 Torez Smith, IBM Corporation. + * + * Based on earlier code: + * Copyright (c) 2006, 2007 IBM Corp. + * Josh Boyer , David Gibson + * + * 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. + */ + +/dts-v1/; + +/memreserve/ 0x01f00000 0x00100000; + +/ { + #address-cells = <2>; + #size-cells = <1>; + model = "ibm,iss-4xx"; + compatible = "ibm,iss-4xx"; + dcr-parent = <&{/cpus/cpu@0}>; + + aliases { + serial0 = &UART0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,4xx"; // real CPU changed in sim + reg = <0>; + clock-frequency = <100000000>; // 100Mhz :-) + timebase-frequency = <100000000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + dcr-controller; + dcr-access-method = "native"; + status = "ok"; + }; + cpu@1 { + device_type = "cpu"; + model = "PowerPC,4xx"; // real CPU changed in sim + reg = <1>; + clock-frequency = <100000000>; // 100Mhz :-) + timebase-frequency = <100000000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + dcr-controller; + dcr-access-method = "native"; + status = "disabled"; + enable-method = "spin-table"; + cpu-release-addr = <0 0x01f00100>; + }; + cpu@2 { + device_type = "cpu"; + model = "PowerPC,4xx"; // real CPU changed in sim + reg = <2>; + clock-frequency = <100000000>; // 100Mhz :-) + timebase-frequency = <100000000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + dcr-controller; + dcr-access-method = "native"; + status = "disabled"; + enable-method = "spin-table"; + cpu-release-addr = <0 0x01f00200>; + }; + cpu@3 { + device_type = "cpu"; + model = "PowerPC,4xx"; // real CPU changed in sim + reg = <3>; + clock-frequency = <100000000>; // 100Mhz :-) + timebase-frequency = <100000000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + dcr-controller; + dcr-access-method = "native"; + status = "disabled"; + enable-method = "spin-table"; + cpu-release-addr = <0 0x01f00300>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000>; // Filled in by zImage + + }; + + MPIC: interrupt-controller { + compatible = "chrp,open-pic"; + interrupt-controller; + dcr-reg = <0xffc00000 0x00030000>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + }; + + plb { + compatible = "ibm,plb-4xx", "ibm,plb4"; /* Could be PLB6, doesn't matter */ + #address-cells = <2>; + #size-cells = <1>; + ranges; + clock-frequency = <0>; // Filled in by zImage + + POB0: opb { + compatible = "ibm,opb-4xx", "ibm,opb"; + #address-cells = <1>; + #size-cells = <1>; + /* Wish there was a nicer way of specifying a full 32-bit + range */ + ranges = <0x00000000 0x00000001 0x00000000 0x80000000 + 0x80000000 0x00000001 0x80000000 0x80000000>; + clock-frequency = <0>; // Filled in by zImage + UART0: serial@40000200 { + device_type = "serial"; + compatible = "ns16550a"; + reg = <0x40000200 0x00000008>; + virtual-reg = <0xe0000200>; + clock-frequency = <11059200>; + current-speed = <115200>; + interrupt-parent = <&MPIC>; + interrupts = <0x0 0x2>; + }; + }; + }; + + nvrtc { + compatible = "ds1743-nvram", "ds1743", "rtc-ds1743"; + reg = <0 0xEF703000 0x2000>; + }; + iss-block { + compatible = "ibm,iss-sim-block-device"; + reg = <0 0xEF701000 0x1000>; + }; + + chosen { + linux,stdout-path = "/plb/opb/serial@40000200"; + }; +}; diff --git a/arch/powerpc/boot/dts/iss4xx.dts b/arch/powerpc/boot/dts/iss4xx.dts new file mode 100644 index 000000000000..4ff6555c866d --- /dev/null +++ b/arch/powerpc/boot/dts/iss4xx.dts @@ -0,0 +1,116 @@ +/* + * Device Tree Source for IBM Embedded PPC 476 Platform + * + * Copyright 2010 Torez Smith, IBM Corporation. + * + * Based on earlier code: + * Copyright (c) 2006, 2007 IBM Corp. + * Josh Boyer , David Gibson + * + * 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. + */ + +/dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <1>; + model = "ibm,iss-4xx"; + compatible = "ibm,iss-4xx"; + dcr-parent = <&{/cpus/cpu@0}>; + + aliases { + serial0 = &UART0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,4xx"; // real CPU changed in sim + reg = <0x00000000>; + clock-frequency = <100000000>; // 100Mhz :-) + timebase-frequency = <100000000>; + i-cache-line-size = <32>; // may need fixup in sim + d-cache-line-size = <32>; // may need fixup in sim + i-cache-size = <32768>; /* may need fixup in sim */ + d-cache-size = <32768>; /* may need fixup in sim */ + dcr-controller; + dcr-access-method = "native"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000>; // Filled in by zImage + }; + + UIC0: interrupt-controller0 { + compatible = "ibm,uic-4xx", "ibm,uic"; + interrupt-controller; + cell-index = <0>; + dcr-reg = <0x0c0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + + }; + + UIC1: interrupt-controller1 { + compatible = "ibm,uic-4xx", "ibm,uic"; + interrupt-controller; + cell-index = <1>; + dcr-reg = <0x0d0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + plb { + compatible = "ibm,plb-4xx", "ibm,plb4"; /* Could be PLB6, doesn't matter */ + #address-cells = <2>; + #size-cells = <1>; + ranges; + clock-frequency = <0>; // Filled in by zImage + + POB0: opb { + compatible = "ibm,opb-4xx", "ibm,opb"; + #address-cells = <1>; + #size-cells = <1>; + /* Wish there was a nicer way of specifying a full 32-bit + range */ + ranges = <0x00000000 0x00000001 0x00000000 0x80000000 + 0x80000000 0x00000001 0x80000000 0x80000000>; + clock-frequency = <0>; // Filled in by zImage + UART0: serial@40000200 { + device_type = "serial"; + compatible = "ns16550a"; + reg = <0x40000200 0x00000008>; + virtual-reg = <0xe0000200>; + clock-frequency = <11059200>; + current-speed = <115200>; + interrupt-parent = <&UIC0>; + interrupts = <0x0 0x4>; + }; + }; + }; + + nvrtc { + compatible = "ds1743-nvram", "ds1743", "rtc-ds1743"; + reg = <0 0xEF703000 0x2000>; + }; + iss-block { + compatible = "ibm,iss-sim-block-device"; + reg = <0 0xEF701000 0x1000>; + }; + + chosen { + linux,stdout-path = "/plb/opb/serial@40000200"; + }; +}; diff --git a/arch/powerpc/boot/treeboot-iss4xx.c b/arch/powerpc/boot/treeboot-iss4xx.c new file mode 100644 index 000000000000..fcc44952874e --- /dev/null +++ b/arch/powerpc/boot/treeboot-iss4xx.c @@ -0,0 +1,56 @@ +/* + * Copyright 2010 Ben. Herrenschmidt, IBM Corporation. + * + * Based on earlier code: + * Copyright (C) Paul Mackerras 1997. + * + * Matt Porter + * Copyright 2002-2005 MontaVista Software Inc. + * + * Eugene Surovegin or + * Copyright (c) 2003, 2004 Zultys Technologies + * + * Copyright 2007 David Gibson, IBM Corporation. + * + * 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. + */ +#include +#include +#include "types.h" +#include "elf.h" +#include "string.h" +#include "stdio.h" +#include "page.h" +#include "ops.h" +#include "reg.h" +#include "io.h" +#include "dcr.h" +#include "4xx.h" +#include "44x.h" +#include "libfdt.h" + +BSS_STACK(4096); + +static void iss_4xx_fixups(void) +{ + ibm4xx_sdram_fixup_memsize(); +} + +#define SPRN_PIR 0x11E /* Processor Indentification Register */ +void platform_init(void) +{ + unsigned long end_of_ram = 0x08000000; + unsigned long avail_ram = end_of_ram - (unsigned long)_end; + u32 pir_reg; + + simple_alloc_init(_end, avail_ram, 128, 64); + platform_ops.fixups = iss_4xx_fixups; + platform_ops.exit = ibm44x_dbcr_reset; + pir_reg = mfspr(SPRN_PIR); + fdt_set_boot_cpuid_phys(_dtb_start, pir_reg); + fdt_init(_dtb_start); + serial_console_init(); +} diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 7160b3b1fb35..cb97e7511d7e 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -241,6 +241,9 @@ gamecube|wii) link_address='0x600000' platformo="$object/$platform-head.o $object/$platform.o" ;; +treeboot-iss4xx-mpic) + platformo="$object/treeboot-iss4xx.o" + ;; esac vmz="$tmpdir/`basename \"$kernel\"`.$ext" diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index b2d1ac635f22..b68f025924a8 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -854,6 +854,9 @@ #define PVR_8245 0x80811014 #define PVR_8260 PVR_8240 +/* 476 Simulator seems to currently have the PVR of the 602... */ +#define PVR_476_ISS 0x00052000 + /* 64-bit processors */ /* XXX the prefix should be PVR_, we'll do a global sweep to fix it one day */ #define PV_NORTHSTAR 0x0033 diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index ad6baf834a76..9556be903e96 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1715,6 +1715,21 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_47x, .platform = "ppc470", }, + { /* 476 iss */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00050000, + .cpu_name = "476", + .cpu_features = CPU_FTRS_47X, + .cpu_user_features = COMMON_USER_BOOKE | + PPC_FEATURE_HAS_FPU, + .cpu_user_features = COMMON_USER_BOOKE, + .mmu_features = MMU_FTR_TYPE_47x | + MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, + .icache_bsize = 32, + .dcache_bsize = 128, + .machine_check = machine_check_47x, + .platform = "ppc470", + }, { /* default match */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 1acd175428c4..5ab484ef06a7 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -715,6 +715,8 @@ _GLOBAL(init_cpu_state) srwi r3,r3,16 cmplwi cr0,r3,PVR_476@h beq head_start_47x + cmplwi cr0,r3,PVR_476_ISS@h + beq head_start_47x #endif /* CONFIG_PPC_47x */ /* diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 9365e530ac5a..eeba0a70e466 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -160,6 +160,17 @@ config YOSEMITE help This option enables support for the AMCC PPC440EP evaluation board. +config ISS4xx + bool "ISS 4xx Simulator" + depends on (44x || 40x) + default n + select 405GP if 40x + select 440GP if 44x && !PPC_47x + select PPC_FPU + select OF_RTC + help + This option enables support for the IBM ISS simulation environment + #config LUAN # bool "Luan" # depends on 44x diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index ee6185aeaa3b..82ff326e0795 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_SAM440EP) += sam440ep.o obj-$(CONFIG_WARP) += warp.o obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o +obj-$(CONFIG_ISS4xx) += iss4xx.o diff --git a/arch/powerpc/platforms/44x/iss4xx.c b/arch/powerpc/platforms/44x/iss4xx.c new file mode 100644 index 000000000000..aa46e9d1e771 --- /dev/null +++ b/arch/powerpc/platforms/44x/iss4xx.c @@ -0,0 +1,167 @@ +/* + * PPC476 board specific routines + * + * Copyright 2010 Torez Smith, IBM Corporation. + * + * Based on earlier code: + * Matt Porter + * Copyright 2002-2005 MontaVista Software Inc. + * + * Eugene Surovegin or + * Copyright (c) 2003-2005 Zultys Technologies + * + * Rewritten and ported to the merged powerpc tree: + * Copyright 2007 David Gibson , IBM Corporation. + * + * 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. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static __initdata struct of_device_id iss4xx_of_bus[] = { + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,plb6", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + {}, +}; + +static int __init iss4xx_device_probe(void) +{ + of_platform_bus_probe(NULL, iss4xx_of_bus, NULL); + of_instantiate_rtc(); + + return 0; +} +machine_device_initcall(iss4xx, iss4xx_device_probe); + +/* We can have either UICs or MPICs */ +static void __init iss4xx_init_irq(void) +{ + struct device_node *np; + + /* Find top level interrupt controller */ + for_each_node_with_property(np, "interrupt-controller") { + if (of_get_property(np, "interrupts", NULL) == NULL) + break; + } + if (np == NULL) + panic("Can't find top level interrupt controller"); + + /* Check type and do appropriate initialization */ + if (of_device_is_compatible(np, "ibm,uic")) { + uic_init_tree(); + ppc_md.get_irq = uic_get_irq; +#ifdef CONFIG_MPIC + } else if (of_device_is_compatible(np, "chrp,open-pic")) { + /* The MPIC driver will get everything it needs from the + * device-tree, just pass 0 to all arguments + */ + struct mpic *mpic = mpic_alloc(np, 0, MPIC_PRIMARY, 0, 0, + " MPIC "); + BUG_ON(mpic == NULL); + mpic_init(mpic); + ppc_md.get_irq = mpic_get_irq; +#endif + } else + panic("Unrecognized top level interrupt controller"); +} + +#ifdef CONFIG_SMP +static void __cpuinit smp_iss4xx_setup_cpu(int cpu) +{ + mpic_setup_this_cpu(); +} + +static void __cpuinit smp_iss4xx_kick_cpu(int cpu) +{ + struct device_node *cpunode = of_get_cpu_node(cpu, NULL); + const u64 *spin_table_addr_prop; + u32 *spin_table; + extern void start_secondary_47x(void); + + BUG_ON(cpunode == NULL); + + /* Assume spin table. We could test for the enable-method in + * the device-tree but currently there's little point as it's + * our only supported method + */ + spin_table_addr_prop = of_get_property(cpunode, "cpu-release-addr", + NULL); + if (spin_table_addr_prop == NULL) { + pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", cpu); + return; + } + + /* Assume it's mapped as part of the linear mapping. This is a bit + * fishy but will work fine for now + */ + spin_table = (u32 *)__va(*spin_table_addr_prop); + pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table); + + spin_table[3] = cpu; + smp_wmb(); + spin_table[1] = __pa(start_secondary_47x); + mb(); +} + +static struct smp_ops_t iss_smp_ops = { + .probe = smp_mpic_probe, + .message_pass = smp_mpic_message_pass, + .setup_cpu = smp_iss4xx_setup_cpu, + .kick_cpu = smp_iss4xx_kick_cpu, + .give_timebase = smp_generic_give_timebase, + .take_timebase = smp_generic_take_timebase, +}; + +static void __init iss4xx_smp_init(void) +{ + if (mmu_has_feature(MMU_FTR_TYPE_47x)) + smp_ops = &iss_smp_ops; +} + +#else /* CONFIG_SMP */ +static void __init iss4xx_smp_init(void) { } +#endif /* CONFIG_SMP */ + +static void __init iss4xx_setup_arch(void) +{ + iss4xx_smp_init(); +} + +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init iss4xx_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "ibm,iss-4xx")) + return 0; + + return 1; +} + +define_machine(iss4xx) { + .name = "ISS-4xx", + .probe = iss4xx_probe, + .progress = udbg_progress, + .init_IRQ = iss4xx_init_irq, + .setup_arch = iss4xx_setup_arch, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; -- cgit v1.2.3-59-g8ed1b From 101c192e1163c1c7e8d29748108b582929975038 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Fri, 5 Mar 2010 10:43:35 +0000 Subject: powerpc/47x: defconfig for 476 on the iss 4xx simulator A defconfig for the IBM ISS 476 simulator Signed-off-by: Dave Kleikamp Signed-off-by: Josh Boyer --- arch/powerpc/configs/44x/iss476-smp_defconfig | 1026 +++++++++++++++++++++++++ 1 file changed, 1026 insertions(+) create mode 100644 arch/powerpc/configs/44x/iss476-smp_defconfig (limited to 'arch') diff --git a/arch/powerpc/configs/44x/iss476-smp_defconfig b/arch/powerpc/configs/44x/iss476-smp_defconfig new file mode 100644 index 000000000000..8683cbc6c3e1 --- /dev/null +++ b/arch/powerpc/configs/44x/iss476-smp_defconfig @@ -0,0 +1,1026 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.33 +# Thu Mar 4 11:50:12 2010 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +# CONFIG_PPC_BOOK3S_32 is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +# CONFIG_40x is not set +CONFIG_44x=y +# CONFIG_E200 is not set +CONFIG_PPC_FPU=y +CONFIG_4xx=y +CONFIG_BOOKE=y +CONFIG_PTE_64BIT=y +CONFIG_PHYS_64BIT=y +CONFIG_PPC_MMU_NOHASH=y +CONFIG_PPC_MMU_NOHASH_32=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_SMP=y +CONFIG_NR_CPUS=4 +# CONFIG_NOT_COHERENT_CACHE is not set +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_MMU=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set +# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_NR_IRQS=512 +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +CONFIG_PPC_UDBG_16550=y +CONFIG_GENERIC_TBSYNC=y +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +CONFIG_DTC=y +# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_PPC_DCR_NATIVE=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_DCR=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y +# CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +# CONFIG_FREEZER is not set + +# +# Platform support +# +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +CONFIG_PPC_47x=y +# CONFIG_BAMBOO is not set +# CONFIG_EBONY is not set +# CONFIG_SAM440EP is not set +# CONFIG_SEQUOIA is not set +# CONFIG_TAISHAN is not set +# CONFIG_KATMAI is not set +# CONFIG_RAINIER is not set +# CONFIG_WARP is not set +# CONFIG_ARCHES is not set +# CONFIG_CANYONLANDS is not set +# CONFIG_GLACIER is not set +# CONFIG_REDWOOD is not set +# CONFIG_EIGER is not set +# CONFIG_YOSEMITE is not set +CONFIG_ISS4xx=y +# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set +# CONFIG_PPC44x_SIMPLE is not set +# CONFIG_PPC4xx_GPIO is not set +# CONFIG_IPIC is not set +CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_FSL_ULI1575 is not set +CONFIG_OF_RTC=y +# CONFIG_SIMPLE_GPIO is not set + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=100 +# CONFIG_SCHED_HRTICK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_MATH_EMULATION=y +# CONFIG_IOMMU_HELPER is not set +# CONFIG_SWIOTLB is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_IRQ_ALL_CPUS=y +CONFIG_SPARSE_IRQ=y +CONFIG_MAX_ACTIVE_REGIONS=32 +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_STDBINUTILS=y +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set +# CONFIG_PPC_256K_PAGES is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_PROC_DEVICETREE=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="root=/dev/issblk0" +CONFIG_EXTRA_TARGETS="" +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_4xx_SOC=y +CONFIG_PPC_PCI_CHOICE=y +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set +# CONFIG_HAS_RAPIDIO is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_PAGE_OFFSET=0xc0000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +CONFIG_OF_DEVICE=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=35000 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_XILINX_SYSACE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_MACINTOSH_DRIVERS is not set +# CONFIG_NETDEVICES is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set +# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_HVC_UDBG is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_GPIOLIB is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_EDAC is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_PPC_DISABLE_WERROR is not set +CONFIG_PPC_WERROR=y +CONFIG_PRINT_STACK_DEPTH=64 +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_PPC_EMULATED_STATS is not set +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_MSI_BITMAP_SELFTEST is not set +# CONFIG_XMON is not set +# CONFIG_IRQSTACKS is not set +# CONFIG_VIRQ_DEBUG is not set +# CONFIG_BDI_SWITCH is not set +CONFIG_PPC_EARLY_DEBUG=y +# CONFIG_PPC_EARLY_DEBUG_LPAR is not set +# CONFIG_PPC_EARLY_DEBUG_G5 is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set +# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set +# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set +# CONFIG_PPC_EARLY_DEBUG_BEAT is not set +CONFIG_PPC_EARLY_DEBUG_44x=y +# CONFIG_PPC_EARLY_DEBUG_40x is not set +# CONFIG_PPC_EARLY_DEBUG_CPM is not set +# CONFIG_PPC_EARLY_DEBUG_USBGECKO is not set +CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0x40000200 +CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set +# CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set -- cgit v1.2.3-59-g8ed1b From a32fe93daf9c6b6ffbab1d9b9e2a8e4c335bda5c Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 27 Apr 2010 22:13:34 +0000 Subject: powerpc/4xx: Add optional "reset_type" property to control reboot via dts By setting "reset_type" to one of the following values, the default software reset mechanism may be overidden. Here the possible values of "reset_type": 1 - PPC4xx core reset 2 - PPC4xx chip reset 3 - PPC4xx system reset (default) This will be used by a new PPC440SPe board port, which needs a "chip reset" instead of the default "system reset" to be asserted. Signed-off-by: Stefan Roese Cc: Josh Boyer Cc: Benjamin Herrenschmidt Acked-by: Josh Boyer Signed-off-by: Josh Boyer --- Documentation/powerpc/dts-bindings/4xx/reboot.txt | 18 +++++++++++++++++ arch/powerpc/sysdev/ppc4xx_soc.c | 24 +++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 Documentation/powerpc/dts-bindings/4xx/reboot.txt (limited to 'arch') diff --git a/Documentation/powerpc/dts-bindings/4xx/reboot.txt b/Documentation/powerpc/dts-bindings/4xx/reboot.txt new file mode 100644 index 000000000000..d7217260589c --- /dev/null +++ b/Documentation/powerpc/dts-bindings/4xx/reboot.txt @@ -0,0 +1,18 @@ +Reboot property to control system reboot on PPC4xx systems: + +By setting "reset_type" to one of the following values, the default +software reset mechanism may be overidden. Here the possible values of +"reset_type": + + 1 - PPC4xx core reset + 2 - PPC4xx chip reset + 3 - PPC4xx system reset (default) + +Example: + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,440SPe"; + ... + reset-type = <2>; /* Use chip-reset */ + }; diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c index 5c014350bf16..d3d6ce3c33b4 100644 --- a/arch/powerpc/sysdev/ppc4xx_soc.c +++ b/arch/powerpc/sysdev/ppc4xx_soc.c @@ -191,11 +191,31 @@ static int __init ppc4xx_l2c_probe(void) arch_initcall(ppc4xx_l2c_probe); /* - * At present, this routine just applies a system reset. + * Apply a system reset. Alternatively a board specific value may be + * provided via the "reset-type" property in the cpu node. */ void ppc4xx_reset_system(char *cmd) { - mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_RST_SYSTEM); + struct device_node *np; + u32 reset_type = DBCR0_RST_SYSTEM; + const u32 *prop; + + np = of_find_node_by_type(NULL, "cpu"); + if (np) { + prop = of_get_property(np, "reset-type", NULL); + + /* + * Check if property exists and if it is in range: + * 1 - PPC4xx core reset + * 2 - PPC4xx chip reset + * 3 - PPC4xx system reset (default) + */ + if ((prop) && ((prop[0] >= 1) && (prop[0] <= 3))) + reset_type = prop[0] << 28; + } + + mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | reset_type); + while (1) ; /* Just in case the reset doesn't work */ } -- cgit v1.2.3-59-g8ed1b From aea561359a30cf3c1f7a2e99684ac5501d0f53ac Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 30 Apr 2010 13:34:11 -0700 Subject: omap2/3/4: Disable CONFIG_FB_OMAP in omap3_defconfig Looks like CONFIG_FB_OMAP prevents somehow mounting root on MMC at least on zoom3 for multi-omap. Disable CONFIG_FB until the omap FB code is fixed. This allows booting omap3_defconfig on various omaps. Tested on 2420-n8x0, 3430-n900, 3630-zoom3 and 4430-blaze. Note that n8x0 still has issues with starting user space because of TLS and VFP. Signed-off-by: Tony Lindgren --- arch/arm/configs/omap3_defconfig | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap3_defconfig index 7855edb9ff24..1efb833147c2 100644 --- a/arch/arm/configs/omap3_defconfig +++ b/arch/arm/configs/omap3_defconfig @@ -1359,16 +1359,8 @@ CONFIG_FB_TILEBLITTING=y # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set # CONFIG_FB_BROADSHEET is not set -CONFIG_FB_OMAP=y +# CONFIG_FB_OMAP is not set CONFIG_FB_OMAP_LCD_VGA=y -# CONFIG_FB_OMAP_031M3R is not set -# CONFIG_FB_OMAP_048M3R is not set -CONFIG_FB_OMAP_079M3R=y -# CONFIG_FB_OMAP_092M9R is not set -# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set -# CONFIG_FB_OMAP_LCD_MIPID is not set -# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set -CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2 # CONFIG_OMAP2_DSS is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y -- cgit v1.2.3-59-g8ed1b From 1c4da2b737cce57f0c17344cda7f9ba1d206bfa5 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Wed, 28 Apr 2010 00:58:25 +0000 Subject: omap: add missing FIQ_START definition required forarch/arm/kernel/fiq.c compilation Several ARM platforms/machines that use FIQ define their value of FIQ_START. Since FIQ is not implemented for OMAP yet, this definition is missing from OMAP header files. Put an arbitrary value for FIQ_START into plat/irqs.h for OMAP. Even if not used by the FIQ handler for Amstrad Delta, this is required for successfull compilation of arch/arm/plat-omap/fiq.c that provides several usefull functions. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/irqs.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index 401701977dbb..c01d9f08a198 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h @@ -428,4 +428,8 @@ void omap3_intc_resume_idle(void); #include +#ifdef CONFIG_FIQ +#define FIQ_START 1024 +#endif + #endif -- cgit v1.2.3-59-g8ed1b From 60c3bf3f1215453a4f30f0b91db7fd301d558693 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Wed, 28 Apr 2010 01:01:29 +0000 Subject: OMAP1: Amstrad Delta: add FIQ handler for serial keyboardport interrupt processing This patch introduces a Fast Interrupt Request (FIQ) handler for Amstrad Delta (E3) videophone. The handler's purpose is to process interrupts generated by a GPIO line that a serial keyboard clock hangs off. It collects consecutive bits into words, pushing them into a buffer, then requests a higher level interrupt after one or more words are ready for further processing by a keyboard port driver. The handler also processes interrupts generated by two other GPIO lines, used by other on-board supported devices, by simply requesting a higher level interrupt, that in turn should invoke those device's specific irq handlers. IRQ12 line, not used by OMAP1510 hardware (described as reserved), has been choosen as a higher level interrupt source. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/Kconfig | 10 + arch/arm/mach-omap1/Makefile | 1 + arch/arm/mach-omap1/ams-delta-fiq-handler.S | 278 +++++++++++++++++++++++ arch/arm/mach-omap1/include/mach/ams-delta-fiq.h | 72 ++++++ 4 files changed, 361 insertions(+) create mode 100644 arch/arm/mach-omap1/ams-delta-fiq-handler.S create mode 100644 arch/arm/mach-omap1/include/mach/ams-delta-fiq.h (limited to 'arch') diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index 27f489747bbd..b18d7c28ab7a 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig @@ -152,6 +152,16 @@ config MACH_AMS_DELTA Support for the Amstrad E3 (codename Delta) videophone. Say Y here if you have such a device. +config AMS_DELTA_FIQ + bool "Fast Interrupt Request (FIQ) support for the E3" + depends on MACH_AMS_DELTA + select FIQ + help + Provide a FIQ handler for the E3. + This allows for fast handling of interrupts generated + by the clock line of the E3 mailboard (or a PS/2 keyboard) + connected to the GPIO based external keyboard port. + config MACH_OMAP_GENERIC bool "Generic OMAP board" depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX) diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index b6a537c875b8..db0d48001344 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_MACH_OMAP_PALMZ71) += board-palmz71.o obj-$(CONFIG_MACH_OMAP_PALMTT) += board-palmtt.o obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o +obj-$(CONFIG_AMS_DELTA_FIQ) += ams-delta-fiq-handler.o obj-$(CONFIG_MACH_SX1) += board-sx1.o board-sx1-mmc.o obj-$(CONFIG_MACH_HERALD) += board-htcherald.o diff --git a/arch/arm/mach-omap1/ams-delta-fiq-handler.S b/arch/arm/mach-omap1/ams-delta-fiq-handler.S new file mode 100644 index 000000000000..927d5a181760 --- /dev/null +++ b/arch/arm/mach-omap1/ams-delta-fiq-handler.S @@ -0,0 +1,278 @@ +/* + * linux/arch/arm/mach-omap1/ams-delta-fiq-handler.S + * + * Based on linux/arch/arm/lib/floppydma.S + * Renamed and modified to work with 2.6 kernel by Matt Callow + * Copyright (C) 1995, 1996 Russell King + * Copyright (C) 2004 Pete Trapps + * Copyright (C) 2006 Matt Callow + * Copyright (C) 2010 Janusz Krzysztofik + * + * 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 + +#include +#include + +#include + +/* + * GPIO related definitions, copied from arch/arm/plat-omap/gpio.c. + * Unfortunately, those were not placed in a separate header file. + */ +#define OMAP1510_GPIO_BASE 0xFFFCE000 +#define OMAP1510_GPIO_DATA_INPUT 0x00 +#define OMAP1510_GPIO_DATA_OUTPUT 0x04 +#define OMAP1510_GPIO_DIR_CONTROL 0x08 +#define OMAP1510_GPIO_INT_CONTROL 0x0c +#define OMAP1510_GPIO_INT_MASK 0x10 +#define OMAP1510_GPIO_INT_STATUS 0x14 +#define OMAP1510_GPIO_PIN_CONTROL 0x18 + +/* GPIO register bitmasks */ +#define KEYBRD_DATA_MASK (0x1 << AMS_DELTA_GPIO_PIN_KEYBRD_DATA) +#define KEYBRD_CLK_MASK (0x1 << AMS_DELTA_GPIO_PIN_KEYBRD_CLK) +#define MODEM_IRQ_MASK (0x1 << AMS_DELTA_GPIO_PIN_MODEM_IRQ) +#define HOOK_SWITCH_MASK (0x1 << AMS_DELTA_GPIO_PIN_HOOK_SWITCH) +#define OTHERS_MASK (MODEM_IRQ_MASK | HOOK_SWITCH_MASK) + +/* IRQ handler register bitmasks */ +#define DEFERRED_FIQ_MASK (0x1 << (INT_DEFERRED_FIQ % IH2_BASE)) +#define GPIO_BANK1_MASK (0x1 << INT_GPIO_BANK1) + +/* Driver buffer byte offsets */ +#define BUF_MASK (FIQ_MASK * 4) +#define BUF_STATE (FIQ_STATE * 4) +#define BUF_KEYS_CNT (FIQ_KEYS_CNT * 4) +#define BUF_TAIL_OFFSET (FIQ_TAIL_OFFSET * 4) +#define BUF_HEAD_OFFSET (FIQ_HEAD_OFFSET * 4) +#define BUF_BUF_LEN (FIQ_BUF_LEN * 4) +#define BUF_KEY (FIQ_KEY * 4) +#define BUF_MISSED_KEYS (FIQ_MISSED_KEYS * 4) +#define BUF_BUFFER_START (FIQ_BUFFER_START * 4) +#define BUF_GPIO_INT_MASK (FIQ_GPIO_INT_MASK * 4) +#define BUF_KEYS_HICNT (FIQ_KEYS_HICNT * 4) +#define BUF_IRQ_PEND (FIQ_IRQ_PEND * 4) +#define BUF_SIR_CODE_L1 (FIQ_SIR_CODE_L1 * 4) +#define BUF_SIR_CODE_L2 (IRQ_SIR_CODE_L2 * 4) +#define BUF_CNT_INT_00 (FIQ_CNT_INT_00 * 4) +#define BUF_CNT_INT_KEY (FIQ_CNT_INT_KEY * 4) +#define BUF_CNT_INT_MDM (FIQ_CNT_INT_MDM * 4) +#define BUF_CNT_INT_03 (FIQ_CNT_INT_03 * 4) +#define BUF_CNT_INT_HSW (FIQ_CNT_INT_HSW * 4) +#define BUF_CNT_INT_05 (FIQ_CNT_INT_05 * 4) +#define BUF_CNT_INT_06 (FIQ_CNT_INT_06 * 4) +#define BUF_CNT_INT_07 (FIQ_CNT_INT_07 * 4) +#define BUF_CNT_INT_08 (FIQ_CNT_INT_08 * 4) +#define BUF_CNT_INT_09 (FIQ_CNT_INT_09 * 4) +#define BUF_CNT_INT_10 (FIQ_CNT_INT_10 * 4) +#define BUF_CNT_INT_11 (FIQ_CNT_INT_11 * 4) +#define BUF_CNT_INT_12 (FIQ_CNT_INT_12 * 4) +#define BUF_CNT_INT_13 (FIQ_CNT_INT_13 * 4) +#define BUF_CNT_INT_14 (FIQ_CNT_INT_14 * 4) +#define BUF_CNT_INT_15 (FIQ_CNT_INT_15 * 4) +#define BUF_CIRC_BUFF (FIQ_CIRC_BUFF * 4) + + +/* + * Register useage + * r8 - temporary + * r9 - the driver buffer + * r10 - temporary + * r11 - interrupts mask + * r12 - base pointers + * r13 - interrupts status + */ + + .text + + .global qwerty_fiqin_end + +ENTRY(qwerty_fiqin_start) + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @ FIQ intrrupt handler + ldr r12, omap_ih1_base @ set pointer to level1 handler + + ldr r11, [r12, #IRQ_MIR_REG_OFFSET] @ fetch interrupts mask + + ldr r13, [r12, #IRQ_ITR_REG_OFFSET] @ fetch interrupts status + bics r13, r13, r11 @ clear masked - any left? + beq exit @ none - spurious FIQ? exit + + ldr r10, [r12, #IRQ_SIR_FIQ_REG_OFFSET] @ get requested interrupt number + + mov r8, #2 @ reset FIQ agreement + str r8, [r12, #IRQ_CONTROL_REG_OFFSET] + + cmp r10, #INT_GPIO_BANK1 @ is it GPIO bank interrupt? + beq gpio @ yes - process it + + mov r8, #1 + orr r8, r11, r8, lsl r10 @ mask spurious interrupt + str r8, [r12, #IRQ_MIR_REG_OFFSET] +exit: + subs pc, lr, #4 @ return from FIQ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + + @@@@@@@@@@@@@@@@@@@@@@@@@@@ +gpio: @ GPIO bank interrupt handler + ldr r12, omap1510_gpio_base @ set base pointer to GPIO bank + + ldr r11, [r12, #OMAP1510_GPIO_INT_MASK] @ fetch GPIO interrupts mask +restart: + ldr r13, [r12, #OMAP1510_GPIO_INT_STATUS] @ fetch status bits + bics r13, r13, r11 @ clear masked - any left? + beq exit @ no - spurious interrupt? exit + + orr r11, r11, r13 @ mask all requested interrupts + str r11, [r12, #OMAP1510_GPIO_INT_MASK] + + ands r10, r13, #KEYBRD_CLK_MASK @ extract keyboard status - set? + beq hksw @ no - try next source + + + @@@@@@@@@@@@@@@@@@@@@@ + @ Keyboard clock FIQ mode interrupt handler + @ r10 now contains KEYBRD_CLK_MASK, use it + str r10, [r12, #OMAP1510_GPIO_INT_STATUS] @ ack the interrupt + bic r11, r11, r10 @ unmask it + str r11, [r12, #OMAP1510_GPIO_INT_MASK] + + @ Process keyboard data + ldr r8, [r12, #OMAP1510_GPIO_DATA_INPUT] @ fetch GPIO input + + ldr r10, [r9, #BUF_STATE] @ fetch kbd interface state + cmp r10, #0 @ are we expecting start bit? + bne data @ no - go to data processing + + ands r8, r8, #KEYBRD_DATA_MASK @ check start bit - detected? + beq hksw @ no - try next source + + @ r8 contains KEYBRD_DATA_MASK, use it + str r8, [r9, #BUF_STATE] @ enter data processing state + @ r10 already contains 0, reuse it + str r10, [r9, #BUF_KEY] @ clear keycode + mov r10, #2 @ reset input bit mask + str r10, [r9, #BUF_MASK] + + @ Mask other GPIO line interrupts till key done + str r11, [r9, #BUF_GPIO_INT_MASK] @ save mask for later restore + mvn r11, #KEYBRD_CLK_MASK @ prepare all except kbd mask + str r11, [r12, #OMAP1510_GPIO_INT_MASK] @ store into the mask register + + b restart @ restart + +data: ldr r10, [r9, #BUF_MASK] @ fetch current input bit mask + + @ r8 still contains GPIO input bits + ands r8, r8, #KEYBRD_DATA_MASK @ is keyboard data line low? + ldreq r8, [r9, #BUF_KEY] @ yes - fetch collected so far, + orreq r8, r8, r10 @ set 1 at current mask position + streq r8, [r9, #BUF_KEY] @ and save back + + mov r10, r10, lsl #1 @ shift mask left + bics r10, r10, #0x800 @ have we got all the bits? + strne r10, [r9, #BUF_MASK] @ not yet - store the mask + bne restart @ and restart + + @ r10 already contains 0, reuse it + str r10, [r9, #BUF_STATE] @ reset state to start + + @ Key done - restore interrupt mask + ldr r10, [r9, #BUF_GPIO_INT_MASK] @ fetch saved mask + and r11, r11, r10 @ unmask all saved as unmasked + str r11, [r12, #OMAP1510_GPIO_INT_MASK] @ restore into the mask register + + @ Try appending the keycode to the circular buffer + ldr r10, [r9, #BUF_KEYS_CNT] @ get saved keystrokes count + ldr r8, [r9, #BUF_BUF_LEN] @ get buffer size + cmp r10, r8 @ is buffer full? + beq hksw @ yes - key lost, next source + + add r10, r10, #1 @ incremet keystrokes counter + str r10, [r9, #BUF_KEYS_CNT] + + ldr r10, [r9, #BUF_TAIL_OFFSET] @ get buffer tail offset + @ r8 already contains buffer size + cmp r10, r8 @ end of buffer? + moveq r10, #0 @ yes - rewind to buffer start + + ldr r12, [r9, #BUF_BUFFER_START] @ get buffer start address + add r12, r12, r10, LSL #2 @ calculate buffer tail address + ldr r8, [r9, #BUF_KEY] @ get last keycode + str r8, [r12] @ append it to the buffer tail + + add r10, r10, #1 @ increment buffer tail offset + str r10, [r9, #BUF_TAIL_OFFSET] + + ldr r10, [r9, #BUF_CNT_INT_KEY] @ increment interrupts counter + add r10, r10, #1 + str r10, [r9, #BUF_CNT_INT_KEY] + @@@@@@@@@@@@@@@@@@@@@@@@ + + +hksw: @Is hook switch interrupt requested? + tst r13, #HOOK_SWITCH_MASK @ is hook switch status bit set? + beq mdm @ no - try next source + + + @@@@@@@@@@@@@@@@@@@@@@@@ + @ Hook switch interrupt FIQ mode simple handler + + @ Don't toggle active edge, the switch always bounces + + @ Increment hook switch interrupt counter + ldr r10, [r9, #BUF_CNT_INT_HSW] + add r10, r10, #1 + str r10, [r9, #BUF_CNT_INT_HSW] + @@@@@@@@@@@@@@@@@@@@@@@@ + + +mdm: @Is it a modem interrupt? + tst r13, #MODEM_IRQ_MASK @ is modem status bit set? + beq irq @ no - check for next interrupt + + + @@@@@@@@@@@@@@@@@@@@@@@@ + @ Modem FIQ mode interrupt handler stub + + @ Increment modem interrupt counter + ldr r10, [r9, #BUF_CNT_INT_MDM] + add r10, r10, #1 + str r10, [r9, #BUF_CNT_INT_MDM] + @@@@@@@@@@@@@@@@@@@@@@@@ + + +irq: @ Place deferred_fiq interrupt request + ldr r12, deferred_fiq_ih_base @ set pointer to IRQ handler + mov r10, #DEFERRED_FIQ_MASK @ set deferred_fiq bit + str r10, [r12, #IRQ_ISR_REG_OFFSET] @ place it in the ISR register + + ldr r12, omap1510_gpio_base @ set pointer back to GPIO bank + b restart @ check for next GPIO interrupt + @@@@@@@@@@@@@@@@@@@@@@@@@@@ + + +/* + * Virtual addresses for IO + */ +omap_ih1_base: + .word OMAP1_IO_ADDRESS(OMAP_IH1_BASE) +deferred_fiq_ih_base: + .word OMAP1_IO_ADDRESS(DEFERRED_FIQ_IH_BASE) +omap1510_gpio_base: + .word OMAP1_IO_ADDRESS(OMAP1510_GPIO_BASE) +qwerty_fiqin_end: + +/* + * Check the size of the FIQ, + * it cannot go beyond 0xffff0200, and is copied to 0xffff001c + */ +.if (qwerty_fiqin_end - qwerty_fiqin_start) > (0x200 - 0x1c) + .err +.endif diff --git a/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h b/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h new file mode 100644 index 000000000000..8dbe75b7b89f --- /dev/null +++ b/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h @@ -0,0 +1,72 @@ +/* + * arch/arm/mach-omap1/include/ams-delta-fiq.h + * + * Taken from the original Amstrad modifications to fiq.h + * + * Copyright (c) 2004 Amstrad Plc + * Copyright (c) 2006 Matt Callow + * Copyright (c) 2010 Janusz Krzysztofik + * + * 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. + */ +#ifndef __AMS_DELTA_FIQ_H +#define __AMS_DELTA_FIQ_H + +#include + +/* + * Interrupt number used for passing control from FIQ to IRQ. + * IRQ12, described as reserved, has been selected. + */ +#define INT_DEFERRED_FIQ INT_1510_RES12 +/* + * Base address of an interrupt handler that the INT_DEFERRED_FIQ belongs to. + */ +#if (INT_DEFERRED_FIQ < IH2_BASE) +#define DEFERRED_FIQ_IH_BASE OMAP_IH1_BASE +#else +#define DEFERRED_FIQ_IH_BASE OMAP_IH2_BASE +#endif + +/* + * These are the offsets from the begining of the fiq_buffer. They are put here + * since the buffer and header need to be accessed by drivers servicing devices + * which generate GPIO interrupts - e.g. keyboard, modem, hook switch. + */ +#define FIQ_MASK 0 +#define FIQ_STATE 1 +#define FIQ_KEYS_CNT 2 +#define FIQ_TAIL_OFFSET 3 +#define FIQ_HEAD_OFFSET 4 +#define FIQ_BUF_LEN 5 +#define FIQ_KEY 6 +#define FIQ_MISSED_KEYS 7 +#define FIQ_BUFFER_START 8 +#define FIQ_GPIO_INT_MASK 9 +#define FIQ_KEYS_HICNT 10 +#define FIQ_IRQ_PEND 11 +#define FIQ_SIR_CODE_L1 12 +#define IRQ_SIR_CODE_L2 13 + +#define FIQ_CNT_INT_00 14 +#define FIQ_CNT_INT_KEY 15 +#define FIQ_CNT_INT_MDM 16 +#define FIQ_CNT_INT_03 17 +#define FIQ_CNT_INT_HSW 18 +#define FIQ_CNT_INT_05 19 +#define FIQ_CNT_INT_06 20 +#define FIQ_CNT_INT_07 21 +#define FIQ_CNT_INT_08 22 +#define FIQ_CNT_INT_09 23 +#define FIQ_CNT_INT_10 24 +#define FIQ_CNT_INT_11 25 +#define FIQ_CNT_INT_12 26 +#define FIQ_CNT_INT_13 27 +#define FIQ_CNT_INT_14 28 +#define FIQ_CNT_INT_15 29 + +#define FIQ_CIRC_BUFF 30 /*Start of circular buffer */ + +#endif -- cgit v1.2.3-59-g8ed1b From 11f9562a423896b6ecd449d829a2f34e06594301 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Wed, 28 Apr 2010 01:03:59 +0000 Subject: OMAP1: Amstrad Delta: add a handler for processing interruptsgenerated by the FIQ routine This patch introduces an IRQ handler used for processing interrupts generated by the FIQ handler when it decides there are data ready for processing. The handler further invokes device specific interrupt routines based on interrupt source counters passed from the FIQ handler. The handler setup function is intended to be called from the board provided init_machine() callback. Signed-off-by: Janusz Krzysztofik [tony@atomide.com: Updated to include linux/io.h instead of plat/io.h Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/Makefile | 2 +- arch/arm/mach-omap1/ams-delta-fiq.c | 155 +++++++++++++++++++++++ arch/arm/mach-omap1/include/mach/ams-delta-fiq.h | 7 + 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-omap1/ams-delta-fiq.c (limited to 'arch') diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index db0d48001344..ea231c7a550a 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_MACH_OMAP_PALMZ71) += board-palmz71.o obj-$(CONFIG_MACH_OMAP_PALMTT) += board-palmtt.o obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o -obj-$(CONFIG_AMS_DELTA_FIQ) += ams-delta-fiq-handler.o +obj-$(CONFIG_AMS_DELTA_FIQ) += ams-delta-fiq.o ams-delta-fiq-handler.o obj-$(CONFIG_MACH_SX1) += board-sx1.o board-sx1-mmc.o obj-$(CONFIG_MACH_HERALD) += board-htcherald.o diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c new file mode 100644 index 000000000000..6c994e2d8879 --- /dev/null +++ b/arch/arm/mach-omap1/ams-delta-fiq.c @@ -0,0 +1,155 @@ +/* + * Amstrad E3 FIQ handling + * + * Copyright (C) 2009 Janusz Krzysztofik + * Copyright (c) 2006 Matt Callow + * Copyright (c) 2004 Amstrad Plc + * Copyright (C) 2001 RidgeRun, Inc. + * + * Parts of this code are taken from linux/arch/arm/mach-omap/irq.c + * in the MontaVista 2.4 kernel (and the Amstrad changes therein) + * + * 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 +#include +#include +#include +#include + +#include + +#include +#include + +static struct fiq_handler fh = { + .name = "ams-delta-fiq" +}; + +/* + * This buffer is shared between FIQ and IRQ contexts. + * The FIQ and IRQ isrs can both read and write it. + * It is structured as a header section several 32bit slots, + * followed by the circular buffer where the FIQ isr stores + * keystrokes received from the qwerty keyboard. + * See ams-delta-fiq.h for details of offsets. + */ +unsigned int fiq_buffer[1024]; +EXPORT_SYMBOL(fiq_buffer); + +static unsigned int irq_counter[16]; + +static irqreturn_t deferred_fiq(int irq, void *dev_id) +{ + struct irq_desc *irq_desc; + struct irq_chip *irq_chip = NULL; + int gpio, irq_num, fiq_count; + + irq_desc = irq_to_desc(IH_GPIO_BASE); + if (irq_desc) + irq_chip = irq_desc->chip; + + /* + * For each handled GPIO interrupt, keep calling its interrupt handler + * until the IRQ counter catches the FIQ incremented interrupt counter. + */ + for (gpio = AMS_DELTA_GPIO_PIN_KEYBRD_CLK; + gpio <= AMS_DELTA_GPIO_PIN_HOOK_SWITCH; gpio++) { + irq_num = gpio_to_irq(gpio); + fiq_count = fiq_buffer[FIQ_CNT_INT_00 + gpio]; + + while (irq_counter[gpio] < fiq_count) { + if (gpio != AMS_DELTA_GPIO_PIN_KEYBRD_CLK) { + /* + * It looks like handle_edge_irq() that + * OMAP GPIO edge interrupts default to, + * expects interrupt already unmasked. + */ + if (irq_chip && irq_chip->unmask) + irq_chip->unmask(irq_num); + } + generic_handle_irq(irq_num); + + irq_counter[gpio]++; + } + } + return IRQ_HANDLED; +} + +void __init ams_delta_init_fiq(void) +{ + void *fiqhandler_start; + unsigned int fiqhandler_length; + struct pt_regs FIQ_regs; + unsigned long val, offset; + int i, retval; + + fiqhandler_start = &qwerty_fiqin_start; + fiqhandler_length = &qwerty_fiqin_end - &qwerty_fiqin_start; + pr_info("Installing fiq handler from %p, length 0x%x\n", + fiqhandler_start, fiqhandler_length); + + retval = claim_fiq(&fh); + if (retval) { + pr_err("ams_delta_init_fiq(): couldn't claim FIQ, ret=%d\n", + retval); + return; + } + + retval = request_irq(INT_DEFERRED_FIQ, deferred_fiq, + IRQ_TYPE_EDGE_RISING, "deferred_fiq", 0); + if (retval < 0) { + pr_err("Failed to get deferred_fiq IRQ, ret=%d\n", retval); + release_fiq(&fh); + return; + } + /* + * Since no set_type() method is provided by OMAP irq chip, + * switch to edge triggered interrupt type manually. + */ + offset = IRQ_ILR0_REG_OFFSET + INT_DEFERRED_FIQ * 0x4; + val = omap_readl(DEFERRED_FIQ_IH_BASE + offset) & ~(1 << 1); + omap_writel(val, DEFERRED_FIQ_IH_BASE + offset); + + set_fiq_handler(fiqhandler_start, fiqhandler_length); + + /* + * Initialise the buffer which is shared + * between FIQ mode and IRQ mode + */ + fiq_buffer[FIQ_GPIO_INT_MASK] = 0; + fiq_buffer[FIQ_MASK] = 0; + fiq_buffer[FIQ_STATE] = 0; + fiq_buffer[FIQ_KEY] = 0; + fiq_buffer[FIQ_KEYS_CNT] = 0; + fiq_buffer[FIQ_KEYS_HICNT] = 0; + fiq_buffer[FIQ_TAIL_OFFSET] = 0; + fiq_buffer[FIQ_HEAD_OFFSET] = 0; + fiq_buffer[FIQ_BUF_LEN] = 256; + fiq_buffer[FIQ_MISSED_KEYS] = 0; + fiq_buffer[FIQ_BUFFER_START] = + (unsigned int) &fiq_buffer[FIQ_CIRC_BUFF]; + + for (i = FIQ_CNT_INT_00; i <= FIQ_CNT_INT_15; i++) + fiq_buffer[i] = 0; + + /* + * FIQ mode r9 always points to the fiq_buffer, becauses the FIQ isr + * will run in an unpredictable context. The fiq_buffer is the FIQ isr's + * only means of communication with the IRQ level and other kernel + * context code. + */ + FIQ_regs.ARM_r9 = (unsigned int)fiq_buffer; + set_fiq_regs(&FIQ_regs); + + pr_info("request_fiq(): fiq_buffer = %p\n", fiq_buffer); + + /* + * Redirect GPIO interrupts to FIQ + */ + offset = IRQ_ILR0_REG_OFFSET + INT_GPIO_BANK1 * 0x4; + val = omap_readl(OMAP_IH1_BASE + offset) | 1; + omap_writel(val, OMAP_IH1_BASE + offset); +} diff --git a/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h b/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h index 8dbe75b7b89f..7a2df29400ca 100644 --- a/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h +++ b/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h @@ -69,4 +69,11 @@ #define FIQ_CIRC_BUFF 30 /*Start of circular buffer */ +#ifndef __ASSEMBLER__ +extern unsigned int fiq_buffer[]; +extern unsigned char qwerty_fiqin_start, qwerty_fiqin_end; + +extern void __init ams_delta_init_fiq(void); +#endif + #endif -- cgit v1.2.3-59-g8ed1b From 4cb2dc67d160642410eb3cbdbfd7e7fb5f3db21a Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Wed, 28 Apr 2010 01:05:47 +0000 Subject: OMAP1: Amstrad Delta: update board initialization code forcomplete modem IRQ GPIO line setup In case of Amstrad Delta modem utilized GPIO line, interrupt is requested from standard serial8250 driver code without first requesting the GPIO pin itself. Even if it works with default OMAP GPIO interrupt handler, it appeared not compatible with recent, optimized version of the board GPIO FIQ handler, required for fast processing of interrupts generated by other GPIO pin that a serial keyboard clock hangs off. This patch fills the board specific modem initialization routine with common GPIO line reservation and direction setup. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-ams-delta.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 7fc11c34b696..9217bbdc35ab 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -263,8 +263,18 @@ static struct platform_device ams_delta_modem_device = { static int __init ams_delta_modem_init(void) { + int err; + omap_cfg_reg(M14_1510_GPIO2); - ams_delta_modem_ports[0].irq = gpio_to_irq(2); + ams_delta_modem_ports[0].irq = + gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ); + + err = gpio_request(AMS_DELTA_GPIO_PIN_MODEM_IRQ, "modem"); + if (err) { + pr_err("Couldn't request gpio pin for modem\n"); + return err; + } + gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ); ams_delta_latch2_write( AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC, -- cgit v1.2.3-59-g8ed1b From e6f740f59693d9a997daeef8fbe7351e6641b743 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Wed, 28 Apr 2010 01:07:42 +0000 Subject: OMAP1: Amstrad Delta: use FIQ for processing GPIO interrupts The patch adds initialization of FIQ related handlers to the Amstrad Delta videophone board code. FIQ will be used instead of a traditional IRQ for processing all GPIO generated interrupts, including a keyboard serial clock line. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-ams-delta.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 9217bbdc35ab..fdd1dd53fa9c 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -33,6 +33,8 @@ #include #include +#include + static u8 ams_delta_latch1_reg; static u16 ams_delta_latch2_reg; @@ -236,6 +238,10 @@ static void __init ams_delta_init(void) omap_usb_init(&ams_delta_usb_config); platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices)); +#ifdef CONFIG_AMS_DELTA_FIQ + ams_delta_init_fiq(); +#endif + omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1); } -- cgit v1.2.3-59-g8ed1b From 9bbb851c7079ff670ba3fe6c7ce93bb5daa9a694 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 30 Apr 2010 19:30:35 +0900 Subject: ARM: S3C24XX: Add initial s3c_gpio configuration code Add support for s3c_gpio_setcfg() and s3c_gpio_setpull() implementations to get ready for removal of the specific code being used by s3c24xx. Also rename the s3c_gpio_setcfg_s3c24xx_banka to s3c_gpio_setcfg_s3c24xx_a as seen in the header file to correct a build warning. Signed-off-by: Ben Dooks --- arch/arm/plat-s3c24xx/Kconfig | 1 + arch/arm/plat-s3c24xx/gpiolib.c | 17 ++++++++++++++++- arch/arm/plat-samsung/gpio-config.c | 4 ++-- arch/arm/plat-samsung/include/plat/gpio-core.h | 3 +++ 4 files changed, 22 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index 6e93ef8f3d43..a830fad6f89e 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig @@ -9,6 +9,7 @@ config PLAT_S3C24XX select NO_IOPORT select ARCH_REQUIRE_GPIOLIB select S3C_DEVICE_NAND + select S3C_GPIO_CFG_S3C24XX help Base platform code for any Samsung S3C24XX device diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c index 4f0f11a6a677..376b061804c2 100644 --- a/arch/arm/plat-s3c24xx/gpiolib.c +++ b/arch/arm/plat-s3c24xx/gpiolib.c @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include #include @@ -77,10 +79,19 @@ static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset) return IRQ_EINT8 + offset; } +static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { + .set_config = s3c_gpio_setcfg_s3c24xx_a, +}; + +struct s3c_gpio_cfg s3c24xx_gpiocfg_default = { + .set_config = s3c_gpio_setcfg_s3c24xx, +}; + struct s3c_gpio_chip s3c24xx_gpios[] = { [0] = { .base = S3C2410_GPACON, .pm = __gpio_pm(&s3c_gpio_pm_1bit), + .config = &s3c24xx_gpiocfg_banka, .chip = { .base = S3C2410_GPA(0), .owner = THIS_MODULE, @@ -168,8 +179,12 @@ static __init int s3c24xx_gpiolib_init(void) struct s3c_gpio_chip *chip = s3c24xx_gpios; int gpn; - for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) + for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) { + if (!chip->config) + chip->config = &s3c24xx_gpiocfg_default; + s3c_gpiolib_add(chip); + } return 0; } diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index 44a84e896546..c5832824e198 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c @@ -61,8 +61,8 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) EXPORT_SYMBOL(s3c_gpio_setpull); #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX -int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip, - unsigned int off, unsigned int cfg) +int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, + unsigned int off, unsigned int cfg) { void __iomem *reg = chip->base; unsigned int shift = off; diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h index 49ff406a7066..f0584f26d493 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-core.h +++ b/arch/arm/plat-samsung/include/plat/gpio-core.h @@ -108,6 +108,9 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip, extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); +/* exported for core SoC support to change */ +extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default; + #ifdef CONFIG_S3C_GPIO_TRACK extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; -- cgit v1.2.3-59-g8ed1b From 1ec7269fd8b05044f2cb4059b679e053d57460f5 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 3 May 2010 14:39:45 +0900 Subject: ARM: S3C24XX: Add the gpio pull configuration for pull-up Add the necessary gpio configuration helper for the devices which have a single-bit pull-up resistor disabled. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/Kconfig | 1 + arch/arm/mach-s3c2410/s3c2410.c | 8 ++++++ arch/arm/mach-s3c2440/Kconfig | 1 + arch/arm/mach-s3c2440/s3c2440.c | 8 ++++++ arch/arm/plat-samsung/gpio-config.c | 32 ++++++++++++++++++++++ .../plat-samsung/include/plat/gpio-cfg-helpers.h | 11 ++++++++ 6 files changed, 61 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 554731868b07..9e5e96f12d86 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -6,6 +6,7 @@ config CPU_S3C2410 bool depends on ARCH_S3C2410 select CPU_ARM920T + select S3C_GPIO_PULL_UP select S3C2410_CLOCK select S3C2410_GPIO select CPU_LLSERIAL_S3C2410 diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c index 91ba42f688ac..adc90a3c5890 100644 --- a/arch/arm/mach-s3c2410/s3c2410.c +++ b/arch/arm/mach-s3c2410/s3c2410.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,10 @@ #include #include +#include +#include +#include + /* Initial IO mappings */ static struct map_desc s3c2410_iodesc[] __initdata = { @@ -65,6 +70,9 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no) void __init s3c2410_map_io(void) { + s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up; + s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up; + iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc)); } diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index 7f465265cf04..9d102b912091 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig @@ -6,6 +6,7 @@ config CPU_S3C2440 bool depends on ARCH_S3C2410 select CPU_ARM920T + select S3C_GPIO_PULL_UP select S3C2410_CLOCK select S3C2410_PM if PM select S3C2410_GPIO diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c index 2b68f7ea45ae..d50f3ae6173d 100644 --- a/arch/arm/mach-s3c2440/s3c2440.c +++ b/arch/arm/mach-s3c2440/s3c2440.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,10 @@ #include #include +#include +#include +#include + static struct sys_device s3c2440_sysdev = { .cls = &s3c2440_sysclass, }; @@ -41,6 +46,9 @@ int __init s3c2440_init(void) { printk("S3C2440: Initialising architecture\n"); + s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up; + s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up; + /* change irq for watchdog */ s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index c5832824e198..8aca88d6c486 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c @@ -164,3 +164,35 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, return (__force s3c_gpio_pull_t)pup; } #endif + +#ifdef CONFIG_S3C_GPIO_PULL_UP +int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t pull) +{ + void __iomem *reg = chip->base + 0x08; + u32 pup = __raw_readl(reg); + + pup = __raw_readl(reg); + + if (pup == S3C_GPIO_PULL_UP) + pup &= ~(1 << off); + else if (pup == S3C_GPIO_PULL_NONE) + pup |= (1 << off); + else + return -EINVAL; + + __raw_writel(pup, reg); + return 0; +} + +s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, + unsigned int off) +{ + void __iomem *reg = chip->base + 0x08; + u32 pup = __raw_readl(reg); + + pup &= (1 << off); + return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP; +} +#endif /* CONFIG_S3C_GPIO_PULL_UP */ + diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h index dda19da037ad..885e9ac642d3 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h @@ -145,6 +145,17 @@ extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip, extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, unsigned int off); +/** + * s3c_gpio_getpull_1up() - Get configuration for choice of up or none + * @chip: The gpio chip that the GPIO pin belongs to + * @off: The offset to the pin to get the configuration of. + * + * This helper function reads the state of the pull-up resistor for the + * given GPIO in the same case as s3c_gpio_setpull_1up. +*/ +extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, + unsigned int off); + /** * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. * @chip: The gpio chip that is being configured. -- cgit v1.2.3-59-g8ed1b From 7ced5eab39809539e8fc7f3fb561bd3001d535e7 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 3 May 2010 17:19:49 +0900 Subject: ARM: S3C24XX: Add extended GPIO used on S3C2443 and beyond Add the GPIO banks that are used on the S3C2443 and above to the list of available GPIOS. Currently we do not have any limit on the SoC GPIO, so these are being registered whether the SoC has them or not. It is currently up to the user not to try and use them. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/gpio-nrs.h | 12 ++++++++ arch/arm/mach-s3c2410/include/mach/regs-gpio.h | 17 ++++++++++ arch/arm/mach-s3c2410/include/mach/regs-gpioj.h | 4 --- arch/arm/plat-s3c24xx/gpiolib.c | 41 ++++++++++++++++++++++++- 4 files changed, 69 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h index 2edbb9c88ab3..f3182ff847cb 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h +++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h @@ -34,6 +34,10 @@ #define S3C2410_GPIO_F_NR (32) #define S3C2410_GPIO_G_NR (32) #define S3C2410_GPIO_H_NR (32) +#define S3C2410_GPIO_J_NR (32) /* technically 16. */ +#define S3C2410_GPIO_K_NR (32) /* technically 16. */ +#define S3C2410_GPIO_L_NR (32) /* technically 15. */ +#define S3C2410_GPIO_M_NR (32) /* technically 2. */ #if CONFIG_S3C_GPIO_SPACE != 0 #error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment @@ -53,6 +57,10 @@ enum s3c_gpio_number { S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E), S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F), S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G), + S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H), + S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J), + S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K), + S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L), }; #endif /* __ASSEMBLY__ */ @@ -67,6 +75,10 @@ enum s3c_gpio_number { #define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr)) #define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr)) #define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr)) +#define S3C2410_GPJ(_nr) (S3C2410_GPIO_J_START + (_nr)) +#define S3C2410_GPK(_nr) (S3C2410_GPIO_K_START + (_nr)) +#define S3C2410_GPL(_nr) (S3C2410_GPIO_L_START + (_nr)) +#define S3C2410_GPM(_nr) (S3C2410_GPIO_M_START + (_nr)) /* compatibility until drivers can be modified */ diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h index fd672f330bf2..821b966bf05a 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h @@ -639,6 +639,23 @@ * for the 2412/2413 from the 2410/2440/2442 */ +/* S3C2443 and above */ +#define S3C2440_GPJCON S3C2410_GPIOREG(0xD0) +#define S3C2440_GPJDAT S3C2410_GPIOREG(0xD4) +#define S3C2440_GPJUP S3C2410_GPIOREG(0xD8) + +#define S3C2443_GPKCON S3C2410_GPIOREG(0xE0) +#define S3C2443_GPKDAT S3C2410_GPIOREG(0xE4) +#define S3C2443_GPKUP S3C2410_GPIOREG(0xE8) + +#define S3C2443_GPLCON S3C2410_GPIOREG(0xF0) +#define S3C2443_GPLDAT S3C2410_GPIOREG(0xF4) +#define S3C2443_GPLUP S3C2410_GPIOREG(0xF8) + +#define S3C2443_GPMCON S3C2410_GPIOREG(0x100) +#define S3C2443_GPMDAT S3C2410_GPIOREG(0x104) +#define S3C2443_GPMUP S3C2410_GPIOREG(0x108) + /* miscellaneous control */ #define S3C2400_MISCCR S3C2410_GPIOREG(0x54) #define S3C2410_MISCCR S3C2410_GPIOREG(0x80) diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h index 1202ca5e99f6..de463bc17b5d 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h @@ -24,10 +24,6 @@ #define S3C2440_GPIO_BANKJ (416) -#define S3C2440_GPJCON S3C2410_GPIOREG(0xd0) -#define S3C2440_GPJDAT S3C2410_GPIOREG(0xd4) -#define S3C2440_GPJUP S3C2410_GPIOREG(0xd8) - #define S3C2413_GPJCON S3C2410_GPIOREG(0x80) #define S3C2413_GPJDAT S3C2410_GPIOREG(0x84) #define S3C2413_GPJUP S3C2410_GPIOREG(0x88) diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c index 376b061804c2..e8c0e8a247ba 100644 --- a/arch/arm/plat-s3c24xx/gpiolib.c +++ b/arch/arm/plat-s3c24xx/gpiolib.c @@ -1,6 +1,6 @@ /* linux/arch/arm/plat-s3c24xx/gpiolib.c * - * Copyright (c) 2008 Simtec Electronics + * Copyright (c) 2008-2010 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks * @@ -172,8 +172,47 @@ struct s3c_gpio_chip s3c24xx_gpios[] = { .ngpio = 11, }, }, + /* GPIOS for the S3C2443 and later devices. */ + { + .base = S3C2440_GPJCON, + .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPJ(0), + .owner = THIS_MODULE, + .label = "GPIOJ", + .ngpio = 16, + }, + }, { + .base = S3C2443_GPKCON, + .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPK(0), + .owner = THIS_MODULE, + .label = "GPIOK", + .ngpio = 16, + }, + }, { + .base = S3C2443_GPLCON, + .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPL(0), + .owner = THIS_MODULE, + .label = "GPIOL", + .ngpio = 15, + }, + }, { + .base = S3C2443_GPMCON, + .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPM(0), + .owner = THIS_MODULE, + .label = "GPIOM", + .ngpio = 2, + }, + }, }; + static __init int s3c24xx_gpiolib_init(void) { struct s3c_gpio_chip *chip = s3c24xx_gpios; -- cgit v1.2.3-59-g8ed1b From f4146a65fbdc5274a437f77ff2f3b4889c0edd0e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 11:23:05 +0900 Subject: ARM: H1940: Change h1940-bluetooth to use gpiolib API Change the h1940-bluetooth driver to use gpiolib to set the output state of GPH1. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/h1940-bluetooth.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c index a3f3c7b1ca38..6d06b7e2579f 100644 --- a/arch/arm/mach-s3c2410/h1940-bluetooth.c +++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c @@ -33,14 +33,15 @@ static void h1940bt_enable(int on) h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER); /* Reset the chip */ mdelay(10); - s3c2410_gpio_setpin(S3C2410_GPH(1), 1); + + gpio_set_value(S3C2410_GPH(1), 1); mdelay(10); - s3c2410_gpio_setpin(S3C2410_GPH(1), 0); + gpio_set_value(S3C2410_GPH(1), 0); } else { - s3c2410_gpio_setpin(S3C2410_GPH(1), 1); + gpio_set_value(S3C2410_GPH(1), 1); mdelay(10); - s3c2410_gpio_setpin(S3C2410_GPH(1), 0); + gpio_set_value(S3C2410_GPH(1), 0); mdelay(10); h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0); } @@ -61,6 +62,12 @@ static int __devinit h1940bt_probe(struct platform_device *pdev) struct rfkill *rfk; int ret = 0; + ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev)); + if (ret) { + dev_err(&pdev->dev, "could not get GPH1\n");\ + return ret; + } + /* Configures BT serial port GPIOs */ s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); s3c2410_gpio_pullup(S3C2410_GPH(0), 1); @@ -100,6 +107,7 @@ static int h1940bt_remove(struct platform_device *pdev) struct rfkill *rfk = platform_get_drvdata(pdev); platform_set_drvdata(pdev, NULL); + gpio_free(S3C2410_GPH(1)); if (rfk) { rfkill_unregister(rfk); -- cgit v1.2.3-59-g8ed1b From afc84ad11b5c1247c2d0df06f10df69ea7206f6a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 11:30:42 +0900 Subject: ARM: JIVE: Update mach-jive to use gpiolib API Change mach-jive to use gpiolib for the GPIO lines that are directly manipulated by it. Note, we ignore any errors from gpio_request(), unlikely to see any. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2412/mach-jive.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c index 14f4798291aa..d2bb7d2510fa 100644 --- a/arch/arm/mach-s3c2412/mach-jive.c +++ b/arch/arm/mach-s3c2412/mach-jive.c @@ -357,8 +357,7 @@ static void jive_lcm_reset(unsigned int set) { printk(KERN_DEBUG "%s(%d)\n", __func__, set); - s3c2410_gpio_setpin(S3C2410_GPG(13), set); - s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT); + gpio_set_value(S3C2410_GPG(13), set); } #undef LCD_UPPER_MARGIN @@ -391,7 +390,7 @@ static struct ili9320_platdata jive_lcm_config = { static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs) { - s3c2410_gpio_setpin(S3C2410_GPB(7), cs ? 0 : 1); + gpio_set_value(S3C2410_GPB(7), cs ? 0 : 1); } static struct s3c2410_spigpio_info jive_lcd_spi = { @@ -413,7 +412,7 @@ static struct platform_device jive_device_lcdspi = { static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs) { - s3c2410_gpio_setpin(S3C2410_GPH(10), cs ? 0 : 1); + gpio_set_value(S3C2410_GPH(10), cs ? 0 : 1); } static struct s3c2410_spigpio_info jive_wm8750_spi = { @@ -636,11 +635,11 @@ static void __init jive_machine_init(void) /* initialise the spi */ - s3c2410_gpio_setpin(S3C2410_GPG(13), 0); - s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT); + gpio_request(S3C2410_GPG(13), "lcm reset"); + gpio_direction_output(S3C2410_GPG(13), 0); - s3c2410_gpio_setpin(S3C2410_GPB(7), 1); - s3c2410_gpio_cfgpin(S3C2410_GPB(7), S3C2410_GPIO_OUTPUT); + gpio_request(S3C2410_GPB(7), "jive spi"); + gpio_direction_output(S3C2410_GPB(7), 1); s3c2410_gpio_setpin(S3C2410_GPB(6), 0); s3c2410_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT); @@ -650,8 +649,8 @@ static void __init jive_machine_init(void) /* initialise the WM8750 spi */ - s3c2410_gpio_setpin(S3C2410_GPH(10), 1); - s3c2410_gpio_cfgpin(S3C2410_GPH(10), S3C2410_GPIO_OUTPUT); + gpio_request(S3C2410_GPH(10), "jive wm8750 spi"); + gpio_direction_output(S3C2410_GPH(10), 1); /* Turn off suspend on both USB ports, and switch the * selectable USB port to USB device mode. */ -- cgit v1.2.3-59-g8ed1b From db61ac54c9bea389b98f88cb4a23f8dd1edde07f Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 11:40:51 +0900 Subject: ARM: H1940: Change mach-h1940 to use gpiolib API Change mach-h1940 to use the gpiolib calls instead of s3c2410_gpio directly. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-h1940.c | 15 ++++++++------- arch/arm/mach-s3c2412/mach-smdk2413.c | 8 ++++---- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index fbedd0760941..5527f746c5e3 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -207,7 +207,7 @@ static int h1940_backlight_init(struct device *dev) { gpio_request(S3C2410_GPB(0), "Backlight"); - s3c2410_gpio_setpin(S3C2410_GPB(0), 0); + gpio_direction_output(S3C2410_GPB(0), 0); s3c2410_gpio_pullup(S3C2410_GPB(0), 0); s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); @@ -216,7 +216,7 @@ static int h1940_backlight_init(struct device *dev) static void h1940_backlight_exit(struct device *dev) { - s3c2410_gpio_cfgpin(S3C2410_GPB(0), 1/*S3C2410_GPB0_OUTP*/); + gpio_direction_output(S3C2410_GPB(0), 1); } static struct platform_pwm_backlight_data backlight_data = { @@ -245,18 +245,18 @@ static void h1940_lcd_power_set(struct plat_lcd_data *pd, if (!power) { /* set to 3ec */ - s3c2410_gpio_setpin(S3C2410_GPC(0), 0); + gpio_direction_output(S3C2410_GPC(0), 0); /* wait for 3ac */ do { - value = s3c2410_gpio_getpin(S3C2410_GPC(6)); + value = gpio_get_value(S3C2410_GPC(6)); } while (value); /* set to 38c */ - s3c2410_gpio_setpin(S3C2410_GPC(5), 0); + gpio_direction_output(S3C2410_GPC(5), 0); } else { /* Set to 3ac */ - s3c2410_gpio_setpin(S3C2410_GPC(5), 1); + gpio_direction_output(S3C2410_GPC(5), 1); /* Set to 3ad */ - s3c2410_gpio_setpin(S3C2410_GPC(0), 1); + gpio_direction_output(S3C2410_GPC(0), 1); } } @@ -332,6 +332,7 @@ static void __init h1940_init(void) gpio_request(S3C2410_GPC(5), "LCD power"); gpio_request(S3C2410_GPC(6), "LCD power"); + gpio_direction_input(S3C2410_GPC(6)); platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices)); } diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c index 0392065af1af..faddb36ed23b 100644 --- a/arch/arm/mach-s3c2412/mach-smdk2413.c +++ b/arch/arm/mach-s3c2412/mach-smdk2413.c @@ -85,10 +85,10 @@ static void smdk2413_udc_pullup(enum s3c2410_udc_cmd_e cmd) switch (cmd) { case S3C2410_UDC_P_ENABLE : - s3c2410_gpio_setpin(S3C2410_GPF(2), 1); + gpio_set_value(S3C2410_GPF(2), 1); break; case S3C2410_UDC_P_DISABLE : - s3c2410_gpio_setpin(S3C2410_GPF(2), 0); + gpio_set_value(S3C2410_GPF(2), 0); break; case S3C2410_UDC_P_RESET : break; @@ -134,8 +134,8 @@ static void __init smdk2413_machine_init(void) { /* Turn off suspend on both USB ports, and switch the * selectable USB port to USB device mode. */ - s3c2410_gpio_setpin(S3C2410_GPF(2), 0); - s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); + WARN_ON(gpio_request(S3C2410_GPF(2), "udc pull")); + gpio_direction_output(S3C2410_GPF(2), 0); s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | S3C2410_MISCCR_USBSUSPND0 | -- cgit v1.2.3-59-g8ed1b From 2d2e0c89982c532f9da6891a733b7be43c7048ce Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 12:32:16 +0900 Subject: ARM: QT2410: Update mach-qt2410 to use gpiolib API Change mach-qt2410.c to use gpiolib for the GPIO lines that are directly manipulated by it. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-qt2410.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c index 92a4ec375d82..e9762fb30d38 100644 --- a/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/arch/arm/mach-s3c2410/mach-qt2410.c @@ -219,10 +219,10 @@ static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs) { switch (cs) { case BITBANG_CS_ACTIVE: - s3c2410_gpio_setpin(S3C2410_GPB(5), 0); + gpio_set_value(S3C2410_GPB(5), 0); break; case BITBANG_CS_INACTIVE: - s3c2410_gpio_setpin(S3C2410_GPB(5), 1); + gpio_set_value(S3C2410_GPB(5), 1); break; } } @@ -353,7 +353,8 @@ static void __init qt2410_machine_init(void) s3c24xx_udc_set_platdata(&qt2410_udc_cfg); s3c_i2c0_set_platdata(NULL); - s3c2410_gpio_cfgpin(S3C2410_GPB(5), S3C2410_GPIO_OUTPUT); + WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs")); + gpio_direction_output(S3C2410_GPB(5), 1); platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices)); s3c_pm_init(); -- cgit v1.2.3-59-g8ed1b From 96efa8dac85372fdddb1682949b468226126e333 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 12:36:33 +0900 Subject: ARM: n30: Update mach-n30 to use gpiolib API Change mach-n30.c to use gpiolib for the GPIO lines that are directly manipulated by it. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 684710f88142..75a9fd37a467 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -86,10 +86,10 @@ static void n30_udc_pullup(enum s3c2410_udc_cmd_e cmd) { switch (cmd) { case S3C2410_UDC_P_ENABLE : - s3c2410_gpio_setpin(S3C2410_GPB(3), 1); + gpio_set_value(S3C2410_GPB(3), 1); break; case S3C2410_UDC_P_DISABLE : - s3c2410_gpio_setpin(S3C2410_GPB(3), 0); + gpio_set_value(S3C2410_GPB(3), 0); break; case S3C2410_UDC_P_RESET : break; @@ -536,6 +536,9 @@ static void __init n30_init(void) platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices)); } + + WARN_ON(gpio_request(S3C2410_GPB(3), "udc pup")); + gpio_direction_output(S3C2410_GPB(3), 0); } MACHINE_START(N30, "Acer-N30") -- cgit v1.2.3-59-g8ed1b From 408c8b8ca46c16fa09a6795613db74a8d2de7980 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 12:49:04 +0900 Subject: ARM: BAST: Update mach-bast to use gpiolib API Change mach-bast .c to use gpiolib for the GPIO lines that are directly manipulated by it. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-bast.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 02b1b6220cba..d03cbe2acde6 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -216,9 +216,7 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { static int bast_pm_suspend(struct sys_device *sd, pm_message_t state) { /* ensure that an nRESET is not generated on resume. */ - s3c2410_gpio_setpin(S3C2410_GPA(21), 1); - s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT); - + gpio_direction_output(S3C2410_GPA(21), 1); return 0; } @@ -658,6 +656,8 @@ static void __init bast_init(void) nor_simtec_init(); simtec_audio_add(NULL, true, &bast_audio); + WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset")); + s3c_cpufreq_setboard(&bast_cpufreq); } -- cgit v1.2.3-59-g8ed1b From 7614e1d9b9cad40ac9c90d934d2da64b36f354d1 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 12:53:11 +0900 Subject: ARM: VR1000: Update mach-vr1000.c to use gpiolib API Change mach-vr1000.c to use gpiolib for gpio control. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-vr1000.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 9051f0d31123..d540d79dd264 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -357,8 +357,7 @@ static struct clk *vr1000_clocks[] __initdata = { static void vr1000_power_off(void) { - s3c2410_gpio_cfgpin(S3C2410_GPB(9), S3C2410_GPIO_OUTPUT); - s3c2410_gpio_setpin(S3C2410_GPB(9), 1); + gpio_direction_output(S3C2410_GPB(9), 1); } static void __init vr1000_map_io(void) @@ -395,6 +394,8 @@ static void __init vr1000_init(void) nor_simtec_init(); simtec_audio_add(NULL, true, NULL); + + WARN_ON(gpio_request(S3C2410_GPB(9), "power off")); } MACHINE_START(VR1000, "Thorcom-VR1000") -- cgit v1.2.3-59-g8ed1b From 27da04049cabdf6a28288aaf083cfea64f7f9805 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 13:20:12 +0900 Subject: ARM: S3C2410: Change s3c2410_gpio_pullupl(x, 1) to use s3c_gpio_cfgpull() Start moving code that is using the old s3c2410_gpio API to using the newer s3c_gpio variants by finding all the usages of s3c2410_gpio_pullup() which disable the pin's pull up and replacing them. sed 's/s3c2410_gpio_pullup\(.*\), 1/s3c_gpio_cfgpull\1, S3C_GPIO_PULL_NONE/g' Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/h1940-bluetooth.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c index 6d06b7e2579f..171a7c38428a 100644 --- a/arch/arm/mach-s3c2410/h1940-bluetooth.c +++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c @@ -70,13 +70,13 @@ static int __devinit h1940bt_probe(struct platform_device *pdev) /* Configures BT serial port GPIOs */ s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); - s3c2410_gpio_pullup(S3C2410_GPH(0), 1); + s3c_gpio_cfgpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE); s3c2410_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT); - s3c2410_gpio_pullup(S3C2410_GPH(1), 1); + s3c_gpio_cfgpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE); s3c2410_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); - s3c2410_gpio_pullup(S3C2410_GPH(2), 1); + s3c_gpio_cfgpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE); s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); - s3c2410_gpio_pullup(S3C2410_GPH(3), 1); + s3c_gpio_cfgpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE); rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH, -- cgit v1.2.3-59-g8ed1b From 82a4b6dcc72da33943b16338f607e7e148d177e4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 13:22:58 +0900 Subject: ARM: S3C24XX: Change s3c2410_gpio_pullupl(x, 1) to use s3c_gpio_cfgpull() Start moving code that is using the old s3c2410_gpio API to using the newer s3c_gpio variants by finding all the usages of s3c2410_gpio_pullup() which disable the pin's pull up and replacing them. sed 's/s3c2410_gpio_pullup\(.*\), 1/s3c_gpio_cfgpull\1, S3C_GPIO_PULL_NONE/g' Signed-off-by: Ben Dooks --- arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c | 6 +++--- arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c | 6 +++--- arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c index da7a61728c18..71256ad6e8ea 100644 --- a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c +++ b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c @@ -29,8 +29,8 @@ void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi, } else { s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT); s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT); - s3c2410_gpio_pullup(S3C2410_GPE(11), 1); - s3c2410_gpio_pullup(S3C2410_GPE(12), 1); - s3c2410_gpio_pullup(S3C2410_GPE(13), 1); + s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE); } } diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c index 89fcf5308cf6..31bda55f6a14 100644 --- a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c +++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c @@ -31,8 +31,8 @@ void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi, } else { s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); - s3c2410_gpio_pullup(S3C2410_GPD(10), 1); - s3c2410_gpio_pullup(S3C2410_GPD(9), 1); - s3c2410_gpio_pullup(S3C2410_GPD(8), 1); + s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE); } } diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c index 86b9edc67413..79105015cdc1 100644 --- a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c +++ b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c @@ -29,8 +29,8 @@ void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi, } else { s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT); s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT); - s3c2410_gpio_pullup(S3C2410_GPG(5), 1); - s3c2410_gpio_pullup(S3C2410_GPG(6), 1); - s3c2410_gpio_pullup(S3C2410_GPG(7), 1); + s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE); } } -- cgit v1.2.3-59-g8ed1b From 40b956f026a3303a67d2ab7fffa2331f72e1e019 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 14:38:49 +0900 Subject: ARM: S3C24XX: Drop s3c2410 specific s3c2410_gpio_cfgpin() The s3c_gpio_cfgpin() call should be functionally equivalent, so replace the s3c2410_gpio_cfgpin() calls in the s3c24xx code with s3c_gpio_cfgpin to allow moving away from a fixed GPIO number to register address mapping Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/h1940-bluetooth.c | 8 ++++---- arch/arm/mach-s3c2410/mach-amlm5900.c | 3 ++- arch/arm/mach-s3c2410/mach-bast.c | 3 ++- arch/arm/mach-s3c2410/mach-h1940.c | 3 ++- arch/arm/mach-s3c2410/mach-qt2410.c | 3 ++- arch/arm/mach-s3c2412/mach-jive.c | 7 ++++--- arch/arm/mach-s3c2440/mach-mini2440.c | 11 ++++++----- arch/arm/mach-s3c2440/mach-nexcoder.c | 9 +++++---- arch/arm/mach-s3c2440/mach-osiris.c | 5 +++-- arch/arm/plat-s3c24xx/common-smdk.c | 9 +++++---- arch/arm/plat-s3c24xx/pm.c | 3 ++- arch/arm/plat-s3c24xx/setup-i2c.c | 5 +++-- arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c | 10 +++++----- arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c | 10 +++++----- arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c | 10 +++++----- 15 files changed, 55 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c index 171a7c38428a..8cdeb14af592 100644 --- a/arch/arm/mach-s3c2410/h1940-bluetooth.c +++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c @@ -69,13 +69,13 @@ static int __devinit h1940bt_probe(struct platform_device *pdev) } /* Configures BT serial port GPIOs */ - s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); + s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); s3c_gpio_cfgpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE); - s3c2410_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT); s3c_gpio_cfgpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE); - s3c2410_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); + s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); s3c_gpio_cfgpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE); - s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); + s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); s3c_gpio_cfgpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE); diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c index 7047317ed7f4..b42a76042af5 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c @@ -56,6 +56,7 @@ #include #include #include +#include #ifdef CONFIG_MTD_PARTITIONS @@ -225,7 +226,7 @@ static void amlm5900_init_pm(void) } else { enable_irq_wake(IRQ_EINT9); /* configure the suspend/resume status pin */ - s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); s3c2410_gpio_pullup(S3C2410_GPF(2), 0); } } diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index d03cbe2acde6..b061ddcf3067 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include "usb-simtec.h" @@ -222,7 +223,7 @@ static int bast_pm_suspend(struct sys_device *sd, pm_message_t state) static int bast_pm_resume(struct sys_device *sd) { - s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT); + s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT); return 0; } diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 5527f746c5e3..e2f7e64a526b 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -50,6 +50,7 @@ #include #include +#include #include #include #include @@ -209,7 +210,7 @@ static int h1940_backlight_init(struct device *dev) gpio_direction_output(S3C2410_GPB(0), 0); s3c2410_gpio_pullup(S3C2410_GPB(0), 0); - s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); + s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); return 0; } diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c index e9762fb30d38..d0e87b6e2e0f 100644 --- a/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/arch/arm/mach-s3c2410/mach-qt2410.c @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -347,7 +348,7 @@ static void __init qt2410_machine_init(void) } s3c24xx_fb_set_platdata(&qt2410_fb_info); - s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT); s3c2410_gpio_setpin(S3C2410_GPB(0), 1); s3c24xx_udc_set_platdata(&qt2410_udc_cfg); diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c index d2bb7d2510fa..43160183571a 100644 --- a/arch/arm/mach-s3c2412/mach-jive.c +++ b/arch/arm/mach-s3c2412/mach-jive.c @@ -48,6 +48,7 @@ #include #include +#include #include #include #include @@ -530,7 +531,7 @@ static void jive_power_off(void) printk(KERN_INFO "powering system down...\n"); s3c2410_gpio_setpin(S3C2410_GPC(5), 1); - s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT); } static void __init jive_machine_init(void) @@ -642,10 +643,10 @@ static void __init jive_machine_init(void) gpio_direction_output(S3C2410_GPB(7), 1); s3c2410_gpio_setpin(S3C2410_GPB(6), 0); - s3c2410_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT); s3c2410_gpio_setpin(S3C2410_GPG(8), 1); - s3c2410_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT); /* initialise the WM8750 spi */ diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c index 571b17683d96..362a2f97f748 100644 --- a/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/arch/arm/mach-s3c2440/mach-mini2440.c @@ -53,6 +53,7 @@ #include #include +#include #include #include #include @@ -632,24 +633,24 @@ static void __init mini2440_init(void) mini2440_parse_features(&features, mini2440_features_str); /* turn LCD on */ - s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND); + s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND); /* Turn the backlight early on */ s3c2410_gpio_setpin(S3C2410_GPG(4), 1); - s3c2410_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT); /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */ s3c2410_gpio_pullup(S3C2410_GPB(1), 0); s3c2410_gpio_setpin(S3C2410_GPB(1), 0); - s3c2410_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT); /* Make sure the D+ pullup pin is output */ - s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT); /* mark the key as input, without pullups (there is one on the board) */ for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) { s3c2410_gpio_pullup(mini2440_buttons[i].gpio, 0); - s3c2410_gpio_cfgpin(mini2440_buttons[i].gpio, + s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT); } if (features.lcd_index != -1) { diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c index 342041593f22..3ff62de45fde 100644 --- a/arch/arm/mach-s3c2440/mach-nexcoder.c +++ b/arch/arm/mach-s3c2440/mach-nexcoder.c @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -122,15 +123,15 @@ static void __init nexcoder_sensorboard_init(void) { // Initialize SCCB bus s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL - s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT); s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA - s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT); // Power up the sensor board s3c2410_gpio_setpin(S3C2410_GPF(1), 1); - s3c2410_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN + s3c_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN s3c2410_gpio_setpin(S3C2410_GPF(2), 0); - s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN + s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN } static void __init nexcoder_map_io(void) diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index f35371db33f5..319458da71a0 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c @@ -49,6 +49,7 @@ #include #include +#include #include #include #include @@ -298,7 +299,7 @@ static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state) /* ensure that an nRESET is not generated on resume. */ s3c2410_gpio_setpin(S3C2410_GPA(21), 1); - s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT); return 0; } @@ -310,7 +311,7 @@ static int osiris_pm_resume(struct sys_device *sd) __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0); - s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT); + s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT); return 0; } diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c index 9e0e20ad2e46..7b44d0c592b5 100644 --- a/arch/arm/plat-s3c24xx/common-smdk.c +++ b/arch/arm/plat-s3c24xx/common-smdk.c @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -185,10 +186,10 @@ void __init smdk_machine_init(void) { /* Configure the LEDs (even if we have no LED support)*/ - s3c2410_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT); - s3c2410_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT); - s3c2410_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT); - s3c2410_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT); s3c2410_gpio_setpin(S3C2410_GPF(4), 1); s3c2410_gpio_setpin(S3C2410_GPF(5), 1); diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c index 3620dd299095..37ea822c5c7b 100644 --- a/arch/arm/plat-s3c24xx/pm.c +++ b/arch/arm/plat-s3c24xx/pm.c @@ -43,6 +43,7 @@ #include +#include #include #define PFX "s3c24xx-pm: " @@ -105,7 +106,7 @@ static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs) } else { if (pinstate == S3C2410_GPIO_IRQ) { S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin); - s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT); } } } diff --git a/arch/arm/plat-s3c24xx/setup-i2c.c b/arch/arm/plat-s3c24xx/setup-i2c.c index 71a6accf114e..9e90a7cbd1d6 100644 --- a/arch/arm/plat-s3c24xx/setup-i2c.c +++ b/arch/arm/plat-s3c24xx/setup-i2c.c @@ -15,12 +15,13 @@ struct platform_device; +#include #include #include #include void s3c_i2c0_cfg_gpio(struct platform_device *dev) { - s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA); - s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL); + s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA); + s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL); } diff --git a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c index 71256ad6e8ea..9793544a6ace 100644 --- a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c +++ b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c @@ -21,14 +21,14 @@ void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi, int enable) { if (enable) { - s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0); - s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0); - s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0); + s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0); + s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0); + s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0); s3c2410_gpio_pullup(S3C2410_GPE(11), 0); s3c2410_gpio_pullup(S3C2410_GPE(13), 0); } else { - s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT); - s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT); s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE); s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE); s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE); diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c index 31bda55f6a14..db9e9e477ec1 100644 --- a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c +++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c @@ -23,14 +23,14 @@ void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi, printk(KERN_INFO "%s(%d)\n", __func__, enable); if (enable) { - s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1); - s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1); - s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1); + s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1); + s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1); + s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1); s3c2410_gpio_pullup(S3C2410_GPD(10), 0); s3c2410_gpio_pullup(S3C2410_GPD(9), 0); } else { - s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); - s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE); s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE); s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE); diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c index 79105015cdc1..8ea663a438bb 100644 --- a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c +++ b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c @@ -21,14 +21,14 @@ void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi, int enable) { if (enable) { - s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1); - s3c2410_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1); - s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1); + s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1); + s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1); + s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1); s3c2410_gpio_pullup(S3C2410_GPG(5), 0); s3c2410_gpio_pullup(S3C2410_GPG(6), 0); } else { - s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT); - s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT); s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE); s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE); s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE); -- cgit v1.2.3-59-g8ed1b From eee2b94f01f7379940a656af8ef097749ce025b5 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 15:01:44 +0900 Subject: ARM: S3C24XX: Remove s3c2410_gpio_setcfg() Remove the implementation of s3c2410_gpio_setcfg() as it should now be functionally equivalent to s3c_gpio_cfgpin(), and add a wrapper for those drivers that are still using this call. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/gpio-fns.h | 35 +++++++++++++------ arch/arm/plat-s3c24xx/gpio.c | 48 --------------------------- 2 files changed, 24 insertions(+), 59 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h index 035a493952db..f50c2a5f7ab3 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h +++ b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h @@ -10,14 +10,28 @@ * published by the Free Software Foundation. */ +#ifndef __MACH_GPIO_FNS_H +#define __MACH_GPIO_FNS_H __FILE__ + /* These functions are in the to-be-removed category and it is strongly * encouraged not to use these in new code. They will be marked deprecated * very soon. * * Most of the functionality can be either replaced by the gpiocfg calls * for the s3c platform or by the generic GPIOlib API. + * + * As of 2.6.35-rc, these will be removed, with the few drivers using them + * either replaced or given a wrapper until the calls can be removed. */ +#include + +static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg) +{ + /* 1:1 mapping between cfgpin and setcfg calls at the moment */ + s3c_gpio_cfgpin(pin, cfg); +} + /* external functions for GPIO support * * These allow various different clients to access the same GPIO @@ -25,17 +39,6 @@ * GPIO register, then it is safe to ioremap/__raw_{read|write} to it. */ -/* s3c2410_gpio_cfgpin - * - * set the configuration of the given pin to the value passed. - * - * eg: - * s3c2410_gpio_cfgpin(S3C2410_GPA(0), S3C2410_GPA0_ADDR0); - * s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1); -*/ - -extern void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function); - extern unsigned int s3c2410_gpio_getcfg(unsigned int pin); /* s3c2410_gpio_getirq @@ -71,6 +74,14 @@ extern int s3c2400_gpio_getirq(unsigned int pin); extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, unsigned int config); +/* s3c2410_gpio_pullup + * + * This call should be replaced with s3c_gpio_setpull(). + * + * As a note, there is currently no distinction between pull-up and pull-down + * in the s3c24xx series devices with only an on/off configuration. + */ + /* s3c2410_gpio_pullup * * configure the pull-up control on the given pin @@ -101,3 +112,5 @@ extern int s3c2410_gpio_getpull(unsigned int pin); extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to); extern unsigned int s3c2410_gpio_getpin(unsigned int pin); + +#endif /* __MACH_GPIO_FNS_H */ diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c index 5467470badfd..0b3b2cb228ab 100644 --- a/arch/arm/plat-s3c24xx/gpio.c +++ b/arch/arm/plat-s3c24xx/gpio.c @@ -34,54 +34,6 @@ #include -void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) -{ - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long mask; - unsigned long con; - unsigned long flags; - - if (pin < S3C2410_GPIO_BANKB) { - mask = 1 << S3C2410_GPIO_OFFSET(pin); - } else { - mask = 3 << S3C2410_GPIO_OFFSET(pin)*2; - } - - switch (function) { - case S3C2410_GPIO_LEAVE: - mask = 0; - function = 0; - break; - - case S3C2410_GPIO_INPUT: - case S3C2410_GPIO_OUTPUT: - case S3C2410_GPIO_SFN2: - case S3C2410_GPIO_SFN3: - if (pin < S3C2410_GPIO_BANKB) { - function -= 1; - function &= 1; - function <<= S3C2410_GPIO_OFFSET(pin); - } else { - function &= 3; - function <<= S3C2410_GPIO_OFFSET(pin)*2; - } - } - - /* modify the specified register wwith IRQs off */ - - local_irq_save(flags); - - con = __raw_readl(base + 0x00); - con &= ~mask; - con |= function; - - __raw_writel(con, base + 0x00); - - local_irq_restore(flags); -} - -EXPORT_SYMBOL(s3c2410_gpio_cfgpin); - unsigned int s3c2410_gpio_getcfg(unsigned int pin) { void __iomem *base = S3C24XX_GPIO_BASE(pin); -- cgit v1.2.3-59-g8ed1b From e6528d5e8730b1f75acf035d7c11e06657963581 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 15:07:43 +0900 Subject: ARM: S3C24XX: Remove s3c2410_gpio_getpull() Remove the unused s3c2410_gpio_getpull() Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/gpio-fns.h | 12 ------------ arch/arm/plat-s3c24xx/gpio.c | 13 ------------- 2 files changed, 25 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h index f50c2a5f7ab3..f453c4f2cb8e 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h +++ b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h @@ -97,18 +97,6 @@ extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to); -/* s3c2410_gpio_getpull - * - * Read the state of the pull-up on a given pin - * - * return: - * < 0 => error code - * 0 => enabled - * 1 => disabled -*/ - -extern int s3c2410_gpio_getpull(unsigned int pin); - extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to); extern unsigned int s3c2410_gpio_getpin(unsigned int pin); diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c index 0b3b2cb228ab..9b3d74c186fc 100644 --- a/arch/arm/plat-s3c24xx/gpio.c +++ b/arch/arm/plat-s3c24xx/gpio.c @@ -20,7 +20,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include #include #include @@ -75,18 +74,6 @@ void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) EXPORT_SYMBOL(s3c2410_gpio_pullup); -int s3c2410_gpio_getpull(unsigned int pin) -{ - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long offs = S3C2410_GPIO_OFFSET(pin); - - if (pin < S3C2410_GPIO_BANKB) - return -EINVAL; - - return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0; -} - -EXPORT_SYMBOL(s3c2410_gpio_getpull); void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) { -- cgit v1.2.3-59-g8ed1b From 5690a6267f0f0f15a01eeed143828726627c6ae6 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 4 May 2010 17:14:10 +0900 Subject: ARM: S3C24XX: Remove s3c2410_gpio_getirq() Remove s3c2410_gpio_getirq() as the only users is the pm code, and it can be replicated by using gpio_to_irq(). Signed-off-by: Ben Dooks --- arch/arm/plat-s3c24xx/gpio.c | 19 ------------------- arch/arm/plat-s3c24xx/pm.c | 2 +- 2 files changed, 1 insertion(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c index 9b3d74c186fc..24c00470b86c 100644 --- a/arch/arm/plat-s3c24xx/gpio.c +++ b/arch/arm/plat-s3c24xx/gpio.c @@ -120,22 +120,3 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) } EXPORT_SYMBOL(s3c2410_modify_misccr); - -int s3c2410_gpio_getirq(unsigned int pin) -{ - if (pin < S3C2410_GPF(0) || pin > S3C2410_GPG(15)) - return -EINVAL; /* not valid interrupts */ - - if (pin < S3C2410_GPG(0) && pin > S3C2410_GPF(7)) - return -EINVAL; /* not valid pin */ - - if (pin < S3C2410_GPF(4)) - return (pin - S3C2410_GPF(0)) + IRQ_EINT0; - - if (pin < S3C2410_GPG(0)) - return (pin - S3C2410_GPF(4)) + IRQ_EINT4; - - return (pin - S3C2410_GPG(0)) + IRQ_EINT8; -} - -EXPORT_SYMBOL(s3c2410_gpio_getirq); diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c index 37ea822c5c7b..691fecc61d53 100644 --- a/arch/arm/plat-s3c24xx/pm.c +++ b/arch/arm/plat-s3c24xx/pm.c @@ -91,7 +91,7 @@ static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs) { unsigned long irqstate; unsigned long pinstate; - int irq = s3c2410_gpio_getirq(pin); + int irq = gpio_to_irq(pin); if (irqoffs < 4) irqstate = s3c_irqwake_intmask & (1L< Date: Thu, 6 May 2010 10:27:16 +0900 Subject: ARM: SAMSUNG: Add GPIO configuration read calls Add the necessary 1,2 and 4 bit configuration read calls for the new gpio code to allow removal of the old s3c24xx gpio code. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/gpiolib.c | 6 +++ arch/arm/mach-s5p6440/gpio.c | 5 +++ arch/arm/plat-s3c24xx/gpiolib.c | 2 + arch/arm/plat-samsung/gpio-config.c | 47 +++++++++++++++++++++- .../plat-samsung/include/plat/gpio-cfg-helpers.h | 41 +++++++++++++++++++ 5 files changed, 100 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c index 66e6794481d2..60c929a3cab6 100644 --- a/arch/arm/mach-s3c64xx/gpiolib.c +++ b/arch/arm/mach-s3c64xx/gpiolib.c @@ -51,6 +51,7 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_noint = { .set_config = s3c_gpio_setcfg_s3c64xx_4bit, + .get_config = s3c_gpio_getcfg_s3c64xx_4bit, .set_pull = s3c_gpio_setpull_updown, .get_pull = s3c_gpio_getpull_updown, }; @@ -58,12 +59,14 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_noint = { static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = { .cfg_eint = 7, .set_config = s3c_gpio_setcfg_s3c64xx_4bit, + .get_config = s3c_gpio_getcfg_s3c64xx_4bit, .set_pull = s3c_gpio_setpull_updown, .get_pull = s3c_gpio_getpull_updown, }; static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = { .cfg_eint = 3, + .get_config = s3c_gpio_getcfg_s3c64xx_4bit, .set_config = s3c_gpio_setcfg_s3c64xx_4bit, .set_pull = s3c_gpio_setpull_updown, .get_pull = s3c_gpio_getpull_updown, @@ -171,6 +174,7 @@ static struct s3c_gpio_chip gpio_4bit2[] = { static struct s3c_gpio_cfg gpio_2bit_cfg_noint = { .set_config = s3c_gpio_setcfg_s3c24xx, + .get_config = s3c_gpio_getcfg_s3c24xx, .set_pull = s3c_gpio_setpull_updown, .get_pull = s3c_gpio_getpull_updown, }; @@ -178,6 +182,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_noint = { static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = { .cfg_eint = 2, .set_config = s3c_gpio_setcfg_s3c24xx, + .get_config = s3c_gpio_getcfg_s3c24xx, .set_pull = s3c_gpio_setpull_updown, .get_pull = s3c_gpio_getpull_updown, }; @@ -185,6 +190,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = { static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = { .cfg_eint = 3, .set_config = s3c_gpio_setcfg_s3c24xx, + .get_config = s3c_gpio_getcfg_s3c24xx, .set_pull = s3c_gpio_setpull_updown, .get_pull = s3c_gpio_getpull_updown, }; diff --git a/arch/arm/mach-s5p6440/gpio.c b/arch/arm/mach-s5p6440/gpio.c index b0ea741177ad..262dc75d5bea 100644 --- a/arch/arm/mach-s5p6440/gpio.c +++ b/arch/arm/mach-s5p6440/gpio.c @@ -161,12 +161,15 @@ static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = { }, { .cfg_eint = 0, .set_config = s3c_gpio_setcfg_s3c24xx, + .get_config = s3c_gpio_getcfg_s3c24xx, }, { .cfg_eint = 2, .set_config = s3c_gpio_setcfg_s3c24xx, + .get_config = s3c_gpio_getcfg_s3c24xx, }, { .cfg_eint = 3, .set_config = s3c_gpio_setcfg_s3c24xx, + .get_config = s3c_gpio_getcfg_s3c24xx, }, }; @@ -279,6 +282,8 @@ void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips) for (; nr_chips > 0; nr_chips--, chipcfg++) { if (!chipcfg->set_config) chipcfg->set_config = s3c_gpio_setcfg_s3c64xx_4bit; + if (!chipcfg->get_config) + chipcfg->get_config = s3c_gpio_getcfg_s3c64xx_4bit; if (!chipcfg->set_pull) chipcfg->set_pull = s3c_gpio_setpull_updown; if (!chipcfg->get_pull) diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c index e8c0e8a247ba..4c0896f2572d 100644 --- a/arch/arm/plat-s3c24xx/gpiolib.c +++ b/arch/arm/plat-s3c24xx/gpiolib.c @@ -81,10 +81,12 @@ static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset) static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { .set_config = s3c_gpio_setcfg_s3c24xx_a, + .get_config = s3c_gpio_getcfg_s3c24xx_a, }; struct s3c_gpio_cfg s3c24xx_gpiocfg_default = { .set_config = s3c_gpio_setcfg_s3c24xx, + .get_config = s3c_gpio_getcfg_s3c24xx, }; struct s3c_gpio_chip s3c24xx_gpios[] = { diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index 8aca88d6c486..19ab89df24c1 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c @@ -1,7 +1,7 @@ /* linux/arch/arm/plat-s3c/gpio-config.c * * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics + * Copyright 2008-2010 Simtec Electronics * Ben Dooks * http://armlinux.simtec.co.uk/ * @@ -87,6 +87,19 @@ int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, return 0; } +unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip, + unsigned int off) +{ + u32 con; + + con = __raw_readl(chip->base); + con >>= off; + con &= 1; + con++; + + return S3C_GPIO_SFN(con); +} + int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, unsigned int off, unsigned int cfg) { @@ -109,6 +122,19 @@ int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, return 0; } + +unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip, + unsigned int off) +{ + u32 con; + + con = __raw_readl(chip->base); + con >>= off * 2; + con &= 3; + + /* this conversion works for IN and OUT as well as special mode */ + return S3C_GPIO_SPECIAL(con); +} #endif #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX @@ -134,6 +160,25 @@ int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, return 0; } + +unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, + unsigned int off) +{ + void __iomem *reg = chip->base; + unsigned int shift = (off & 7) * 4; + u32 con; + + if (off < 8 && chip->chip.ngpio > 8) + reg -= 4; + + con = __raw_readl(reg); + con >>= shift; + con &= 0xf; + + /* this conversion works for IN and OUT as well as special mode */ + return S3C_GPIO_SPECIAL(con); +} + #endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */ #ifdef CONFIG_S3C_GPIO_PULL_UPDOWN diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h index 885e9ac642d3..a8868c429f7a 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h @@ -52,6 +52,18 @@ static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip, extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, unsigned int off, unsigned int cfg); +/** + * s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * + * The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg + * could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the + * S3C_GPIO_SPECIAL() macro. + */ +unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip, + unsigned int off); + /** * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A) * @chip: The gpio chip that is being configured. @@ -65,6 +77,21 @@ extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, unsigned int off, unsigned int cfg); + +/** + * s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A) + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * + * The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable + * GPIO configuration value. + * + * @sa s3c_gpio_getcfg_s3c24xx + * @sa s3c_gpio_getcfg_s3c64xx_4bit + */ +extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip, + unsigned int off); + /** * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config. * @chip: The gpio chip that is being configured. @@ -85,6 +112,20 @@ extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, unsigned int off, unsigned int cfg); +/** + * s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * + * The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration + * register setting into a value the software can use, such as could be passed + * to s3c_gpio_setcfg_s3c64xx_4bit(). + * + * @sa s3c_gpio_getcfg_s3c24xx + */ +extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, + unsigned int off); + /* Pull-{up,down} resistor controls. * * S3C2410,S3C2440,S3C24A0 = Pull-UP, -- cgit v1.2.3-59-g8ed1b From 9933847b29bb3d3447d19236375ccc84bfbcf3df Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 6 May 2010 10:50:42 +0900 Subject: ARM: S3C24XX: Remove s3c2410_gpio_getcfg(), implement s3c_gpio_getcfg() Add s3c_gpio_getcfg() and change anything using s3c2410_gpio_getcfg() to use this instead. Signed-off-by: Ben Dooks --- arch/arm/plat-s3c24xx/gpio.c | 19 ------------------- arch/arm/plat-s3c24xx/pm.c | 4 ++-- arch/arm/plat-samsung/gpio-config.c | 20 ++++++++++++++++++++ .../arm/plat-samsung/include/plat/gpio-cfg-helpers.h | 6 ++++++ arch/arm/plat-samsung/include/plat/gpio-cfg.h | 11 +++++++++++ 5 files changed, 39 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c index 24c00470b86c..c7c0cd73b946 100644 --- a/arch/arm/plat-s3c24xx/gpio.c +++ b/arch/arm/plat-s3c24xx/gpio.c @@ -33,25 +33,6 @@ #include -unsigned int s3c2410_gpio_getcfg(unsigned int pin) -{ - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long val = __raw_readl(base); - - if (pin < S3C2410_GPIO_BANKB) { - val >>= S3C2410_GPIO_OFFSET(pin); - val &= 1; - val += 1; - } else { - val >>= S3C2410_GPIO_OFFSET(pin)*2; - val &= 3; - } - - return val | S3C2410_GPIO_INPUT; -} - -EXPORT_SYMBOL(s3c2410_gpio_getcfg); - void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) { void __iomem *base = S3C24XX_GPIO_BASE(pin); diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c index 691fecc61d53..60627e63a254 100644 --- a/arch/arm/plat-s3c24xx/pm.c +++ b/arch/arm/plat-s3c24xx/pm.c @@ -98,11 +98,11 @@ static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs) else irqstate = s3c_irqwake_eintmask & (1L<chip.base; + + local_irq_save(flags); + ret = s3c_gpio_do_getcfg(chip, offset); + local_irq_restore(flags); + } + + return ret; +} +EXPORT_SYMBOL(s3c_gpio_getcfg); + + int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) { struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h index a8868c429f7a..3e21c75feefa 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h @@ -30,6 +30,12 @@ static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip, return (chip->config->set_config)(chip, off, config); } +static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip, + unsigned int off) +{ + return (chip->config->get_config)(chip, off); +} + static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip, unsigned int off, s3c_gpio_pull_t pull) { diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index 29cd6a86cade..8d01e853df39 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h @@ -77,6 +77,17 @@ struct s3c_gpio_cfg { */ extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); +/** + * s3c_gpio_getcfg - Read the current function for a GPIO pin + * @pin: The pin to read the configuration value for. + * + * Read the configuration state of the given @pin, returning a value that + * could be passed back to s3c_gpio_cfgpin(). + * + * @sa s3c_gpio_cfgpin + */ +extern unsigned s3c_gpio_getcfg(unsigned int pin); + /* Define values for the pull-{up,down} available for each gpio pin. * * These values control the state of the weak pull-{up,down} resistors -- cgit v1.2.3-59-g8ed1b From 64f508da584f983642eb8cf808fcca68f9efa44a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 6 May 2010 10:59:55 +0900 Subject: ARM: mini2440: Move to using gpiolib API and s3c_gpio functions Move the mach-mini2440 to using the gpiolib API for GPIOS it directly uses, and s3c_gpio calls for configuration. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2440/mach-mini2440.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c index 362a2f97f748..a76bcda210ad 100644 --- a/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/arch/arm/mach-s3c2440/mach-mini2440.c @@ -103,10 +103,10 @@ static void mini2440_udc_pullup(enum s3c2410_udc_cmd_e cmd) switch (cmd) { case S3C2410_UDC_P_ENABLE : - s3c2410_gpio_setpin(S3C2410_GPC(5), 1); + gpio_set_value(S3C2410_GPC(5), 1); break; case S3C2410_UDC_P_DISABLE : - s3c2410_gpio_setpin(S3C2410_GPC(5), 0); + gpio_set_value(S3C2410_GPC(5), 0); break; case S3C2410_UDC_P_RESET : break; @@ -636,22 +636,22 @@ static void __init mini2440_init(void) s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND); /* Turn the backlight early on */ - s3c2410_gpio_setpin(S3C2410_GPG(4), 1); - s3c_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT); + WARN_ON(gpio_request(S3C2410_GPG(4), "backlight")); + gpio_direction_output(S3C2410_GPG(4), 1); /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */ - s3c2410_gpio_pullup(S3C2410_GPB(1), 0); + s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP); s3c2410_gpio_setpin(S3C2410_GPB(1), 0); s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT); /* Make sure the D+ pullup pin is output */ - s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT); + WARN_ON(gpio_request(S3C2410_GPC(5), "udc pup")); + gpio_direction_output(S3C2410_GPC(5), 0); /* mark the key as input, without pullups (there is one on the board) */ for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) { - s3c2410_gpio_pullup(mini2440_buttons[i].gpio, 0); - s3c_gpio_cfgpin(mini2440_buttons[i].gpio, - S3C2410_GPIO_INPUT); + s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP); + s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT); } if (features.lcd_index != -1) { int li; -- cgit v1.2.3-59-g8ed1b From fb3787470ee6fee5900026170c05261c8c090a06 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 6 May 2010 11:03:50 +0900 Subject: ARM: S3C2410: Remove the users of s3c2410_gpio_pullup() Remove the last s3c2410_gpio_pullup() users in arch/arm/mach-s3c2410 Note, since mach-h1940.c is setting output and a pull-up, the call has vbeen chanerd to S3C_GPIO_PULL_NONE instead of S3C_GPIO_PULL_UP. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-amlm5900.c | 2 +- arch/arm/mach-s3c2410/mach-h1940.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c index b42a76042af5..34fc05a4244b 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c @@ -227,7 +227,7 @@ static void amlm5900_init_pm(void) enable_irq_wake(IRQ_EINT9); /* configure the suspend/resume status pin */ s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); - s3c2410_gpio_pullup(S3C2410_GPF(2), 0); + s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP); } } static void __init amlm5900_init(void) diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index e2f7e64a526b..9531b4c41deb 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -209,7 +209,7 @@ static int h1940_backlight_init(struct device *dev) gpio_request(S3C2410_GPB(0), "Backlight"); gpio_direction_output(S3C2410_GPB(0), 0); - s3c2410_gpio_pullup(S3C2410_GPB(0), 0); + s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE); s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); return 0; -- cgit v1.2.3-59-g8ed1b From 31da46d9f11ccdb11d7f2f07421f5cccb64fbbd6 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 6 May 2010 11:21:05 +0900 Subject: ARM: S3C24XX: Wrapper s3c2410_gpio_setpin and s3c2410_gpio_pullup() Change s3c2410_gpio_setpin() and s3c2410_gpio_pullup() to use the new s3c_ gpio configuration calls until all their users are converted. Signed-off-by: Ben Dooks --- arch/arm/plat-s3c24xx/gpio.c | 47 ++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c index c7c0cd73b946..45126d3aafc6 100644 --- a/arch/arm/plat-s3c24xx/gpio.c +++ b/arch/arm/plat-s3c24xx/gpio.c @@ -1,6 +1,6 @@ /* linux/arch/arm/plat-s3c24xx/gpio.c * - * Copyright (c) 2004-2005 Simtec Electronics + * Copyright (c) 2004-2010 Simtec Electronics * Ben Dooks * * S3C24XX GPIO support @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -33,44 +34,34 @@ #include +/* gpiolib wrappers until these are totally eliminated */ + void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) { - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long offs = S3C2410_GPIO_OFFSET(pin); - unsigned long flags; - unsigned long up; + int ret; - if (pin < S3C2410_GPIO_BANKB) - return; + WARN_ON(to); /* should be none of these left */ - local_irq_save(flags); - - up = __raw_readl(base + 0x08); - up &= ~(1L << offs); - up |= to << offs; - __raw_writel(up, base + 0x08); + if (!to) { + /* if pull is enabled, try first with up, and if that + * fails, try using down */ - local_irq_restore(flags); + ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP); + if (ret) + s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN); + } else { + s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); + } } - EXPORT_SYMBOL(s3c2410_gpio_pullup); - void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) { - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long offs = S3C2410_GPIO_OFFSET(pin); - unsigned long flags; - unsigned long dat; + /* do this via gpiolib until all users removed */ - local_irq_save(flags); - - dat = __raw_readl(base + 0x04); - dat &= ~(1 << offs); - dat |= to << offs; - __raw_writel(dat, base + 0x04); - - local_irq_restore(flags); + gpio_request(pin, "temporary"); + gpio_set_value(pin, to); + gpio_free(pin); } EXPORT_SYMBOL(s3c2410_gpio_setpin); -- cgit v1.2.3-59-g8ed1b From 9772b7586efb189ac2dcac1d6f7d09c6d879ac64 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 6 May 2010 11:23:35 +0900 Subject: ARM: S3C24XX: Remove S3C2410_GPJ numbering Remove the old S3C2410_GPJ as we will be moving to the new gpiolib based driver code and these numbers will become invalid. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/regs-gpioj.h | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h index de463bc17b5d..502575711246 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h @@ -22,81 +22,62 @@ * pull up works like all other ports. */ -#define S3C2440_GPIO_BANKJ (416) - #define S3C2413_GPJCON S3C2410_GPIOREG(0x80) #define S3C2413_GPJDAT S3C2410_GPIOREG(0x84) #define S3C2413_GPJUP S3C2410_GPIOREG(0x88) #define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C) -#define S3C2440_GPJ0 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 0) #define S3C2440_GPJ0_INP (0x00 << 0) #define S3C2440_GPJ0_OUTP (0x01 << 0) #define S3C2440_GPJ0_CAMDATA0 (0x02 << 0) -#define S3C2440_GPJ1 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 1) #define S3C2440_GPJ1_INP (0x00 << 2) #define S3C2440_GPJ1_OUTP (0x01 << 2) #define S3C2440_GPJ1_CAMDATA1 (0x02 << 2) -#define S3C2440_GPJ2 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 2) #define S3C2440_GPJ2_INP (0x00 << 4) #define S3C2440_GPJ2_OUTP (0x01 << 4) #define S3C2440_GPJ2_CAMDATA2 (0x02 << 4) -#define S3C2440_GPJ3 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 3) #define S3C2440_GPJ3_INP (0x00 << 6) #define S3C2440_GPJ3_OUTP (0x01 << 6) #define S3C2440_GPJ3_CAMDATA3 (0x02 << 6) -#define S3C2440_GPJ4 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 4) #define S3C2440_GPJ4_INP (0x00 << 8) #define S3C2440_GPJ4_OUTP (0x01 << 8) #define S3C2440_GPJ4_CAMDATA4 (0x02 << 8) -#define S3C2440_GPJ5 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 5) #define S3C2440_GPJ5_INP (0x00 << 10) #define S3C2440_GPJ5_OUTP (0x01 << 10) #define S3C2440_GPJ5_CAMDATA5 (0x02 << 10) -#define S3C2440_GPJ6 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 6) #define S3C2440_GPJ6_INP (0x00 << 12) #define S3C2440_GPJ6_OUTP (0x01 << 12) #define S3C2440_GPJ6_CAMDATA6 (0x02 << 12) -#define S3C2440_GPJ7 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 7) #define S3C2440_GPJ7_INP (0x00 << 14) #define S3C2440_GPJ7_OUTP (0x01 << 14) #define S3C2440_GPJ7_CAMDATA7 (0x02 << 14) -#define S3C2440_GPJ8 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 8) #define S3C2440_GPJ8_INP (0x00 << 16) #define S3C2440_GPJ8_OUTP (0x01 << 16) #define S3C2440_GPJ8_CAMPCLK (0x02 << 16) -#define S3C2440_GPJ9 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 9) #define S3C2440_GPJ9_INP (0x00 << 18) #define S3C2440_GPJ9_OUTP (0x01 << 18) #define S3C2440_GPJ9_CAMVSYNC (0x02 << 18) -#define S3C2440_GPJ10 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 10) #define S3C2440_GPJ10_INP (0x00 << 20) #define S3C2440_GPJ10_OUTP (0x01 << 20) #define S3C2440_GPJ10_CAMHREF (0x02 << 20) -#define S3C2440_GPJ11 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 11) #define S3C2440_GPJ11_INP (0x00 << 22) #define S3C2440_GPJ11_OUTP (0x01 << 22) #define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22) -#define S3C2440_GPJ12 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 12) #define S3C2440_GPJ12_INP (0x00 << 24) #define S3C2440_GPJ12_OUTP (0x01 << 24) #define S3C2440_GPJ12_CAMRESET (0x02 << 24) -#define S3C2443_GPJ13 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 13) -#define S3C2443_GPJ14 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 14) -#define S3C2443_GPJ15 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 15) - #endif /* __ASM_ARCH_REGS_GPIOJ_H */ -- cgit v1.2.3-59-g8ed1b From 1d3ef014b5fe959a789c2df708713d58c9491c3b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 6 May 2010 11:32:14 +0900 Subject: ARM: S3C24XX: Remove _INP macros in Remove the _INP definitions, they are all zero and also unused Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/regs-gpioj.h | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h index 502575711246..19575e061114 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h @@ -27,55 +27,42 @@ #define S3C2413_GPJUP S3C2410_GPIOREG(0x88) #define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C) -#define S3C2440_GPJ0_INP (0x00 << 0) #define S3C2440_GPJ0_OUTP (0x01 << 0) #define S3C2440_GPJ0_CAMDATA0 (0x02 << 0) -#define S3C2440_GPJ1_INP (0x00 << 2) #define S3C2440_GPJ1_OUTP (0x01 << 2) #define S3C2440_GPJ1_CAMDATA1 (0x02 << 2) -#define S3C2440_GPJ2_INP (0x00 << 4) #define S3C2440_GPJ2_OUTP (0x01 << 4) #define S3C2440_GPJ2_CAMDATA2 (0x02 << 4) -#define S3C2440_GPJ3_INP (0x00 << 6) #define S3C2440_GPJ3_OUTP (0x01 << 6) #define S3C2440_GPJ3_CAMDATA3 (0x02 << 6) -#define S3C2440_GPJ4_INP (0x00 << 8) #define S3C2440_GPJ4_OUTP (0x01 << 8) #define S3C2440_GPJ4_CAMDATA4 (0x02 << 8) -#define S3C2440_GPJ5_INP (0x00 << 10) #define S3C2440_GPJ5_OUTP (0x01 << 10) #define S3C2440_GPJ5_CAMDATA5 (0x02 << 10) -#define S3C2440_GPJ6_INP (0x00 << 12) #define S3C2440_GPJ6_OUTP (0x01 << 12) #define S3C2440_GPJ6_CAMDATA6 (0x02 << 12) -#define S3C2440_GPJ7_INP (0x00 << 14) #define S3C2440_GPJ7_OUTP (0x01 << 14) #define S3C2440_GPJ7_CAMDATA7 (0x02 << 14) -#define S3C2440_GPJ8_INP (0x00 << 16) #define S3C2440_GPJ8_OUTP (0x01 << 16) #define S3C2440_GPJ8_CAMPCLK (0x02 << 16) -#define S3C2440_GPJ9_INP (0x00 << 18) #define S3C2440_GPJ9_OUTP (0x01 << 18) #define S3C2440_GPJ9_CAMVSYNC (0x02 << 18) -#define S3C2440_GPJ10_INP (0x00 << 20) #define S3C2440_GPJ10_OUTP (0x01 << 20) #define S3C2440_GPJ10_CAMHREF (0x02 << 20) -#define S3C2440_GPJ11_INP (0x00 << 22) #define S3C2440_GPJ11_OUTP (0x01 << 22) #define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22) -#define S3C2440_GPJ12_INP (0x00 << 24) #define S3C2440_GPJ12_OUTP (0x01 << 24) #define S3C2440_GPJ12_CAMRESET (0x02 << 24) -- cgit v1.2.3-59-g8ed1b From 5faf5011841dc2a4797093b845e49bc40b4b4666 Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Wed, 19 Aug 2009 16:31:05 +0300 Subject: ARM: S3C: Add S3C2416 detection to uncompress code Add S3C2416 serial port setup to uncompress code. Signed-off-by: Yauhen Kharuzhy Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/uncompress.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/uncompress.h b/arch/arm/mach-s3c2410/include/mach/uncompress.h index 72f756c5e504..8b283f847daa 100644 --- a/arch/arm/mach-s3c2410/include/mach/uncompress.h +++ b/arch/arm/mach-s3c2410/include/mach/uncompress.h @@ -40,7 +40,9 @@ static void arch_detect_cpu(void) cpuid &= S3C2410_GSTATUS1_IDMASK; if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 || - cpuid == S3C2410_GSTATUS1_2442) { + cpuid == S3C2410_GSTATUS1_2442 || + cpuid == S3C2410_GSTATUS1_2416 || + cpuid == S3C2410_GSTATUS1_2450) { fifo_mask = S3C2440_UFSTAT_TXMASK; fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT; } else { -- cgit v1.2.3-59-g8ed1b From 9b7a37853a8cd69829eb1d9715a6c09aae01eeec Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 6 May 2010 15:09:45 +0900 Subject: sh: Make initrd detection more robust. Various boot loaders go to various extents to thwart the initrd detection logic (mostly on account of not being able to be bothered with adhering to the established boot ABI), so we make the detection logic a bit more robust. This makes it possible to work around the SDK7786's firmware's attempts to thwart compressed image booting. Victory is mine. Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 78 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 14735d5ede52..9c7f7811af70 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -188,6 +188,63 @@ static inline void __init reserve_crashkernel(void) {} #endif +static void __init check_for_initrd(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + unsigned long start, end; + + /* + * Check for the rare cases where boot loaders adhere to the boot + * ABI. + */ + if (!LOADER_TYPE || !INITRD_START || !INITRD_SIZE) + goto disable; + + start = INITRD_START + __MEMORY_START; + end = start + INITRD_SIZE; + + if (unlikely(end <= start)) + goto disable; + if (unlikely(start & ~PAGE_MASK)) { + pr_err("initrd must be page aligned\n"); + goto disable; + } + + if (unlikely(start < PAGE_OFFSET)) { + pr_err("initrd start < PAGE_OFFSET\n"); + goto disable; + } + + if (unlikely(end > lmb_end_of_DRAM())) { + pr_err("initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + end, (unsigned long)lmb_end_of_DRAM()); + goto disable; + } + + /* + * If we got this far inspite of the boot loader's best efforts + * to the contrary, assume we actually have a valid initrd and + * fix up the root dev. + */ + ROOT_DEV = Root_RAM0; + + /* + * Address sanitization + */ + initrd_start = (unsigned long)__va(__pa(start)); + initrd_end = initrd_start + INITRD_SIZE; + + reserve_bootmem(__pa(initrd_start), INITRD_SIZE, BOOTMEM_DEFAULT); + + return; + +disable: + pr_info("initrd disabled\n"); + initrd_start = initrd_end = 0; +#endif +} + void __cpuinit calibrate_delay(void) { struct clk *clk = clk_get(NULL, "cpu_clk"); @@ -277,26 +334,7 @@ void __init setup_bootmem_allocator(unsigned long free_pfn) sparse_memory_present_with_active_regions(0); -#ifdef CONFIG_BLK_DEV_INITRD - ROOT_DEV = Root_RAM0; - - if (LOADER_TYPE && INITRD_START) { - unsigned long initrd_start_phys = INITRD_START + __MEMORY_START; - - if (initrd_start_phys + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) { - reserve_bootmem(initrd_start_phys, INITRD_SIZE, - BOOTMEM_DEFAULT); - initrd_start = (unsigned long)__va(initrd_start_phys); - initrd_end = initrd_start + INITRD_SIZE; - } else { - printk("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - initrd_start_phys + INITRD_SIZE, - (unsigned long)PFN_PHYS(max_low_pfn)); - initrd_start = 0; - } - } -#endif + check_for_initrd(); reserve_crashkernel(); } -- cgit v1.2.3-59-g8ed1b From 4f47b4c9f0b711bf84adb8c27774ae80d346b628 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 5 May 2010 13:22:25 -0700 Subject: x86, acpi/irq: Define gsi_end when X86_IO_APIC is undefined My recent changes introducing a global gsi_end variable failed to take into account the case of using acpi on a system not built to support IO_APICs, causing the build to fail. Define gsi_end to 15 when CONFIG_X86_IO_APIC is not set to avoid compile errors. Signed-off-by: Eric W. Biederman Cc: Yinghai Lu LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/include/asm/io_apic.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 9da192a17f0f..63cb4096c3dc 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -197,6 +197,7 @@ static const int timer_through_8259 = 0; static inline void ioapic_init_mappings(void) { } static inline void ioapic_insert_resources(void) { } static inline void probe_nr_irqs_gsi(void) { } +#define gsi_end (NR_IRQS_LEGACY - 1) static inline int mp_find_ioapic(u32 gsi) { return 0; } struct io_apic_irq_attr; -- cgit v1.2.3-59-g8ed1b From f8b67691828321f5c85bb853283aa101ae673130 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 28 Apr 2010 13:39:41 +0000 Subject: powerpc/pseries: Make query_cpu_stopped callable outside hotplug cpu This moves query_cpu_stopped() out of the hotplug cpu code and into smp.c so it can called in other places and renames it to smp_query_cpu_stopped(). It also cleans up the return values by adding some #defines Cc: Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 30 ++++--------------------- arch/powerpc/platforms/pseries/plpar_wrappers.h | 8 +++++++ arch/powerpc/platforms/pseries/smp.c | 22 ++++++++++++++++++ 3 files changed, 34 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index a8e1d5d17a28..b0760d7701b4 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -154,30 +154,6 @@ static void pseries_mach_cpu_die(void) for(;;); } -static int qcss_tok; /* query-cpu-stopped-state token */ - -/* Get state of physical CPU. - * Return codes: - * 0 - The processor is in the RTAS stopped state - * 1 - stop-self is in progress - * 2 - The processor is not in the RTAS stopped state - * -1 - Hardware Error - * -2 - Hardware Busy, Try again later. - */ -static int query_cpu_stopped(unsigned int pcpu) -{ - int cpu_status, status; - - status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); - if (status != 0) { - printk(KERN_ERR - "RTAS query-cpu-stopped-state failed: %i\n", status); - return status; - } - - return cpu_status; -} - static int pseries_cpu_disable(void) { int cpu = smp_processor_id(); @@ -224,8 +200,9 @@ static void pseries_cpu_die(unsigned int cpu) } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) { for (tries = 0; tries < 25; tries++) { - cpu_status = query_cpu_stopped(pcpu); - if (cpu_status == 0 || cpu_status == -1) + cpu_status = smp_query_cpu_stopped(pcpu); + if (cpu_status == QCSS_STOPPED || + cpu_status == QCSS_HARDWARE_ERROR) break; cpu_relax(); } @@ -388,6 +365,7 @@ static int __init pseries_cpu_hotplug_init(void) struct device_node *np; const char *typep; int cpu; + int qcss_tok; for_each_node_by_name(np, "interrupt-controller") { typep = of_get_property(np, "compatible", NULL); diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index a05f8d427856..6c4fd2c3f385 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -4,6 +4,14 @@ #include #include +/* Get state of physical CPU from query_cpu_stopped */ +int smp_query_cpu_stopped(unsigned int pcpu); +#define QCSS_STOPPED 0 +#define QCSS_STOPPING 1 +#define QCSS_NOT_STOPPED 2 +#define QCSS_HARDWARE_ERROR -1 +#define QCSS_HARDWARE_BUSY -2 + static inline long poll_pending(void) { return plpar_hcall_norets(H_POLL_PENDING); diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 4e7f89a84561..20b694280a66 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -57,6 +57,28 @@ */ static cpumask_t of_spin_map; +/* Query where a cpu is now. Return codes #defined in plpar_wrappers.h */ +int smp_query_cpu_stopped(unsigned int pcpu) +{ + int cpu_status, status; + int qcss_tok = rtas_token("query-cpu-stopped-state"); + + if (qcss_tok == RTAS_UNKNOWN_SERVICE) { + printk(KERN_INFO "Firmware doesn't support " + "query-cpu-stopped-state\n"); + return QCSS_HARDWARE_ERROR; + } + + status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); + if (status != 0) { + printk(KERN_ERR + "RTAS query-cpu-stopped-state failed: %i\n", status); + return status; + } + + return cpu_status; +} + /** * smp_startup_cpu() - start the given cpu * -- cgit v1.2.3-59-g8ed1b From aef40e87d866355ffd279ab21021de733242d0d5 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 28 Apr 2010 13:39:41 +0000 Subject: powerpc/pseries: Only call start-cpu when a CPU is stopped Currently we always call start-cpu irrespective of if the CPU is stopped or not. Unfortunatley on POWER7, firmware seems to not like start-cpu being called when a cpu already been started. This was not the case on POWER6 and earlier. This patch checks to see if the CPU is stopped or not via an query-cpu-stopped-state call, and only calls start-cpu on CPUs which are stopped. This fixes a bug with kexec on POWER7 on PHYP where only the primary thread would make it to the second kernel. Reported-by: Ankita Garg Cc: Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/smp.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 20b694280a66..8979982eb2ee 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -104,6 +104,12 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) pcpu = get_hard_smp_processor_id(lcpu); + /* Check to see if the CPU out of FW already for kexec */ + if (smp_query_cpu_stopped(pcpu) == QCSS_NOT_STOPPED){ + cpu_set(lcpu, of_spin_map); + return 1; + } + /* Fixup atomic count: it exited inside IRQ handler. */ task_thread_info(paca[lcpu].__current)->preempt_count = 0; -- cgit v1.2.3-59-g8ed1b From 75c1d539ea13117cbe95e2c343e52af67d735145 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 27 Apr 2010 21:22:55 +0000 Subject: powerpc: Fix CONFIG_DEBUG_PAGEALLOC on 603/e300 So we tried to speed things up a bit using flush_hash_pages() directly but that falls over on 603 of course meaning we fail to flush the TLB properly and we may even end up having it corrupt memory randomly by accessing a hash table that doesn't exist. This removes the "optimization" by always going through flush_tlb_page() for now at least. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/pgtable_32.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 767b0cf17d33..9fc02dc72ce9 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -393,11 +393,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot) return -EINVAL; __set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0); wmb(); -#ifdef CONFIG_PPC_STD_MMU - flush_hash_pages(0, address, pmd_val(*kpmd), 1); -#else flush_tlb_page(NULL, address); -#endif pte_unmap(kpte); return 0; -- cgit v1.2.3-59-g8ed1b From 7cad19784950f947bf8b332b92d83c75788f897a Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Mon, 26 Apr 2010 22:50:21 +0000 Subject: powerpc: Correct parport interrupt parsing Currently the parsing of the device tree in arch/powerpc/include/asm/parport.h assumes that the interrupt provided in the parallel port node is a valid virtual irq. The values for the interrupts provided in the device tree should have meaning in the context of the driver for the specific interrupt controller to which the interrupt is connected and irq_of_parse_and_map() should be used to determine the correct virtual irq. Signed-off-by: Martyn Welch Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/parport.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/parport.h b/arch/powerpc/include/asm/parport.h index 94942d60ddfd..1ca1102b4a2f 100644 --- a/arch/powerpc/include/asm/parport.h +++ b/arch/powerpc/include/asm/parport.h @@ -19,6 +19,8 @@ static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) u32 io1, io2; int propsize; int count = 0; + int virq; + for (np = NULL; (np = of_find_compatible_node(np, "parallel", "pnpPNP,400")) != NULL;) { @@ -26,10 +28,13 @@ static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) if (!prop || propsize > 6*sizeof(u32)) continue; io1 = prop[1]; io2 = prop[2]; - prop = of_get_property(np, "interrupts", NULL); - if (!prop) + + virq = irq_of_parse_and_map(np, 0); + if (virq == NO_IRQ) continue; - if (parport_pc_probe_port(io1, io2, prop[0], autodma, NULL, 0) != NULL) + + if (parport_pc_probe_port(io1, io2, virq, autodma, NULL, 0) + != NULL) count++; } return count; -- cgit v1.2.3-59-g8ed1b From 91eea67c6d8704396a98226508c56a8501e141e3 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Wed, 21 Apr 2010 16:21:03 +0000 Subject: powerpc/mm: Track backing pages allocated by vmemmap_populate() We need to keep track of the backing pages that get allocated by vmemmap_populate() so that when we use kdump, the dump-capture kernel knows where these pages are. We use a simple linked list of structures that contain the physical address of the backing page and corresponding virtual address to track the backing pages. To save space, we just use a pointer to the next struct vmemmap_backing. We can also do this because we never remove nodes. We call the pointer "list" to be compatible with changes made to the crash utility. vmemmap_populate() is called either at boot-time or on a memory hotplug operation. We don't have to worry about the boot-time calls because they will be inherently single-threaded, and for a memory hotplug operation vmemmap_populate() is called through: sparse_add_one_section() | V kmalloc_section_memmap() | V sparse_mem_map_populate() | V vmemmap_populate() and in sparse_add_one_section() we're protected by pgdat_resize_lock(). So, we don't need a spinlock to protect the vmemmap_list. We allocate space for the vmemmap_backing structs by allocating whole pages in vmemmap_list_alloc() and then handing out chunks of this to vmemmap_list_populate(). This means that we waste at most just under one page, but this keeps the code is simple. Signed-off-by: Mark Nelson Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/pgalloc-64.h | 6 +++++ arch/powerpc/mm/init_64.c | 43 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h index 605f5c5398d1..292725cec2e3 100644 --- a/arch/powerpc/include/asm/pgalloc-64.h +++ b/arch/powerpc/include/asm/pgalloc-64.h @@ -11,6 +11,12 @@ #include #include +struct vmemmap_backing { + struct vmemmap_backing *list; + unsigned long phys; + unsigned long virt_addr; +}; + /* * Functions that deal with pagetables that could be at any level of * the table need to be passed an "index_size" so they know how to diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index d7fa50b09b4a..e267f223fdff 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -252,6 +252,47 @@ static void __meminit vmemmap_create_mapping(unsigned long start, } #endif /* CONFIG_PPC_BOOK3E */ +struct vmemmap_backing *vmemmap_list; + +static __meminit struct vmemmap_backing * vmemmap_list_alloc(int node) +{ + static struct vmemmap_backing *next; + static int num_left; + + /* allocate a page when required and hand out chunks */ + if (!next || !num_left) { + next = vmemmap_alloc_block(PAGE_SIZE, node); + if (unlikely(!next)) { + WARN_ON(1); + return NULL; + } + num_left = PAGE_SIZE / sizeof(struct vmemmap_backing); + } + + num_left--; + + return next++; +} + +static __meminit void vmemmap_list_populate(unsigned long phys, + unsigned long start, + int node) +{ + struct vmemmap_backing *vmem_back; + + vmem_back = vmemmap_list_alloc(node); + if (unlikely(!vmem_back)) { + WARN_ON(1); + return; + } + + vmem_back->phys = phys; + vmem_back->virt_addr = start; + vmem_back->list = vmemmap_list; + + vmemmap_list = vmem_back; +} + int __meminit vmemmap_populate(struct page *start_page, unsigned long nr_pages, int node) { @@ -276,6 +317,8 @@ int __meminit vmemmap_populate(struct page *start_page, if (!p) return -ENOMEM; + vmemmap_list_populate(__pa(p), start, node); + pr_debug(" * %016lx..%016lx allocated at %p\n", start, start + page_size, p); -- cgit v1.2.3-59-g8ed1b From e460c2c91af44374cbfa3f1c70f5ca9bbf099aa9 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 6 May 2010 17:15:58 +1000 Subject: powerpc: Invoke oom-killer from page fault As explained in commit 1c0fe6e3bd, we want to call the architecture independent oom killer when getting an unexplained OOM from handle_mm_fault, rather than simply killing current. Cc: linuxppc-dev@ozlabs.org Cc: Benjamin Herrenschmidt Cc: linux-arch@vger.kernel.org Signed-off-by: Nick Piggin Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/fault.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 83ac4935eb10..1bd712c33ce2 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -308,7 +308,6 @@ good_area: * make sure we exit gracefully rather than endlessly redo * the fault. */ - survive: ret = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); if (unlikely(ret & VM_FAULT_ERROR)) { if (ret & VM_FAULT_OOM) @@ -360,15 +359,10 @@ bad_area_nosemaphore: */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { - yield(); - down_read(&mm->mmap_sem); - goto survive; - } - printk("VM: killing process %s\n", current->comm); - if (user_mode(regs)) - do_group_exit(SIGKILL); - return SIGKILL; + if (!user_mode(regs)) + return SIGKILL; + pagefault_out_of_memory(); + return 0; do_sigbus: up_read(&mm->mmap_sem); -- cgit v1.2.3-59-g8ed1b From 1b095cf4029f43db363981c0e5f02216e495ac9f Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:32 +0000 Subject: powerpc/cpumask: Use cpu_online_mask Change &cpu_online_map to cpu_online_mask. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pasemi/cpufreq.c | 2 +- arch/powerpc/platforms/powermac/cpufreq_64.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c index d35e0520abf0..c16537bc0c6e 100644 --- a/arch/powerpc/platforms/pasemi/cpufreq.c +++ b/arch/powerpc/platforms/pasemi/cpufreq.c @@ -213,7 +213,7 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) pr_debug("current astate is at %d\n",cur_astate); policy->cur = pas_freqs[cur_astate].frequency; - cpumask_copy(policy->cpus, &cpu_online_map); + cpumask_copy(policy->cpus, cpu_online_mask); ppc_proc_freq = policy->cur * 1000ul; diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c index 3ca09d3ccce3..9650c6029c82 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -362,7 +362,7 @@ static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) /* secondary CPUs are tied to the primary one by the * cpufreq core if in the secondary policy we tell it that * it actually must be one policy together with all others. */ - cpumask_copy(policy->cpus, &cpu_online_map); + cpumask_copy(policy->cpus, cpu_online_mask); cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu); return cpufreq_frequency_table_cpuinfo(policy, -- cgit v1.2.3-59-g8ed1b From d5f86fe3457f48f27eecd40c605e7876d026af7c Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:33 +0000 Subject: powerpc/cpumask: Convert rtasd to new cpumask API Use cpumask_first, cpumask_next in rtasd code. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/rtasd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 4190eae7850a..e907ca66f75a 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -411,9 +411,9 @@ static void rtas_event_scan(struct work_struct *w) get_online_cpus(); - cpu = next_cpu(smp_processor_id(), cpu_online_map); - if (cpu == NR_CPUS) { - cpu = first_cpu(cpu_online_map); + cpu = cpumask_next(smp_processor_id(), cpu_online_mask); + if (cpu >= nr_cpu_ids) { + cpu = cpumask_first(cpu_online_mask); if (first_pass) { first_pass = 0; @@ -466,8 +466,8 @@ static void start_event_scan(void) /* Retreive errors from nvram if any */ retreive_nvram_error_log(); - schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work, - event_scan_delay); + schedule_delayed_work_on(cpumask_first(cpu_online_mask), + &event_scan_work, event_scan_delay); } static int __init rtas_init(void) -- cgit v1.2.3-59-g8ed1b From bfb9126defa80cbed6d91ed9685b238b0d7e81c4 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:34 +0000 Subject: powerpc/cpumask: Convert smp_cpus_done to new cpumask API Use the new cpumask_* functions and dynamically allocate the cpumask in smp_cpus_done. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/smp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 3fe4de2b685e..17523a0abf66 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -562,19 +562,22 @@ int setup_profiling_timer(unsigned int multiplier) void __init smp_cpus_done(unsigned int max_cpus) { - cpumask_t old_mask; + cpumask_var_t old_mask; /* We want the setup_cpu() here to be called from CPU 0, but our * init thread may have been "borrowed" by another CPU in the meantime * se we pin us down to CPU 0 for a short while */ - old_mask = current->cpus_allowed; + alloc_cpumask_var(&old_mask, GFP_NOWAIT); + cpumask_copy(old_mask, ¤t->cpus_allowed); set_cpus_allowed_ptr(current, cpumask_of(boot_cpuid)); if (smp_ops && smp_ops->setup_cpu) smp_ops->setup_cpu(boot_cpuid); - set_cpus_allowed_ptr(current, &old_mask); + set_cpus_allowed_ptr(current, old_mask); + + free_cpumask_var(old_mask); snapshot_timebases(); -- cgit v1.2.3-59-g8ed1b From b6decb707952c678d110699abb5ed86d45ca6927 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:35 +0000 Subject: powerpc/cpumask: Convert fixup_irqs to new cpumask API Use new cpumask_* functions, and dynamically allocate cpumask in fixup_irqs. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/smp.h | 2 +- arch/powerpc/kernel/irq.c | 17 ++++++++++------- arch/powerpc/kernel/smp.c | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 1d3b270d3083..4d332296c40d 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -40,7 +40,7 @@ extern void smp_message_recv(int); DECLARE_PER_CPU(unsigned int, cpu_pvr); #ifdef CONFIG_HOTPLUG_CPU -extern void fixup_irqs(cpumask_t map); +extern void fixup_irqs(const struct cpumask *map); int generic_cpu_disable(void); int generic_cpu_enable(unsigned int cpu); void generic_cpu_die(unsigned int cpu); diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 64f6f2031c22..250ee2ebf288 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -290,30 +290,33 @@ u64 arch_irq_stat_cpu(unsigned int cpu) } #ifdef CONFIG_HOTPLUG_CPU -void fixup_irqs(cpumask_t map) +void fixup_irqs(const struct cpumask *map) { struct irq_desc *desc; unsigned int irq; static int warned; + cpumask_var_t mask; - for_each_irq(irq) { - cpumask_t mask; + alloc_cpumask_var(&mask, GFP_KERNEL); + for_each_irq(irq) { desc = irq_to_desc(irq); if (desc && desc->status & IRQ_PER_CPU) continue; - cpumask_and(&mask, desc->affinity, &map); - if (any_online_cpu(mask) == NR_CPUS) { + cpumask_and(mask, desc->affinity, map); + if (cpumask_any(mask) >= nr_cpu_ids) { printk("Breaking affinity for irq %i\n", irq); - mask = map; + cpumask_copy(mask, map); } if (desc->chip->set_affinity) - desc->chip->set_affinity(irq, &mask); + desc->chip->set_affinity(irq, mask); else if (desc->action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } + free_cpumask_var(mask); + local_irq_enable(); mdelay(1); local_irq_disable(); diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 17523a0abf66..62e82c25c583 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -313,7 +313,7 @@ int generic_cpu_disable(void) set_cpu_online(cpu, false); #ifdef CONFIG_PPC64 vdso_data->processorCount--; - fixup_irqs(cpu_online_map); + fixup_irqs(cpu_online_mask); #endif return 0; } @@ -333,7 +333,7 @@ int generic_cpu_enable(unsigned int cpu) cpu_relax(); #ifdef CONFIG_PPC64 - fixup_irqs(cpu_online_map); + fixup_irqs(cpu_online_mask); /* counter the irq disable in fixup_irqs */ local_irq_enable(); #endif -- cgit v1.2.3-59-g8ed1b From 115731312fb3207705023e3ff247d1b9d039838d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:36 +0000 Subject: powerpc/cpumask: Convert iseries SMP code to new cpumask API Use new cpumask functions in iseries SMP startup code. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/iseries/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c index 722335e32fd4..6590850045af 100644 --- a/arch/powerpc/platforms/iseries/smp.c +++ b/arch/powerpc/platforms/iseries/smp.c @@ -83,7 +83,7 @@ static void smp_iSeries_message_pass(int target, int msg) static int smp_iSeries_probe(void) { - return cpus_weight(cpu_possible_map); + return cpumask_weight(cpu_possible_mask); } static void smp_iSeries_kick_cpu(int nr) -- cgit v1.2.3-59-g8ed1b From af831e1e44619a7429eba8ece4eba8f977ee7c4f Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:37 +0000 Subject: powerpc/cpumask: Convert pseries SMP code to new cpumask API Use new cpumask functions in pseries SMP startup code. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/smp.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 8979982eb2ee..3b1bf61c45be 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -55,7 +55,7 @@ * The Primary thread of each non-boot processor was started from the OF client * interface by prom_hold_cpus and is spinning on secondary_hold_spinloop. */ -static cpumask_t of_spin_map; +static cpumask_var_t of_spin_mask; /* Query where a cpu is now. Return codes #defined in plpar_wrappers.h */ int smp_query_cpu_stopped(unsigned int pcpu) @@ -98,7 +98,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) unsigned int pcpu; int start_cpu; - if (cpu_isset(lcpu, of_spin_map)) + if (cpumask_test_cpu(lcpu, of_spin_mask)) /* Already started by OF and sitting in spin loop */ return 1; @@ -106,7 +106,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) /* Check to see if the CPU out of FW already for kexec */ if (smp_query_cpu_stopped(pcpu) == QCSS_NOT_STOPPED){ - cpu_set(lcpu, of_spin_map); + cpumask_set_cpu(lcpu, of_spin_mask); return 1; } @@ -143,7 +143,7 @@ static void __devinit smp_xics_setup_cpu(int cpu) if (firmware_has_feature(FW_FEATURE_SPLPAR)) vpa_init(cpu); - cpu_clear(cpu, of_spin_map); + cpumask_clear_cpu(cpu, of_spin_mask); set_cpu_current_state(cpu, CPU_STATE_ONLINE); set_default_offline_state(cpu); @@ -214,17 +214,19 @@ static void __init smp_init_pseries(void) pr_debug(" -> smp_init_pSeries()\n"); + alloc_bootmem_cpumask_var(&of_spin_mask); + /* Mark threads which are still spinning in hold loops. */ if (cpu_has_feature(CPU_FTR_SMT)) { for_each_present_cpu(i) { if (cpu_thread_in_core(i) == 0) - cpu_set(i, of_spin_map); + cpumask_set_cpu(i, of_spin_mask); } } else { - of_spin_map = cpu_present_map; + cpumask_copy(of_spin_mask, cpu_present_mask); } - cpu_clear(boot_cpuid, of_spin_map); + cpumask_clear_cpu(boot_cpuid, of_spin_mask); /* Non-lpar has additional take/give timebase */ if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { -- cgit v1.2.3-59-g8ed1b From 64fe220c13440a12d0bd8e32ebdf679e869e3ce3 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:38 +0000 Subject: powerpc/cpumask: Convert xics driver to new cpumask API Use the new cpumask API and add some comments to clarify how get_irq_server works. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/xics.c | 38 +++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 1bcedd8b4616..f19d19468393 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -163,29 +163,37 @@ static inline void lpar_qirr_info(int n_cpu , u8 value) /* Interface to generic irq subsystem */ #ifdef CONFIG_SMP -static int get_irq_server(unsigned int virq, cpumask_t cpumask, +/* + * For the moment we only implement delivery to all cpus or one cpu. + * + * If the requested affinity is cpu_all_mask, we set global affinity. + * If not we set it to the first cpu in the mask, even if multiple cpus + * are set. This is so things like irqbalance (which set core and package + * wide affinities) do the right thing. + */ +static int get_irq_server(unsigned int virq, const struct cpumask *cpumask, unsigned int strict_check) { - int server; - /* For the moment only implement delivery to all cpus or one cpu */ - cpumask_t tmp = CPU_MASK_NONE; if (!distribute_irqs) return default_server; - if (!cpus_equal(cpumask, CPU_MASK_ALL)) { - cpus_and(tmp, cpu_online_map, cpumask); - - server = first_cpu(tmp); + if (!cpumask_equal(cpumask, cpu_all_mask)) { + int server = cpumask_first_and(cpu_online_mask, cpumask); - if (server < NR_CPUS) + if (server < nr_cpu_ids) return get_hard_smp_processor_id(server); if (strict_check) return -1; } - if (cpus_equal(cpu_online_map, cpu_present_map)) + /* + * Workaround issue with some versions of JS20 firmware that + * deliver interrupts to cpus which haven't been started. This + * happens when using the maxcpus= boot option. + */ + if (cpumask_equal(cpu_online_mask, cpu_present_mask)) return default_distrib_server; return default_server; @@ -207,7 +215,7 @@ static void xics_unmask_irq(unsigned int virq) if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) return; - server = get_irq_server(virq, *(irq_to_desc(virq)->affinity), 0); + server = get_irq_server(virq, irq_to_desc(virq)->affinity, 0); call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, DEFAULT_PRIORITY); @@ -398,11 +406,7 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask) return -1; } - /* - * For the moment only implement delivery to all cpus or one cpu. - * Get current irq_server for the given irq - */ - irq_server = get_irq_server(virq, *cpumask, 1); + irq_server = get_irq_server(virq, cpumask, 1); if (irq_server == -1) { char cpulist[128]; cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); @@ -611,7 +615,7 @@ int __init smp_xics_probe(void) { xics_request_ipi(); - return cpus_weight(cpu_possible_map); + return cpumask_weight(cpu_possible_mask); } #endif /* CONFIG_SMP */ -- cgit v1.2.3-59-g8ed1b From 2c2df038450cbf628426183c9efffc17cfea3406 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:39 +0000 Subject: powerpc/cpumask: Refactor /proc/cpuinfo code This separates the per cpu output from the summary output at the end of the file, making it easier to convert to the new cpumask API in a subsequent patch. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/setup-common.c | 62 ++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 48f0a008b20b..58699a43eaa2 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -161,6 +161,38 @@ extern u32 cpu_temp_both(unsigned long cpu); DEFINE_PER_CPU(unsigned int, cpu_pvr); #endif +static void show_cpuinfo_summary(struct seq_file *m) +{ + struct device_node *root; + const char *model = NULL; +#if defined(CONFIG_SMP) && defined(CONFIG_PPC32) + unsigned long bogosum = 0; + int i; + for_each_online_cpu(i) + bogosum += loops_per_jiffy; + seq_printf(m, "total bogomips\t: %lu.%02lu\n", + bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); +#endif /* CONFIG_SMP && CONFIG_PPC32 */ + seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); + if (ppc_md.name) + seq_printf(m, "platform\t: %s\n", ppc_md.name); + root = of_find_node_by_path("/"); + if (root) + model = of_get_property(root, "model", NULL); + if (model) + seq_printf(m, "model\t\t: %s\n", model); + of_node_put(root); + + if (ppc_md.show_cpuinfo != NULL) + ppc_md.show_cpuinfo(m); + +#ifdef CONFIG_PPC32 + /* Display the amount of memory */ + seq_printf(m, "Memory\t\t: %d MB\n", + (unsigned int)(total_memory / (1024 * 1024))); +#endif +} + static int show_cpuinfo(struct seq_file *m, void *v) { unsigned long cpu_id = (unsigned long)v - 1; @@ -169,35 +201,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) unsigned short min; if (cpu_id == NR_CPUS) { - struct device_node *root; - const char *model = NULL; -#if defined(CONFIG_SMP) && defined(CONFIG_PPC32) - unsigned long bogosum = 0; - int i; - for_each_online_cpu(i) - bogosum += loops_per_jiffy; - seq_printf(m, "total bogomips\t: %lu.%02lu\n", - bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); -#endif /* CONFIG_SMP && CONFIG_PPC32 */ - seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); - if (ppc_md.name) - seq_printf(m, "platform\t: %s\n", ppc_md.name); - root = of_find_node_by_path("/"); - if (root) - model = of_get_property(root, "model", NULL); - if (model) - seq_printf(m, "model\t\t: %s\n", model); - of_node_put(root); - - if (ppc_md.show_cpuinfo != NULL) - ppc_md.show_cpuinfo(m); - -#ifdef CONFIG_PPC32 - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", - (unsigned int)(total_memory / (1024 * 1024))); -#endif - + show_cpuinfo_summary(m); return 0; } -- cgit v1.2.3-59-g8ed1b From e6532c63cc3dbefc79936fc9c9c68a151004fe46 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:40 +0000 Subject: powerpc/cpumask: Convert /proc/cpuinfo to new cpumask API Use new cpumask API in /proc/cpuinfo code. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/setup-common.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 58699a43eaa2..8dcec47a7b39 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -200,11 +200,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) unsigned short maj; unsigned short min; - if (cpu_id == NR_CPUS) { - show_cpuinfo_summary(m); - return 0; - } - /* We only show online cpus: disable preempt (overzealous, I * knew) to prevent cpu going down. */ preempt_disable(); @@ -312,19 +307,28 @@ static int show_cpuinfo(struct seq_file *m, void *v) #endif preempt_enable(); + + /* If this is the last cpu, print the summary */ + if (cpumask_next(cpu_id, cpu_online_mask) >= nr_cpu_ids) + show_cpuinfo_summary(m); + return 0; } static void *c_start(struct seq_file *m, loff_t *pos) { - unsigned long i = *pos; - - return i <= NR_CPUS ? (void *)(i + 1) : NULL; + if (*pos == 0) /* just in case, cpu 0 is not the first */ + *pos = cpumask_first(cpu_online_mask); + else + *pos = cpumask_next(*pos - 1, cpu_online_mask); + if ((*pos) < nr_cpu_ids) + return (void *)(unsigned long)(*pos + 1); + return NULL; } static void *c_next(struct seq_file *m, void *v, loff_t *pos) { - ++*pos; + (*pos)++; return c_start(m, pos); } -- cgit v1.2.3-59-g8ed1b From cc1ba8ea6dde3f049b2b365d8fdc13976aee25cb Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:41 +0000 Subject: powerpc/cpumask: Dynamically allocate cpu_sibling_map and cpu_core_map cpumasks Dynamically allocate cpu_sibling_map and cpu_core_map cpumasks. We don't need to set_cpu_online() the boot cpu in smp_prepare_boot_cpu, init/main.c does it for us. We also postpone setting of the boot cpu in cpu_sibling_map and cpu_core_map until when the memory allocator is available (smp_prepare_cpus), similar to x86. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/smp.h | 16 +++++++++--- arch/powerpc/include/asm/topology.h | 4 +-- arch/powerpc/kernel/smp.c | 42 ++++++++++++++++++------------- arch/powerpc/platforms/cell/cbe_cpufreq.c | 2 +- 4 files changed, 40 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 4d332296c40d..66e237bbe15f 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -68,8 +68,19 @@ static inline void set_hard_smp_processor_id(int cpu, int phys) } #endif -DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); -DECLARE_PER_CPU(cpumask_t, cpu_core_map); +DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map); +DECLARE_PER_CPU(cpumask_var_t, cpu_core_map); + +static inline struct cpumask *cpu_sibling_mask(int cpu) +{ + return per_cpu(cpu_sibling_map, cpu); +} + +static inline struct cpumask *cpu_core_mask(int cpu) +{ + return per_cpu(cpu_core_map, cpu); +} + extern int cpu_to_core_id(int cpu); /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. @@ -93,7 +104,6 @@ void smp_init_pSeries(void); void smp_init_cell(void); void smp_init_celleb(void); void smp_setup_cpu_maps(void); -void smp_setup_cpu_sibling_map(void); extern int __cpu_disable(void); extern void __cpu_die(unsigned int cpu); diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index a7d769491555..789599b69960 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -112,8 +112,8 @@ static inline void sysfs_remove_device_from_node(struct sys_device *dev, #ifdef CONFIG_PPC64 #include -#define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) -#define topology_core_cpumask(cpu) (&per_cpu(cpu_core_map, cpu)) +#define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) +#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) #define topology_core_id(cpu) (cpu_to_core_id(cpu)) #endif #endif diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 62e82c25c583..39babb1e2ce1 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -59,8 +59,8 @@ struct thread_info *secondary_ti; -DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE; -DEFINE_PER_CPU(cpumask_t, cpu_core_map) = CPU_MASK_NONE; +DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); +DEFINE_PER_CPU(cpumask_var_t, cpu_core_map); EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); EXPORT_PER_CPU_SYMBOL(cpu_core_map); @@ -271,6 +271,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_store_cpu_info(boot_cpuid); cpu_callin_map[boot_cpuid] = 1; + for_each_possible_cpu(cpu) { + zalloc_cpumask_var_node(&per_cpu(cpu_sibling_map, cpu), + GFP_KERNEL, cpu_to_node(cpu)); + zalloc_cpumask_var_node(&per_cpu(cpu_core_map, cpu), + GFP_KERNEL, cpu_to_node(cpu)); + } + + cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid)); + cpumask_set_cpu(boot_cpuid, cpu_core_mask(boot_cpuid)); + if (smp_ops) if (smp_ops->probe) max_cpus = smp_ops->probe(); @@ -289,10 +299,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) void __devinit smp_prepare_boot_cpu(void) { BUG_ON(smp_processor_id() != boot_cpuid); - - set_cpu_online(boot_cpuid, true); - cpu_set(boot_cpuid, per_cpu(cpu_sibling_map, boot_cpuid)); - cpu_set(boot_cpuid, per_cpu(cpu_core_map, boot_cpuid)); #ifdef CONFIG_PPC64 paca[boot_cpuid].__current = current; #endif @@ -525,15 +531,15 @@ int __devinit start_secondary(void *unused) for (i = 0; i < threads_per_core; i++) { if (cpu_is_offline(base + i)) continue; - cpu_set(cpu, per_cpu(cpu_sibling_map, base + i)); - cpu_set(base + i, per_cpu(cpu_sibling_map, cpu)); + cpumask_set_cpu(cpu, cpu_sibling_mask(base + i)); + cpumask_set_cpu(base + i, cpu_sibling_mask(cpu)); /* cpu_core_map should be a superset of * cpu_sibling_map even if we don't have cache * information, so update the former here, too. */ - cpu_set(cpu, per_cpu(cpu_core_map, base +i)); - cpu_set(base + i, per_cpu(cpu_core_map, cpu)); + cpumask_set_cpu(cpu, cpu_core_mask(base + i)); + cpumask_set_cpu(base + i, cpu_core_mask(cpu)); } l2_cache = cpu_to_l2cache(cpu); for_each_online_cpu(i) { @@ -541,8 +547,8 @@ int __devinit start_secondary(void *unused) if (!np) continue; if (np == l2_cache) { - cpu_set(cpu, per_cpu(cpu_core_map, i)); - cpu_set(i, per_cpu(cpu_core_map, cpu)); + cpumask_set_cpu(cpu, cpu_core_mask(i)); + cpumask_set_cpu(i, cpu_core_mask(cpu)); } of_node_put(np); } @@ -602,10 +608,10 @@ int __cpu_disable(void) /* Update sibling maps */ base = cpu_first_thread_in_core(cpu); for (i = 0; i < threads_per_core; i++) { - cpu_clear(cpu, per_cpu(cpu_sibling_map, base + i)); - cpu_clear(base + i, per_cpu(cpu_sibling_map, cpu)); - cpu_clear(cpu, per_cpu(cpu_core_map, base +i)); - cpu_clear(base + i, per_cpu(cpu_core_map, cpu)); + cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i)); + cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu)); + cpumask_clear_cpu(cpu, cpu_core_mask(base + i)); + cpumask_clear_cpu(base + i, cpu_core_mask(cpu)); } l2_cache = cpu_to_l2cache(cpu); @@ -614,8 +620,8 @@ int __cpu_disable(void) if (!np) continue; if (np == l2_cache) { - cpu_clear(cpu, per_cpu(cpu_core_map, i)); - cpu_clear(i, per_cpu(cpu_core_map, cpu)); + cpumask_clear_cpu(cpu, cpu_core_mask(i)); + cpumask_clear_cpu(i, cpu_core_mask(cpu)); } of_node_put(np); } diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c index e6506cd0ff94..bfa2c0cb3d1e 100644 --- a/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c @@ -118,7 +118,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cur = cbe_freqs[cur_pmode].frequency; #ifdef CONFIG_SMP - cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu)); + cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); #endif cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); -- cgit v1.2.3-59-g8ed1b From 8729faaa5e87557876c02f1665d517e2b41299f1 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:42 +0000 Subject: powerpc/cpumask: Convert hotplug-cpu code to new cpumask API Convert hotplug-cpu code to new cpumask API. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 33 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index b0760d7701b4..235f363f732d 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -163,7 +163,7 @@ static int pseries_cpu_disable(void) /*fix boot_cpuid here*/ if (cpu == boot_cpuid) - boot_cpuid = any_online_cpu(cpu_online_map); + boot_cpuid = cpumask_any(cpu_online_mask); /* FIXME: abstract this to not be platform specific later on */ xics_migrate_irqs_away(); @@ -231,7 +231,7 @@ static void pseries_cpu_die(unsigned int cpu) static int pseries_add_processor(struct device_node *np) { unsigned int cpu; - cpumask_t candidate_map, tmp = CPU_MASK_NONE; + cpumask_var_t candidate_mask, tmp; int err = -ENOSPC, len, nthreads, i; const u32 *intserv; @@ -239,48 +239,53 @@ static int pseries_add_processor(struct device_node *np) if (!intserv) return 0; + zalloc_cpumask_var(&candidate_mask, GFP_KERNEL); + zalloc_cpumask_var(&tmp, GFP_KERNEL); + nthreads = len / sizeof(u32); for (i = 0; i < nthreads; i++) - cpu_set(i, tmp); + cpumask_set_cpu(i, tmp); cpu_maps_update_begin(); - BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map)); + BUG_ON(!cpumask_subset(cpu_present_mask, cpu_possible_mask)); /* Get a bitmap of unoccupied slots. */ - cpus_xor(candidate_map, cpu_possible_map, cpu_present_map); - if (cpus_empty(candidate_map)) { + cpumask_xor(candidate_mask, cpu_possible_mask, cpu_present_mask); + if (cpumask_empty(candidate_mask)) { /* If we get here, it most likely means that NR_CPUS is * less than the partition's max processors setting. */ printk(KERN_ERR "Cannot add cpu %s; this system configuration" " supports %d logical cpus.\n", np->full_name, - cpus_weight(cpu_possible_map)); + cpumask_weight(cpu_possible_mask)); goto out_unlock; } - while (!cpus_empty(tmp)) - if (cpus_subset(tmp, candidate_map)) + while (!cpumask_empty(tmp)) + if (cpumask_subset(tmp, candidate_mask)) /* Found a range where we can insert the new cpu(s) */ break; else - cpus_shift_left(tmp, tmp, nthreads); + cpumask_shift_left(tmp, tmp, nthreads); - if (cpus_empty(tmp)) { + if (cpumask_empty(tmp)) { printk(KERN_ERR "Unable to find space in cpu_present_map for" " processor %s with %d thread(s)\n", np->name, nthreads); goto out_unlock; } - for_each_cpu_mask(cpu, tmp) { - BUG_ON(cpu_isset(cpu, cpu_present_map)); + for_each_cpu(cpu, tmp) { + BUG_ON(cpumask_test_cpu(cpu, cpu_present_mask)); set_cpu_present(cpu, true); set_hard_smp_processor_id(cpu, *intserv++); } err = 0; out_unlock: cpu_maps_update_done(); + free_cpumask_var(candidate_mask); + free_cpumask_var(tmp); return err; } @@ -311,7 +316,7 @@ static void pseries_remove_processor(struct device_node *np) set_hard_smp_processor_id(cpu, -1); break; } - if (cpu == NR_CPUS) + if (cpu >= nr_cpu_ids) printk(KERN_WARNING "Could not find cpu to remove " "with physical id 0x%x\n", intserv[i]); } -- cgit v1.2.3-59-g8ed1b From 25863de07af9cb90e6365cc8216bdd17f2394515 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:43 +0000 Subject: powerpc/cpumask: Convert NUMA code to new cpumask API Convert NUMA code to new cpumask API. We shift the node to cpumask setup code until after we complete bootmem allocation so we can dynamically allocate the cpumasks. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/mmzone.h | 2 +- arch/powerpc/include/asm/topology.h | 2 +- arch/powerpc/mm/numa.c | 58 ++++++++++++++++++++++++++++--------- 3 files changed, 47 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/mmzone.h b/arch/powerpc/include/asm/mmzone.h index 35acac90c8ca..aac87cbceb57 100644 --- a/arch/powerpc/include/asm/mmzone.h +++ b/arch/powerpc/include/asm/mmzone.h @@ -30,7 +30,7 @@ extern struct pglist_data *node_data[]; */ extern int numa_cpu_lookup_table[]; -extern cpumask_t numa_cpumask_lookup_table[]; +extern cpumask_var_t node_to_cpumask_map[]; #ifdef CONFIG_MEMORY_HOTPLUG extern unsigned long max_pfn; #endif diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 789599b69960..84ad11f65dc2 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -29,7 +29,7 @@ static inline int cpu_to_node(int cpu) #define cpumask_of_node(node) ((node) == -1 ? \ cpu_all_mask : \ - &numa_cpumask_lookup_table[node]) + node_to_cpumask_map[node]) int of_node_to_nid(struct device_node *device); diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 64c00227b997..d68491b31e38 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -33,16 +33,41 @@ static int numa_debug; #define dbg(args...) if (numa_debug) { printk(KERN_INFO args); } int numa_cpu_lookup_table[NR_CPUS]; -cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES]; +cpumask_var_t node_to_cpumask_map[MAX_NUMNODES]; struct pglist_data *node_data[MAX_NUMNODES]; EXPORT_SYMBOL(numa_cpu_lookup_table); -EXPORT_SYMBOL(numa_cpumask_lookup_table); +EXPORT_SYMBOL(node_to_cpumask_map); EXPORT_SYMBOL(node_data); static int min_common_depth; static int n_mem_addr_cells, n_mem_size_cells; +/* + * Allocate node_to_cpumask_map based on number of available nodes + * Requires node_possible_map to be valid. + * + * Note: node_to_cpumask() is not valid until after this is done. + */ +static void __init setup_node_to_cpumask_map(void) +{ + unsigned int node, num = 0; + + /* setup nr_node_ids if not done yet */ + if (nr_node_ids == MAX_NUMNODES) { + for_each_node_mask(node, node_possible_map) + num = node; + nr_node_ids = num + 1; + } + + /* allocate the map */ + for (node = 0; node < nr_node_ids; node++) + alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]); + + /* cpumask_of_node() will now work */ + dbg("Node to cpumask map for %d nodes\n", nr_node_ids); +} + static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn, unsigned int *nid) { @@ -138,8 +163,8 @@ static void __cpuinit map_cpu_to_node(int cpu, int node) dbg("adding cpu %d to node %d\n", cpu, node); - if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node]))) - cpu_set(cpu, numa_cpumask_lookup_table[node]); + if (!(cpumask_test_cpu(cpu, node_to_cpumask_map[node]))) + cpumask_set_cpu(cpu, node_to_cpumask_map[node]); } #ifdef CONFIG_HOTPLUG_CPU @@ -149,8 +174,8 @@ static void unmap_cpu_from_node(unsigned long cpu) dbg("removing cpu %lu from node %d\n", cpu, node); - if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) { - cpu_clear(cpu, numa_cpumask_lookup_table[node]); + if (cpumask_test_cpu(cpu, node_to_cpumask_map[node])) { + cpumask_set_cpu(cpu, node_to_cpumask_map[node]); } else { printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n", cpu, node); @@ -737,8 +762,9 @@ void __init dump_numa_cpu_topology(void) * If we used a CPU iterator here we would miss printing * the holes in the cpumap. */ - for (cpu = 0; cpu < NR_CPUS; cpu++) { - if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) { + for (cpu = 0; cpu < nr_cpu_ids; cpu++) { + if (cpumask_test_cpu(cpu, + node_to_cpumask_map[node])) { if (count == 0) printk(" %u", cpu); ++count; @@ -750,7 +776,7 @@ void __init dump_numa_cpu_topology(void) } if (count > 1) - printk("-%u", NR_CPUS - 1); + printk("-%u", nr_cpu_ids - 1); printk("\n"); } } @@ -926,10 +952,6 @@ void __init do_init_bootmem(void) else dump_numa_memory_topology(); - register_cpu_notifier(&ppc64_numa_nb); - cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE, - (void *)(unsigned long)boot_cpuid); - for_each_online_node(nid) { unsigned long start_pfn, end_pfn; void *bootmem_vaddr; @@ -983,6 +1005,16 @@ void __init do_init_bootmem(void) } init_bootmem_done = 1; + + /* + * Now bootmem is initialised we can create the node to cpumask + * lookup tables and setup the cpu callback to populate them. + */ + setup_node_to_cpumask_map(); + + register_cpu_notifier(&ppc64_numa_nb); + cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE, + (void *)(unsigned long)boot_cpuid); } void __init paging_init(void) -- cgit v1.2.3-59-g8ed1b From 828a69869ba266cabb486a6b59ea8643d56b33ce Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:44 +0000 Subject: powerpc/cpumask: Update some comments Since the *_map cpumask variants are deprecated, change the comments to instead refer to *_mask. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/setup-common.c | 6 +++--- arch/powerpc/kernel/smp.c | 2 +- arch/powerpc/platforms/powermac/setup.c | 2 +- arch/powerpc/platforms/powermac/smp.c | 4 ++-- arch/powerpc/platforms/pseries/hotplug-cpu.c | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 8dcec47a7b39..5e4d852f640c 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -394,14 +394,14 @@ static void __init cpu_init_thread_core_maps(int tpc) /** * setup_cpu_maps - initialize the following cpu maps: - * cpu_possible_map - * cpu_present_map + * cpu_possible_mask + * cpu_present_mask * * Having the possible map set up early allows us to restrict allocations * of things like irqstacks to num_possible_cpus() rather than NR_CPUS. * * We do not initialize the online map here; cpus set their own bits in - * cpu_online_map as they come up. + * cpu_online_mask as they come up. * * This function is valid only for Open Firmware systems. finish_device_tree * must be called before using this. diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 39babb1e2ce1..bf366167d369 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -468,7 +468,7 @@ out: return id; } -/* Must be called when no change can occur to cpu_present_map, +/* Must be called when no change can occur to cpu_present_mask, * i.e. during cpu online or offline. */ static struct device_node *cpu_to_l2cache(int cpu) diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 15c2241f9c72..47a2b4488557 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -480,7 +480,7 @@ static void __init pmac_init_early(void) #endif /* SMP Init has to be done early as we need to patch up - * cpu_possible_map before interrupt stacks are allocated + * cpu_possible_mask before interrupt stacks are allocated * or kaboom... */ #ifdef CONFIG_SMP diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 6898e8241cd0..02d0b8e5b13c 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -315,7 +315,7 @@ static int __init smp_psurge_probe(void) /* This is necessary because OF doesn't know about the * secondary cpu(s), and thus there aren't nodes in the * device tree for them, and smp_setup_cpu_maps hasn't - * set their bits in cpu_present_map. + * set their bits in cpu_present_mask. */ if (ncpus > NR_CPUS) ncpus = NR_CPUS; @@ -944,7 +944,7 @@ void __init pmac_setup_smp(void) } #ifdef CONFIG_PPC32 else { - /* We have to set bits in cpu_possible_map here since the + /* We have to set bits in cpu_possible_mask here since the * secondary CPU(s) aren't in the device tree. Various * things won't be initialized for CPUs not in the possible * map, so we really need to fix it up here. diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 235f363f732d..8f85f399ab9f 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -222,7 +222,7 @@ static void pseries_cpu_die(unsigned int cpu) } /* - * Update cpu_present_map and paca(s) for a new cpu node. The wrinkle + * Update cpu_present_mask and paca(s) for a new cpu node. The wrinkle * here is that a cpu device node may represent up to two logical cpus * in the SMT case. We must honor the assumption in other code that * the logical ids for sibling SMT threads x and y are adjacent, such @@ -270,7 +270,7 @@ static int pseries_add_processor(struct device_node *np) cpumask_shift_left(tmp, tmp, nthreads); if (cpumask_empty(tmp)) { - printk(KERN_ERR "Unable to find space in cpu_present_map for" + printk(KERN_ERR "Unable to find space in cpu_present_mask for" " processor %s with %d thread(s)\n", np->name, nthreads); goto out_unlock; -- cgit v1.2.3-59-g8ed1b From 2ef613cb94556ff69860f6bf004298f4e131c216 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 6 May 2010 18:01:46 +1000 Subject: powerpc/cpumask: Convert mpic driver to new cpumask API Convert to the new cpumask API. irq_choose_cpu can be simplified by using cpumask_next and cpumask_first. smp_mpic_message_pass was doing open coded cpumask manipulation and passing an int for a cpumask into mpic_send_ipi. Since mpic_send_ipi is only used locally, make it static and convert it to take a cpumask. This allows us to clean up the mess in smp_mpic_message_pass. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/mpic.h | 3 -- arch/powerpc/sysdev/mpic.c | 72 ++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index 61913d9a21a0..e000cce8f6dd 100644 --- a/arch/powerpc/include/asm/mpic.h +++ b/arch/powerpc/include/asm/mpic.h @@ -463,9 +463,6 @@ extern void mpic_cpu_set_priority(int prio); /* Request IPIs on primary mpic */ extern void mpic_request_ipis(void); -/* Send an IPI (non offseted number 0..3) */ -extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask); - /* Send a message (IPI) to a given target (cpu number or MSG_*) */ void smp_mpic_message_pass(int target, int msg); diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 260295b10557..2102487612a4 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -568,12 +568,12 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) #endif /* CONFIG_MPIC_U3_HT_IRQS */ #ifdef CONFIG_SMP -static int irq_choose_cpu(const cpumask_t *mask) +static int irq_choose_cpu(const struct cpumask *mask) { int cpuid; if (cpumask_equal(mask, cpu_all_mask)) { - static int irq_rover; + static int irq_rover = 0; static DEFINE_RAW_SPINLOCK(irq_rover_lock); unsigned long flags; @@ -581,15 +581,11 @@ static int irq_choose_cpu(const cpumask_t *mask) do_round_robin: raw_spin_lock_irqsave(&irq_rover_lock, flags); - while (!cpu_online(irq_rover)) { - if (++irq_rover >= NR_CPUS) - irq_rover = 0; - } + irq_rover = cpumask_next(irq_rover, cpu_online_mask); + if (irq_rover >= nr_cpu_ids) + irq_rover = cpumask_first(cpu_online_mask); + cpuid = irq_rover; - do { - if (++irq_rover >= NR_CPUS) - irq_rover = 0; - } while (!cpu_online(irq_rover)); raw_spin_unlock_irqrestore(&irq_rover_lock, flags); } else { @@ -601,7 +597,7 @@ static int irq_choose_cpu(const cpumask_t *mask) return get_hard_smp_processor_id(cpuid); } #else -static int irq_choose_cpu(const cpumask_t *mask) +static int irq_choose_cpu(const struct cpumask *mask) { return hard_smp_processor_id(); } @@ -814,12 +810,16 @@ int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask) mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid); } else { - cpumask_t tmp; + cpumask_var_t tmp; - cpumask_and(&tmp, cpumask, cpu_online_mask); + alloc_cpumask_var(&tmp, GFP_KERNEL); + + cpumask_and(tmp, cpumask, cpu_online_mask); mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), - mpic_physmask(cpus_addr(tmp)[0])); + mpic_physmask(cpumask_bits(tmp)[0])); + + free_cpumask_var(tmp); } return 0; @@ -1479,21 +1479,6 @@ void mpic_teardown_this_cpu(int secondary) } -void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) -{ - struct mpic *mpic = mpic_primary; - - BUG_ON(mpic == NULL); - -#ifdef DEBUG_IPI - DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); -#endif - - mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) + - ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), - mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); -} - static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg) { u32 src; @@ -1589,8 +1574,25 @@ void mpic_request_ipis(void) } } +static void mpic_send_ipi(unsigned int ipi_no, const struct cpumask *cpu_mask) +{ + struct mpic *mpic = mpic_primary; + + BUG_ON(mpic == NULL); + +#ifdef DEBUG_IPI + DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); +#endif + + mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) + + ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), + mpic_physmask(cpumask_bits(cpu_mask)[0])); +} + void smp_mpic_message_pass(int target, int msg) { + cpumask_var_t tmp; + /* make sure we're sending something that translates to an IPI */ if ((unsigned int)msg > 3) { printk("SMP %d: smp_message_pass: unknown msg %d\n", @@ -1599,13 +1601,17 @@ void smp_mpic_message_pass(int target, int msg) } switch (target) { case MSG_ALL: - mpic_send_ipi(msg, 0xffffffff); + mpic_send_ipi(msg, cpu_online_mask); break; case MSG_ALL_BUT_SELF: - mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id())); + alloc_cpumask_var(&tmp, GFP_NOWAIT); + cpumask_andnot(tmp, cpu_online_mask, + cpumask_of(smp_processor_id())); + mpic_send_ipi(msg, tmp); + free_cpumask_var(tmp); break; default: - mpic_send_ipi(msg, 1 << target); + mpic_send_ipi(msg, cpumask_of(target)); break; } } @@ -1616,7 +1622,7 @@ int __init smp_mpic_probe(void) DBG("smp_mpic_probe()...\n"); - nr_cpus = cpus_weight(cpu_possible_map); + nr_cpus = cpumask_weight(cpu_possible_mask); DBG("nr_cpus: %d\n", nr_cpus); -- cgit v1.2.3-59-g8ed1b From ceba1abcb00b0ef0b1efcd715285f6e05523edef Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 26 Apr 2010 15:32:46 +0000 Subject: powerpc/cpumask: Add DEBUG_PER_CPU_MAPS option Enable the DEBUG_PER_CPU_MAPS option so we can look for problems with cpumasks . Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/Kconfig.debug | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 5cdd7ed9a12e..53696da4518f 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -44,6 +44,18 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. +config DEBUG_PER_CPU_MAPS + bool "Debug access to per_cpu maps" + depends on DEBUG_KERNEL + depends on SMP + default n + ---help--- + Say Y to verify that the per_cpu map being accessed has + been setup. Adds a fair amount of code to kernel memory + and decreases performance. + + Say N if unsure. + config HCALL_STATS bool "Hypervisor call instrumentation" depends on PPC_PSERIES && DEBUG_FS && TRACEPOINTS -- cgit v1.2.3-59-g8ed1b From 3de668ee8d5b1e08da3200f926ff5a28aeb99bc2 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 3 May 2010 15:00:25 +0200 Subject: oprofile/x86: notify cpus only when daemon is running This patch moves the cpu notifier registration from nmi_init() to nmi_setup(). The corresponding unregistration function is now in nmi_shutdown(). Thus, the hotplug code is only active, if the oprofile daemon is running. Cc: Andi Kleen Signed-off-by: Robert Richter --- arch/x86/oprofile/nmi_int.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 7de0572b0a5e..2a086726cad1 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -504,6 +504,7 @@ static int nmi_setup(void) goto fail; get_online_cpus(); + register_cpu_notifier(&oprofile_cpu_nb); on_each_cpu(nmi_cpu_setup, NULL, 1); nmi_enabled = 1; put_online_cpus(); @@ -519,6 +520,7 @@ static void nmi_shutdown(void) struct op_msrs *msrs; get_online_cpus(); + unregister_cpu_notifier(&oprofile_cpu_nb); on_each_cpu(nmi_cpu_shutdown, NULL, 1); nmi_enabled = 0; ctr_running = 0; @@ -739,12 +741,6 @@ int __init op_nmi_init(struct oprofile_operations *ops) return -ENODEV; } - get_online_cpus(); - register_cpu_notifier(&oprofile_cpu_nb); - nmi_enabled = 0; - ctr_running = 0; - put_online_cpus(); - /* default values, can be overwritten by model */ ops->create_files = nmi_create_files; ops->setup = nmi_setup; @@ -771,14 +767,8 @@ int __init op_nmi_init(struct oprofile_operations *ops) void op_nmi_exit(void) { - if (using_nmi) { + if (using_nmi) exit_sysfs(); - get_online_cpus(); - unregister_cpu_notifier(&oprofile_cpu_nb); - nmi_enabled = 0; - ctr_running = 0; - put_online_cpus(); - } if (model->exit) model->exit(); } -- cgit v1.2.3-59-g8ed1b From bae663bc635e2726c7c5228dbf0f2051e16d1c81 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 5 May 2010 17:47:17 +0200 Subject: oprofile/x86: make AMD IBS hotplug capable Current IBS code is not hotplug capable. An offline cpu might not be initialized or deinitialized properly. This patch fixes this by removing on_each_cpu() functions. The IBS init/deinit code is executed in the per-cpu functions model->setup_ctrs() and model->cpu_down() which are also called by hotplug notifiers. model->cpu_down() replaces model->exit() that became obsolete. Cc: Andi Kleen Signed-off-by: Robert Richter --- arch/x86/oprofile/nmi_int.c | 4 +-- arch/x86/oprofile/op_model_amd.c | 54 ++++++++++++---------------------------- arch/x86/oprofile/op_x86_model.h | 2 +- 3 files changed, 19 insertions(+), 41 deletions(-) (limited to 'arch') diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 2a086726cad1..b28d2f1253bb 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -397,6 +397,8 @@ static void nmi_cpu_shutdown(void *dummy) apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu)); apic_write(APIC_LVTERR, v); nmi_cpu_restore_registers(msrs); + if (model->cpu_down) + model->cpu_down(); } static void nmi_cpu_up(void *dummy) @@ -769,6 +771,4 @@ void op_nmi_exit(void) { if (using_nmi) exit_sysfs(); - if (model->exit) - model->exit(); } diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 384c52410480..b67a6b5aa8d4 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -374,6 +374,15 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, val |= op_x86_get_ctrl(model, &counter_config[virt]); wrmsrl(msrs->controls[i].addr, val); } + + if (ibs_caps) + setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0); +} + +static void op_amd_cpu_shutdown(void) +{ + if (ibs_caps) + setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1); } static int op_amd_check_ctrs(struct pt_regs * const regs, @@ -436,28 +445,16 @@ static void op_amd_stop(struct op_msrs const * const msrs) op_amd_stop_ibs(); } -static u8 ibs_eilvt_off; - -static inline void apic_init_ibs_nmi_per_cpu(void *arg) -{ - ibs_eilvt_off = setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0); -} - -static inline void apic_clear_ibs_nmi_per_cpu(void *arg) -{ - setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1); -} - -static int init_ibs_nmi(void) +static int __init_ibs_nmi(void) { #define IBSCTL_LVTOFFSETVAL (1 << 8) #define IBSCTL 0x1cc struct pci_dev *cpu_cfg; int nodes; u32 value = 0; + u8 ibs_eilvt_off; - /* per CPU setup */ - on_each_cpu(apic_init_ibs_nmi_per_cpu, NULL, 1); + ibs_eilvt_off = setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1); nodes = 0; cpu_cfg = NULL; @@ -487,21 +484,15 @@ static int init_ibs_nmi(void) return 0; } -/* uninitialize the APIC for the IBS interrupts if needed */ -static void clear_ibs_nmi(void) -{ - on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1); -} - /* initialize the APIC for the IBS interrupts if available */ -static void ibs_init(void) +static void init_ibs(void) { ibs_caps = get_ibs_caps(); if (!ibs_caps) return; - if (init_ibs_nmi()) { + if (__init_ibs_nmi()) { ibs_caps = 0; return; } @@ -510,14 +501,6 @@ static void ibs_init(void) (unsigned)ibs_caps); } -static void ibs_exit(void) -{ - if (!ibs_caps) - return; - - clear_ibs_nmi(); -} - static int (*create_arch_files)(struct super_block *sb, struct dentry *root); static int setup_ibs_files(struct super_block *sb, struct dentry *root) @@ -566,17 +549,12 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root) static int op_amd_init(struct oprofile_operations *ops) { - ibs_init(); + init_ibs(); create_arch_files = ops->create_files; ops->create_files = setup_ibs_files; return 0; } -static void op_amd_exit(void) -{ - ibs_exit(); -} - struct op_x86_model_spec op_amd_spec = { .num_counters = NUM_COUNTERS, .num_controls = NUM_COUNTERS, @@ -584,9 +562,9 @@ struct op_x86_model_spec op_amd_spec = { .reserved = MSR_AMD_EVENTSEL_RESERVED, .event_mask = OP_EVENT_MASK, .init = op_amd_init, - .exit = op_amd_exit, .fill_in_addresses = &op_amd_fill_in_addresses, .setup_ctrs = &op_amd_setup_ctrs, + .cpu_down = &op_amd_cpu_shutdown, .check_ctrs = &op_amd_check_ctrs, .start = &op_amd_start, .stop = &op_amd_stop, diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h index 551401398fba..89017fa1fd63 100644 --- a/arch/x86/oprofile/op_x86_model.h +++ b/arch/x86/oprofile/op_x86_model.h @@ -40,10 +40,10 @@ struct op_x86_model_spec { u64 reserved; u16 event_mask; int (*init)(struct oprofile_operations *ops); - void (*exit)(void); int (*fill_in_addresses)(struct op_msrs * const msrs); void (*setup_ctrs)(struct op_x86_model_spec const *model, struct op_msrs const * const msrs); + void (*cpu_down)(void); int (*check_ctrs)(struct pt_regs * const regs, struct op_msrs const * const msrs); void (*start)(struct op_msrs const * const msrs); -- cgit v1.2.3-59-g8ed1b From 3fc1f1e27a5b807791d72e5d992aa33b668a6626 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 6 May 2010 18:49:20 +0200 Subject: stop_machine: reimplement using cpu_stop Reimplement stop_machine using cpu_stop. As cpu stoppers are guaranteed to be available for all online cpus, stop_machine_create/destroy() are no longer necessary and removed. With resource management and synchronization handled by cpu_stop, the new implementation is much simpler. Asking the cpu_stop to execute the stop_cpu() state machine on all online cpus with cpu hotplug disabled is enough. stop_machine itself doesn't need to manage any global resources anymore, so all per-instance information is rolled into struct stop_machine_data and the mutex and all static data variables are removed. The previous implementation created and destroyed RT workqueues as necessary which made stop_machine() calls highly expensive on very large machines. According to Dimitri Sivanich, preventing the dynamic creation/destruction makes booting faster more than twice on very large machines. cpu_stop resources are preallocated for all online cpus and should have the same effect. Signed-off-by: Tejun Heo Acked-by: Rusty Russell Acked-by: Peter Zijlstra Cc: Oleg Nesterov Cc: Dimitri Sivanich --- arch/s390/kernel/time.c | 1 - drivers/xen/manage.c | 14 +--- include/linux/stop_machine.h | 20 ------ kernel/cpu.c | 8 --- kernel/module.c | 14 +--- kernel/stop_machine.c | 158 +++++++++++-------------------------------- 6 files changed, 42 insertions(+), 173 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index fba6dec156bf..03d96569f187 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -390,7 +390,6 @@ static void __init time_init_wq(void) if (time_sync_wq) return; time_sync_wq = create_singlethread_workqueue("timesync"); - stop_machine_create(); } /* diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 2ac4440e7b08..8943b8ccee1a 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -80,12 +80,6 @@ static void do_suspend(void) shutting_down = SHUTDOWN_SUSPEND; - err = stop_machine_create(); - if (err) { - printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err); - goto out; - } - #ifdef CONFIG_PREEMPT /* If the kernel is preemptible, we need to freeze all the processes to prevent them from being in the middle of a pagetable update @@ -93,7 +87,7 @@ static void do_suspend(void) err = freeze_processes(); if (err) { printk(KERN_ERR "xen suspend: freeze failed %d\n", err); - goto out_destroy_sm; + goto out; } #endif @@ -136,12 +130,8 @@ out_resume: out_thaw: #ifdef CONFIG_PREEMPT thaw_processes(); - -out_destroy_sm: -#endif - stop_machine_destroy(); - out: +#endif shutting_down = SHUTDOWN_INVALID; } #endif /* CONFIG_PM_SLEEP */ diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h index efcbd6c37947..0e552e72a4c4 100644 --- a/include/linux/stop_machine.h +++ b/include/linux/stop_machine.h @@ -67,23 +67,6 @@ int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus); */ int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus); -/** - * stop_machine_create: create all stop_machine threads - * - * Description: This causes all stop_machine threads to be created before - * stop_machine actually gets called. This can be used by subsystems that - * need a non failing stop_machine infrastructure. - */ -int stop_machine_create(void); - -/** - * stop_machine_destroy: destroy all stop_machine threads - * - * Description: This causes all stop_machine threads which were created with - * stop_machine_create to be destroyed again. - */ -void stop_machine_destroy(void); - #else static inline int stop_machine(int (*fn)(void *), void *data, @@ -96,8 +79,5 @@ static inline int stop_machine(int (*fn)(void *), void *data, return ret; } -static inline int stop_machine_create(void) { return 0; } -static inline void stop_machine_destroy(void) { } - #endif /* CONFIG_SMP */ #endif /* _LINUX_STOP_MACHINE */ diff --git a/kernel/cpu.c b/kernel/cpu.c index 914aedcde849..545777574779 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -266,9 +266,6 @@ int __ref cpu_down(unsigned int cpu) { int err; - err = stop_machine_create(); - if (err) - return err; cpu_maps_update_begin(); if (cpu_hotplug_disabled) { @@ -280,7 +277,6 @@ int __ref cpu_down(unsigned int cpu) out: cpu_maps_update_done(); - stop_machine_destroy(); return err; } EXPORT_SYMBOL(cpu_down); @@ -361,9 +357,6 @@ int disable_nonboot_cpus(void) { int cpu, first_cpu, error; - error = stop_machine_create(); - if (error) - return error; cpu_maps_update_begin(); first_cpu = cpumask_first(cpu_online_mask); /* @@ -394,7 +387,6 @@ int disable_nonboot_cpus(void) printk(KERN_ERR "Non-boot CPUs are not disabled\n"); } cpu_maps_update_done(); - stop_machine_destroy(); return error; } diff --git a/kernel/module.c b/kernel/module.c index 1016b75b026a..0838246d8c94 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -723,16 +723,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, return -EFAULT; name[MODULE_NAME_LEN-1] = '\0'; - /* Create stop_machine threads since free_module relies on - * a non-failing stop_machine call. */ - ret = stop_machine_create(); - if (ret) - return ret; - - if (mutex_lock_interruptible(&module_mutex) != 0) { - ret = -EINTR; - goto out_stop; - } + if (mutex_lock_interruptible(&module_mutex) != 0) + return -EINTR; mod = find_module(name); if (!mod) { @@ -792,8 +784,6 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, out: mutex_unlock(&module_mutex); -out_stop: - stop_machine_destroy(); return ret; } diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 7e3f9182aef3..884c7a1afeed 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c @@ -388,174 +388,92 @@ enum stopmachine_state { /* Exit */ STOPMACHINE_EXIT, }; -static enum stopmachine_state state; struct stop_machine_data { - int (*fn)(void *); - void *data; - int fnret; + int (*fn)(void *); + void *data; + /* Like num_online_cpus(), but hotplug cpu uses us, so we need this. */ + unsigned int num_threads; + const struct cpumask *active_cpus; + + enum stopmachine_state state; + atomic_t thread_ack; }; -/* Like num_online_cpus(), but hotplug cpu uses us, so we need this. */ -static unsigned int num_threads; -static atomic_t thread_ack; -static DEFINE_MUTEX(lock); -/* setup_lock protects refcount, stop_machine_wq and stop_machine_work. */ -static DEFINE_MUTEX(setup_lock); -/* Users of stop_machine. */ -static int refcount; -static struct workqueue_struct *stop_machine_wq; -static struct stop_machine_data active, idle; -static const struct cpumask *active_cpus; -static void __percpu *stop_machine_work; - -static void set_state(enum stopmachine_state newstate) +static void set_state(struct stop_machine_data *smdata, + enum stopmachine_state newstate) { /* Reset ack counter. */ - atomic_set(&thread_ack, num_threads); + atomic_set(&smdata->thread_ack, smdata->num_threads); smp_wmb(); - state = newstate; + smdata->state = newstate; } /* Last one to ack a state moves to the next state. */ -static void ack_state(void) +static void ack_state(struct stop_machine_data *smdata) { - if (atomic_dec_and_test(&thread_ack)) - set_state(state + 1); + if (atomic_dec_and_test(&smdata->thread_ack)) + set_state(smdata, smdata->state + 1); } -/* This is the actual function which stops the CPU. It runs - * in the context of a dedicated stopmachine workqueue. */ -static void stop_cpu(struct work_struct *unused) +/* This is the cpu_stop function which stops the CPU. */ +static int stop_machine_cpu_stop(void *data) { + struct stop_machine_data *smdata = data; enum stopmachine_state curstate = STOPMACHINE_NONE; - struct stop_machine_data *smdata = &idle; - int cpu = smp_processor_id(); - int err; + int cpu = smp_processor_id(), err = 0; + bool is_active; + + if (!smdata->active_cpus) + is_active = cpu == cpumask_first(cpu_online_mask); + else + is_active = cpumask_test_cpu(cpu, smdata->active_cpus); - if (!active_cpus) { - if (cpu == cpumask_first(cpu_online_mask)) - smdata = &active; - } else { - if (cpumask_test_cpu(cpu, active_cpus)) - smdata = &active; - } /* Simple state machine */ do { /* Chill out and ensure we re-read stopmachine_state. */ cpu_relax(); - if (state != curstate) { - curstate = state; + if (smdata->state != curstate) { + curstate = smdata->state; switch (curstate) { case STOPMACHINE_DISABLE_IRQ: local_irq_disable(); hard_irq_disable(); break; case STOPMACHINE_RUN: - /* On multiple CPUs only a single error code - * is needed to tell that something failed. */ - err = smdata->fn(smdata->data); - if (err) - smdata->fnret = err; + if (is_active) + err = smdata->fn(smdata->data); break; default: break; } - ack_state(); + ack_state(smdata); } } while (curstate != STOPMACHINE_EXIT); local_irq_enable(); + return err; } -/* Callback for CPUs which aren't supposed to do anything. */ -static int chill(void *unused) -{ - return 0; -} - -int stop_machine_create(void) -{ - mutex_lock(&setup_lock); - if (refcount) - goto done; - stop_machine_wq = create_rt_workqueue("kstop"); - if (!stop_machine_wq) - goto err_out; - stop_machine_work = alloc_percpu(struct work_struct); - if (!stop_machine_work) - goto err_out; -done: - refcount++; - mutex_unlock(&setup_lock); - return 0; - -err_out: - if (stop_machine_wq) - destroy_workqueue(stop_machine_wq); - mutex_unlock(&setup_lock); - return -ENOMEM; -} -EXPORT_SYMBOL_GPL(stop_machine_create); - -void stop_machine_destroy(void) -{ - mutex_lock(&setup_lock); - refcount--; - if (refcount) - goto done; - destroy_workqueue(stop_machine_wq); - free_percpu(stop_machine_work); -done: - mutex_unlock(&setup_lock); -} -EXPORT_SYMBOL_GPL(stop_machine_destroy); - int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus) { - struct work_struct *sm_work; - int i, ret; - - /* Set up initial state. */ - mutex_lock(&lock); - num_threads = num_online_cpus(); - active_cpus = cpus; - active.fn = fn; - active.data = data; - active.fnret = 0; - idle.fn = chill; - idle.data = NULL; - - set_state(STOPMACHINE_PREPARE); - - /* Schedule the stop_cpu work on all cpus: hold this CPU so one - * doesn't hit this CPU until we're ready. */ - get_cpu(); - for_each_online_cpu(i) { - sm_work = per_cpu_ptr(stop_machine_work, i); - INIT_WORK(sm_work, stop_cpu); - queue_work_on(i, stop_machine_wq, sm_work); - } - /* This will release the thread on our CPU. */ - put_cpu(); - flush_workqueue(stop_machine_wq); - ret = active.fnret; - mutex_unlock(&lock); - return ret; + struct stop_machine_data smdata = { .fn = fn, .data = data, + .num_threads = num_online_cpus(), + .active_cpus = cpus }; + + /* Set the initial state and stop all online cpus. */ + set_state(&smdata, STOPMACHINE_PREPARE); + return stop_cpus(cpu_online_mask, stop_machine_cpu_stop, &smdata); } int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus) { int ret; - ret = stop_machine_create(); - if (ret) - return ret; /* No CPUs can come up or down during this. */ get_online_cpus(); ret = __stop_machine(fn, data, cpus); put_online_cpus(); - stop_machine_destroy(); return ret; } EXPORT_SYMBOL_GPL(stop_machine); -- cgit v1.2.3-59-g8ed1b From 6b07aaedc029d507501a931aabfd3d0a70f1828f Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 6 May 2010 10:40:47 +0100 Subject: ARM: 6099/1: nomadik-gpio: fix mask/unmask Mask/unmask should modify the interrupt mask register (RIMSC and FIMSC) not the wakeup mask registers (RWIMSC and FWIMSC). Acked-by: Alessandro Rubini Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/plat-nomadik/gpio.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 092f380063b3..38fc3b5d9872 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -123,14 +123,14 @@ static void nmk_gpio_irq_mask(unsigned int irq) /* we must individually clear the two edges */ spin_lock_irqsave(&nmk_chip->lock, flags); if (nmk_chip->edge_rising & bitmask) { - reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); + reg = readl(nmk_chip->addr + NMK_GPIO_RIMSC); reg &= ~bitmask; - writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC); + writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC); } if (nmk_chip->edge_falling & bitmask) { - reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); + reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC); reg &= ~bitmask; - writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC); + writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC); } spin_unlock_irqrestore(&nmk_chip->lock, flags); }; @@ -151,14 +151,14 @@ static void nmk_gpio_irq_unmask(unsigned int irq) /* we must individually set the two edges */ spin_lock_irqsave(&nmk_chip->lock, flags); if (nmk_chip->edge_rising & bitmask) { - reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); + reg = readl(nmk_chip->addr + NMK_GPIO_RIMSC); reg |= bitmask; - writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC); + writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC); } if (nmk_chip->edge_falling & bitmask) { - reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); + reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC); reg |= bitmask; - writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC); + writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC); } spin_unlock_irqrestore(&nmk_chip->lock, flags); } -- cgit v1.2.3-59-g8ed1b From 040e5ecddaa72f1f982b83cb205509bc9ce7f91e Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 6 May 2010 10:42:42 +0100 Subject: ARM: 6100/1: nomadik-gpio: factor out helper to enable/disable irqs Remove some nearly-duplicated code to make the following patch simpler. Acked-by: Alessandro Rubini Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/plat-nomadik/gpio.c | 57 +++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 38fc3b5d9872..a8ac545ddadc 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -107,40 +107,37 @@ static void nmk_gpio_irq_ack(unsigned int irq) writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); } -static void nmk_gpio_irq_mask(unsigned int irq) +static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, + int gpio, bool enable) { - int gpio; - struct nmk_gpio_chip *nmk_chip; - unsigned long flags; - u32 bitmask, reg; - - gpio = NOMADIK_IRQ_TO_GPIO(irq); - nmk_chip = get_irq_chip_data(irq); - bitmask = nmk_gpio_get_bitmask(gpio); - if (!nmk_chip) - return; + u32 bitmask = nmk_gpio_get_bitmask(gpio); + u32 reg; - /* we must individually clear the two edges */ - spin_lock_irqsave(&nmk_chip->lock, flags); + /* we must individually set/clear the two edges */ if (nmk_chip->edge_rising & bitmask) { reg = readl(nmk_chip->addr + NMK_GPIO_RIMSC); - reg &= ~bitmask; + if (enable) + reg |= bitmask; + else + reg &= ~bitmask; writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC); } if (nmk_chip->edge_falling & bitmask) { reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC); - reg &= ~bitmask; + if (enable) + reg |= bitmask; + else + reg &= ~bitmask; writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC); } - spin_unlock_irqrestore(&nmk_chip->lock, flags); -}; +} -static void nmk_gpio_irq_unmask(unsigned int irq) +static void nmk_gpio_irq_modify(unsigned int irq, bool enable) { int gpio; struct nmk_gpio_chip *nmk_chip; unsigned long flags; - u32 bitmask, reg; + u32 bitmask; gpio = NOMADIK_IRQ_TO_GPIO(irq); nmk_chip = get_irq_chip_data(irq); @@ -148,21 +145,21 @@ static void nmk_gpio_irq_unmask(unsigned int irq) if (!nmk_chip) return; - /* we must individually set the two edges */ spin_lock_irqsave(&nmk_chip->lock, flags); - if (nmk_chip->edge_rising & bitmask) { - reg = readl(nmk_chip->addr + NMK_GPIO_RIMSC); - reg |= bitmask; - writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC); - } - if (nmk_chip->edge_falling & bitmask) { - reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC); - reg |= bitmask; - writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC); - } + __nmk_gpio_irq_modify(nmk_chip, gpio, enable); spin_unlock_irqrestore(&nmk_chip->lock, flags); } +static void nmk_gpio_irq_mask(unsigned int irq) +{ + nmk_gpio_irq_modify(irq, false); +}; + +static void nmk_gpio_irq_unmask(unsigned int irq) +{ + nmk_gpio_irq_modify(irq, true); +} + static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) { int gpio; -- cgit v1.2.3-59-g8ed1b From 7a852d8060e1bb3a5e621caaebea86c43cf4a62d Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 6 May 2010 10:43:55 +0100 Subject: ARM: 6101/1: nomadik-gpio: don't enable in set_type On this peripheral, setting the trigger type enables the interrupt, and the current set_type() implementation unconditionally enables the interrupt, even if it is called when the interrupt is disabled. Fix set_type() to: - if the interrupt is disabled, defer the actual trigger setting to when it is unmasked - if the interrupt is enabled, change the type immediately by clearing the old type and then re-enabling with the new type. Acked-by: Alessandro Rubini Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/plat-nomadik/gpio.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index a8ac545ddadc..b877d76878f9 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -162,6 +162,7 @@ static void nmk_gpio_irq_unmask(unsigned int irq) static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) { + bool enabled = !(irq_to_desc(irq)->status & IRQ_DISABLED); int gpio; struct nmk_gpio_chip *nmk_chip; unsigned long flags; @@ -180,19 +181,21 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) spin_lock_irqsave(&nmk_chip->lock, flags); + if (enabled) + __nmk_gpio_irq_modify(nmk_chip, gpio, false); + nmk_chip->edge_rising &= ~bitmask; if (type & IRQ_TYPE_EDGE_RISING) nmk_chip->edge_rising |= bitmask; - writel(nmk_chip->edge_rising, nmk_chip->addr + NMK_GPIO_RIMSC); nmk_chip->edge_falling &= ~bitmask; if (type & IRQ_TYPE_EDGE_FALLING) nmk_chip->edge_falling |= bitmask; - writel(nmk_chip->edge_falling, nmk_chip->addr + NMK_GPIO_FIMSC); - spin_unlock_irqrestore(&nmk_chip->lock, flags); + if (enabled) + __nmk_gpio_irq_modify(nmk_chip, gpio, true); - nmk_gpio_irq_unmask(irq); + spin_unlock_irqrestore(&nmk_chip->lock, flags); return 0; } -- cgit v1.2.3-59-g8ed1b From 2210d6453b4d888c122b2b1c236f50b0a2d30bfa Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 6 May 2010 10:45:18 +0100 Subject: ARM: 6102/1: nomadik-gpio: set a default trigger for interrupts Set a default trigger type for interrupts, otherwise if request_irq is called without specifiying a trigger type, the interrupt will not actually be enabled. Acked-by: Alessandro Rubini Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/plat-nomadik/gpio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index b877d76878f9..eac9c9a7fbf9 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -245,6 +245,7 @@ static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) set_irq_handler(i, handle_edge_irq); set_irq_flags(i, IRQF_VALID); set_irq_chip_data(i, nmk_chip); + set_irq_type(i, IRQ_TYPE_EDGE_FALLING); } set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); set_irq_data(nmk_chip->parent_irq, nmk_chip); -- cgit v1.2.3-59-g8ed1b From dc6048c7f97beaf8c5bb97ed772f43330d04727a Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 6 May 2010 10:47:25 +0100 Subject: ARM: 6103/1: nomadik: define clocks statically Add a table for clocks to be defined statically, so that new clocks can be added without having to call nmdk_clk_create() for each of them. Remove the now unused nmdk_clk_create() function. Acked-by: Alessandro Rubini Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-nomadik/board-nhk8815.c | 10 +--------- arch/arm/mach-nomadik/clock.c | 28 ++++++++++++++++++++-------- arch/arm/mach-nomadik/clock.h | 1 - 3 files changed, 21 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index ab3712c86d2b..841d459ad59d 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -32,7 +32,6 @@ #include #include #include -#include "clock.h" /* Initial value for SRC control register: all timers use MXTAL/8 source */ #define SRC_CR_INIT_MASK 0x00007fff @@ -202,11 +201,6 @@ static struct amba_device *amba_devs[] __initdata = { &uart1_device, }; -/* We have a fixed clock alone, by now */ -static struct clk nhk8815_clk_48 = { - .rate = 48*1000*1000, -}; - static struct resource nhk8815_eth_resources[] = { { .name = "smc91x-regs", @@ -276,10 +270,8 @@ static void __init nhk8815_platform_init(void) platform_add_devices(nhk8815_platform_devices, ARRAY_SIZE(nhk8815_platform_devices)); - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - nmdk_clk_create(&nhk8815_clk_48, amba_devs[i]->dev.init_name); + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) amba_device_register(amba_devs[i], &iomem_resource); - } } MACHINE_START(NOMADIK, "NHK8815") diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c index 9f92502a0083..7af785017782 100644 --- a/arch/arm/mach-nomadik/clock.c +++ b/arch/arm/mach-nomadik/clock.c @@ -32,14 +32,26 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL(clk_disable); -/* Create a clock structure with the given name */ -int nmdk_clk_create(struct clk *clk, const char *dev_id) -{ - struct clk_lookup *clkdev; +/* We have a fixed clock alone, for now */ +static struct clk clk_48 = { + .rate = 48 * 1000 * 1000, +}; + +#define CLK(_clk, dev) \ + { \ + .clk = _clk, \ + .dev_id = dev, \ + } + +static struct clk_lookup lookups[] = { + CLK(&clk_48, "uart0"), + CLK(&clk_48, "uart1"), +}; - clkdev = clkdev_alloc(clk, NULL, dev_id); - if (!clkdev) - return -ENOMEM; - clkdev_add(clkdev); +static int __init clk_init(void) +{ + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); return 0; } + +arch_initcall(clk_init); diff --git a/arch/arm/mach-nomadik/clock.h b/arch/arm/mach-nomadik/clock.h index 235faec7f627..5563985a2cc7 100644 --- a/arch/arm/mach-nomadik/clock.h +++ b/arch/arm/mach-nomadik/clock.h @@ -11,4 +11,3 @@ struct clk { unsigned long rate; }; -extern int nmdk_clk_create(struct clk *clk, const char *dev_id); -- cgit v1.2.3-59-g8ed1b From af7dc2281fd3cedc04cb51bcc0887cdaf65c3fcc Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 6 May 2010 11:14:17 +0100 Subject: ARM: 6104/1: nomadik-gpio: use clk API Add clocks with appropriate names in platforms that use it, and use the clk API in nomadik-gpio. Acked-by: Alessandro Rubini Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mach-nomadik/clock.c | 10 ++++++++++ arch/arm/mach-ux500/clock.c | 16 +++++++++++----- arch/arm/plat-nomadik/gpio.c | 20 +++++++++++++++++++- 3 files changed, 40 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c index 7af785017782..60f5bee09f2e 100644 --- a/arch/arm/mach-nomadik/clock.c +++ b/arch/arm/mach-nomadik/clock.c @@ -37,6 +37,12 @@ static struct clk clk_48 = { .rate = 48 * 1000 * 1000, }; +/* + * Catch-all default clock to satisfy drivers using the clk API. We don't + * model the actual hardware clocks yet. + */ +static struct clk clk_default; + #define CLK(_clk, dev) \ { \ .clk = _clk, \ @@ -46,6 +52,10 @@ static struct clk clk_48 = { static struct clk_lookup lookups[] = { CLK(&clk_48, "uart0"), CLK(&clk_48, "uart1"), + CLK(&clk_default, "gpio.0"), + CLK(&clk_default, "gpio.1"), + CLK(&clk_default, "gpio.2"), + CLK(&clk_default, "gpio.3"), }; static int __init clk_init(void) diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index c325dad1679c..1b2c9890e8b4 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -364,7 +364,8 @@ static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); static struct clk_lookup u8500_common_clks[] = { /* Peripheral Cluster #1 */ - CLK(gpio0, "gpioblock0", NULL), + CLK(gpio0, "gpio.0", NULL), + CLK(gpio0, "gpio.1", NULL), CLK(slimbus0, "slimbus0", NULL), CLK(i2c2, "nmk-i2c.2", NULL), CLK(sdi0, "sdi0", NULL), @@ -374,7 +375,10 @@ static struct clk_lookup u8500_common_clks[] = { CLK(uart0, "uart0", NULL), /* Peripheral Cluster #3 */ - CLK(gpio2, "gpioblock2", NULL), + CLK(gpio2, "gpio.2", NULL), + CLK(gpio2, "gpio.3", NULL), + CLK(gpio2, "gpio.4", NULL), + CLK(gpio2, "gpio.5", NULL), CLK(sdi5, "sdi5", NULL), CLK(uart2, "uart2", NULL), CLK(ske, "ske", NULL), @@ -383,7 +387,7 @@ static struct clk_lookup u8500_common_clks[] = { CLK(fsmc, "fsmc", NULL), /* Peripheral Cluster #5 */ - CLK(gpio3, "gpioblock3", NULL), + CLK(gpio3, "gpio.8", NULL), /* Peripheral Cluster #6 */ CLK(hash1, "hash1", NULL), @@ -418,7 +422,8 @@ static struct clk_lookup u8500_ed_clks[] = { CLK(msp1_ed, "msp1", NULL), /* Peripheral Cluster #2 */ - CLK(gpio1_ed, "gpioblock1", NULL), + CLK(gpio1_ed, "gpio.6", NULL), + CLK(gpio1_ed, "gpio.7", NULL), CLK(ssitx_ed, "ssitx", NULL), CLK(ssirx_ed, "ssirx", NULL), CLK(spi0_ed, "spi0", NULL), @@ -458,7 +463,8 @@ static struct clk_lookup u8500_v1_clks[] = { CLK(msp1_v1, "msp1", NULL), /* Peripheral Cluster #2 */ - CLK(gpio1_v1, "gpioblock1", NULL), + CLK(gpio1_v1, "gpio.6", NULL), + CLK(gpio1_v1, "gpio.7", NULL), CLK(ssitx_v1, "ssitx", NULL), CLK(ssirx_v1, "ssirx", NULL), CLK(spi0_v1, "spi0", NULL), diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index eac9c9a7fbf9..d28900cfa541 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include #include @@ -35,6 +37,7 @@ struct nmk_gpio_chip { struct gpio_chip chip; void __iomem *addr; + struct clk *clk; unsigned int parent_irq; spinlock_t lock; /* Keep track of configured edges */ @@ -310,6 +313,7 @@ static int __init nmk_gpio_probe(struct platform_device *dev) struct nmk_gpio_chip *nmk_chip; struct gpio_chip *chip; struct resource *res; + struct clk *clk; int irq; int ret; @@ -334,15 +338,24 @@ static int __init nmk_gpio_probe(struct platform_device *dev) goto out; } + clk = clk_get(&dev->dev, NULL); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto out_release; + } + + clk_enable(clk); + nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); if (!nmk_chip) { ret = -ENOMEM; - goto out_release; + goto out_clk; } /* * The virt address in nmk_chip->addr is in the nomadik register space, * so we can simply convert the resource address, without remapping */ + nmk_chip->clk = clk; nmk_chip->addr = io_p2v(res->start); nmk_chip->chip = nmk_gpio_template; nmk_chip->parent_irq = irq; @@ -368,6 +381,9 @@ static int __init nmk_gpio_probe(struct platform_device *dev) out_free: kfree(nmk_chip); +out_clk: + clk_disable(clk); + clk_put(clk); out_release: release_mem_region(res->start, resource_size(res)); out: @@ -385,6 +401,8 @@ static int __exit nmk_gpio_remove(struct platform_device *dev) nmk_chip = platform_get_drvdata(dev); gpiochip_remove(&nmk_chip->chip); + clk_disable(nmk_chip->clk); + clk_put(nmk_chip->clk); kfree(nmk_chip); release_mem_region(res->start, resource_size(res)); return 0; -- cgit v1.2.3-59-g8ed1b From 28552c2eae472a0a52d1cdb02eb32766c7f690e1 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 25 Feb 2010 15:36:38 -0800 Subject: davinci: misc cleanups from sparse - Convert data/functions to static - include headers for missing declarations - pointer cleanups: struct foo *__iomem f --> struct foo __iomem *f; Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm644x-evm.c | 2 +- arch/arm/mach-davinci/board-neuros-osd2.c | 2 +- arch/arm/mach-davinci/board-sffsdr.c | 2 +- arch/arm/mach-davinci/cdce949.c | 1 + arch/arm/mach-davinci/clock.c | 1 + arch/arm/mach-davinci/devices.c | 2 ++ arch/arm/mach-davinci/dm355.c | 2 +- arch/arm/mach-davinci/dm365.c | 2 +- arch/arm/mach-davinci/dm644x.c | 4 ++-- arch/arm/mach-davinci/dm646x.c | 6 +++--- arch/arm/mach-davinci/gpio.c | 24 ++++++++++++------------ arch/arm/mach-davinci/include/mach/gpio.h | 8 ++++---- arch/arm/mach-davinci/mux.c | 1 + 13 files changed, 31 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 976e11b7fa4a..95cef1f46ef2 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -111,7 +111,7 @@ static struct platform_device davinci_evm_norflash_device = { * It may used instead of the (default) NOR chip to boot, using TI's * tools to install the secondary boot loader (UBL) and U-Boot. */ -struct mtd_partition davinci_evm_nandflash_partition[] = { +static struct mtd_partition davinci_evm_nandflash_partition[] = { /* Bootloader layout depends on whose u-boot is installed, but we * can hide all the details. * - block 0 for u-boot environment ... in mainline u-boot diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index bd9ca079b69d..1fadc68d9fbb 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -60,7 +60,7 @@ #define NAND_BLOCK_SIZE SZ_128K -struct mtd_partition davinci_ntosd2_nandflash_partition[] = { +static struct mtd_partition davinci_ntosd2_nandflash_partition[] = { { /* UBL (a few copies) plus U-Boot */ .name = "bootloader", diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index 08d373bfcc8a..a7cf810bb13e 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -48,7 +48,7 @@ #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e00000 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 -struct mtd_partition davinci_sffsdr_nandflash_partition[] = { +static struct mtd_partition davinci_sffsdr_nandflash_partition[] = { /* U-Boot Environment: Block 0 * UBL: Block 1 * U-Boot: Blocks 6-7 (256 kb) diff --git a/arch/arm/mach-davinci/cdce949.c b/arch/arm/mach-davinci/cdce949.c index aec375690543..ba8b12b2913b 100644 --- a/arch/arm/mach-davinci/cdce949.c +++ b/arch/arm/mach-davinci/cdce949.c @@ -19,6 +19,7 @@ #include #include +#include #include "clock.h" diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index bf6218ee94e1..058c77f72a07 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -22,6 +22,7 @@ #include +#include #include #include #include "clock.h" diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 147949650c25..ef28080b1fda 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -23,6 +23,8 @@ #include #include +#include "clock.h" + #define DAVINCI_I2C_BASE 0x01C21000 #define DAVINCI_MMCSD0_BASE 0x01E10000 #define DM355_MMCSD0_BASE 0x01E11000 diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 3dc0a88712eb..5efce70ccdd0 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -798,7 +798,7 @@ static void __iomem *dm355_psc_bases[] = { * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) * T1_TOP: Timer 1, top : */ -struct davinci_timer_info dm355_timer_info = { +static struct davinci_timer_info dm355_timer_info = { .timers = davinci_timer_instance, .clockevent_id = T0_BOT, .clocksource_id = T0_TOP, diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 0d6ee583f65c..871be5af2735 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1010,7 +1010,7 @@ static void __iomem *dm365_psc_bases[] = { IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), }; -struct davinci_timer_info dm365_timer_info = { +static struct davinci_timer_info dm365_timer_info = { .timers = davinci_timer_instance, .clockevent_id = T0_BOT, .clocksource_id = T0_TOP, diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 2f2ae8bc77bb..23cbe9d04bc5 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -277,7 +277,7 @@ static struct clk timer2_clk = { .usecount = 1, /* REVISIT: why cant' this be disabled? */ }; -struct clk_lookup dm644x_clks[] = { +static struct clk_lookup dm644x_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll1", &pll1_clk), CLK(NULL, "pll1_sysclk1", &pll1_sysclk1), @@ -687,7 +687,7 @@ static void __iomem *dm644x_psc_bases[] = { * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) * T1_TOP: Timer 1, top : */ -struct davinci_timer_info dm644x_timer_info = { +static struct davinci_timer_info dm644x_timer_info = { .timers = davinci_timer_instance, .clockevent_id = T0_BOT, .clocksource_id = T0_TOP, diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 893baf4ad37d..b67b997d0bbc 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -311,7 +311,7 @@ static struct clk vpif1_clk = { .flags = ALWAYS_ENABLED, }; -struct clk_lookup dm646x_clks[] = { +static struct clk_lookup dm646x_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "aux", &aux_clkin), CLK(NULL, "pll1", &pll1_clk), @@ -797,7 +797,7 @@ static void __iomem *dm646x_psc_bases[] = { * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) * T1_TOP: Timer 1, top : */ -struct davinci_timer_info dm646x_timer_info = { +static struct davinci_timer_info dm646x_timer_info = { .timers = davinci_timer_instance, .clockevent_id = T0_BOT, .clocksource_id = T0_TOP, @@ -867,7 +867,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .sram_len = SZ_32K, }; -void __init dm646x_init_ide() +void __init dm646x_init_ide(void) { davinci_cfg_reg(DM646X_ATAEN); platform_device_register(&ide_dev); diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 744755b53236..3f7706266ca6 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -24,14 +24,14 @@ static DEFINE_SPINLOCK(gpio_lock); struct davinci_gpio { struct gpio_chip chip; - struct gpio_controller *__iomem regs; + struct gpio_controller __iomem *regs; int irq_base; }; static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; /* create a non-inlined version */ -static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio) +static struct gpio_controller __iomem __init *gpio2controller(unsigned gpio) { return __gpio_to_controller(gpio); } @@ -48,7 +48,7 @@ static int __init davinci_gpio_irq_setup(void); static int davinci_direction_in(struct gpio_chip *chip, unsigned offset) { struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); - struct gpio_controller *__iomem g = d->regs; + struct gpio_controller __iomem *g = d->regs; u32 temp; spin_lock(&gpio_lock); @@ -70,7 +70,7 @@ static int davinci_direction_in(struct gpio_chip *chip, unsigned offset) static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset) { struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); - struct gpio_controller *__iomem g = d->regs; + struct gpio_controller __iomem *g = d->regs; return (1 << offset) & __raw_readl(&g->in_data); } @@ -79,7 +79,7 @@ static int davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value) { struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); - struct gpio_controller *__iomem g = d->regs; + struct gpio_controller __iomem *g = d->regs; u32 temp; u32 mask = 1 << offset; @@ -99,7 +99,7 @@ static void davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); - struct gpio_controller *__iomem g = d->regs; + struct gpio_controller __iomem *g = d->regs; __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data); } @@ -161,7 +161,7 @@ pure_initcall(davinci_gpio_setup); static void gpio_irq_disable(unsigned irq) { - struct gpio_controller *__iomem g = get_irq_chip_data(irq); + struct gpio_controller __iomem *g = get_irq_chip_data(irq); u32 mask = (u32) get_irq_data(irq); __raw_writel(mask, &g->clr_falling); @@ -170,7 +170,7 @@ static void gpio_irq_disable(unsigned irq) static void gpio_irq_enable(unsigned irq) { - struct gpio_controller *__iomem g = get_irq_chip_data(irq); + struct gpio_controller __iomem *g = get_irq_chip_data(irq); u32 mask = (u32) get_irq_data(irq); unsigned status = irq_desc[irq].status; @@ -186,7 +186,7 @@ static void gpio_irq_enable(unsigned irq) static int gpio_irq_type(unsigned irq, unsigned trigger) { - struct gpio_controller *__iomem g = get_irq_chip_data(irq); + struct gpio_controller __iomem *g = get_irq_chip_data(irq); u32 mask = (u32) get_irq_data(irq); if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) @@ -215,7 +215,7 @@ static struct irq_chip gpio_irqchip = { static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { - struct gpio_controller *__iomem g = get_irq_chip_data(irq); + struct gpio_controller __iomem *g = get_irq_chip_data(irq); u32 mask = 0xffff; /* we only care about one bank */ @@ -276,7 +276,7 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) static int gpio_irq_type_unbanked(unsigned irq, unsigned trigger) { - struct gpio_controller *__iomem g = get_irq_chip_data(irq); + struct gpio_controller __iomem *g = get_irq_chip_data(irq); u32 mask = (u32) get_irq_data(irq); if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) @@ -305,7 +305,7 @@ static int __init davinci_gpio_irq_setup(void) u32 binten = 0; unsigned ngpio, bank_irq; struct davinci_soc_info *soc_info = &davinci_soc_info; - struct gpio_controller *__iomem g; + struct gpio_controller __iomem *g; ngpio = soc_info->gpio_num; diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h index f3b8ef878158..0099e6e5aff8 100644 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ b/arch/arm/mach-davinci/include/mach/gpio.h @@ -67,10 +67,10 @@ struct gpio_controller { * * These are NOT part of the cross-platform GPIO interface */ -static inline struct gpio_controller *__iomem +static inline struct gpio_controller __iomem * __gpio_to_controller(unsigned gpio) { - void *__iomem ptr; + void __iomem *ptr; void __iomem *base = davinci_soc_info.gpio_base; if (gpio < 32 * 1) @@ -102,7 +102,7 @@ static inline u32 __gpio_mask(unsigned gpio) static inline void gpio_set_value(unsigned gpio, int value) { if (__builtin_constant_p(value) && gpio < DAVINCI_N_GPIO) { - struct gpio_controller *__iomem g; + struct gpio_controller __iomem *g; u32 mask; g = __gpio_to_controller(gpio); @@ -128,7 +128,7 @@ static inline void gpio_set_value(unsigned gpio, int value) */ static inline int gpio_get_value(unsigned gpio) { - struct gpio_controller *__iomem g; + struct gpio_controller __iomem *g; if (!__builtin_constant_p(gpio) || gpio >= DAVINCI_N_GPIO) return __gpio_get_value(gpio); diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c index f757e83415f3..c942c893a2eb 100644 --- a/arch/arm/mach-davinci/mux.c +++ b/arch/arm/mach-davinci/mux.c @@ -21,6 +21,7 @@ #include #include +#include /* * Sets the DAVINCI MUX register based on the table -- cgit v1.2.3-59-g8ed1b From 21ce873d211a42e315558d6ae09a8bb04508a592 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 25 Feb 2010 16:49:56 -0800 Subject: davinci: sparse: gpio: void casting Cleanup usage of void pointers when using genirq. genirq API takes and returns void *, where this GPIO API is using those as __iomem pointers. Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/gpio.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 3f7706266ca6..5476ad132044 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -36,6 +36,15 @@ static struct gpio_controller __iomem __init *gpio2controller(unsigned gpio) return __gpio_to_controller(gpio); } +static inline struct gpio_controller __iomem *irq2controller(int irq) +{ + struct gpio_controller __iomem *g; + + g = (__force struct gpio_controller __iomem *)get_irq_chip_data(irq); + + return g; +} + static int __init davinci_gpio_irq_setup(void); /*--------------------------------------------------------------------------*/ @@ -161,7 +170,7 @@ pure_initcall(davinci_gpio_setup); static void gpio_irq_disable(unsigned irq) { - struct gpio_controller __iomem *g = get_irq_chip_data(irq); + struct gpio_controller __iomem *g = irq2controller(irq); u32 mask = (u32) get_irq_data(irq); __raw_writel(mask, &g->clr_falling); @@ -170,7 +179,7 @@ static void gpio_irq_disable(unsigned irq) static void gpio_irq_enable(unsigned irq) { - struct gpio_controller __iomem *g = get_irq_chip_data(irq); + struct gpio_controller __iomem *g = irq2controller(irq); u32 mask = (u32) get_irq_data(irq); unsigned status = irq_desc[irq].status; @@ -186,7 +195,7 @@ static void gpio_irq_enable(unsigned irq) static int gpio_irq_type(unsigned irq, unsigned trigger) { - struct gpio_controller __iomem *g = get_irq_chip_data(irq); + struct gpio_controller __iomem *g = irq2controller(irq); u32 mask = (u32) get_irq_data(irq); if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) @@ -215,7 +224,7 @@ static struct irq_chip gpio_irqchip = { static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { - struct gpio_controller __iomem *g = get_irq_chip_data(irq); + struct gpio_controller __iomem *g = irq2controller(irq); u32 mask = 0xffff; /* we only care about one bank */ @@ -276,7 +285,7 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) static int gpio_irq_type_unbanked(unsigned irq, unsigned trigger) { - struct gpio_controller __iomem *g = get_irq_chip_data(irq); + struct gpio_controller __iomem *g = irq2controller(irq); u32 mask = (u32) get_irq_data(irq); if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) @@ -362,7 +371,7 @@ static int __init davinci_gpio_irq_setup(void) for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) { set_irq_chip(irq, &gpio_irqchip_unbanked); set_irq_data(irq, (void *) __gpio_mask(gpio)); - set_irq_chip_data(irq, g); + set_irq_chip_data(irq, (__force void *) g); irq_desc[irq].status |= IRQ_TYPE_EDGE_BOTH; } @@ -385,12 +394,12 @@ static int __init davinci_gpio_irq_setup(void) /* set up all irqs in this bank */ set_irq_chained_handler(bank_irq, gpio_irq_handler); - set_irq_chip_data(bank_irq, g); - set_irq_data(bank_irq, (void *)irq); + set_irq_chip_data(bank_irq, (__force void *) g); + set_irq_data(bank_irq, (void *) irq); for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { set_irq_chip(irq, &gpio_irqchip); - set_irq_chip_data(irq, g); + set_irq_chip_data(irq, (__force void *) g); set_irq_data(irq, (void *) __gpio_mask(gpio)); set_irq_handler(irq, handle_simple_irq); set_irq_flags(irq, IRQF_VALID); -- cgit v1.2.3-59-g8ed1b From 8ccfd3f074f75135971905d2413811729e19580e Mon Sep 17 00:00:00 2001 From: Vipin Bhandari Date: Wed, 10 Mar 2010 14:03:01 +0530 Subject: davinci: da830/omap-l137 evm: add support for GPIO based MMC/SD card detection The DA830/OMAP-L137 EVM has GPIO based card detection logic, but the current code does not use it. Add support for GPIO based card detection to avoid reading the card to see if a card is present or not. Signed-off-by: Vipin Bhandari Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da830-evm.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index dc19870b23cd..8e670372d7fe 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -229,14 +229,21 @@ static const short da830_evm_mmc_sd_pins[] = { }; #define DA830_MMCSD_WP_PIN GPIO_TO_PIN(2, 1) +#define DA830_MMCSD_CD_PIN GPIO_TO_PIN(2, 2) static int da830_evm_mmc_get_ro(int index) { return gpio_get_value(DA830_MMCSD_WP_PIN); } +static int da830_evm_mmc_get_cd(int index) +{ + return !gpio_get_value(DA830_MMCSD_CD_PIN); +} + static struct davinci_mmc_config da830_evm_mmc_config = { .get_ro = da830_evm_mmc_get_ro, + .get_cd = da830_evm_mmc_get_cd, .wires = 4, .max_freq = 50000000, .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, @@ -262,6 +269,14 @@ static inline void da830_evm_init_mmc(void) } gpio_direction_input(DA830_MMCSD_WP_PIN); + ret = gpio_request(DA830_MMCSD_CD_PIN, "MMC CD\n"); + if (ret) { + pr_warning("da830_evm_init: can not open GPIO %d\n", + DA830_MMCSD_CD_PIN); + return; + } + gpio_direction_input(DA830_MMCSD_CD_PIN); + ret = da8xx_register_mmcsd0(&da830_evm_mmc_config); if (ret) { pr_warning("da830_evm_init: mmc/sd registration failed: %d\n", -- cgit v1.2.3-59-g8ed1b From d154fed7234331dc29240deb04f92f382000e66b Mon Sep 17 00:00:00 2001 From: Vipin Bhandari Date: Wed, 10 Mar 2010 14:03:02 +0530 Subject: davinci: da830/omap-l137 evm: use 8-wire MMC/SD card support The merge for 2.6.34 brings in 8-bit support to the DaVinci MMC/SD driver. This patch updates the platform data for DA830/OMAP-L137 EVM to use 8-wire support available in the driver. Signed-off-by: Vipin Bhandari Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da830-evm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 8e670372d7fe..ea293b8a596a 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -244,7 +244,7 @@ static int da830_evm_mmc_get_cd(int index) static struct davinci_mmc_config da830_evm_mmc_config = { .get_ro = da830_evm_mmc_get_ro, .get_cd = da830_evm_mmc_get_cd, - .wires = 4, + .wires = 8, .max_freq = 50000000, .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, .version = MMC_CTLR_VERSION_2, -- cgit v1.2.3-59-g8ed1b From a7e05065f562ae347db36b0ef644525cd1e89ecd Mon Sep 17 00:00:00 2001 From: Anuj Aggarwal Date: Mon, 8 Mar 2010 15:05:58 +0530 Subject: davinci: edma: clear interrupt status for interrupt enabled channels only Currently, the ISR in the EDMA driver clears the pending interrupt for all channels without regard to whether that channel has a registered callback or not. This causes problems for devices like DM355/DM365 where the multimedia accelerator uses EDMA by polling on the interrupt pending bits of some of the EDMA channels. Since these channels are actually allocated through the Linux EDMA driver (by an out-of-kernel module), the same shadow region is used by Linux and accelerator. There a race between the Linux ISR and the polling code running on the accelerator on the IPR (interrupt pending register). This patch fixes the issue by making the ISR clear the interrupts only for those channels which have interrupt enabled. The channels which are allocated for the purpose of being polled on by the accelerator will not have a callback function provided and so will not have IER (interrupt enable register) bits set. Tested on DM365 and OMAP-L137/L138 with audio and MMC/SD (as EDMA users). Signed-off-by: Anuj Aggarwal Signed-off-by: Sekhar Nori CC: Archith John Bency Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dma.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index 53137387aee1..0bf290befa23 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -359,9 +359,11 @@ static irqreturn_t dma_irq_handler(int irq, void *data) while (1) { int j; - if (edma_shadow0_read_array(ctlr, SH_IPR, 0)) + if (edma_shadow0_read_array(ctlr, SH_IPR, 0) & + edma_shadow0_read_array(ctlr, SH_IER, 0)) j = 0; - else if (edma_shadow0_read_array(ctlr, SH_IPR, 1)) + else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) & + edma_shadow0_read_array(ctlr, SH_IER, 1)) j = 1; else break; @@ -369,8 +371,9 @@ static irqreturn_t dma_irq_handler(int irq, void *data) edma_shadow0_read_array(ctlr, SH_IPR, j)); for (i = 0; i < 32; i++) { int k = (j << 5) + i; - if (edma_shadow0_read_array(ctlr, SH_IPR, j) & - (1 << i)) { + if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i)) + && (edma_shadow0_read_array(ctlr, + SH_IER, j) & BIT(i))) { /* Clear the corresponding IPR bits */ edma_shadow0_write_array(ctlr, SH_ICR, j, (1 << i)); -- cgit v1.2.3-59-g8ed1b From b722049d7e60356fe04bcac6065a7c8b1c64c06f Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Thu, 25 Mar 2010 17:43:44 -0400 Subject: Davinci: allow SOCs based on other ARM CPUs Preliminary modification prior to adding support for TNETV107X based on ARM1176. This change allows for CPUs other than ARM926T to be used for Davinci derivative SoCs. Existing devices (DA8x and DMx) operate unchanged. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/Kconfig | 1 - arch/arm/mach-davinci/Kconfig | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 92622eb5cc0d..1151d1afd756 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -776,7 +776,6 @@ config ARCH_NOMADIK config ARCH_DAVINCI bool "TI DaVinci" - select CPU_ARM926T select GENERIC_TIME select GENERIC_CLOCKEVENTS select GENERIC_GPIO diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 0ebe185610bf..0316e201ada0 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -7,6 +7,7 @@ config CP_INTC bool config ARCH_DAVINCI_DMx + select CPU_ARM926T bool menu "TI DaVinci Implementations" @@ -41,6 +42,7 @@ config ARCH_DAVINCI_DA850 select ARCH_HAS_CPUFREQ config ARCH_DAVINCI_DA8XX + select CPU_ARM926T bool config ARCH_DAVINCI_DM365 -- cgit v1.2.3-59-g8ed1b From 8ca2e597fc8f3337cef1f8febab482fe8c52b004 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Thu, 25 Mar 2010 17:43:45 -0400 Subject: Davinci: enable timer clock before use timer_init() programs timer64 hardware. The module should ideally be brought out of reset before this happens. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/time.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 9e0b106b4f5f..b21f7633d9a8 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -361,13 +361,13 @@ static void __init davinci_timer_init(void) } } - /* init timer hw */ - timer_init(); - timer_clk = clk_get(NULL, "timer0"); BUG_ON(IS_ERR(timer_clk)); clk_enable(timer_clk); + /* init timer hw */ + timer_init(); + davinci_clock_tick_rate = clk_get_rate(timer_clk); /* setup clocksource */ -- cgit v1.2.3-59-g8ed1b From 449ef7f6a9c732657938b222f8804d3e34a3603e Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Thu, 25 Mar 2010 17:43:46 -0400 Subject: Davinci: cpintc host map configuration Host map configuration instructs the interrupt controller to route interrupt channels to FIQ or IRQ lines. Currently, DA8xx family of devices leave these registers at their reset-default values. TNETV107X however does not have sane reset defaults, and therefore this architecture needs to reconfigure the host-map such that channels 0 and 1 go to FIQ, and the remaining channels raise IRQs. This patch adds an optional host map argument to cp_intc_init() for this. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da830-evm.c | 2 +- arch/arm/mach-davinci/board-da850-evm.c | 2 +- arch/arm/mach-davinci/cp_intc.c | 6 +++++- arch/arm/mach-davinci/include/mach/cp_intc.h | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index ea293b8a596a..db5ac0f3788e 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -569,7 +569,7 @@ static __init void da830_evm_irq_init(void) struct davinci_soc_info *soc_info = &davinci_soc_info; cp_intc_init((void __iomem *)DA8XX_CP_INTC_VIRT, DA830_N_CP_INTC_IRQ, - soc_info->intc_irq_prios); + soc_info->intc_irq_prios, NULL); } static void __init da830_evm_map_io(void) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 411284d0b0fa..ef691ae5e67a 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -741,7 +741,7 @@ static __init void da850_evm_irq_init(void) struct davinci_soc_info *soc_info = &davinci_soc_info; cp_intc_init((void __iomem *)DA8XX_CP_INTC_VIRT, DA850_N_CP_INTC_IRQ, - soc_info->intc_irq_prios); + soc_info->intc_irq_prios, NULL); } static void __init da850_evm_map_io(void) diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c index 37311d1830eb..2a8d26ee4bbf 100644 --- a/arch/arm/mach-davinci/cp_intc.c +++ b/arch/arm/mach-davinci/cp_intc.c @@ -101,7 +101,7 @@ static struct irq_chip cp_intc_irq_chip = { }; void __init cp_intc_init(void __iomem *base, unsigned short num_irq, - u8 *irq_prio) + u8 *irq_prio, u32 *host_map) { unsigned num_reg = BITS_TO_LONGS(num_irq); int i; @@ -157,6 +157,10 @@ void __init cp_intc_init(void __iomem *base, unsigned short num_irq, cp_intc_write(0x0f0f0f0f, CP_INTC_CHAN_MAP(i)); } + if (host_map) + 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++) { set_irq_chip(i, &cp_intc_irq_chip); diff --git a/arch/arm/mach-davinci/include/mach/cp_intc.h b/arch/arm/mach-davinci/include/mach/cp_intc.h index c4d27eec8064..121b114df755 100644 --- a/arch/arm/mach-davinci/include/mach/cp_intc.h +++ b/arch/arm/mach-davinci/include/mach/cp_intc.h @@ -52,6 +52,6 @@ #define CP_INTC_VECTOR_ADDR(n) (0x2000 + (n << 2)) void __init cp_intc_init(void __iomem *base, unsigned short num_irq, - u8 *irq_prio); + u8 *irq_prio, u32 *host_map); #endif /* __ASM_HARDWARE_CP_INTC_H */ -- cgit v1.2.3-59-g8ed1b From 52958be3ad6e2b72a5943718f339ed4e11685739 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Thu, 25 Mar 2010 17:43:47 -0400 Subject: Davinci: support LPSC SwRstDisable state The current clock control code always gates the clock (PSC state Disable = 2) on clk_disable(). Some on-chip peripherals (e.g. LCD controller on TNETV107X) need to be put into SwRstDisable = 0 on clock disable, to maintain hardware sanity. This patch extends the davinci_psc_config() arguments to pass in the desired module state instead of a boolean enable/disable. Further, clk_disable() now checks for the PSC_SWRSTDISABLE clk flag before selecting the target state. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/clock.c | 12 +++++++++--- arch/arm/mach-davinci/clock.h | 7 ++++--- arch/arm/mach-davinci/include/mach/psc.h | 8 +++++++- arch/arm/mach-davinci/psc.c | 3 +-- 4 files changed, 21 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 058c77f72a07..5de60ae57903 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -43,7 +43,8 @@ static void __clk_enable(struct clk *clk) if (clk->parent) __clk_enable(clk->parent); if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) - davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 1); + davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, + PSC_STATE_ENABLE); } static void __clk_disable(struct clk *clk) @@ -52,7 +53,9 @@ static void __clk_disable(struct clk *clk) return; if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC)) - davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 0); + davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, + (clk->flags & PSC_SWRSTDISABLE) ? + PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE); if (clk->parent) __clk_disable(clk->parent); } @@ -234,7 +237,10 @@ static int __init clk_disable_unused(void) continue; pr_info("Clocks: disable unused %s\n", ck->name); - davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, 0); + + davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, + (ck->flags & PSC_SWRSTDISABLE) ? + PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE); } spin_unlock_irq(&clockfw_lock); diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index aa0a61150325..53a0f7b90119 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -101,10 +101,11 @@ struct clk { /* Clock flags: SoC-specific flags start at BIT(16) */ #define ALWAYS_ENABLED BIT(1) -#define CLK_PSC BIT(2) -#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */ +#define CLK_PSC BIT(2) +#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */ #define CLK_PLL BIT(4) /* PLL-derived clock */ -#define PRE_PLL BIT(5) /* source is before PLL mult/div */ +#define PRE_PLL BIT(5) /* source is before PLL mult/div */ +#define PSC_SWRSTDISABLE BIT(6) /* Disable state is SwRstDisable */ #define CLK(dev, con, ck) \ { \ diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 651f6d8158fa..7dd2962ad586 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -189,13 +189,19 @@ #define MDSTAT 0x800 #define MDCTL 0xA00 +/* PSC module states */ +#define PSC_STATE_SWRSTDISABLE 0 +#define PSC_STATE_SYNCRST 1 +#define PSC_STATE_DISABLE 2 +#define PSC_STATE_ENABLE 3 + #define MDSTAT_STATE_MASK 0x1f #ifndef __ASSEMBLER__ extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, - unsigned int id, char enable); + unsigned int id, u32 next_state); #endif diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index adf6b5c7f1e5..d7cb438c4df6 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c @@ -47,12 +47,11 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) /* Enable or disable a PSC domain */ void davinci_psc_config(unsigned int domain, unsigned int ctlr, - unsigned int id, char enable) + unsigned int id, u32 next_state) { u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; void __iomem *psc_base; struct davinci_soc_info *soc_info = &davinci_soc_info; - u32 next_state = enable ? 0x3 : 0x2; /* 0x3 enables, 0x2 disables */ if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { pr_warning("PSC: Bad psc data: 0x%x[%d]\n", -- cgit v1.2.3-59-g8ed1b From 3821d10a538ac9d750987badd404c8f860ffa774 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Thu, 25 Mar 2010 17:43:48 -0400 Subject: Davinci: promote da8xx_pinmux_setup() Rename da8xx_pinmux_setup() to davinci_cfg_reg_list() and promote it for use in other SOCs that may need the ability to configure multiple pins in one shot. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da830-evm.c | 14 +++++++------- arch/arm/mach-davinci/board-da850-evm.c | 18 +++++++++--------- arch/arm/mach-davinci/include/mach/da8xx.h | 6 ------ arch/arm/mach-davinci/include/mach/mux.h | 5 +++++ arch/arm/mach-davinci/mux.c | 3 +-- 5 files changed, 22 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index db5ac0f3788e..925705649ed0 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -157,7 +157,7 @@ static __init void da830_evm_usb_init(void) __func__, ret); } - ret = da8xx_pinmux_setup(da830_evm_usb11_pins); + ret = davinci_cfg_reg_list(da830_evm_usb11_pins); if (ret) { pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", __func__, ret); @@ -254,7 +254,7 @@ static inline void da830_evm_init_mmc(void) { int ret; - ret = da8xx_pinmux_setup(da830_evm_mmc_sd_pins); + ret = davinci_cfg_reg_list(da830_evm_mmc_sd_pins); if (ret) { pr_warning("da830_evm_init: mmc/sd mux setup failed: %d\n", ret); @@ -407,7 +407,7 @@ static inline void da830_evm_init_nand(int mux_mode) return; } - ret = da8xx_pinmux_setup(da830_evm_emif25_pins); + ret = davinci_cfg_reg_list(da830_evm_emif25_pins); if (ret) pr_warning("da830_evm_init: emif25 mux setup failed: %d\n", ret); @@ -427,7 +427,7 @@ static inline void da830_evm_init_lcdc(int mux_mode) { int ret; - ret = da8xx_pinmux_setup(da830_lcdcntl_pins); + ret = davinci_cfg_reg_list(da830_lcdcntl_pins); if (ret) pr_warning("da830_evm_init: lcdcntl mux setup failed: %d\n", ret); @@ -507,7 +507,7 @@ static __init void da830_evm_init(void) pr_warning("da830_evm_init: edma registration failed: %d\n", ret); - ret = da8xx_pinmux_setup(da830_i2c0_pins); + ret = davinci_cfg_reg_list(da830_i2c0_pins); if (ret) pr_warning("da830_evm_init: i2c0 mux setup failed: %d\n", ret); @@ -523,7 +523,7 @@ static __init void da830_evm_init(void) soc_info->emac_pdata->mdio_max_freq = DA830_EVM_MDIO_FREQUENCY; soc_info->emac_pdata->rmii_en = 1; - ret = da8xx_pinmux_setup(da830_cpgmac_pins); + ret = davinci_cfg_reg_list(da830_cpgmac_pins); if (ret) pr_warning("da830_evm_init: cpgmac mux setup failed: %d\n", ret); @@ -542,7 +542,7 @@ static __init void da830_evm_init(void) i2c_register_board_info(1, da830_evm_i2c_devices, ARRAY_SIZE(da830_evm_i2c_devices)); - ret = da8xx_pinmux_setup(da830_evm_mcasp1_pins); + ret = davinci_cfg_reg_list(da830_evm_mcasp1_pins); if (ret) pr_warning("da830_evm_init: mcasp1 mux setup failed: %d\n", ret); diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index ef691ae5e67a..6c137e0492ff 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -206,12 +206,12 @@ static __init void da850_evm_setup_nor_nand(void) int ret = 0; if (ui_card_detected & !HAS_MMC) { - ret = da8xx_pinmux_setup(da850_nand_pins); + ret = davinci_cfg_reg_list(da850_nand_pins); if (ret) pr_warning("da850_evm_init: nand mux setup failed: " "%d\n", ret); - ret = da8xx_pinmux_setup(da850_nor_pins); + ret = davinci_cfg_reg_list(da850_nor_pins); if (ret) pr_warning("da850_evm_init: nor mux setup failed: %d\n", ret); @@ -568,12 +568,12 @@ static int __init da850_evm_config_emac(void) if (rmii_en) { val |= BIT(8); - ret = da8xx_pinmux_setup(da850_rmii_pins); + ret = davinci_cfg_reg_list(da850_rmii_pins); pr_info("EMAC: RMII PHY configured, MII PHY will not be" " functional\n"); } else { val &= ~BIT(8); - ret = da8xx_pinmux_setup(da850_cpgmac_pins); + ret = davinci_cfg_reg_list(da850_cpgmac_pins); pr_info("EMAC: MII PHY configured, RMII PHY will not be" " functional\n"); } @@ -626,7 +626,7 @@ static __init void da850_evm_init(void) pr_warning("da850_evm_init: edma registration failed: %d\n", ret); - ret = da8xx_pinmux_setup(da850_i2c0_pins); + ret = davinci_cfg_reg_list(da850_i2c0_pins); if (ret) pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n", ret); @@ -643,7 +643,7 @@ static __init void da850_evm_init(void) ret); if (HAS_MMC) { - ret = da8xx_pinmux_setup(da850_mmcsd0_pins); + ret = davinci_cfg_reg_list(da850_mmcsd0_pins); if (ret) pr_warning("da850_evm_init: mmcsd0 mux setup failed:" " %d\n", ret); @@ -679,20 +679,20 @@ static __init void da850_evm_init(void) __raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30); __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); - ret = da8xx_pinmux_setup(da850_mcasp_pins); + ret = davinci_cfg_reg_list(da850_mcasp_pins); if (ret) pr_warning("da850_evm_init: mcasp mux setup failed: %d\n", ret); da8xx_register_mcasp(0, &da850_evm_snd_data); - ret = da8xx_pinmux_setup(da850_lcdcntl_pins); + ret = davinci_cfg_reg_list(da850_lcdcntl_pins); if (ret) pr_warning("da850_evm_init: lcdcntl mux setup failed: %d\n", ret); /* Handle board specific muxing for LCD here */ - ret = da8xx_pinmux_setup(da850_evm_lcdc_pins); + ret = davinci_cfg_reg_list(da850_evm_lcdc_pins); if (ret) pr_warning("da850_evm_init: evm specific lcd mux setup " "failed: %d\n", ret); diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 03acfd39042b..33471c9cbca3 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -146,10 +146,4 @@ extern const short da850_mmcsd0_pins[]; extern const short da850_nand_pins[]; extern const short da850_nor_pins[]; -#ifdef CONFIG_DAVINCI_MUX -int da8xx_pinmux_setup(const short pins[]); -#else -static inline int da8xx_pinmux_setup(const short pins[]) { return 0; } -#endif - #endif /* __ASM_ARCH_DAVINCI_DA8XX_H */ diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index 2a68c1d8a24b..48888db00fad 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -907,9 +907,14 @@ enum davinci_da850_index { #ifdef CONFIG_DAVINCI_MUX /* setup pin muxing */ extern int davinci_cfg_reg(unsigned long reg_cfg); +extern int davinci_cfg_reg_list(const short pins[]); #else /* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */ static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; } +static inline int davinci_cfg_reg_list(const short pins[]) +{ + return 0; +} #endif #endif /* __INC_MACH_MUX_H */ diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c index c942c893a2eb..e9d530a8f79f 100644 --- a/arch/arm/mach-davinci/mux.c +++ b/arch/arm/mach-davinci/mux.c @@ -21,7 +21,6 @@ #include #include -#include /* * Sets the DAVINCI MUX register based on the table @@ -92,7 +91,7 @@ int __init_or_module davinci_cfg_reg(const unsigned long index) } EXPORT_SYMBOL(davinci_cfg_reg); -int da8xx_pinmux_setup(const short pins[]) +int __init_or_module davinci_cfg_reg_list(const short pins[]) { int i, error = -EINVAL; -- cgit v1.2.3-59-g8ed1b From 0e23f71d60bdb4c202402c5f5c709deacc5d0f17 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Thu, 25 Mar 2010 17:43:49 -0400 Subject: Davinci: tnetv107x pin list Added list of muxed pins on the tnetv107x SOC. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/mux.h | 269 +++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index 48888db00fad..863890342a0a 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -904,6 +904,275 @@ enum davinci_da850_index { DA850_RTC_ALARM, }; +enum davinci_tnetv107x_index { + TNETV107X_ASR_A00, + TNETV107X_GPIO32, + TNETV107X_ASR_A01, + TNETV107X_GPIO33, + TNETV107X_ASR_A02, + TNETV107X_GPIO34, + TNETV107X_ASR_A03, + TNETV107X_GPIO35, + TNETV107X_ASR_A04, + TNETV107X_GPIO36, + TNETV107X_ASR_A05, + TNETV107X_GPIO37, + TNETV107X_ASR_A06, + TNETV107X_GPIO38, + TNETV107X_ASR_A07, + TNETV107X_GPIO39, + TNETV107X_ASR_A08, + TNETV107X_GPIO40, + TNETV107X_ASR_A09, + TNETV107X_GPIO41, + TNETV107X_ASR_A10, + TNETV107X_GPIO42, + TNETV107X_ASR_A11, + TNETV107X_BOOT_STRP_0, + TNETV107X_ASR_A12, + TNETV107X_BOOT_STRP_1, + TNETV107X_ASR_A13, + TNETV107X_GPIO43, + TNETV107X_ASR_A14, + TNETV107X_GPIO44, + TNETV107X_ASR_A15, + TNETV107X_GPIO45, + TNETV107X_ASR_A16, + TNETV107X_GPIO46, + TNETV107X_ASR_A17, + TNETV107X_GPIO47, + TNETV107X_ASR_A18, + TNETV107X_GPIO48, + TNETV107X_SDIO1_DATA3_0, + TNETV107X_ASR_A19, + TNETV107X_GPIO49, + TNETV107X_SDIO1_DATA2_0, + TNETV107X_ASR_A20, + TNETV107X_GPIO50, + TNETV107X_SDIO1_DATA1_0, + TNETV107X_ASR_A21, + TNETV107X_GPIO51, + TNETV107X_SDIO1_DATA0_0, + TNETV107X_ASR_A22, + TNETV107X_GPIO52, + TNETV107X_SDIO1_CMD_0, + TNETV107X_ASR_A23, + TNETV107X_GPIO53, + TNETV107X_SDIO1_CLK_0, + TNETV107X_ASR_BA_1, + TNETV107X_GPIO54, + TNETV107X_SYS_PLL_CLK, + TNETV107X_ASR_CS0, + TNETV107X_ASR_CS1, + TNETV107X_ASR_CS2, + TNETV107X_TDM_PLL_CLK, + TNETV107X_ASR_CS3, + TNETV107X_ETH_PHY_CLK, + TNETV107X_ASR_D00, + TNETV107X_GPIO55, + TNETV107X_ASR_D01, + TNETV107X_GPIO56, + TNETV107X_ASR_D02, + TNETV107X_GPIO57, + TNETV107X_ASR_D03, + TNETV107X_GPIO58, + TNETV107X_ASR_D04, + TNETV107X_GPIO59_0, + TNETV107X_ASR_D05, + TNETV107X_GPIO60_0, + TNETV107X_ASR_D06, + TNETV107X_GPIO61_0, + TNETV107X_ASR_D07, + TNETV107X_GPIO62_0, + TNETV107X_ASR_D08, + TNETV107X_GPIO63_0, + TNETV107X_ASR_D09, + TNETV107X_GPIO64_0, + TNETV107X_ASR_D10, + TNETV107X_SDIO1_DATA3_1, + TNETV107X_ASR_D11, + TNETV107X_SDIO1_DATA2_1, + TNETV107X_ASR_D12, + TNETV107X_SDIO1_DATA1_1, + TNETV107X_ASR_D13, + TNETV107X_SDIO1_DATA0_1, + TNETV107X_ASR_D14, + TNETV107X_SDIO1_CMD_1, + TNETV107X_ASR_D15, + TNETV107X_SDIO1_CLK_1, + TNETV107X_ASR_OE, + TNETV107X_BOOT_STRP_2, + TNETV107X_ASR_RNW, + TNETV107X_GPIO29_0, + TNETV107X_ASR_WAIT, + TNETV107X_GPIO30_0, + TNETV107X_ASR_WE, + TNETV107X_BOOT_STRP_3, + TNETV107X_ASR_WE_DQM0, + TNETV107X_GPIO31, + TNETV107X_LCD_PD17_0, + TNETV107X_ASR_WE_DQM1, + TNETV107X_ASR_BA0_0, + TNETV107X_VLYNQ_CLK, + TNETV107X_GPIO14, + TNETV107X_LCD_PD19_0, + TNETV107X_VLYNQ_RXD0, + TNETV107X_GPIO15, + TNETV107X_LCD_PD20_0, + TNETV107X_VLYNQ_RXD1, + TNETV107X_GPIO16, + TNETV107X_LCD_PD21_0, + TNETV107X_VLYNQ_TXD0, + TNETV107X_GPIO17, + TNETV107X_LCD_PD22_0, + TNETV107X_VLYNQ_TXD1, + TNETV107X_GPIO18, + TNETV107X_LCD_PD23_0, + TNETV107X_SDIO0_CLK, + TNETV107X_GPIO19, + TNETV107X_SDIO0_CMD, + TNETV107X_GPIO20, + TNETV107X_SDIO0_DATA0, + TNETV107X_GPIO21, + TNETV107X_SDIO0_DATA1, + TNETV107X_GPIO22, + TNETV107X_SDIO0_DATA2, + TNETV107X_GPIO23, + TNETV107X_SDIO0_DATA3, + TNETV107X_GPIO24, + TNETV107X_EMU0, + TNETV107X_EMU1, + TNETV107X_RTCK, + TNETV107X_TRST_N, + TNETV107X_TCK, + TNETV107X_TDI, + TNETV107X_TDO, + TNETV107X_TMS, + TNETV107X_TDM1_CLK, + TNETV107X_TDM1_RX, + TNETV107X_TDM1_TX, + TNETV107X_TDM1_FS, + TNETV107X_KEYPAD_R0, + TNETV107X_KEYPAD_R1, + TNETV107X_KEYPAD_R2, + TNETV107X_KEYPAD_R3, + TNETV107X_KEYPAD_R4, + TNETV107X_KEYPAD_R5, + TNETV107X_KEYPAD_R6, + TNETV107X_GPIO12, + TNETV107X_KEYPAD_R7, + TNETV107X_GPIO10, + TNETV107X_KEYPAD_C0, + TNETV107X_KEYPAD_C1, + TNETV107X_KEYPAD_C2, + TNETV107X_KEYPAD_C3, + TNETV107X_KEYPAD_C4, + TNETV107X_KEYPAD_C5, + TNETV107X_KEYPAD_C6, + TNETV107X_GPIO13, + TNETV107X_TEST_CLK_IN, + TNETV107X_KEYPAD_C7, + TNETV107X_GPIO11, + TNETV107X_SSP0_0, + TNETV107X_SCC_DCLK, + TNETV107X_LCD_PD20_1, + TNETV107X_SSP0_1, + TNETV107X_SCC_CS_N, + TNETV107X_LCD_PD21_1, + TNETV107X_SSP0_2, + TNETV107X_SCC_D, + TNETV107X_LCD_PD22_1, + TNETV107X_SSP0_3, + TNETV107X_SCC_RESETN, + TNETV107X_LCD_PD23_1, + TNETV107X_SSP1_0, + TNETV107X_GPIO25, + TNETV107X_UART2_CTS, + TNETV107X_SSP1_1, + TNETV107X_GPIO26, + TNETV107X_UART2_RD, + TNETV107X_SSP1_2, + TNETV107X_GPIO27, + TNETV107X_UART2_RTS, + TNETV107X_SSP1_3, + TNETV107X_GPIO28, + TNETV107X_UART2_TD, + TNETV107X_UART0_CTS, + TNETV107X_UART0_RD, + TNETV107X_UART0_RTS, + TNETV107X_UART0_TD, + TNETV107X_UART1_RD, + TNETV107X_UART1_TD, + TNETV107X_LCD_AC_NCS, + TNETV107X_LCD_HSYNC_RNW, + TNETV107X_LCD_VSYNC_A0, + TNETV107X_LCD_MCLK, + TNETV107X_LCD_PD16_0, + TNETV107X_LCD_PCLK_E, + TNETV107X_LCD_PD00, + TNETV107X_LCD_PD01, + TNETV107X_LCD_PD02, + TNETV107X_LCD_PD03, + TNETV107X_LCD_PD04, + TNETV107X_LCD_PD05, + TNETV107X_LCD_PD06, + TNETV107X_LCD_PD07, + TNETV107X_LCD_PD08, + TNETV107X_GPIO59_1, + TNETV107X_LCD_PD09, + TNETV107X_GPIO60_1, + TNETV107X_LCD_PD10, + TNETV107X_ASR_BA0_1, + TNETV107X_GPIO61_1, + TNETV107X_LCD_PD11, + TNETV107X_GPIO62_1, + TNETV107X_LCD_PD12, + TNETV107X_GPIO63_1, + TNETV107X_LCD_PD13, + TNETV107X_GPIO64_1, + TNETV107X_LCD_PD14, + TNETV107X_GPIO29_1, + TNETV107X_LCD_PD15, + TNETV107X_GPIO30_1, + TNETV107X_EINT0, + TNETV107X_GPIO08, + TNETV107X_EINT1, + TNETV107X_GPIO09, + TNETV107X_GPIO00, + TNETV107X_LCD_PD20_2, + TNETV107X_TDM_CLK_IN_2, + TNETV107X_GPIO01, + TNETV107X_LCD_PD21_2, + TNETV107X_24M_CLK_OUT_1, + TNETV107X_GPIO02, + TNETV107X_LCD_PD22_2, + TNETV107X_GPIO03, + TNETV107X_LCD_PD23_2, + TNETV107X_GPIO04, + TNETV107X_LCD_PD16_1, + TNETV107X_USB0_RXERR, + TNETV107X_GPIO05, + TNETV107X_LCD_PD17_1, + TNETV107X_TDM_CLK_IN_1, + TNETV107X_GPIO06, + TNETV107X_LCD_PD18, + TNETV107X_24M_CLK_OUT_2, + TNETV107X_GPIO07, + TNETV107X_LCD_PD19_1, + TNETV107X_USB1_RXERR, + TNETV107X_ETH_PLL_CLK, + TNETV107X_MDIO, + TNETV107X_MDC, + TNETV107X_AIC_MUTE_STAT_N, + TNETV107X_TDM0_CLK, + TNETV107X_AIC_HNS_EN_N, + TNETV107X_TDM0_FS, + TNETV107X_AIC_HDS_EN_STAT_N, + TNETV107X_TDM0_TX, + TNETV107X_AIC_HNF_EN_STAT_N, + TNETV107X_TDM0_RX, +}; + #ifdef CONFIG_DAVINCI_MUX /* setup pin muxing */ extern int davinci_cfg_reg(unsigned long reg_cfg); -- cgit v1.2.3-59-g8ed1b From 7520f4eded66091b59c9aa3054c6fc8843a6c9a6 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Thu, 25 Mar 2010 17:43:50 -0400 Subject: Davinci: tnetv107x LPSC modules Added definitions for LPSC modules in the tnetv107x SOC Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/psc.h | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 7dd2962ad586..983da6e4554c 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -180,6 +180,53 @@ #define DA8XX_LPSC1_CR_P3_SS 26 #define DA8XX_LPSC1_L3_CBA_RAM 31 +/* TNETV107X LPSC Assignments */ +#define TNETV107X_LPSC_ARM 0 +#define TNETV107X_LPSC_GEM 1 +#define TNETV107X_LPSC_DDR2_PHY 2 +#define TNETV107X_LPSC_TPCC 3 +#define TNETV107X_LPSC_TPTC0 4 +#define TNETV107X_LPSC_TPTC1 5 +#define TNETV107X_LPSC_RAM 6 +#define TNETV107X_LPSC_MBX_LITE 7 +#define TNETV107X_LPSC_LCD 8 +#define TNETV107X_LPSC_ETHSS 9 +#define TNETV107X_LPSC_AEMIF 10 +#define TNETV107X_LPSC_CHIP_CFG 11 +#define TNETV107X_LPSC_TSC 12 +#define TNETV107X_LPSC_ROM 13 +#define TNETV107X_LPSC_UART2 14 +#define TNETV107X_LPSC_PKTSEC 15 +#define TNETV107X_LPSC_SECCTL 16 +#define TNETV107X_LPSC_KEYMGR 17 +#define TNETV107X_LPSC_KEYPAD 18 +#define TNETV107X_LPSC_GPIO 19 +#define TNETV107X_LPSC_MDIO 20 +#define TNETV107X_LPSC_SDIO0 21 +#define TNETV107X_LPSC_UART0 22 +#define TNETV107X_LPSC_UART1 23 +#define TNETV107X_LPSC_TIMER0 24 +#define TNETV107X_LPSC_TIMER1 25 +#define TNETV107X_LPSC_WDT_ARM 26 +#define TNETV107X_LPSC_WDT_DSP 27 +#define TNETV107X_LPSC_SSP 28 +#define TNETV107X_LPSC_TDM0 29 +#define TNETV107X_LPSC_VLYNQ 30 +#define TNETV107X_LPSC_MCDMA 31 +#define TNETV107X_LPSC_USB0 32 +#define TNETV107X_LPSC_TDM1 33 +#define TNETV107X_LPSC_DEBUGSS 34 +#define TNETV107X_LPSC_ETHSS_RGMII 35 +#define TNETV107X_LPSC_SYSTEM 36 +#define TNETV107X_LPSC_IMCOP 37 +#define TNETV107X_LPSC_SPARE 38 +#define TNETV107X_LPSC_SDIO1 39 +#define TNETV107X_LPSC_USB1 40 +#define TNETV107X_LPSC_USBSS 41 +#define TNETV107X_LPSC_DDR2_EMIF1_VRST 42 +#define TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST 43 +#define TNETV107X_LPSC_MAX 44 + /* PSC register offsets */ #define EPCPR 0x070 #define PTCMD 0x120 -- cgit v1.2.3-59-g8ed1b From 6cc20cd8ed876ce21b558006f18d4c86f2efbdfd Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Thu, 25 Mar 2010 17:43:51 -0400 Subject: Davinci: tnetv107x IRQ definitions IRQ numbers as defined for tnetv107x cp_intc. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/irqs.h | 97 +++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-davinci/include/mach/irqs.h b/arch/arm/mach-davinci/include/mach/irqs.h index 354af71798dc..ec76c7775c2e 100644 --- a/arch/arm/mach-davinci/include/mach/irqs.h +++ b/arch/arm/mach-davinci/include/mach/irqs.h @@ -401,6 +401,103 @@ #define DA850_N_CP_INTC_IRQ 101 + +/* TNETV107X specific interrupts */ +#define IRQ_TNETV107X_TDM1_TXDMA 0 +#define IRQ_TNETV107X_EXT_INT_0 1 +#define IRQ_TNETV107X_EXT_INT_1 2 +#define IRQ_TNETV107X_GPIO_INT12 3 +#define IRQ_TNETV107X_GPIO_INT13 4 +#define IRQ_TNETV107X_TIMER_0_TINT12 5 +#define IRQ_TNETV107X_TIMER_1_TINT12 6 +#define IRQ_TNETV107X_UART0 7 +#define IRQ_TNETV107X_TDM1_RXDMA 8 +#define IRQ_TNETV107X_MCDMA_INT0 9 +#define IRQ_TNETV107X_MCDMA_INT1 10 +#define IRQ_TNETV107X_TPCC 11 +#define IRQ_TNETV107X_TPCC_INT0 12 +#define IRQ_TNETV107X_TPCC_INT1 13 +#define IRQ_TNETV107X_TPCC_INT2 14 +#define IRQ_TNETV107X_TPCC_INT3 15 +#define IRQ_TNETV107X_TPTC0 16 +#define IRQ_TNETV107X_TPTC1 17 +#define IRQ_TNETV107X_TIMER_0_TINT34 18 +#define IRQ_TNETV107X_ETHSS 19 +#define IRQ_TNETV107X_TIMER_1_TINT34 20 +#define IRQ_TNETV107X_DSP2ARM_INT0 21 +#define IRQ_TNETV107X_DSP2ARM_INT1 22 +#define IRQ_TNETV107X_ARM_NPMUIRQ 23 +#define IRQ_TNETV107X_USB1 24 +#define IRQ_TNETV107X_VLYNQ 25 +#define IRQ_TNETV107X_UART0_DMATX 26 +#define IRQ_TNETV107X_UART0_DMARX 27 +#define IRQ_TNETV107X_TDM1_TXMCSP 28 +#define IRQ_TNETV107X_SSP 29 +#define IRQ_TNETV107X_MCDMA_INT2 30 +#define IRQ_TNETV107X_MCDMA_INT3 31 +#define IRQ_TNETV107X_TDM_CODECIF_EOT 32 +#define IRQ_TNETV107X_IMCOP_SQR_ARM 33 +#define IRQ_TNETV107X_USB0 34 +#define IRQ_TNETV107X_USB_CDMA 35 +#define IRQ_TNETV107X_LCD 36 +#define IRQ_TNETV107X_KEYPAD 37 +#define IRQ_TNETV107X_KEYPAD_FREE 38 +#define IRQ_TNETV107X_RNG 39 +#define IRQ_TNETV107X_PKA 40 +#define IRQ_TNETV107X_TDM0_TXDMA 41 +#define IRQ_TNETV107X_TDM0_RXDMA 42 +#define IRQ_TNETV107X_TDM0_TXMCSP 43 +#define IRQ_TNETV107X_TDM0_RXMCSP 44 +#define IRQ_TNETV107X_TDM1_RXMCSP 45 +#define IRQ_TNETV107X_SDIO1 46 +#define IRQ_TNETV107X_SDIO0 47 +#define IRQ_TNETV107X_TSC 48 +#define IRQ_TNETV107X_TS 49 +#define IRQ_TNETV107X_UART1 50 +#define IRQ_TNETV107X_MBX_LITE 51 +#define IRQ_TNETV107X_GPIO_INT00 52 +#define IRQ_TNETV107X_GPIO_INT01 53 +#define IRQ_TNETV107X_GPIO_INT02 54 +#define IRQ_TNETV107X_GPIO_INT03 55 +#define IRQ_TNETV107X_UART2 56 +#define IRQ_TNETV107X_UART2_DMATX 57 +#define IRQ_TNETV107X_UART2_DMARX 58 +#define IRQ_TNETV107X_IMCOP_IMX 59 +#define IRQ_TNETV107X_IMCOP_VLCD 60 +#define IRQ_TNETV107X_AES 61 +#define IRQ_TNETV107X_DES 62 +#define IRQ_TNETV107X_SHAMD5 63 +#define IRQ_TNETV107X_TPCC_ERR 68 +#define IRQ_TNETV107X_TPCC_PROT 69 +#define IRQ_TNETV107X_TPTC0_ERR 70 +#define IRQ_TNETV107X_TPTC1_ERR 71 +#define IRQ_TNETV107X_UART0_ERR 72 +#define IRQ_TNETV107X_UART1_ERR 73 +#define IRQ_TNETV107X_AEMIF_ERR 74 +#define IRQ_TNETV107X_DDR_ERR 75 +#define IRQ_TNETV107X_WDTARM_INT0 76 +#define IRQ_TNETV107X_MCDMA_ERR 77 +#define IRQ_TNETV107X_GPIO_ERR 78 +#define IRQ_TNETV107X_MPU_ADDR 79 +#define IRQ_TNETV107X_MPU_PROT 80 +#define IRQ_TNETV107X_IOPU_ADDR 81 +#define IRQ_TNETV107X_IOPU_PROT 82 +#define IRQ_TNETV107X_KEYPAD_ADDR_ERR 83 +#define IRQ_TNETV107X_WDT0_ADDR_ERR 84 +#define IRQ_TNETV107X_WDT1_ADDR_ERR 85 +#define IRQ_TNETV107X_CLKCTL_ADDR_ERR 86 +#define IRQ_TNETV107X_PLL_UNLOCK 87 +#define IRQ_TNETV107X_WDTDSP_INT0 88 +#define IRQ_TNETV107X_SEC_CTRL_VIOLATION 89 +#define IRQ_TNETV107X_KEY_MNG_VIOLATION 90 +#define IRQ_TNETV107X_PBIST_CPU 91 +#define IRQ_TNETV107X_WDTARM 92 +#define IRQ_TNETV107X_PSC 93 +#define IRQ_TNETV107X_MMC0 94 +#define IRQ_TNETV107X_MMC1 95 + +#define TNETV107X_N_CP_INTC_IRQ 96 + /* da850 currently has the most gpio pins (144) */ #define DAVINCI_N_GPIO 144 /* da850 currently has the most irqs so use DA850_N_CP_INTC_IRQ */ -- cgit v1.2.3-59-g8ed1b From ef03592a1a8112309f1fca1c11fbaef8ab541ef2 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Thu, 25 Mar 2010 17:43:53 -0400 Subject: Davinci: tnetv107x cpu types Added tnetv107x cpu type definitions and cpu identification macros. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/cputype.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-davinci/include/mach/cputype.h b/arch/arm/mach-davinci/include/mach/cputype.h index 189b1ff13642..cea6b8972043 100644 --- a/arch/arm/mach-davinci/include/mach/cputype.h +++ b/arch/arm/mach-davinci/include/mach/cputype.h @@ -33,6 +33,7 @@ struct davinci_id { #define DAVINCI_CPU_ID_DM365 0x03650000 #define DAVINCI_CPU_ID_DA830 0x08300000 #define DAVINCI_CPU_ID_DA850 0x08500000 +#define DAVINCI_CPU_ID_TNETV107X 0x0b8a0000 #define IS_DAVINCI_CPU(type, id) \ static inline int is_davinci_ ##type(void) \ @@ -46,6 +47,7 @@ IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355) IS_DAVINCI_CPU(dm365, DAVINCI_CPU_ID_DM365) IS_DAVINCI_CPU(da830, DAVINCI_CPU_ID_DA830) IS_DAVINCI_CPU(da850, DAVINCI_CPU_ID_DA850) +IS_DAVINCI_CPU(tnetv107x, DAVINCI_CPU_ID_TNETV107X) #ifdef CONFIG_ARCH_DAVINCI_DM644x #define cpu_is_davinci_dm644x() is_davinci_dm644x() @@ -83,4 +85,10 @@ IS_DAVINCI_CPU(da850, DAVINCI_CPU_ID_DA850) #define cpu_is_davinci_da850() 0 #endif +#ifdef CONFIG_ARCH_DAVINCI_TNETV107X +#define cpu_is_davinci_tnetv107x() is_davinci_tnetv107x() +#else +#define cpu_is_davinci_tnetv107x() 0 +#endif + #endif -- cgit v1.2.3-59-g8ed1b From 7034217467abe91b5bc63fc2993bb8eec1cf3c9f Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 16 Apr 2010 21:29:11 +0400 Subject: DaVinci: move AEMIF #define's to the proper headers Currently each DaVinci board file #define's its own version of the EMIFA base addresses (all named DAVINCI_ASYNC_EMIF_*_BASE), which leads to duplication. Move these #define's to the SoC specific headers, changing their prefixes from 'DAVINCI' to the 'DM355', 'DM644X', and 'DM646X' since all these base addresses are SoC specific... And while at it, rename DM646X_ASYNC_EMIF_DATA_CE0_BASE to DM646X_ASYNC_EMIF_CS2_SPACE_BASE in order to match the DM646x datasheet. Signed-off-by: Sergei Shtylyov Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm355-evm.c | 11 ++++------- arch/arm/mach-davinci/board-dm355-leopard.c | 11 ++++------- arch/arm/mach-davinci/board-dm365-evm.c | 5 ----- arch/arm/mach-davinci/board-dm644x-evm.c | 18 ++++++------------ arch/arm/mach-davinci/board-dm646x-evm.c | 11 ++++------- arch/arm/mach-davinci/board-neuros-osd2.c | 11 ++++------- arch/arm/mach-davinci/board-sffsdr.c | 11 ++++------- arch/arm/mach-davinci/include/mach/dm355.h | 3 +++ arch/arm/mach-davinci/include/mach/dm365.h | 4 ++++ arch/arm/mach-davinci/include/mach/dm644x.h | 6 ++++++ arch/arm/mach-davinci/include/mach/dm646x.h | 3 +++ 11 files changed, 42 insertions(+), 52 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index aa48e3f69715..a0ad7d9f5c85 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -33,9 +33,6 @@ #include #include -#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000 -#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 - /* NOTE: this is geared for the standard config, with a socketed * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you * swap chips, maybe with a different block size, partitioning may @@ -86,12 +83,12 @@ static struct davinci_nand_pdata davinci_nand_data = { static struct resource davinci_nand_resources[] = { { - .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, - .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, + .start = DM355_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, .flags = IORESOURCE_MEM, }, { - .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, - .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .start = DM355_ASYNC_EMIF_CONTROL_BASE, + .end = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, }; diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index 21f32eb41e8c..c3d5a70a7f38 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -30,9 +30,6 @@ #include #include -#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000 -#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 - /* NOTE: this is geared for the standard config, with a socketed * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you * swap chips, maybe with a different block size, partitioning may @@ -82,12 +79,12 @@ static struct davinci_nand_pdata davinci_nand_data = { static struct resource davinci_nand_resources[] = { { - .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, - .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, + .start = DM355_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, .flags = IORESOURCE_MEM, }, { - .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, - .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .start = DM355_ASYNC_EMIF_CONTROL_BASE, + .end = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, }; diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index df4ab2105869..b98b35c9e0e2 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -54,11 +54,6 @@ static inline int have_tvp7002(void) return 0; } - -#define DM365_ASYNC_EMIF_CONTROL_BASE 0x01d10000 -#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 -#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 - #define DM365_EVM_PHY_MASK (0x2) #define DM365_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 95cef1f46ef2..d028bab6f981 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -43,12 +43,6 @@ #define DAVINCI_CFC_ATA_BASE 0x01C66000 -#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e00000 -#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE 0x06000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE 0x08000000 - #define LXT971_PHY_ID (0x001378e2) #define LXT971_PHY_MASK (0xfffffff0) @@ -92,8 +86,8 @@ static struct physmap_flash_data davinci_evm_norflash_data = { /* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF * limits addresses to 16M, so using addresses past 16M will wrap */ static struct resource davinci_evm_norflash_resource = { - .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, - .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, + .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, .flags = IORESOURCE_MEM, }; @@ -154,12 +148,12 @@ static struct davinci_nand_pdata davinci_evm_nandflash_data = { static struct resource davinci_evm_nandflash_resource[] = { { - .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, - .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, + .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, .flags = IORESOURCE_MEM, }, { - .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, - .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .start = DM644X_ASYNC_EMIF_CONTROL_BASE, + .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, }; diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 5ba3cb2daaa0..b22e22cefcdd 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -80,17 +80,14 @@ static struct davinci_nand_pdata davinci_nand_data = { .options = 0, }; -#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x20008000 -#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x42000000 - static struct resource davinci_nand_resources[] = { { - .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, - .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, + .start = DM646X_ASYNC_EMIF_CS2_SPACE_BASE, + .end = DM646X_ASYNC_EMIF_CS2_SPACE_BASE + SZ_32M - 1, .flags = IORESOURCE_MEM, }, { - .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, - .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .start = DM646X_ASYNC_EMIF_CONTROL_BASE, + .end = DM646X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, }; diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 1fadc68d9fbb..5afe37e3a4cb 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -43,9 +43,6 @@ #define DAVINCI_CFC_ATA_BASE 0x01C66000 -#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e00000 -#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 - #define LXT971_PHY_ID 0x001378e2 #define LXT971_PHY_MASK 0xfffffff0 @@ -98,12 +95,12 @@ static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = { static struct resource davinci_ntosd2_nandflash_resource[] = { { - .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, - .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, + .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, .flags = IORESOURCE_MEM, }, { - .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, - .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .start = DM644X_ASYNC_EMIF_CONTROL_BASE, + .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, }; diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index a7cf810bb13e..1ed0662cc0e4 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -45,9 +45,6 @@ #define SFFSDR_PHY_MASK (0x2) #define SFFSDR_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ -#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e00000 -#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 - static struct mtd_partition davinci_sffsdr_nandflash_partition[] = { /* U-Boot Environment: Block 0 * UBL: Block 1 @@ -76,12 +73,12 @@ static struct flash_platform_data davinci_sffsdr_nandflash_data = { static struct resource davinci_sffsdr_nandflash_resource[] = { { - .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, - .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, + .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, .flags = IORESOURCE_MEM, }, { - .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, - .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .start = DM644X_ASYNC_EMIF_CONTROL_BASE, + .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, }; diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h index 85536d8e8336..36dff4a0ce3f 100644 --- a/arch/arm/mach-davinci/include/mach/dm355.h +++ b/arch/arm/mach-davinci/include/mach/dm355.h @@ -15,6 +15,9 @@ #include #include +#define DM355_ASYNC_EMIF_CONTROL_BASE 0x01E10000 +#define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 + #define ASP1_TX_EVT_EN 1 #define ASP1_RX_EVT_EN 2 diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h index 3a37b5a6983c..ea5df3b49ec4 100644 --- a/arch/arm/mach-davinci/include/mach/dm365.h +++ b/arch/arm/mach-davinci/include/mach/dm365.h @@ -36,6 +36,10 @@ #define DAVINCI_DMA_VC_TX 2 #define DAVINCI_DMA_VC_RX 3 +#define DM365_ASYNC_EMIF_CONTROL_BASE 0x01D10000 +#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 +#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 + void __init dm365_init(void); void __init dm365_init_asp(struct snd_platform_data *pdata); void __init dm365_init_vc(struct snd_platform_data *pdata); diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h index 1a8b09ccc3c8..6fca568a0fd2 100644 --- a/arch/arm/mach-davinci/include/mach/dm644x.h +++ b/arch/arm/mach-davinci/include/mach/dm644x.h @@ -34,6 +34,12 @@ #define DM644X_EMAC_MDIO_OFFSET (0x4000) #define DM644X_EMAC_CNTRL_RAM_SIZE (0x2000) +#define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01E00000 +#define DM644X_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 +#define DM644X_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 +#define DM644X_ASYNC_EMIF_DATA_CE2_BASE 0x06000000 +#define DM644X_ASYNC_EMIF_DATA_CE3_BASE 0x08000000 + void __init dm644x_init(void); void __init dm644x_init_asp(struct snd_platform_data *pdata); void dm644x_set_vpfe_config(struct vpfe_config *cfg); diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h index 846da98b619a..4d62db7b6f94 100644 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ b/arch/arm/mach-davinci/include/mach/dm646x.h @@ -27,6 +27,9 @@ #define DM646X_ATA_REG_BASE (0x01C66000) +#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000 +#define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000 + void __init dm646x_init(void); void __init dm646x_init_ide(void); void __init dm646x_init_mcasp0(struct snd_platform_data *pdata); -- cgit v1.2.3-59-g8ed1b From 002cb2d2f1dde524b2aef6e43922984f6d1c8adc Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 16 Apr 2010 21:29:20 +0400 Subject: DA830 EVM: use DA8XX_AEMIF_*_BASE #define's The board file #define's its own version of EMIFA base addresses, while there are DA8XX_AEMIF_*_BASE macros #define'd in . Start using them instead. Signed-off-by: Sergei Shtylyov Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da830-evm.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 925705649ed0..8f079d2f1af9 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -33,9 +33,6 @@ #define DA830_EVM_PHY_MASK 0x0 #define DA830_EVM_MDIO_FREQUENCY 2200000 /* PHY bus frequency */ -#define DA830_EMIF25_ASYNC_DATA_CE3_BASE 0x62000000 -#define DA830_EMIF25_CONTROL_BASE 0x68000000 - /* * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4]. */ @@ -375,13 +372,13 @@ static struct davinci_nand_pdata da830_evm_nand_pdata = { static struct resource da830_evm_nand_resources[] = { [0] = { /* First memory resource is NAND I/O window */ - .start = DA830_EMIF25_ASYNC_DATA_CE3_BASE, - .end = DA830_EMIF25_ASYNC_DATA_CE3_BASE + PAGE_SIZE - 1, + .start = DA8XX_AEMIF_CS3_BASE, + .end = DA8XX_AEMIF_CS3_BASE + PAGE_SIZE - 1, .flags = IORESOURCE_MEM, }, [1] = { /* Second memory resource is AEMIF control registers */ - .start = DA830_EMIF25_CONTROL_BASE, - .end = DA830_EMIF25_CONTROL_BASE + SZ_32K - 1, + .start = DA8XX_AEMIF_CTL_BASE, + .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1, .flags = IORESOURCE_MEM, }, }; -- cgit v1.2.3-59-g8ed1b From ce100669d2ee202acac94d39f1a585c6b066cecc Mon Sep 17 00:00:00 2001 From: Thomas Koeller Date: Thu, 8 Apr 2010 17:01:56 +0200 Subject: davinci: DM365: Allow use of GPIO64_57 Extended the MUX configuration to allow use of GPIO terminals 64..57. Signed-off-by: Thomas Koeller Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm365.c | 1 + arch/arm/mach-davinci/include/mach/mux.h | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 871be5af2735..1ee3fc818174 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -576,6 +576,7 @@ MUX_CFG(DM365, SPI4_SDENA1, 4, 16, 3, 2, false) MUX_CFG(DM365, GPIO20, 3, 21, 3, 0, false) MUX_CFG(DM365, GPIO33, 4, 12, 3, 0, false) MUX_CFG(DM365, GPIO40, 4, 26, 3, 0, false) +MUX_CFG(DM365, GPIO64_57, 2, 6, 1, 0, false) MUX_CFG(DM365, VOUT_FIELD, 1, 18, 3, 1, false) MUX_CFG(DM365, VOUT_FIELD_G81, 1, 18, 3, 0, false) diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index 863890342a0a..923debec7487 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -291,6 +291,7 @@ enum davinci_dm365_index { DM365_GPIO20, DM365_GPIO33, DM365_GPIO40, + DM365_GPIO64_57, /* Video */ DM365_VOUT_FIELD, -- cgit v1.2.3-59-g8ed1b From d6961e6889a26de427aa6e0df823c789cf4a848f Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Wed, 14 Apr 2010 14:44:49 -0400 Subject: Davinci: configurable pll divider mask This patch allows socs to override the divider ratio mask by setting an optional field (div_ratio_mask) in the pll_data structure. Signed-off-by: Cyril Chemparathy Tested-by: Sandeep Paulraj Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/clock.c | 9 ++++++--- arch/arm/mach-davinci/clock.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 5de60ae57903..868cb7693499 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -279,7 +279,7 @@ static unsigned long clk_sysclk_recalc(struct clk *clk) v = __raw_readl(pll->base + clk->div_reg); if (v & PLLDIV_EN) { - plldiv = (v & PLLDIV_RATIO_MASK) + 1; + plldiv = (v & pll->div_ratio_mask) + 1; if (plldiv) rate /= plldiv; } @@ -319,7 +319,7 @@ static unsigned long clk_pllclk_recalc(struct clk *clk) if (pll->flags & PLL_HAS_PREDIV) { prediv = __raw_readl(pll->base + PREDIV); if (prediv & PLLDIV_EN) - prediv = (prediv & PLLDIV_RATIO_MASK) + 1; + prediv = (prediv & pll->div_ratio_mask) + 1; else prediv = 1; } @@ -331,7 +331,7 @@ static unsigned long clk_pllclk_recalc(struct clk *clk) if (pll->flags & PLL_HAS_POSTDIV) { postdiv = __raw_readl(pll->base + POSTDIV); if (postdiv & PLLDIV_EN) - postdiv = (postdiv & PLLDIV_RATIO_MASK) + 1; + postdiv = (postdiv & pll->div_ratio_mask) + 1; else postdiv = 1; } @@ -458,6 +458,9 @@ int __init davinci_clk_init(struct clk_lookup *clocks) clk->recalc = clk_leafclk_recalc; } + if (clk->pll_data && !clk->pll_data->div_ratio_mask) + clk->pll_data->div_ratio_mask = PLLDIV_RATIO_MASK; + if (clk->recalc) clk->rate = clk->recalc(clk); diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index 53a0f7b90119..ce260153a717 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -76,6 +76,7 @@ struct pll_data { u32 num; u32 flags; u32 input_rate; + u32 div_ratio_mask; }; #define PLL_HAS_PREDIV 0x01 #define PLL_HAS_POSTDIV 0x02 -- cgit v1.2.3-59-g8ed1b From 280faffb4e059b3f453e297af7060d9c277c0ca9 Mon Sep 17 00:00:00 2001 From: Thomas Koeller Date: Wed, 21 Apr 2010 15:33:32 +0200 Subject: davinci: mach/common.h: add missing includes linux/compiler.h is required for __iomem linux/types.h is required u32 Signed-off-by: Thomas Koeller Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/common.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 50a955f05ef9..d88104e6d66b 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -12,6 +12,9 @@ #ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H #define __ARCH_ARM_MACH_DAVINCI_COMMON_H +#include +#include + struct sys_timer; extern struct sys_timer davinci_timer; -- cgit v1.2.3-59-g8ed1b From 7a9978a1e2225507025a8b90b4289d506a416bd9 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 21 Apr 2010 18:11:33 +0400 Subject: DaVinci: move IDE platform device to its proper place The IDE platform device is registered in three different places (2 board files for DM644x and in dm646x.c for DM646x) while both the IDE base address and the IDE IRQ are the same for both SoCs -- therefore, the proper place for the IDE platform seems to be in devices.c. Merge the IDE platform data and registration code and create davinci_init_ide() in place of dm646x_init_ide()... Signed-off-by: Sergei Shtylyov Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm644x-evm.c | 33 +--------------------- arch/arm/mach-davinci/board-dm646x-evm.c | 2 +- arch/arm/mach-davinci/board-neuros-osd2.c | 34 ++-------------------- arch/arm/mach-davinci/devices.c | 44 +++++++++++++++++++++++++++++ arch/arm/mach-davinci/dm646x.c | 32 --------------------- arch/arm/mach-davinci/include/mach/common.h | 1 + arch/arm/mach-davinci/include/mach/dm646x.h | 3 -- 7 files changed, 49 insertions(+), 100 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index d028bab6f981..73c0b04a75ff 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -41,8 +41,6 @@ #define DM644X_EVM_PHY_MASK (0x2) #define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ -#define DAVINCI_CFC_ATA_BASE 0x01C66000 - #define LXT971_PHY_ID (0x001378e2) #define LXT971_PHY_MASK (0xfffffff0) @@ -252,32 +250,6 @@ static struct platform_device rtc_dev = { .id = -1, }; -static struct resource ide_resources[] = { - { - .start = DAVINCI_CFC_ATA_BASE, - .end = DAVINCI_CFC_ATA_BASE + 0x7ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_IDE, - .end = IRQ_IDE, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 ide_dma_mask = DMA_BIT_MASK(32); - -static struct platform_device ide_dev = { - .name = "palm_bk3710", - .id = -1, - .resource = ide_resources, - .num_resources = ARRAY_SIZE(ide_resources), - .dev = { - .dma_mask = &ide_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - static struct snd_platform_data dm644x_evm_snd_data; /*----------------------------------------------------------------------*/ @@ -698,10 +670,7 @@ static __init void davinci_evm_init(void) pr_warning("WARNING: both IDE and Flash are " "enabled, but they share AEMIF pins.\n" "\tDisable IDE for NAND/NOR support.\n"); - davinci_cfg_reg(DM644X_HPIEN_DISABLE); - davinci_cfg_reg(DM644X_ATAEN); - davinci_cfg_reg(DM644X_HDIREN); - platform_device_register(&ide_dev); + davinci_init_ide(); } else if (HAS_NAND || HAS_NOR) { davinci_cfg_reg(DM644X_HPIEN_DISABLE); davinci_cfg_reg(DM644X_ATAEN_DISABLE); diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index b22e22cefcdd..e2ac06fac02a 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -733,7 +733,7 @@ static __init void evm_init(void) platform_device_register(&davinci_nand_device); if (HAS_ATA) - dm646x_init_ide(); + davinci_init_ide(); soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK; soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY; diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 5afe37e3a4cb..875770cdea0a 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -41,8 +42,6 @@ #define NEUROS_OSD2_PHY_MASK 0x2 #define NEUROS_OSD2_MDIO_FREQUENCY 2200000 /* PHY bus frequency */ -#define DAVINCI_CFC_ATA_BASE 0x01C66000 - #define LXT971_PHY_ID 0x001378e2 #define LXT971_PHY_MASK 0xfffffff0 @@ -127,32 +126,6 @@ static struct platform_device davinci_fb_device = { .num_resources = 0, }; -static struct resource ide_resources[] = { - { - .start = DAVINCI_CFC_ATA_BASE, - .end = DAVINCI_CFC_ATA_BASE + 0x7ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_IDE, - .end = IRQ_IDE, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 ide_dma_mask = DMA_BIT_MASK(32); - -static struct platform_device ide_dev = { - .name = "palm_bk3710", - .id = -1, - .resource = ide_resources, - .num_resources = ARRAY_SIZE(ide_resources), - .dev = { - .dma_mask = &ide_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - static struct snd_platform_data dm644x_ntosd2_snd_data; static struct gpio_led ntosd2_leds[] = { @@ -256,10 +229,7 @@ static __init void davinci_ntosd2_init(void) pr_warning("WARNING: both IDE and Flash are " "enabled, but they share AEMIF pins.\n" "\tDisable IDE for NAND/NOR support.\n"); - davinci_cfg_reg(DM644X_HPIEN_DISABLE); - davinci_cfg_reg(DM644X_ATAEN); - davinci_cfg_reg(DM644X_HDIREN); - platform_device_register(&ide_dev); + davinci_init_ide(); } else if (HAS_NAND) { davinci_cfg_reg(DM644X_HPIEN_DISABLE); davinci_cfg_reg(DM644X_ATAEN_DISABLE); diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index ef28080b1fda..d9c82ee434e0 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -26,6 +26,7 @@ #include "clock.h" #define DAVINCI_I2C_BASE 0x01C21000 +#define DAVINCI_ATA_BASE 0x01C66000 #define DAVINCI_MMCSD0_BASE 0x01E10000 #define DM355_MMCSD0_BASE 0x01E11000 #define DM355_MMCSD1_BASE 0x01E00000 @@ -60,6 +61,49 @@ void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata) (void) platform_device_register(&davinci_i2c_device); } +static struct resource ide_resources[] = { + { + .start = DAVINCI_ATA_BASE, + .end = DAVINCI_ATA_BASE + 0x7ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_IDE, + .end = IRQ_IDE, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 ide_dma_mask = DMA_BIT_MASK(32); + +static struct platform_device ide_device = { + .name = "palm_bk3710", + .id = -1, + .resource = ide_resources, + .num_resources = ARRAY_SIZE(ide_resources), + .dev = { + .dma_mask = &ide_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init davinci_init_ide(void) +{ + if (cpu_is_davinci_dm644x()) { + davinci_cfg_reg(DM644X_HPIEN_DISABLE); + davinci_cfg_reg(DM644X_ATAEN); + davinci_cfg_reg(DM644X_HDIREN); + } else if (cpu_is_davinci_dm646x()) { + /* IRQ_DM646X_IDE is the same as IRQ_IDE */ + davinci_cfg_reg(DM646X_ATAEN); + } else { + WARN_ON(1); + return; + } + + platform_device_register(&ide_device); +} + #if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE) static u64 mmcsd0_dma_mask = DMA_BIT_MASK(32); diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index b67b997d0bbc..a0b373957838 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -596,32 +596,6 @@ static struct platform_device dm646x_edma_device = { .resource = edma_resources, }; -static struct resource ide_resources[] = { - { - .start = DM646X_ATA_REG_BASE, - .end = DM646X_ATA_REG_BASE + 0x7ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_DM646X_IDE, - .end = IRQ_DM646X_IDE, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 ide_dma_mask = DMA_BIT_MASK(32); - -static struct platform_device ide_dev = { - .name = "palm_bk3710", - .id = -1, - .resource = ide_resources, - .num_resources = ARRAY_SIZE(ide_resources), - .dev = { - .dma_mask = &ide_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - static struct resource dm646x_mcasp0_resources[] = { { .name = "mcasp0", @@ -867,12 +841,6 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .sram_len = SZ_32K, }; -void __init dm646x_init_ide(void) -{ - davinci_cfg_reg(DM646X_ATAEN); - platform_device_register(&ide_dev); -} - void __init dm646x_init_mcasp0(struct snd_platform_data *pdata) { dm646x_mcasp0_device.dev.platform_data = pdata; diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index d88104e6d66b..884dc726e9b9 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -70,6 +70,7 @@ struct davinci_soc_info { extern struct davinci_soc_info davinci_soc_info; extern void davinci_common_init(struct davinci_soc_info *soc_info); +extern void davinci_init_ide(void); /* standard place to map on-chip SRAMs; they *may* support DMA */ #define SRAM_VIRT 0xfffe0000 diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h index 4d62db7b6f94..add6f794a362 100644 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ b/arch/arm/mach-davinci/include/mach/dm646x.h @@ -25,13 +25,10 @@ #define DM646X_EMAC_MDIO_OFFSET (0x4000) #define DM646X_EMAC_CNTRL_RAM_SIZE (0x2000) -#define DM646X_ATA_REG_BASE (0x01C66000) - #define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000 #define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000 void __init dm646x_init(void); -void __init dm646x_init_ide(void); void __init dm646x_init_mcasp0(struct snd_platform_data *pdata); void __init dm646x_init_mcasp1(struct snd_platform_data *pdata); void __init dm646x_board_setup_refclk(struct clk *clk); -- cgit v1.2.3-59-g8ed1b From ba4a984e838dfb1c46135ff8cadeea5f8ca5fd0a Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Sat, 1 May 2010 18:37:51 -0400 Subject: Davinci: gpio - minor cleanup macroized repeated container_of()s to improve readability. unified direction in/out functions. Signed-off-by: Cyril Chemparathy Tested-by: Sandeep Paulraj Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/gpio.c | 50 ++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 5476ad132044..93f7c686153a 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -28,6 +28,9 @@ struct davinci_gpio { int irq_base; }; +#define chip2controller(chip) \ + container_of(chip, struct davinci_gpio, chip) + static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; /* create a non-inlined version */ @@ -54,21 +57,39 @@ static int __init davinci_gpio_irq_setup(void); * needed, and enable the GPIO clock. */ -static int davinci_direction_in(struct gpio_chip *chip, unsigned offset) +static inline int __davinci_direction(struct gpio_chip *chip, + unsigned offset, bool out, int value) { - struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); + struct davinci_gpio *d = chip2controller(chip); struct gpio_controller __iomem *g = d->regs; u32 temp; + u32 mask = 1 << offset; spin_lock(&gpio_lock); temp = __raw_readl(&g->dir); - temp |= (1 << offset); + if (out) { + temp &= ~mask; + __raw_writel(mask, value ? &g->set_data : &g->clr_data); + } else { + temp |= mask; + } __raw_writel(temp, &g->dir); spin_unlock(&gpio_lock); return 0; } +static int davinci_direction_in(struct gpio_chip *chip, unsigned offset) +{ + return __davinci_direction(chip, offset, false, 0); +} + +static int +davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value) +{ + return __davinci_direction(chip, offset, true, value); +} + /* * Read the pin's value (works even if it's set up as output); * returns zero/nonzero. @@ -78,36 +99,19 @@ static int davinci_direction_in(struct gpio_chip *chip, unsigned offset) */ static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset) { - struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); + struct davinci_gpio *d = chip2controller(chip); struct gpio_controller __iomem *g = d->regs; return (1 << offset) & __raw_readl(&g->in_data); } -static int -davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value) -{ - struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); - struct gpio_controller __iomem *g = d->regs; - u32 temp; - u32 mask = 1 << offset; - - spin_lock(&gpio_lock); - temp = __raw_readl(&g->dir); - temp &= ~mask; - __raw_writel(mask, value ? &g->set_data : &g->clr_data); - __raw_writel(temp, &g->dir); - spin_unlock(&gpio_lock); - return 0; -} - /* * Assuming the pin is muxed as a gpio output, set its output value. */ static void davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { - struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); + struct davinci_gpio *d = chip2controller(chip); struct gpio_controller __iomem *g = d->regs; __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data); @@ -262,7 +266,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset) { - struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip); + struct davinci_gpio *d = chip2controller(chip); if (d->irq_base >= 0) return d->irq_base + offset; -- cgit v1.2.3-59-g8ed1b From 99e9e52de635728d7c89a0fdf79b307f3082cf3a Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Sat, 1 May 2010 18:37:52 -0400 Subject: Davinci: gpio - structs and functions renamed Renamed gpio types to something more sensible: struct gpio_controller --> struct davinci_gpio_regs struct davinci_gpio --> struct davinci_gpio_controller gpio2controller() --> gpio2regs() irq2controller() --> irq2regs() This change also moves davinci_gpio_controller definition to gpio.h. Eventually, the gpio registers structure will be moved to gpio.c and no longer a common cross-soc definition. Signed-off-by: Cyril Chemparathy Tested-by: Sandeep Paulraj Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/gpio.c | 50 ++++++++++++++----------------- arch/arm/mach-davinci/include/mach/gpio.h | 14 ++++++--- 2 files changed, 32 insertions(+), 32 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 93f7c686153a..c77683c3c3d2 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -22,28 +22,22 @@ static DEFINE_SPINLOCK(gpio_lock); -struct davinci_gpio { - struct gpio_chip chip; - struct gpio_controller __iomem *regs; - int irq_base; -}; - #define chip2controller(chip) \ - container_of(chip, struct davinci_gpio, chip) + container_of(chip, struct davinci_gpio_controller, chip) -static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; +static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; /* create a non-inlined version */ -static struct gpio_controller __iomem __init *gpio2controller(unsigned gpio) +static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio) { return __gpio_to_controller(gpio); } -static inline struct gpio_controller __iomem *irq2controller(int irq) +static inline struct davinci_gpio_regs __iomem *irq2regs(int irq) { - struct gpio_controller __iomem *g; + struct davinci_gpio_regs __iomem *g; - g = (__force struct gpio_controller __iomem *)get_irq_chip_data(irq); + g = (__force struct davinci_gpio_regs __iomem *)get_irq_chip_data(irq); return g; } @@ -60,8 +54,8 @@ static int __init davinci_gpio_irq_setup(void); static inline int __davinci_direction(struct gpio_chip *chip, unsigned offset, bool out, int value) { - struct davinci_gpio *d = chip2controller(chip); - struct gpio_controller __iomem *g = d->regs; + struct davinci_gpio_controller *d = chip2controller(chip); + struct davinci_gpio_regs __iomem *g = d->regs; u32 temp; u32 mask = 1 << offset; @@ -99,8 +93,8 @@ davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value) */ static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset) { - struct davinci_gpio *d = chip2controller(chip); - struct gpio_controller __iomem *g = d->regs; + struct davinci_gpio_controller *d = chip2controller(chip); + struct davinci_gpio_regs __iomem *g = d->regs; return (1 << offset) & __raw_readl(&g->in_data); } @@ -111,8 +105,8 @@ static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset) static void davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { - struct davinci_gpio *d = chip2controller(chip); - struct gpio_controller __iomem *g = d->regs; + struct davinci_gpio_controller *d = chip2controller(chip); + struct davinci_gpio_regs __iomem *g = d->regs; __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data); } @@ -150,7 +144,7 @@ static int __init davinci_gpio_setup(void) if (chips[i].chip.ngpio > 32) chips[i].chip.ngpio = 32; - chips[i].regs = gpio2controller(base); + chips[i].regs = gpio2regs(base); gpiochip_add(&chips[i].chip); } @@ -174,7 +168,7 @@ pure_initcall(davinci_gpio_setup); static void gpio_irq_disable(unsigned irq) { - struct gpio_controller __iomem *g = irq2controller(irq); + struct davinci_gpio_regs __iomem *g = irq2regs(irq); u32 mask = (u32) get_irq_data(irq); __raw_writel(mask, &g->clr_falling); @@ -183,7 +177,7 @@ static void gpio_irq_disable(unsigned irq) static void gpio_irq_enable(unsigned irq) { - struct gpio_controller __iomem *g = irq2controller(irq); + struct davinci_gpio_regs __iomem *g = irq2regs(irq); u32 mask = (u32) get_irq_data(irq); unsigned status = irq_desc[irq].status; @@ -199,7 +193,7 @@ static void gpio_irq_enable(unsigned irq) static int gpio_irq_type(unsigned irq, unsigned trigger) { - struct gpio_controller __iomem *g = irq2controller(irq); + struct davinci_gpio_regs __iomem *g = irq2regs(irq); u32 mask = (u32) get_irq_data(irq); if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) @@ -228,7 +222,7 @@ static struct irq_chip gpio_irqchip = { static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { - struct gpio_controller __iomem *g = irq2controller(irq); + struct davinci_gpio_regs __iomem *g = irq2regs(irq); u32 mask = 0xffff; /* we only care about one bank */ @@ -266,7 +260,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset) { - struct davinci_gpio *d = chip2controller(chip); + struct davinci_gpio_controller *d = chip2controller(chip); if (d->irq_base >= 0) return d->irq_base + offset; @@ -289,7 +283,7 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) static int gpio_irq_type_unbanked(unsigned irq, unsigned trigger) { - struct gpio_controller __iomem *g = irq2controller(irq); + struct davinci_gpio_regs __iomem *g = irq2regs(irq); u32 mask = (u32) get_irq_data(irq); if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) @@ -318,7 +312,7 @@ static int __init davinci_gpio_irq_setup(void) u32 binten = 0; unsigned ngpio, bank_irq; struct davinci_soc_info *soc_info = &davinci_soc_info; - struct gpio_controller __iomem *g; + struct davinci_gpio_regs __iomem *g; ngpio = soc_info->gpio_num; @@ -367,7 +361,7 @@ static int __init davinci_gpio_irq_setup(void) gpio_irqchip_unbanked.set_type = gpio_irq_type_unbanked; /* default trigger: both edges */ - g = gpio2controller(0); + g = gpio2regs(0); __raw_writel(~0, &g->set_falling); __raw_writel(~0, &g->set_rising); @@ -392,7 +386,7 @@ static int __init davinci_gpio_irq_setup(void) unsigned i; /* disabled by default, enabled only as needed */ - g = gpio2controller(gpio); + g = gpio2regs(gpio); __raw_writel(~0, &g->clr_falling); __raw_writel(~0, &g->clr_rising); diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h index 0099e6e5aff8..bdab001950ba 100644 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ b/arch/arm/mach-davinci/include/mach/gpio.h @@ -45,7 +45,7 @@ /* Convert GPIO signal to GPIO pin number */ #define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio)) -struct gpio_controller { +struct davinci_gpio_regs { u32 dir; u32 out_data; u32 set_data; @@ -58,6 +58,12 @@ struct gpio_controller { u32 intstat; }; +struct davinci_gpio_controller { + struct davinci_gpio_regs __iomem *regs; + struct gpio_chip chip; + int irq_base; +}; + /* The __gpio_to_controller() and __gpio_mask() functions inline to constants * with constant parameters; or in outlined code they execute at runtime. * @@ -67,7 +73,7 @@ struct gpio_controller { * * These are NOT part of the cross-platform GPIO interface */ -static inline struct gpio_controller __iomem * +static inline struct davinci_gpio_regs __iomem * __gpio_to_controller(unsigned gpio) { void __iomem *ptr; @@ -102,7 +108,7 @@ static inline u32 __gpio_mask(unsigned gpio) static inline void gpio_set_value(unsigned gpio, int value) { if (__builtin_constant_p(value) && gpio < DAVINCI_N_GPIO) { - struct gpio_controller __iomem *g; + struct davinci_gpio_regs __iomem *g; u32 mask; g = __gpio_to_controller(gpio); @@ -128,7 +134,7 @@ static inline void gpio_set_value(unsigned gpio, int value) */ static inline int gpio_get_value(unsigned gpio) { - struct gpio_controller __iomem *g; + struct davinci_gpio_regs __iomem *g; if (!__builtin_constant_p(gpio) || gpio >= DAVINCI_N_GPIO) return __gpio_get_value(gpio); -- cgit v1.2.3-59-g8ed1b From c12f415a9144a76dc99df34f56ce3022207ad1d0 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Sat, 1 May 2010 18:37:53 -0400 Subject: Davinci: gpio - register layout invariant inlines This patch renders the inlined gpio accessors in gpio.h independent of the underlying controller's register layout. This is done by including three new fields in davinci_gpio_controller to hold the addresses of the set, clear, and in data registers. Other changes: 1. davinci_gpio_regs structure definition moved to gpio.c. This structure is no longer common across all davinci socs (davinci_gpio_controller is). 2. controller base address calculation code (gpio2controller()) moved to gpio.c as this was no longer necessary for the inline implementation. 3. modified inline range checks to use davinci_soc_info.gpio_num instead of DAVINCI_N_GPIO. Signed-off-by: Cyril Chemparathy Tested-by: Sandeep Paulraj Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/gpio.c | 41 ++++++++++++++++-- arch/arm/mach-davinci/include/mach/common.h | 4 ++ arch/arm/mach-davinci/include/mach/gpio.h | 65 ++++++++++------------------- 3 files changed, 65 insertions(+), 45 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index c77683c3c3d2..d241b4f2abe2 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -20,6 +20,19 @@ #include +struct davinci_gpio_regs { + u32 dir; + u32 out_data; + u32 set_data; + u32 clr_data; + u32 in_data; + u32 set_rising; + u32 clr_rising; + u32 set_falling; + u32 clr_falling; + u32 intstat; +}; + static DEFINE_SPINLOCK(gpio_lock); #define chip2controller(chip) \ @@ -27,10 +40,24 @@ static DEFINE_SPINLOCK(gpio_lock); static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; -/* create a non-inlined version */ static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio) { - return __gpio_to_controller(gpio); + void __iomem *ptr; + void __iomem *base = davinci_soc_info.gpio_base; + + if (gpio < 32 * 1) + ptr = base + 0x10; + else if (gpio < 32 * 2) + ptr = base + 0x38; + else if (gpio < 32 * 3) + ptr = base + 0x60; + else if (gpio < 32 * 4) + ptr = base + 0x88; + else if (gpio < 32 * 5) + ptr = base + 0xb0; + else + ptr = NULL; + return ptr; } static inline struct davinci_gpio_regs __iomem *irq2regs(int irq) @@ -116,6 +143,7 @@ static int __init davinci_gpio_setup(void) int i, base; unsigned ngpio; struct davinci_soc_info *soc_info = &davinci_soc_info; + struct davinci_gpio_regs *regs; /* * The gpio banks conceptually expose a segmented bitmap, @@ -144,11 +172,18 @@ static int __init davinci_gpio_setup(void) if (chips[i].chip.ngpio > 32) chips[i].chip.ngpio = 32; - chips[i].regs = gpio2regs(base); + regs = gpio2regs(base); + chips[i].regs = regs; + chips[i].set_data = ®s->set_data; + chips[i].clr_data = ®s->clr_data; + chips[i].in_data = ®s->in_data; gpiochip_add(&chips[i].chip); } + soc_info->gpio_ctlrs = chips; + soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32); + davinci_gpio_irq_setup(); return 0; } diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 884dc726e9b9..1d72883f593e 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -37,6 +37,8 @@ struct davinci_timer_info { unsigned int clocksource_id; }; +struct davinci_gpio_controller; + /* SoC specific init support */ struct davinci_soc_info { struct map_desc *io_desc; @@ -61,6 +63,8 @@ struct davinci_soc_info { unsigned gpio_num; unsigned gpio_irq; unsigned gpio_unbanked; + struct davinci_gpio_controller *gpio_ctlrs; + int gpio_ctlrs_num; struct platform_device *serial_dev; struct emac_platform_data *emac_pdata; dma_addr_t sram_dma; diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h index bdab001950ba..82591d0d48fb 100644 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ b/arch/arm/mach-davinci/include/mach/gpio.h @@ -45,23 +45,13 @@ /* Convert GPIO signal to GPIO pin number */ #define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio)) -struct davinci_gpio_regs { - u32 dir; - u32 out_data; - u32 set_data; - u32 clr_data; - u32 in_data; - u32 set_rising; - u32 clr_rising; - u32 set_falling; - u32 clr_falling; - u32 intstat; -}; - struct davinci_gpio_controller { - struct davinci_gpio_regs __iomem *regs; struct gpio_chip chip; int irq_base; + void __iomem *regs; + void __iomem *set_data; + void __iomem *clr_data; + void __iomem *in_data; }; /* The __gpio_to_controller() and __gpio_mask() functions inline to constants @@ -73,25 +63,16 @@ struct davinci_gpio_controller { * * These are NOT part of the cross-platform GPIO interface */ -static inline struct davinci_gpio_regs __iomem * +static inline struct davinci_gpio_controller * __gpio_to_controller(unsigned gpio) { - void __iomem *ptr; - void __iomem *base = davinci_soc_info.gpio_base; - - if (gpio < 32 * 1) - ptr = base + 0x10; - else if (gpio < 32 * 2) - ptr = base + 0x38; - else if (gpio < 32 * 3) - ptr = base + 0x60; - else if (gpio < 32 * 4) - ptr = base + 0x88; - else if (gpio < 32 * 5) - ptr = base + 0xb0; - else - ptr = NULL; - return ptr; + struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs; + int index = gpio / 32; + + if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num) + return NULL; + + return ctlrs + index; } static inline u32 __gpio_mask(unsigned gpio) @@ -107,16 +88,16 @@ static inline u32 __gpio_mask(unsigned gpio) */ static inline void gpio_set_value(unsigned gpio, int value) { - if (__builtin_constant_p(value) && gpio < DAVINCI_N_GPIO) { - struct davinci_gpio_regs __iomem *g; - u32 mask; + if (__builtin_constant_p(value) && gpio < davinci_soc_info.gpio_num) { + struct davinci_gpio_controller *ctlr; + u32 mask; - g = __gpio_to_controller(gpio); + ctlr = __gpio_to_controller(gpio); mask = __gpio_mask(gpio); if (value) - __raw_writel(mask, &g->set_data); + __raw_writel(mask, ctlr->set_data); else - __raw_writel(mask, &g->clr_data); + __raw_writel(mask, ctlr->clr_data); return; } @@ -134,18 +115,18 @@ static inline void gpio_set_value(unsigned gpio, int value) */ static inline int gpio_get_value(unsigned gpio) { - struct davinci_gpio_regs __iomem *g; + struct davinci_gpio_controller *ctlr; - if (!__builtin_constant_p(gpio) || gpio >= DAVINCI_N_GPIO) + if (!__builtin_constant_p(gpio) || gpio >= davinci_soc_info.gpio_num) return __gpio_get_value(gpio); - g = __gpio_to_controller(gpio); - return __gpio_mask(gpio) & __raw_readl(&g->in_data); + ctlr = __gpio_to_controller(gpio); + return __gpio_mask(gpio) & __raw_readl(ctlr->in_data); } static inline int gpio_cansleep(unsigned gpio) { - if (__builtin_constant_p(gpio) && gpio < DAVINCI_N_GPIO) + if (__builtin_constant_p(gpio) && gpio < davinci_soc_info.gpio_num) return 0; else return __gpio_cansleep(gpio); -- cgit v1.2.3-59-g8ed1b From 686b634a07451fc4fe3b712fe211bfa861a53241 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Sat, 1 May 2010 18:37:54 -0400 Subject: Davinci: gpio - controller type support This patch allows for gpio controllers that deviate from those found on traditional davinci socs. davinci_soc_info has an added field to indicate the soc-specific gpio controller type. The gpio initialization code then bails out if necessary. More elements (tnetv107x) to be added later into enum davinci_gpio_type. Signed-off-by: Cyril Chemparathy Tested-by: Sandeep Paulraj Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/da830.c | 2 ++ arch/arm/mach-davinci/da850.c | 2 ++ arch/arm/mach-davinci/dm355.c | 1 + arch/arm/mach-davinci/dm365.c | 1 + arch/arm/mach-davinci/dm644x.c | 1 + arch/arm/mach-davinci/dm646x.c | 1 + arch/arm/mach-davinci/gpio.c | 3 +++ arch/arm/mach-davinci/include/mach/common.h | 1 + arch/arm/mach-davinci/include/mach/gpio.h | 4 ++++ 9 files changed, 16 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 122e61a9f505..68e52337a1d9 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "clock.h" #include "mux.h" @@ -1199,6 +1200,7 @@ static struct davinci_soc_info davinci_soc_info_da830 = { .intc_irq_prios = da830_default_priorities, .intc_irq_num = DA830_N_CP_INTC_IRQ, .timer_info = &da830_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, .gpio_base = IO_ADDRESS(DA8XX_GPIO_BASE), .gpio_num = 128, .gpio_irq = IRQ_DA8XX_GPIO0, diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index d0fd7566712a..8aefcffa5ae2 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "clock.h" #include "mux.h" @@ -1084,6 +1085,7 @@ static struct davinci_soc_info davinci_soc_info_da850 = { .intc_irq_prios = da850_default_priorities, .intc_irq_num = DA850_N_CP_INTC_IRQ, .timer_info = &da850_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, .gpio_base = IO_ADDRESS(DA8XX_GPIO_BASE), .gpio_num = 144, .gpio_irq = IRQ_DA8XX_GPIO0, diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 5efce70ccdd0..f9a54ff2d249 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -859,6 +859,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .intc_irq_prios = dm355_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm355_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), .gpio_num = 104, .gpio_irq = IRQ_DM355_GPIOBNK0, diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 1ee3fc818174..05666754aebe 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1064,6 +1064,7 @@ static struct davinci_soc_info davinci_soc_info_dm365 = { .intc_irq_prios = dm365_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm365_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), .gpio_num = 104, .gpio_irq = IRQ_DM365_GPIO0, diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 23cbe9d04bc5..4af349efbd54 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -748,6 +748,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .intc_irq_prios = dm644x_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm644x_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), .gpio_num = 71, .gpio_irq = IRQ_GPIOBNK0, diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index a0b373957838..bdb1acebe203 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -832,6 +832,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .intc_irq_prios = dm646x_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm646x_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), .gpio_num = 43, /* Only 33 usable */ .gpio_irq = IRQ_DM646X_GPIOBNK0, diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index d241b4f2abe2..e422cd300d4c 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -145,6 +145,9 @@ static int __init davinci_gpio_setup(void) struct davinci_soc_info *soc_info = &davinci_soc_info; struct davinci_gpio_regs *regs; + if (soc_info->gpio_type != GPIO_TYPE_DAVINCI) + return 0; + /* * The gpio banks conceptually expose a segmented bitmap, * and "ngpio" is one more than the largest zero-based diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 1d72883f593e..8ffef5bbd9cf 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -59,6 +59,7 @@ struct davinci_soc_info { u8 *intc_irq_prios; unsigned long intc_irq_num; struct davinci_timer_info *timer_info; + int gpio_type; void __iomem *gpio_base; unsigned gpio_num; unsigned gpio_irq; diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h index 82591d0d48fb..9a71a26eb77f 100644 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ b/arch/arm/mach-davinci/include/mach/gpio.h @@ -21,6 +21,10 @@ #define DAVINCI_GPIO_BASE 0x01C67000 +enum davinci_gpio_type { + GPIO_TYPE_DAVINCI = 0, +}; + /* * basic gpio routines * -- cgit v1.2.3-59-g8ed1b From b27b6d03f245e5eaf6473da58a2612077fb7cfe7 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Sat, 1 May 2010 18:37:55 -0400 Subject: Davinci: gpio - fine grained locking This patch eliminates the global gpio_lock, and implements a per-controller lock instead. This also switches to irqsave/irqrestore locks in case gpios are manipulated in isr. Signed-off-by: Cyril Chemparathy Tested-by: Sandeep Paulraj Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/gpio.c | 9 +++++---- arch/arm/mach-davinci/include/mach/gpio.h | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index e422cd300d4c..b62d5e2bd37e 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -33,8 +33,6 @@ struct davinci_gpio_regs { u32 intstat; }; -static DEFINE_SPINLOCK(gpio_lock); - #define chip2controller(chip) \ container_of(chip, struct davinci_gpio_controller, chip) @@ -83,10 +81,11 @@ static inline int __davinci_direction(struct gpio_chip *chip, { struct davinci_gpio_controller *d = chip2controller(chip); struct davinci_gpio_regs __iomem *g = d->regs; + unsigned long flags; u32 temp; u32 mask = 1 << offset; - spin_lock(&gpio_lock); + spin_lock_irqsave(&d->lock, flags); temp = __raw_readl(&g->dir); if (out) { temp &= ~mask; @@ -95,7 +94,7 @@ static inline int __davinci_direction(struct gpio_chip *chip, temp |= mask; } __raw_writel(temp, &g->dir); - spin_unlock(&gpio_lock); + spin_unlock_irqrestore(&d->lock, flags); return 0; } @@ -175,6 +174,8 @@ static int __init davinci_gpio_setup(void) if (chips[i].chip.ngpio > 32) chips[i].chip.ngpio = 32; + spin_lock_init(&chips[i].lock); + regs = gpio2regs(base); chips[i].regs = regs; chips[i].set_data = ®s->set_data; diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h index 9a71a26eb77f..504cc180a60b 100644 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ b/arch/arm/mach-davinci/include/mach/gpio.h @@ -14,6 +14,8 @@ #define __DAVINCI_GPIO_H #include +#include + #include #include @@ -52,6 +54,7 @@ enum davinci_gpio_type { struct davinci_gpio_controller { struct gpio_chip chip; int irq_base; + spinlock_t lock; void __iomem *regs; void __iomem *set_data; void __iomem *clr_data; -- cgit v1.2.3-59-g8ed1b From 5b3a05ca911688c53680f2b020a1512b9da29c89 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Sat, 1 May 2010 18:38:27 -0400 Subject: Davinci: eliminate pinmux offset verbosity Pinmux registers are sequential, and do not need to be enumerated out as they currently are. This reduces code volume and keeps things simple. If some future SoC comes up with a discontiguous register map, PINMUX() can then be expanded with local token pasting. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm355.c | 5 ----- arch/arm/mach-davinci/dm365.c | 5 ----- arch/arm/mach-davinci/dm644x.c | 3 --- arch/arm/mach-davinci/dm646x.c | 3 --- arch/arm/mach-davinci/gpio.c | 6 +----- arch/arm/mach-davinci/include/mach/da8xx.h | 21 --------------------- arch/arm/mach-davinci/include/mach/mux.h | 2 ++ arch/arm/mach-davinci/mux.h | 2 +- 8 files changed, 4 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index f9a54ff2d249..f91e9a1ab921 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -450,11 +450,6 @@ void __init dm355_init_spi0(unsigned chipselect_mask, /*----------------------------------------------------------------------*/ -#define PINMUX0 0x00 -#define PINMUX1 0x04 -#define PINMUX2 0x08 -#define PINMUX3 0x0c -#define PINMUX4 0x10 #define INTMUX 0x18 #define EVTMUX 0x1c diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 05666754aebe..f2b1d93b2256 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -467,11 +467,6 @@ static struct clk_lookup dm365_clks[] = { /*----------------------------------------------------------------------*/ -#define PINMUX0 0x00 -#define PINMUX1 0x04 -#define PINMUX2 0x08 -#define PINMUX3 0x0c -#define PINMUX4 0x10 #define INTMUX 0x18 #define EVTMUX 0x1c diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 4af349efbd54..85c88ecd6cf0 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -350,9 +350,6 @@ static struct platform_device dm644x_emac_device = { .resource = dm644x_emac_resources, }; -#define PINMUX0 0x00 -#define PINMUX1 0x04 - /* * Device specific mux setup * diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index bdb1acebe203..a8189c919e92 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -401,9 +401,6 @@ static struct platform_device dm646x_emac_device = { .resource = dm646x_emac_resources, }; -#define PINMUX0 0x00 -#define PINMUX1 0x04 - /* * Device specific mux setup * diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index b62d5e2bd37e..2efb4468ebd0 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -71,11 +71,7 @@ static int __init davinci_gpio_irq_setup(void); /*--------------------------------------------------------------------------*/ -/* - * board setup code *MUST* set PINMUX0 and PINMUX1 as - * needed, and enable the GPIO clock. - */ - +/* board setup code *MUST* setup pinmux and enable the GPIO clock. */ static inline int __davinci_direction(struct gpio_chip *chip, unsigned offset, bool out, int value) { diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 33471c9cbca3..dbb4ebe4d114 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -64,27 +64,6 @@ extern void __iomem *da8xx_syscfg1_base; #define DA8XX_DDR2_CTL_BASE 0xb0000000 #define DA8XX_ARM_RAM_BASE 0xffff0000 -#define PINMUX0 0x00 -#define PINMUX1 0x04 -#define PINMUX2 0x08 -#define PINMUX3 0x0c -#define PINMUX4 0x10 -#define PINMUX5 0x14 -#define PINMUX6 0x18 -#define PINMUX7 0x1c -#define PINMUX8 0x20 -#define PINMUX9 0x24 -#define PINMUX10 0x28 -#define PINMUX11 0x2c -#define PINMUX12 0x30 -#define PINMUX13 0x34 -#define PINMUX14 0x38 -#define PINMUX15 0x3c -#define PINMUX16 0x40 -#define PINMUX17 0x44 -#define PINMUX18 0x48 -#define PINMUX19 0x4c - void __init da830_init(void); void __init da850_init(void); diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index 923debec7487..743dbd2e0ea3 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -1174,6 +1174,8 @@ enum davinci_tnetv107x_index { TNETV107X_TDM0_RX, }; +#define PINMUX(x) (4 * (x)) + #ifdef CONFIG_DAVINCI_MUX /* setup pin muxing */ extern int davinci_cfg_reg(unsigned long reg_cfg); diff --git a/arch/arm/mach-davinci/mux.h b/arch/arm/mach-davinci/mux.h index adc869413371..5aad1e7dd210 100644 --- a/arch/arm/mach-davinci/mux.h +++ b/arch/arm/mach-davinci/mux.h @@ -20,7 +20,7 @@ .name = #desc, \ .debug = dbg, \ .mux_reg_name = "PINMUX"#muxreg, \ - .mux_reg = PINMUX##muxreg, \ + .mux_reg = PINMUX(muxreg), \ .mask_offset = mode_offset, \ .mask = mode_mask, \ .mode = mux_mode, \ -- cgit v1.2.3-59-g8ed1b From c78a5bc2e77e8fc5be29cda5b28c9b9afd0f4b6d Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Sat, 1 May 2010 18:38:28 -0400 Subject: Davinci: watchdog reset separation across socs The earlier watchdog reset mechanism had a couple of limitations. First, it embedded a reference to "davinci_wdt_device" inside common code. This forced all derived platforms (da8xx and tnetv107x) to define such a device. This also would have caused problems in including multiple socs in a single build due to symbol redefinition. With this patch, davinci_watchdog_reset() now takes the platform device as an argument. The davinci_soc_info struct has been extended to include a reset function and a watchdog platform_device. arch_reset() then uses these elements to reset the system in a SoC specific fashion. Signed-off-by: Cyril Chemparathy Tested-by: Sandeep Paulraj Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/clock.h | 1 + arch/arm/mach-davinci/common.c | 3 +++ arch/arm/mach-davinci/da830.c | 1 + arch/arm/mach-davinci/da850.c | 1 + arch/arm/mach-davinci/devices-da8xx.c | 4 ++-- arch/arm/mach-davinci/dm355.c | 1 + arch/arm/mach-davinci/dm365.c | 1 + arch/arm/mach-davinci/dm644x.c | 1 + arch/arm/mach-davinci/dm646x.c | 1 + arch/arm/mach-davinci/include/mach/common.h | 2 ++ arch/arm/mach-davinci/include/mach/da8xx.h | 2 ++ arch/arm/mach-davinci/include/mach/system.h | 5 +++-- arch/arm/mach-davinci/time.c | 9 ++++++--- 13 files changed, 25 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index ce260153a717..01e36483ac3d 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -120,6 +120,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv, unsigned int mult, unsigned int postdiv); extern struct platform_device davinci_wdt_device; +extern void davinci_watchdog_reset(struct platform_device *); #endif diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 94f27cbcd55a..f8221c5ee380 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -77,6 +77,9 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) local_flush_tlb_all(); flush_cache_all(); + if (!davinci_soc_info.reset) + davinci_soc_info.reset = davinci_watchdog_reset; + /* * We want to check CPU revision early for cpu_is_xxxx() macros. * IO space mapping must be initialized before we can do that. diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 68e52337a1d9..83879f894a21 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -1206,6 +1206,7 @@ static struct davinci_soc_info davinci_soc_info_da830 = { .gpio_irq = IRQ_DA8XX_GPIO0, .serial_dev = &da8xx_serial_device, .emac_pdata = &da8xx_emac_pdata, + .reset_device = &da8xx_wdt_device, }; void __init da830_init(void) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 8aefcffa5ae2..2b6dd59d72f2 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1093,6 +1093,7 @@ static struct davinci_soc_info davinci_soc_info_da850 = { .emac_pdata = &da8xx_emac_pdata, .sram_dma = DA8XX_ARM_RAM_BASE, .sram_len = SZ_8K, + .reset_device = &da8xx_wdt_device, }; void __init da850_init(void) diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 0a96791d3b0f..67a6fbcb2e09 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -326,7 +326,7 @@ static struct resource da8xx_watchdog_resources[] = { }, }; -struct platform_device davinci_wdt_device = { +struct platform_device da8xx_wdt_device = { .name = "watchdog", .id = -1, .num_resources = ARRAY_SIZE(da8xx_watchdog_resources), @@ -335,7 +335,7 @@ struct platform_device davinci_wdt_device = { int __init da8xx_register_watchdog(void) { - return platform_device_register(&davinci_wdt_device); + return platform_device_register(&da8xx_wdt_device); } static struct resource da8xx_emac_resources[] = { diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index f91e9a1ab921..0c62a68a90a3 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -861,6 +861,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .serial_dev = &dm355_serial_device, .sram_dma = 0x00010000, .sram_len = SZ_32K, + .reset_device = &davinci_wdt_device, }; void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata) diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index f2b1d93b2256..ed7645088052 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1068,6 +1068,7 @@ static struct davinci_soc_info davinci_soc_info_dm365 = { .emac_pdata = &dm365_emac_pdata, .sram_dma = 0x00010000, .sram_len = SZ_32K, + .reset_device = &davinci_wdt_device, }; void __init dm365_init_asp(struct snd_platform_data *pdata) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 85c88ecd6cf0..7f36c22a2684 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -753,6 +753,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .emac_pdata = &dm644x_emac_pdata, .sram_dma = 0x00008000, .sram_len = SZ_16K, + .reset_device = &davinci_wdt_device, }; void __init dm644x_init_asp(struct snd_platform_data *pdata) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index a8189c919e92..8dd0afee7593 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -837,6 +837,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .emac_pdata = &dm646x_emac_pdata, .sram_dma = 0x10010000, .sram_len = SZ_32K, + .reset_device = &davinci_wdt_device, }; void __init dm646x_init_mcasp0(struct snd_platform_data *pdata) diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 8ffef5bbd9cf..a58bd88ba02d 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -70,6 +70,8 @@ struct davinci_soc_info { struct emac_platform_data *emac_pdata; dma_addr_t sram_dma; unsigned sram_len; + struct platform_device *reset_device; + void (*reset)(struct platform_device *); }; extern struct davinci_soc_info davinci_soc_info; diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index dbb4ebe4d114..1b31a9aa8fba 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -87,6 +87,8 @@ extern struct emac_platform_data da8xx_emac_pdata; extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata; extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata; +extern struct platform_device da8xx_wdt_device; + extern const short da830_emif25_pins[]; extern const short da830_spi0_pins[]; extern const short da830_spi1_pins[]; diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h index 5a7d7581b8ce..e65629c20769 100644 --- a/arch/arm/mach-davinci/include/mach/system.h +++ b/arch/arm/mach-davinci/include/mach/system.h @@ -11,7 +11,7 @@ #ifndef __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H -extern void davinci_watchdog_reset(void); +#include static inline void arch_idle(void) { @@ -20,7 +20,8 @@ static inline void arch_idle(void) static inline void arch_reset(char mode, const char *cmd) { - davinci_watchdog_reset(); + if (davinci_soc_info.reset) + davinci_soc_info.reset(davinci_soc_info.reset_device); } #endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index b21f7633d9a8..e5c598a387be 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -399,13 +399,16 @@ struct sys_timer davinci_timer = { /* reset board using watchdog timer */ -void davinci_watchdog_reset(void) +void davinci_watchdog_reset(struct platform_device *pdev) { u32 tgcr, wdtcr; - struct platform_device *pdev = &davinci_wdt_device; - void __iomem *base = IO_ADDRESS(pdev->resource[0].start); + void __iomem *base; struct clk *wd_clk; + base = ioremap(pdev->resource[0].start, SZ_4K); + if (WARN_ON(!base)) + return; + wd_clk = clk_get(&pdev->dev, NULL); if (WARN_ON(IS_ERR(wd_clk))) return; -- cgit v1.2.3-59-g8ed1b From da0122ca8b7804b9cd8fa7eff466bafba27f09a3 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Sun, 2 May 2010 14:28:12 -0400 Subject: Davinci: serial - remove unnecessary define The uart pdata array is already terminated by a zero flag field. This patch reuses this terminator and eliminates DAVINCI_MAX_NR_UARTS definition. This way, future platforms can have different number of uarts initialized via davinci_serial_init(). Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/serial.h | 1 - arch/arm/mach-davinci/serial.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h index a584697a9e70..f6c4f34909a2 100644 --- a/arch/arm/mach-davinci/include/mach/serial.h +++ b/arch/arm/mach-davinci/include/mach/serial.h @@ -13,7 +13,6 @@ #include -#define DAVINCI_MAX_NR_UARTS 3 #define DAVINCI_UART0_BASE (IO_PHYS + 0x20000) #define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) #define DAVINCI_UART2_BASE (IO_PHYS + 0x20800) diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c index 7ce5ba086575..709e1a90ec2a 100644 --- a/arch/arm/mach-davinci/serial.c +++ b/arch/arm/mach-davinci/serial.c @@ -77,7 +77,7 @@ int __init davinci_serial_init(struct davinci_uart_config *info) * Make sure the serial ports are muxed on at this point. * You have to mux them off in device drivers later on if not needed. */ - for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++, p++) { + for (i = 0; p->flags; i++, p++) { if (!(info->enabled_uarts & (1 << i))) continue; -- cgit v1.2.3-59-g8ed1b From 9ee1acefa86083c6acf4112983b88a0057eb7785 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Sun, 2 May 2010 14:28:13 -0400 Subject: Davinci: serial - use ioremap() This patch implements davinci serial cleanups towards having this code reusable on tnetv107x. The change reuses the platform data membase field to hold the remapped space. By disabling the UPF_IOREMAP flag in the platform data, we prevent the 8250 driver from repeating the ioremap. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/serial.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c index 709e1a90ec2a..81af42ca29d2 100644 --- a/arch/arm/mach-davinci/serial.c +++ b/arch/arm/mach-davinci/serial.c @@ -35,14 +35,20 @@ static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, int offset) { offset <<= up->regshift; - return (unsigned int)__raw_readl(IO_ADDRESS(up->mapbase) + offset); + + WARN_ONCE(!up->membase, "unmapped read: uart[%d]\n", offset); + + return (unsigned int)__raw_readl(up->membase + offset); } static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, int value) { offset <<= p->regshift; - __raw_writel(value, IO_ADDRESS(p->mapbase) + offset); + + WARN_ONCE(!p->membase, "unmapped write: uart[%d]\n", offset); + + __raw_writel(value, p->membase + offset); } static void __init davinci_serial_reset(struct plat_serial8250_port *p) @@ -83,14 +89,26 @@ int __init davinci_serial_init(struct davinci_uart_config *info) sprintf(name, "uart%d", i); uart_clk = clk_get(dev, name); - if (IS_ERR(uart_clk)) + if (IS_ERR(uart_clk)) { printk(KERN_ERR "%s:%d: failed to get UART%d clock\n", __func__, __LINE__, i); - else { - clk_enable(uart_clk); - p->uartclk = clk_get_rate(uart_clk); - davinci_serial_reset(p); + continue; } + + clk_enable(uart_clk); + p->uartclk = clk_get_rate(uart_clk); + + if (!p->membase && p->mapbase) { + p->membase = ioremap(p->mapbase, SZ_4K); + + if (p->membase) + p->flags &= ~UPF_IOREMAP; + else + pr_err("uart regs ioremap failed\n"); + } + + if (p->membase) + davinci_serial_reset(p); } return platform_device_register(soc_info->serial_dev); -- cgit v1.2.3-59-g8ed1b From e2800007f3b9aab51c1fe866034db576d3a9fd83 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Sun, 2 May 2010 14:28:14 -0400 Subject: Davinci: serial - conditional reset via pwremu With this patch, AR7 type uart ports are not reset via pwremu registers. This allows davinci_serial_init() reuse on tnetv107x soc. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c index 81af42ca29d2..1875740fe27c 100644 --- a/arch/arm/mach-davinci/serial.c +++ b/arch/arm/mach-davinci/serial.c @@ -107,7 +107,7 @@ int __init davinci_serial_init(struct davinci_uart_config *info) pr_err("uart regs ioremap failed\n"); } - if (p->membase) + if (p->membase && p->type != PORT_AR7) davinci_serial_reset(p); } -- cgit v1.2.3-59-g8ed1b From 3f68b98a75381f785f4e13085296c52c75ea29ac Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Tue, 4 May 2010 14:11:35 +0530 Subject: davinci: edma: use a more intuitive name for edma_info 'edma_info' structure inside the edma driver represents a single instance of edma channel controller. Call it 'edma_cc' instead. This also avoids readers confusing it with an instance of edma_soc_info structre which carries the platform data for a single channel controller instance. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dma.c | 158 +++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 81 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index 0bf290befa23..b705089e2bef 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -243,7 +243,7 @@ struct edma { } intr_data[EDMA_MAX_DMACH]; }; -static struct edma *edma_info[EDMA_MAX_CC]; +static struct edma *edma_cc[EDMA_MAX_CC]; static int arch_num_cc; /* dummy param set used to (re)initialize parameter RAM slots */ @@ -261,7 +261,7 @@ static void map_dmach_queue(unsigned ctlr, unsigned ch_no, /* default to low priority queue */ if (queue_no == EVENTQ_DEFAULT) - queue_no = edma_info[ctlr]->default_queue; + queue_no = edma_cc[ctlr]->default_queue; queue_no &= 7; edma_modify_array(ctlr, EDMA_DMAQNUM, (ch_no >> 3), @@ -315,8 +315,8 @@ setup_dma_interrupt(unsigned lch, (1 << (lch & 0x1f))); } - edma_info[ctlr]->intr_data[lch].callback = callback; - edma_info[ctlr]->intr_data[lch].data = data; + edma_cc[ctlr]->intr_data[lch].callback = callback; + edma_cc[ctlr]->intr_data[lch].data = data; if (callback) { edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5, @@ -328,11 +328,10 @@ setup_dma_interrupt(unsigned lch, static int irq2ctlr(int irq) { - if (irq >= edma_info[0]->irq_res_start && - irq <= edma_info[0]->irq_res_end) + if (irq >= edma_cc[0]->irq_res_start && irq <= edma_cc[0]->irq_res_end) return 0; - else if (irq >= edma_info[1]->irq_res_start && - irq <= edma_info[1]->irq_res_end) + else if (irq >= edma_cc[1]->irq_res_start && + irq <= edma_cc[1]->irq_res_end) return 1; return -1; @@ -377,10 +376,10 @@ static irqreturn_t dma_irq_handler(int irq, void *data) /* Clear the corresponding IPR bits */ edma_shadow0_write_array(ctlr, SH_ICR, j, (1 << i)); - if (edma_info[ctlr]->intr_data[k].callback) { - edma_info[ctlr]->intr_data[k].callback( + if (edma_cc[ctlr]->intr_data[k].callback) { + edma_cc[ctlr]->intr_data[k].callback( k, DMA_COMPLETE, - edma_info[ctlr]->intr_data[k]. + edma_cc[ctlr]->intr_data[k]. data); } } @@ -433,12 +432,12 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) /* Clear any SER */ edma_shadow0_write_array(ctlr, SH_SECR, j, (1 << i)); - if (edma_info[ctlr]->intr_data[k]. + if (edma_cc[ctlr]->intr_data[k]. callback) { - edma_info[ctlr]->intr_data[k]. + edma_cc[ctlr]->intr_data[k]. callback(k, DMA_CC_ERROR, - edma_info[ctlr]->intr_data + edma_cc[ctlr]->intr_data [k].data); } } @@ -514,9 +513,9 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id, int stop_slot = start_slot; DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY); - for (i = start_slot; i < edma_info[ctlr]->num_slots; ++i) { + for (i = start_slot; i < edma_cc[ctlr]->num_slots; ++i) { j = EDMA_CHAN_SLOT(i); - if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse)) { + if (!test_and_set_bit(j, edma_cc[ctlr]->edma_inuse)) { /* Record our current beginning slot */ if (count == num_slots) stop_slot = i; @@ -543,12 +542,12 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id, * of contiguous parameter RAM slots but do not find the exact number * requested as we may reach the total number of parameter RAM slots */ - if (i == edma_info[ctlr]->num_slots) + if (i == edma_cc[ctlr]->num_slots) stop_slot = i; for (j = start_slot; j < stop_slot; j++) if (test_bit(j, tmp_inuse)) - clear_bit(j, edma_info[ctlr]->edma_inuse); + clear_bit(j, edma_cc[ctlr]->edma_inuse); if (count) return -EBUSY; @@ -570,7 +569,7 @@ static int prepare_unused_channel_list(struct device *dev, void *data) (int)pdev->resource[i].start >= 0) { ctlr = EDMA_CTLR(pdev->resource[i].start); clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start), - edma_info[ctlr]->edma_unused); + edma_cc[ctlr]->edma_unused); } } @@ -644,14 +643,13 @@ int edma_alloc_channel(int channel, for (i = 0; i < arch_num_cc; i++) { channel = 0; for (;;) { - channel = find_next_bit(edma_info[i]-> - edma_unused, - edma_info[i]->num_channels, + channel = find_next_bit(edma_cc[i]->edma_unused, + edma_cc[i]->num_channels, channel); - if (channel == edma_info[i]->num_channels) + if (channel == edma_cc[i]->num_channels) break; if (!test_and_set_bit(channel, - edma_info[i]->edma_inuse)) { + edma_cc[i]->edma_inuse)) { done = 1; ctlr = i; break; @@ -663,9 +661,9 @@ int edma_alloc_channel(int channel, } if (!done) return -ENOMEM; - } else if (channel >= edma_info[ctlr]->num_channels) { + } else if (channel >= edma_cc[ctlr]->num_channels) { return -EINVAL; - } else if (test_and_set_bit(channel, edma_info[ctlr]->edma_inuse)) { + } else if (test_and_set_bit(channel, edma_cc[ctlr]->edma_inuse)) { return -EBUSY; } @@ -706,7 +704,7 @@ void edma_free_channel(unsigned channel) ctlr = EDMA_CTLR(channel); channel = EDMA_CHAN_SLOT(channel); - if (channel >= edma_info[ctlr]->num_channels) + if (channel >= edma_cc[ctlr]->num_channels) return; setup_dma_interrupt(channel, NULL, NULL); @@ -714,7 +712,7 @@ void edma_free_channel(unsigned channel) memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel), &dummy_paramset, PARM_SIZE); - clear_bit(channel, edma_info[ctlr]->edma_inuse); + clear_bit(channel, edma_cc[ctlr]->edma_inuse); } EXPORT_SYMBOL(edma_free_channel); @@ -738,20 +736,19 @@ int edma_alloc_slot(unsigned ctlr, int slot) slot = EDMA_CHAN_SLOT(slot); if (slot < 0) { - slot = edma_info[ctlr]->num_channels; + slot = edma_cc[ctlr]->num_channels; for (;;) { - slot = find_next_zero_bit(edma_info[ctlr]->edma_inuse, - edma_info[ctlr]->num_slots, slot); - if (slot == edma_info[ctlr]->num_slots) + slot = find_next_zero_bit(edma_cc[ctlr]->edma_inuse, + edma_cc[ctlr]->num_slots, slot); + if (slot == edma_cc[ctlr]->num_slots) return -ENOMEM; - if (!test_and_set_bit(slot, - edma_info[ctlr]->edma_inuse)) + if (!test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) break; } - } else if (slot < edma_info[ctlr]->num_channels || - slot >= edma_info[ctlr]->num_slots) { + } else if (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots) { return -EINVAL; - } else if (test_and_set_bit(slot, edma_info[ctlr]->edma_inuse)) { + } else if (test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) { return -EBUSY; } @@ -777,13 +774,13 @@ void edma_free_slot(unsigned slot) ctlr = EDMA_CTLR(slot); slot = EDMA_CHAN_SLOT(slot); - if (slot < edma_info[ctlr]->num_channels || - slot >= edma_info[ctlr]->num_slots) + if (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots) return; memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), &dummy_paramset, PARM_SIZE); - clear_bit(slot, edma_info[ctlr]->edma_inuse); + clear_bit(slot, edma_cc[ctlr]->edma_inuse); } EXPORT_SYMBOL(edma_free_slot); @@ -821,8 +818,8 @@ int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) * of slots */ if ((id != EDMA_CONT_PARAMS_ANY) && - (slot < edma_info[ctlr]->num_channels || - slot >= edma_info[ctlr]->num_slots)) + (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots)) return -EINVAL; /* @@ -831,13 +828,13 @@ int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) * channels */ if (count < 1 || count > - (edma_info[ctlr]->num_slots - edma_info[ctlr]->num_channels)) + (edma_cc[ctlr]->num_slots - edma_cc[ctlr]->num_channels)) return -EINVAL; switch (id) { case EDMA_CONT_PARAMS_ANY: return reserve_contiguous_slots(ctlr, id, count, - edma_info[ctlr]->num_channels); + edma_cc[ctlr]->num_channels); case EDMA_CONT_PARAMS_FIXED_EXACT: case EDMA_CONT_PARAMS_FIXED_NOT_EXACT: return reserve_contiguous_slots(ctlr, id, count, slot); @@ -869,8 +866,8 @@ int edma_free_cont_slots(unsigned slot, int count) ctlr = EDMA_CTLR(slot); slot = EDMA_CHAN_SLOT(slot); - if (slot < edma_info[ctlr]->num_channels || - slot >= edma_info[ctlr]->num_slots || + if (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots || count < 1) return -EINVAL; @@ -880,7 +877,7 @@ int edma_free_cont_slots(unsigned slot, int count) memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free), &dummy_paramset, PARM_SIZE); - clear_bit(slot_to_free, edma_info[ctlr]->edma_inuse); + clear_bit(slot_to_free, edma_cc[ctlr]->edma_inuse); } return 0; @@ -910,7 +907,7 @@ void edma_set_src(unsigned slot, dma_addr_t src_port, ctlr = EDMA_CTLR(slot); slot = EDMA_CHAN_SLOT(slot); - if (slot < edma_info[ctlr]->num_slots) { + if (slot < edma_cc[ctlr]->num_slots) { unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot); if (mode) { @@ -948,7 +945,7 @@ void edma_set_dest(unsigned slot, dma_addr_t dest_port, ctlr = EDMA_CTLR(slot); slot = EDMA_CHAN_SLOT(slot); - if (slot < edma_info[ctlr]->num_slots) { + if (slot < edma_cc[ctlr]->num_slots) { unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot); if (mode) { @@ -1008,7 +1005,7 @@ void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx) ctlr = EDMA_CTLR(slot); slot = EDMA_CHAN_SLOT(slot); - if (slot < edma_info[ctlr]->num_slots) { + if (slot < edma_cc[ctlr]->num_slots) { edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot, 0xffff0000, src_bidx); edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot, @@ -1034,7 +1031,7 @@ void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx) ctlr = EDMA_CTLR(slot); slot = EDMA_CHAN_SLOT(slot); - if (slot < edma_info[ctlr]->num_slots) { + if (slot < edma_cc[ctlr]->num_slots) { edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot, 0x0000ffff, dest_bidx << 16); edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot, @@ -1081,7 +1078,7 @@ void edma_set_transfer_params(unsigned slot, ctlr = EDMA_CTLR(slot); slot = EDMA_CHAN_SLOT(slot); - if (slot < edma_info[ctlr]->num_slots) { + if (slot < edma_cc[ctlr]->num_slots) { edma_parm_modify(ctlr, PARM_LINK_BCNTRLD, slot, 0x0000ffff, bcnt_rld << 16); if (sync_mode == ASYNC) @@ -1111,9 +1108,9 @@ void edma_link(unsigned from, unsigned to) ctlr_to = EDMA_CTLR(to); to = EDMA_CHAN_SLOT(to); - if (from >= edma_info[ctlr_from]->num_slots) + if (from >= edma_cc[ctlr_from]->num_slots) return; - if (to >= edma_info[ctlr_to]->num_slots) + if (to >= edma_cc[ctlr_to]->num_slots) return; edma_parm_modify(ctlr_from, PARM_LINK_BCNTRLD, from, 0xffff0000, PARM_OFFSET(to)); @@ -1134,7 +1131,7 @@ void edma_unlink(unsigned from) ctlr = EDMA_CTLR(from); from = EDMA_CHAN_SLOT(from); - if (from >= edma_info[ctlr]->num_slots) + if (from >= edma_cc[ctlr]->num_slots) return; edma_parm_or(ctlr, PARM_LINK_BCNTRLD, from, 0xffff); } @@ -1161,7 +1158,7 @@ void edma_write_slot(unsigned slot, const struct edmacc_param *param) ctlr = EDMA_CTLR(slot); slot = EDMA_CHAN_SLOT(slot); - if (slot >= edma_info[ctlr]->num_slots) + if (slot >= edma_cc[ctlr]->num_slots) return; memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), param, PARM_SIZE); @@ -1183,7 +1180,7 @@ void edma_read_slot(unsigned slot, struct edmacc_param *param) ctlr = EDMA_CTLR(slot); slot = EDMA_CHAN_SLOT(slot); - if (slot >= edma_info[ctlr]->num_slots) + if (slot >= edma_cc[ctlr]->num_slots) return; memcpy_fromio(param, edmacc_regs_base[ctlr] + PARM_OFFSET(slot), PARM_SIZE); @@ -1208,7 +1205,7 @@ void edma_pause(unsigned channel) ctlr = EDMA_CTLR(channel); channel = EDMA_CHAN_SLOT(channel); - if (channel < edma_info[ctlr]->num_channels) { + if (channel < edma_cc[ctlr]->num_channels) { unsigned int mask = (1 << (channel & 0x1f)); edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask); @@ -1229,7 +1226,7 @@ void edma_resume(unsigned channel) ctlr = EDMA_CTLR(channel); channel = EDMA_CHAN_SLOT(channel); - if (channel < edma_info[ctlr]->num_channels) { + if (channel < edma_cc[ctlr]->num_channels) { unsigned int mask = (1 << (channel & 0x1f)); edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask); @@ -1255,12 +1252,12 @@ int edma_start(unsigned channel) ctlr = EDMA_CTLR(channel); channel = EDMA_CHAN_SLOT(channel); - if (channel < edma_info[ctlr]->num_channels) { + if (channel < edma_cc[ctlr]->num_channels) { int j = channel >> 5; unsigned int mask = (1 << (channel & 0x1f)); /* EDMA channels without event association */ - if (test_bit(channel, edma_info[ctlr]->edma_unused)) { + if (test_bit(channel, edma_cc[ctlr]->edma_unused)) { pr_debug("EDMA: ESR%d %08x\n", j, edma_shadow0_read_array(ctlr, SH_ESR, j)); edma_shadow0_write_array(ctlr, SH_ESR, j, mask); @@ -1301,7 +1298,7 @@ void edma_stop(unsigned channel) ctlr = EDMA_CTLR(channel); channel = EDMA_CHAN_SLOT(channel); - if (channel < edma_info[ctlr]->num_channels) { + if (channel < edma_cc[ctlr]->num_channels) { int j = channel >> 5; unsigned int mask = (1 << (channel & 0x1f)); @@ -1340,7 +1337,7 @@ void edma_clean_channel(unsigned channel) ctlr = EDMA_CTLR(channel); channel = EDMA_CHAN_SLOT(channel); - if (channel < edma_info[ctlr]->num_channels) { + if (channel < edma_cc[ctlr]->num_channels) { int j = (channel >> 5); unsigned int mask = 1 << (channel & 0x1f); @@ -1368,7 +1365,7 @@ void edma_clear_event(unsigned channel) ctlr = EDMA_CTLR(channel); channel = EDMA_CHAN_SLOT(channel); - if (channel >= edma_info[ctlr]->num_channels) + if (channel >= edma_cc[ctlr]->num_channels) return; if (channel < 32) edma_write(ctlr, EDMA_ECR, 1 << channel); @@ -1423,38 +1420,37 @@ static int __init edma_probe(struct platform_device *pdev) goto fail1; } - edma_info[j] = kmalloc(sizeof(struct edma), GFP_KERNEL); - if (!edma_info[j]) { + edma_cc[j] = kmalloc(sizeof(struct edma), GFP_KERNEL); + if (!edma_cc[j]) { status = -ENOMEM; goto fail1; } - memset(edma_info[j], 0, sizeof(struct edma)); + memset(edma_cc[j], 0, sizeof(struct edma)); - edma_info[j]->num_channels = min_t(unsigned, info[j].n_channel, + edma_cc[j]->num_channels = min_t(unsigned, info[j].n_channel, EDMA_MAX_DMACH); - edma_info[j]->num_slots = min_t(unsigned, info[j].n_slot, + edma_cc[j]->num_slots = min_t(unsigned, info[j].n_slot, EDMA_MAX_PARAMENTRY); - edma_info[j]->num_cc = min_t(unsigned, info[j].n_cc, - EDMA_MAX_CC); + edma_cc[j]->num_cc = min_t(unsigned, info[j].n_cc, EDMA_MAX_CC); - edma_info[j]->default_queue = info[j].default_queue; - if (!edma_info[j]->default_queue) - edma_info[j]->default_queue = EVENTQ_1; + edma_cc[j]->default_queue = info[j].default_queue; + if (!edma_cc[j]->default_queue) + edma_cc[j]->default_queue = EVENTQ_1; dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n", edmacc_regs_base[j]); - for (i = 0; i < edma_info[j]->num_slots; i++) + for (i = 0; i < edma_cc[j]->num_slots; i++) memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i), &dummy_paramset, PARM_SIZE); /* Mark all channels as unused */ - memset(edma_info[j]->edma_unused, 0xff, - sizeof(edma_info[j]->edma_unused)); + memset(edma_cc[j]->edma_unused, 0xff, + sizeof(edma_cc[j]->edma_unused)); sprintf(irq_name, "edma%d", j); irq[j] = platform_get_irq_byname(pdev, irq_name); - edma_info[j]->irq_res_start = irq[j]; + edma_cc[j]->irq_res_start = irq[j]; status = request_irq(irq[j], dma_irq_handler, 0, "edma", &pdev->dev); if (status < 0) { @@ -1465,7 +1461,7 @@ static int __init edma_probe(struct platform_device *pdev) sprintf(irq_name, "edma%d_err", j); err_irq[j] = platform_get_irq_byname(pdev, irq_name); - edma_info[j]->irq_res_end = err_irq[j]; + edma_cc[j]->irq_res_end = err_irq[j]; status = request_irq(err_irq[j], dma_ccerr_handler, 0, "edma_error", &pdev->dev); if (status < 0) { @@ -1478,7 +1474,7 @@ static int __init edma_probe(struct platform_device *pdev) * specified. This way, long transfers on the low priority queue * started by the codec engine will not cause audio defects. */ - for (i = 0; i < edma_info[j]->num_channels; i++) + for (i = 0; i < edma_cc[j]->num_channels; i++) map_dmach_queue(j, i, EVENTQ_1); queue_tc_mapping = info[j].queue_tc_mapping; @@ -1541,7 +1537,7 @@ fail1: release_mem_region(r[i]->start, len[i]); if (edmacc_regs_base[i]) iounmap(edmacc_regs_base[i]); - kfree(edma_info[i]); + kfree(edma_cc[i]); } return status; } -- cgit v1.2.3-59-g8ed1b From 243bc65447a74fbc674fc7fab6f212cce62e0152 Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Tue, 4 May 2010 14:11:36 +0530 Subject: davinci: edma: fix coding style issue related to usage of braces In the edma driver, there are couple of instances where braces are used for a single statement 'if' construct. There are other instances where 'else' part of the if-else construct does not use braces even if the 'if' part is a multi-line statement. This patch fixes both. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dma.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index b705089e2bef..cc5fcdad9b92 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -310,10 +310,9 @@ setup_dma_interrupt(unsigned lch, ctlr = EDMA_CTLR(lch); lch = EDMA_CHAN_SLOT(lch); - if (!callback) { + if (!callback) edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5, (1 << (lch & 0x1f))); - } edma_cc[ctlr]->intr_data[lch].callback = callback; edma_cc[ctlr]->intr_data[lch].data = data; @@ -376,12 +375,11 @@ static irqreturn_t dma_irq_handler(int irq, void *data) /* Clear the corresponding IPR bits */ edma_shadow0_write_array(ctlr, SH_ICR, j, (1 << i)); - if (edma_cc[ctlr]->intr_data[k].callback) { + if (edma_cc[ctlr]->intr_data[k].callback) edma_cc[ctlr]->intr_data[k].callback( k, DMA_COMPLETE, edma_cc[ctlr]->intr_data[k]. data); - } } } cnt++; @@ -473,9 +471,8 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) && (edma_read_array(ctlr, EDMA_EMR, 1) == 0) && (edma_read(ctlr, EDMA_QEMR) == 0) - && (edma_read(ctlr, EDMA_CCERR) == 0)) { + && (edma_read(ctlr, EDMA_CCERR) == 0)) break; - } cnt++; if (cnt > 10) break; @@ -531,8 +528,9 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id, if (id == EDMA_CONT_PARAMS_FIXED_EXACT) { stop_slot = i; break; - } else + } else { count = num_slots; + } } } @@ -1402,8 +1400,9 @@ static int __init edma_probe(struct platform_device *pdev) break; else return -ENODEV; - } else + } else { found = 1; + } len[j] = resource_size(r[j]); -- cgit v1.2.3-59-g8ed1b From ff3c25fa1b7f0a3c7b112c25af6d259cb8c59bc1 Mon Sep 17 00:00:00 2001 From: Pinkava J Date: Thu, 6 May 2010 15:18:06 +0200 Subject: ARM: n30: Enable Acer n35 if Acer n30 is selected All code already present for Acer n35 is useless unless MACH_N35 is defined. Signed-off-by: Jiri Pinkava [ben-linux@fluff.org: minor edit of subject] Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 554731868b07..2b5a33f36e3b 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -95,12 +95,19 @@ config PM_H1940 config MACH_N30 bool "Acer N30 family" select CPU_S3C2410 + select MACH_N35 select S3C_DEV_USB_HOST select S3C_DEV_NAND help Say Y here if you want suppt for the Acer N30, Acer N35, Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs. +config MACH_N35 + bool + help + Internal node in order to enable support for Acer N35 if Acer N30 is + selected. + config ARCH_BAST bool "Simtec Electronics BAST (EB2410ITX)" select CPU_S3C2410 -- cgit v1.2.3-59-g8ed1b From be7c4cf632f47d798ad6a27da15de0195ddf6f30 Mon Sep 17 00:00:00 2001 From: Pinkava J Date: Thu, 6 May 2010 15:19:19 +0200 Subject: ARM: n30: fix: suspended wrong USB port on Acer n35 There is bug in USB setup code for Acer n35 (it is related directly to s3c2410, see doc). We want suspend host port (is not connected) but device port should be active. Signed-off-by: Jiri Pinkava Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 684710f88142..1b635fda4ea5 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -532,7 +532,7 @@ static void __init n30_init(void) s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | S3C2410_MISCCR_USBSUSPND0 | S3C2410_MISCCR_USBSUSPND1, - S3C2410_MISCCR_USBSUSPND1); + S3C2410_MISCCR_USBSUSPND0); platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices)); } -- cgit v1.2.3-59-g8ed1b From 8ecad34918174580b069f7d4dcef3f46a099e8f7 Mon Sep 17 00:00:00 2001 From: Pinkava J Date: Thu, 6 May 2010 15:20:36 +0200 Subject: ARM: n30: Add RTC platform device for Acer n30 / Acer n35 Signed-off-by: Jiri Pinkava Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 1b635fda4ea5..ce1172ef5b72 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -323,6 +323,7 @@ static struct platform_device *n30_devices[] __initdata = { &s3c_device_i2c0, &s3c_device_iis, &s3c_device_ohci, + &s3c_device_rtc, &s3c_device_usbgadget, &n30_button_device, &n30_blue_led, @@ -334,6 +335,7 @@ static struct platform_device *n35_devices[] __initdata = { &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, + &s3c_device_rtc, &s3c_device_usbgadget, &n35_button_device, }; -- cgit v1.2.3-59-g8ed1b From 319887ee800f889e4c81d73f0ee4bcf532f9c34d Mon Sep 17 00:00:00 2001 From: Pinkava J Date: Thu, 6 May 2010 15:21:16 +0200 Subject: ARM: n35: Add support for LEDs on Acer n35 Signed-off-by: Jiri Pinkava Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index ce1172ef5b72..b83eabdf709b 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -264,6 +264,14 @@ static struct s3c24xx_led_platdata n30_blue_led_pdata = { .def_trigger = "", }; +/* This is the blue LED on the device. Originaly used to indicate GPS activity + * by flashing. */ +static struct s3c24xx_led_platdata n35_blue_led_pdata = { + .name = "blue_led", + .gpio = S3C2410_GPD(8), + .def_trigger = "", +}; + /* This LED is driven by the battery microcontroller, and is blinking * red, blinking green or solid green when the battery is low, * charging or full respectively. By driving GPD9 low, it's possible @@ -275,6 +283,13 @@ static struct s3c24xx_led_platdata n30_warning_led_pdata = { .def_trigger = "", }; +static struct s3c24xx_led_platdata n35_warning_led_pdata = { + .name = "warning_led", + .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, + .gpio = S3C2410_GPD(9), + .def_trigger = "", +}; + static struct platform_device n30_blue_led = { .name = "s3c24xx_led", .id = 1, @@ -283,6 +298,14 @@ static struct platform_device n30_blue_led = { }, }; +static struct platform_device n35_blue_led = { + .name = "s3c24xx_led", + .id = 1, + .dev = { + .platform_data = &n35_blue_led_pdata, + }, +}; + static struct platform_device n30_warning_led = { .name = "s3c24xx_led", .id = 2, @@ -291,6 +314,14 @@ static struct platform_device n30_warning_led = { }, }; +static struct platform_device n35_warning_led = { + .name = "s3c24xx_led", + .id = 2, + .dev = { + .platform_data = &n35_warning_led_pdata, + }, +}; + static struct s3c2410fb_display n30_display __initdata = { .type = S3C2410_LCDCON1_TFT, .width = 240, @@ -338,6 +369,8 @@ static struct platform_device *n35_devices[] __initdata = { &s3c_device_rtc, &s3c_device_usbgadget, &n35_button_device, + &n35_blue_led, + &n35_warning_led, }; static struct s3c2410_platform_i2c __initdata n30_i2ccfg = { -- cgit v1.2.3-59-g8ed1b From aeb1b7e49f97e96e8b63c76c22f6fe6186a46ff3 Mon Sep 17 00:00:00 2001 From: Pinkava J Date: Thu, 6 May 2010 15:21:50 +0200 Subject: ARM: n35: Enable wake-up by Power button on Acer n35 Signed-off-by: Jiri Pinkava Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index b83eabdf709b..d63b48f8dcee 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -172,8 +172,10 @@ static struct gpio_keys_button n35_buttons[] = { { .gpio = S3C2410_GPF(0), .code = KEY_POWER, + .type = EV_PWR, .desc = "Power", .active_low = 0, + .wakeup = 1, }, { .gpio = S3C2410_GPG(9), -- cgit v1.2.3-59-g8ed1b From 50cdba782c3de35bf6d454096213c986146f46a5 Mon Sep 17 00:00:00 2001 From: Pinkava J Date: Thu, 6 May 2010 15:22:28 +0200 Subject: ARM: n30: Add support for MMC card reader on Acer n30 / Acer n35 Signed-off-by: Jiri Pinkava Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index d63b48f8dcee..81973aa8194b 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,7 @@ #include #include #include +#include #include #include @@ -350,6 +352,12 @@ static struct s3c2410fb_mach_info n30_fb_info __initdata = { .lpcsel = 0x06, }; +static struct s3c24xx_mci_pdata n30_mci_cfg __initdata = { + .gpio_detect = S3C2410_GPF(1), + .gpio_wprotect = S3C2410_GPG(10), + .ocr_avail = MMC_VDD_32_33, +}; + static struct platform_device *n30_devices[] __initdata = { &s3c_device_lcd, &s3c_device_wdt, @@ -358,6 +366,7 @@ static struct platform_device *n30_devices[] __initdata = { &s3c_device_ohci, &s3c_device_rtc, &s3c_device_usbgadget, + &s3c_device_sdi, &n30_button_device, &n30_blue_led, &n30_warning_led, @@ -370,6 +379,7 @@ static struct platform_device *n35_devices[] __initdata = { &s3c_device_iis, &s3c_device_rtc, &s3c_device_usbgadget, + &s3c_device_sdi, &n35_button_device, &n35_blue_led, &n35_warning_led, @@ -538,6 +548,7 @@ static void __init n30_init(void) { s3c24xx_fb_set_platdata(&n30_fb_info); s3c24xx_udc_set_platdata(&n30_udc_cfg); + s3c24xx_mci_set_platdata(&n30_mci_cfg); s3c_i2c0_set_platdata(&n30_i2ccfg); /* Turn off suspend on both USB ports, and switch the -- cgit v1.2.3-59-g8ed1b From 271d323237a1ab96b74c69fa48a8612963245266 Mon Sep 17 00:00:00 2001 From: Pinkava J Date: Thu, 6 May 2010 15:23:24 +0200 Subject: ARM: n30: Add support for power on/off on Acer n30 / Acer n35 MMC card reader Signed-off-by: Jiri Pinkava Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 81973aa8194b..f25275ef8bc8 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -352,10 +352,25 @@ static struct s3c2410fb_mach_info n30_fb_info __initdata = { .lpcsel = 0x06, }; +static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd) +{ + switch (power_mode) { + case MMC_POWER_ON: + case MMC_POWER_UP: + s3c2410_gpio_setpin(S3C2410_GPG(4), 1); + break; + case MMC_POWER_OFF: + default: + s3c2410_gpio_setpin(S3C2410_GPG(4), 0); + break; + } +} + static struct s3c24xx_mci_pdata n30_mci_cfg __initdata = { .gpio_detect = S3C2410_GPF(1), .gpio_wprotect = S3C2410_GPG(10), .ocr_avail = MMC_VDD_32_33, + .set_power = n30_sdi_set_power, }; static struct platform_device *n30_devices[] __initdata = { -- cgit v1.2.3-59-g8ed1b From 8a19ebb0938752af8da142c4731f310bb8f9d130 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 7 May 2010 09:59:11 +0900 Subject: ARM: n30: Fixup gpiolib calls for mmc power Move to using gpio_request() and gpio_set_value() for the MMC power control calls. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index f25275ef8bc8..dfa09eac160c 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -88,10 +88,10 @@ static void n30_udc_pullup(enum s3c2410_udc_cmd_e cmd) { switch (cmd) { case S3C2410_UDC_P_ENABLE : - s3c2410_gpio_setpin(S3C2410_GPB(3), 1); + gpio_set_value(S3C2410_GPB(3), 1); break; case S3C2410_UDC_P_DISABLE : - s3c2410_gpio_setpin(S3C2410_GPB(3), 0); + gpio_set_value(S3C2410_GPB(3), 0); break; case S3C2410_UDC_P_RESET : break; @@ -357,11 +357,11 @@ static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd) switch (power_mode) { case MMC_POWER_ON: case MMC_POWER_UP: - s3c2410_gpio_setpin(S3C2410_GPG(4), 1); + gpio_set_value(S3C2410_GPG(4), 1); break; case MMC_POWER_OFF: default: - s3c2410_gpio_setpin(S3C2410_GPG(4), 0); + gpio_set_value(S3C2410_GPG(4), 0); break; } } @@ -561,6 +561,8 @@ static void __init n30_init_irq(void) static void __init n30_init(void) { + WARN_ON(gpio_request(S3C2410_GPG(4), "mmc power")); + s3c24xx_fb_set_platdata(&n30_fb_info); s3c24xx_udc_set_platdata(&n30_udc_cfg); s3c24xx_mci_set_platdata(&n30_mci_cfg); -- cgit v1.2.3-59-g8ed1b From 0c3767b161a91eab5b23d602d374b9c070c067a9 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 7 May 2010 10:01:28 +0900 Subject: ARM: n30: Just call s3c24xx_init_irq() directly from machine definition The n30_init_irq() call is simply a call to s3c24xx_init_irq, so just remove it and update the machine definitions to call the IRQ initialision call directly. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index dfa09eac160c..9e2565ad973d 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -552,11 +552,6 @@ static void __init n30_map_io(void) s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs)); } -static void __init n30_init_irq(void) -{ - s3c24xx_init_irq(); -} - /* GPB3 is the line that controls the pull-up for the USB D+ line */ static void __init n30_init(void) @@ -612,7 +607,7 @@ MACHINE_START(N30, "Acer-N30") .boot_params = S3C2410_SDRAM_PA + 0x100, .timer = &s3c24xx_timer, .init_machine = n30_init, - .init_irq = n30_init_irq, + .init_irq = s3c24xx_init_irq, .map_io = n30_map_io, MACHINE_END @@ -624,6 +619,6 @@ MACHINE_START(N35, "Acer-N35") .boot_params = S3C2410_SDRAM_PA + 0x100, .timer = &s3c24xx_timer, .init_machine = n30_init, - .init_irq = n30_init_irq, + .init_irq = s3c24xx_init_irq, .map_io = n30_map_io, MACHINE_END -- cgit v1.2.3-59-g8ed1b From a2a47c6c3d1a7c01da4464b3b7be93b924f874c1 Mon Sep 17 00:00:00 2001 From: Ky Srinivasan Date: Thu, 6 May 2010 12:08:41 -0700 Subject: x86: Detect running on a Microsoft HyperV system This patch integrates HyperV detection within the framework currently used by VmWare. With this patch, we can avoid having to replicate the HyperV detection code in each of the Microsoft HyperV drivers. Reworked and tweaked by Greg K-H to build properly. Signed-off-by: K. Y. Srinivasan LKML-Reference: <20100506190841.GA1605@kroah.com> Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Vadim Rozenfeld Cc: Avi Kivity Cc: Gleb Natapov Cc: Frederic Weisbecker Cc: Alexey Dobriyan Cc: "K.Prasad" Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Paul Mackerras Cc: Alan Cox Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/hyperv.h | 6 ++++ arch/x86/include/asm/mshyperv.h | 7 +++++ arch/x86/include/asm/processor.h | 3 ++ arch/x86/kernel/cpu/Makefile | 2 +- arch/x86/kernel/cpu/hypervisor.c | 10 ++++-- arch/x86/kernel/cpu/mshyperv.c | 67 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 arch/x86/include/asm/mshyperv.h create mode 100644 arch/x86/kernel/cpu/mshyperv.c (limited to 'arch') diff --git a/arch/x86/include/asm/hyperv.h b/arch/x86/include/asm/hyperv.h index e153a2b3889a..46040473e122 100644 --- a/arch/x86/include/asm/hyperv.h +++ b/arch/x86/include/asm/hyperv.h @@ -14,6 +14,9 @@ #define HYPERV_CPUID_ENLIGHTMENT_INFO 0x40000004 #define HYPERV_CPUID_IMPLEMENT_LIMITS 0x40000005 +#define HYPERV_HYPERVISOR_PRESENT_BIT 0x80000000 +#define HYPERV_CPUID_MIN 0x40000005 + /* * Feature identification. EAX indicates which features are available * to the partition based upon the current partition privileges. @@ -129,6 +132,9 @@ /* MSR used to provide vcpu index */ #define HV_X64_MSR_VP_INDEX 0x40000002 +/* MSR used to read the per-partition time reference counter */ +#define HV_X64_MSR_TIME_REF_COUNT 0x40000020 + /* Define the virtual APIC registers */ #define HV_X64_MSR_EOI 0x40000070 #define HV_X64_MSR_ICR 0x40000071 diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h new file mode 100644 index 000000000000..6cd8101d1344 --- /dev/null +++ b/arch/x86/include/asm/mshyperv.h @@ -0,0 +1,7 @@ +#ifndef ASM_X86__MSHYPER_H +#define ASM_X86__MSHYPER_H + +int ms_hyperv_platform(void); +void __cpuinit ms_hyperv_set_feature_bits(struct cpuinfo_x86 *c); + +#endif diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index b753ea59703a..597c041bd124 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -114,6 +114,8 @@ struct cpuinfo_x86 { u16 cpu_index; #endif unsigned int x86_hyper_vendor; + /* The layout of this field is hypervisor specific */ + unsigned int x86_hyper_features; } __attribute__((__aligned__(SMP_CACHE_BYTES))); #define X86_VENDOR_INTEL 0 @@ -129,6 +131,7 @@ struct cpuinfo_x86 { #define X86_HYPER_VENDOR_NONE 0 #define X86_HYPER_VENDOR_VMWARE 1 +#define X86_HYPER_VENDOR_MSFT 2 /* * capabilities of CPUs diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index c202b62f3671..3a785da34b6f 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -14,7 +14,7 @@ CFLAGS_common.o := $(nostackp) obj-y := intel_cacheinfo.o addon_cpuid_features.o obj-y += proc.o capflags.o powerflags.o common.o -obj-y += vmware.o hypervisor.o sched.o +obj-y += vmware.o hypervisor.o sched.o mshyperv.o obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o obj-$(CONFIG_X86_64) += bugs_64.o diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index 08be922de33a..de3f4e0ce8eb 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c @@ -23,6 +23,7 @@ #include #include +#include #include static inline void __cpuinit @@ -30,6 +31,8 @@ detect_hypervisor_vendor(struct cpuinfo_x86 *c) { if (vmware_platform()) c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE; + else if (ms_hyperv_platform()) + c->x86_hyper_vendor = X86_HYPER_VENDOR_MSFT; else c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE; } @@ -37,10 +40,11 @@ detect_hypervisor_vendor(struct cpuinfo_x86 *c) static inline void __cpuinit hypervisor_set_feature_bits(struct cpuinfo_x86 *c) { - if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) { + if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) vmware_set_feature_bits(c); - return; - } + else if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_MSFT) + ms_hyperv_set_feature_bits(c); + return; } void __cpuinit init_hypervisor(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c new file mode 100644 index 000000000000..2443b61cdb17 --- /dev/null +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -0,0 +1,67 @@ +/* + * HyperV Detection code. + * + * Copyright (C) 2010, Novell, Inc. + * Author : K. Y. Srinivasan + * + * 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, GOOD TITLE or + * NON INFRINGEMENT. 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 St, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include + + +int ms_hyperv_platform(void) +{ + u32 eax, ebx, ecx, edx; + char hyp_signature[13]; + + cpuid(1, &eax, &ebx, &ecx, &edx); + if (!(ecx & HYPERV_HYPERVISOR_PRESENT_BIT)) + return 0; + + cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, &eax, &ebx, &ecx, &edx); + *(u32 *)(hyp_signature + 0) = ebx; + *(u32 *)(hyp_signature + 4) = ecx; + *(u32 *)(hyp_signature + 8) = edx; + + if ((eax < HYPERV_CPUID_MIN) || (memcmp("Microsoft Hv", hyp_signature, 12))) + return 0; + return 1; +} + +void __cpuinit ms_hyperv_set_feature_bits(struct cpuinfo_x86 *c) +{ + u32 eax, ebx, ecx, edx; + + c->x86_hyper_features = 0; + /* + * Extract the features, recommendations etc. + * The first 9 bits will be used to track hypervisor features. + * The next 6 bits will be used to track the hypervisor + * recommendations. + */ + cpuid(HYPERV_CPUID_FEATURES, &eax, &ebx, &ecx, &edx); + c->x86_hyper_features |= (eax & 0x1ff); + + cpuid(HYPERV_CPUID_ENLIGHTMENT_INFO, &eax, &ebx, &ecx, &edx); + c->x86_hyper_features |= ((eax & 0x3f) << 9); + printk(KERN_INFO "Detected HyperV with features: %x\n", + c->x86_hyper_features); +} -- cgit v1.2.3-59-g8ed1b From 39e0786d3cf39c6d2f47b4818ae2da8b8ebc9ce2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 6 May 2010 22:01:53 -0700 Subject: microblaze: Kill NET_SKB_PAD and NET_IP_ALIGN overrides. NET_IP_ALIGN defaults to 2, no need to override. NET_SKB_PAD is now 64, which is much larger than microblaze's L1_CACHE_SIZE so no need to override that either. Signed-off-by: David S. Miller --- arch/microblaze/include/asm/system.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h index 48c4f0335e3f..b1e2f0710098 100644 --- a/arch/microblaze/include/asm/system.h +++ b/arch/microblaze/include/asm/system.h @@ -97,14 +97,4 @@ extern struct dentry *of_debugfs_root; #define arch_align_stack(x) (x) -/* - * MicroBlaze doesn't handle unaligned accesses in hardware. - * - * Based on this we force the IP header alignment in network drivers. - * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining - * cacheline alignment of buffers. - */ -#define NET_IP_ALIGN 2 -#define NET_SKB_PAD L1_CACHE_BYTES - #endif /* _ASM_MICROBLAZE_SYSTEM_H */ -- cgit v1.2.3-59-g8ed1b From a5ec39507129a086d8838228ac1ca0a2eab38f91 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 7 May 2010 14:54:55 +0900 Subject: sh: convert kexec crash kernel management to LMB. This migrates the crash kernel handling off of bootmem and over to LMB. Signed-off-by: Paul Mundt --- arch/sh/include/asm/kexec.h | 8 +++++++ arch/sh/kernel/machine_kexec.c | 51 +++++++++++++++++++++++++++++++++++++++++- arch/sh/kernel/setup.c | 43 ----------------------------------- 3 files changed, 58 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/kexec.h b/arch/sh/include/asm/kexec.h index 765a5e1660fc..ad6ef8a275ee 100644 --- a/arch/sh/include/asm/kexec.h +++ b/arch/sh/include/asm/kexec.h @@ -26,6 +26,10 @@ /* The native architecture */ #define KEXEC_ARCH KEXEC_ARCH_SH +#ifdef CONFIG_KEXEC +/* arch/sh/kernel/machine_kexec.c */ +void reserve_crashkernel(void); + static inline void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs) { @@ -59,4 +63,8 @@ static inline void crash_setup_regs(struct pt_regs *newregs, newregs->pc = (unsigned long)current_text_addr(); } } +#else +static inline void reserve_crashkernel(void) { } +#endif /* CONFIG_KEXEC */ + #endif /* __ASM_SH_KEXEC_H */ diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index 7672141c841b..f0f049caa6e2 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -8,7 +8,6 @@ * This source code is licensed under the GNU General Public License, * Version 2. See the file COPYING for more details. */ - #include #include #include @@ -16,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -148,3 +148,52 @@ void arch_crash_save_vmcoreinfo(void) VMCOREINFO_LENGTH(node_data, MAX_NUMNODES); #endif } + +void __init reserve_crashkernel(void) +{ + unsigned long long crash_size, crash_base; + int ret; + + /* this is necessary because of lmb_phys_mem_size() */ + lmb_analyze(); + + ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(), + &crash_size, &crash_base); + if (ret == 0 && crash_size > 0) { + crashk_res.start = crash_base; + crashk_res.end = crash_base + crash_size - 1; + } + + if (crashk_res.end == crashk_res.start) + goto disable; + + crash_size = PAGE_ALIGN(crashk_res.end - crashk_res.start + 1); + if (!crashk_res.start) { + crashk_res.start = lmb_alloc(crash_size, PAGE_SIZE); + if (!crashk_res.start) { + pr_err("crashkernel allocation failed\n"); + goto disable; + } + } else { + ret = lmb_reserve(crashk_res.start, crash_size); + if (unlikely(ret < 0)) { + pr_err("crashkernel reservation failed - " + "memory is in use\n"); + goto disable; + } + } + + pr_info("Reserving %ldMB of memory at %ldMB " + "for crashkernel (System RAM: %ldMB)\n", + (unsigned long)(crash_size >> 20), + (unsigned long)(crashk_res.start >> 20), + (unsigned long)(lmb_phys_mem_size() >> 20)); + + crashk_res.end = crashk_res.start + crash_size - 1; + insert_resource(&iomem_resource, &crashk_res); + + return; + +disable: + crashk_res.start = crashk_res.end = 0; +} diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 9c7f7811af70..d67a8a386907 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -145,49 +145,6 @@ static void __init register_bootmem_low_pages(void) free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages)); } -#ifdef CONFIG_KEXEC -static void __init reserve_crashkernel(void) -{ - unsigned long long free_mem; - unsigned long long crash_size, crash_base; - void *vp; - int ret; - - free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT; - - ret = parse_crashkernel(boot_command_line, free_mem, - &crash_size, &crash_base); - if (ret == 0 && crash_size) { - if (crash_base <= 0) { - vp = alloc_bootmem_nopanic(crash_size); - if (!vp) { - printk(KERN_INFO "crashkernel allocation " - "failed\n"); - return; - } - crash_base = __pa(vp); - } else if (reserve_bootmem(crash_base, crash_size, - BOOTMEM_EXCLUSIVE) < 0) { - printk(KERN_INFO "crashkernel reservation failed - " - "memory is in use\n"); - return; - } - - printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " - "for crashkernel (System RAM: %ldMB)\n", - (unsigned long)(crash_size >> 20), - (unsigned long)(crash_base >> 20), - (unsigned long)(free_mem >> 20)); - crashk_res.start = crash_base; - crashk_res.end = crash_base + crash_size - 1; - insert_resource(&iomem_resource, &crashk_res); - } -} -#else -static inline void __init reserve_crashkernel(void) -{} -#endif - static void __init check_for_initrd(void) { #ifdef CONFIG_BLK_DEV_INITRD -- cgit v1.2.3-59-g8ed1b From 36fa06d6b5ef1874d012c04b23d5b8982b1f8dea Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 7 May 2010 15:10:07 +0900 Subject: sh: convert initrd reservation to LMB. This switches over from bootmem -> LMB for the initrd area reservation. Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index d67a8a386907..08001729f5ee 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -192,7 +192,7 @@ static void __init check_for_initrd(void) initrd_start = (unsigned long)__va(__pa(start)); initrd_end = initrd_start + INITRD_SIZE; - reserve_bootmem(__pa(initrd_start), INITRD_SIZE, BOOTMEM_DEFAULT); + lmb_reserve(__pa(initrd_start), INITRD_SIZE); return; -- cgit v1.2.3-59-g8ed1b From 080e71e13d99d850875c0335c364766162eae7c6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 7 May 2010 15:10:42 +0900 Subject: sh: bump up extra LMB reservations in bootmem init. This bumps up the extra LMB reservations in ordering so that they're accounted for prior to iterating over the region list. This ensures that reservations are visible both within the LMB and bootmem context. Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 08001729f5ee..e3f0da7b865d 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -275,6 +275,12 @@ void __init setup_bootmem_allocator(unsigned long free_pfn) __add_active_range(0, start_pfn, end_pfn); } + /* + * Handle additional early reservations + */ + check_for_initrd(); + reserve_crashkernel(); + /* * Add all physical memory to the bootmem map and mark each * area as present. @@ -290,10 +296,6 @@ void __init setup_bootmem_allocator(unsigned long free_pfn) node_set_online(0); sparse_memory_present_with_active_regions(0); - - check_for_initrd(); - - reserve_crashkernel(); } #ifndef CONFIG_NEED_MULTIPLE_NODES -- cgit v1.2.3-59-g8ed1b From d523e1ae6addd4f18a609da39f23719eaecfedf0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 7 May 2010 16:39:09 +0900 Subject: sh: flag kdump as broken on SMP for now. There's still quite a bit of shootdown logic that needs to be hacked up to support SMP for kdump properly, so just add in a BROKEN_ON_SMP dependency for now. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index c2325bd48fd3..38611bcdf74c 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -633,7 +633,7 @@ config KEXEC config CRASH_DUMP bool "kernel crash dumps (EXPERIMENTAL)" - depends on SUPERH32 && EXPERIMENTAL + depends on SUPERH32 && EXPERIMENTAL && BROKEN_ON_SMP help Generate crash dump after being started by kexec. This should be normally only set in special crash dump kernels -- cgit v1.2.3-59-g8ed1b From aa424bbb8cf5f7f3c6a70065bcb28a6e6af7897d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 7 May 2010 17:14:00 +0900 Subject: sh: Ensure that X2 TLB settings are reflected in vmcore. This rolls in the X2TLB config settings for vmcore. Signed-off-by: Paul Mundt --- arch/sh/kernel/machine_kexec.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index 7672141c841b..0e90c7f9564f 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -147,4 +147,7 @@ void arch_crash_save_vmcoreinfo(void) VMCOREINFO_SYMBOL(node_data); VMCOREINFO_LENGTH(node_data, MAX_NUMNODES); #endif +#ifdef CONFIG_X2TLB + VMCOREINFO_CONFIG(X2TLB); +#endif } -- cgit v1.2.3-59-g8ed1b From 7aed3b34fb0a98e89d0e999f5833ceebdb3876b9 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 7 May 2010 17:58:55 +0900 Subject: sh: shuffle the elfcorehdr handling over to the crash dump code. The elfcorehdr parsing was just tossed in setup.c, but nothing outside of the crash dump code/vmcore bits require it, so we just move it out of the way, as per ppc. Signed-off-by: Paul Mundt --- arch/sh/kernel/crash_dump.c | 20 +++++++++++++++++++- arch/sh/kernel/setup.c | 19 ------------------- 2 files changed, 19 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c index 95d216255565..37c97d444576 100644 --- a/arch/sh/kernel/crash_dump.c +++ b/arch/sh/kernel/crash_dump.c @@ -4,7 +4,6 @@ * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) * Copyright (C) IBM Corporation, 2004. All rights reserved */ - #include #include #include @@ -13,6 +12,25 @@ /* Stores the physical address of elf header of crash image. */ unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; +/* + * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by + * is_kdump_kernel() to determine if we are booting after a panic. Hence + * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE. + * + * elfcorehdr= specifies the location of elf core header + * stored by the crashed kernel. + */ +static int __init parse_elfcorehdr(char *arg) +{ + if (!arg) + return -EINVAL; + + elfcorehdr_addr = memparse(arg, &arg); + + return 0; +} +early_param("elfcorehdr", parse_elfcorehdr); + /** * copy_oldmem_page - copy one page from "oldmem" * @pfn: page frame number to be copied diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 9c7f7811af70..4f1585f41f2b 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -380,25 +380,6 @@ static void __init setup_memory(void) extern void __init setup_memory(void); #endif -/* - * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by - * is_kdump_kernel() to determine if we are booting after a panic. Hence - * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE. - */ -#ifdef CONFIG_CRASH_DUMP -/* elfcorehdr= specifies the location of elf core header - * stored by the crashed kernel. - */ -static int __init parse_elfcorehdr(char *arg) -{ - if (!arg) - return -EINVAL; - elfcorehdr_addr = memparse(arg, &arg); - return 0; -} -early_param("elfcorehdr", parse_elfcorehdr); -#endif - void __init __attribute__ ((weak)) plat_early_device_setup(void) { } -- cgit v1.2.3-59-g8ed1b From 4261e0e0efd9e04b6c69e0773c3cf4d6f337c416 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 13 Apr 2010 22:23:10 +0200 Subject: perf, x86: Move perfctr init code to x86_setup_perfctr() Split __hw_perf_event_init() to configure pmu events other than perfctrs. Perfctr code is moved to a separate function x86_setup_perfctr(). This and the following patches refactor the code. Split in multiple patches for better review. Signed-off-by: Robert Richter Signed-off-by: Peter Zijlstra LKML-Reference: <1271190201-25705-2-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 7de70613e6c3..801441a54245 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -426,6 +426,8 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event_attr *attr) return 0; } +static int x86_setup_perfctr(struct perf_event *event); + static int x86_pmu_hw_config(struct perf_event *event) { /* @@ -453,9 +455,6 @@ static int x86_pmu_hw_config(struct perf_event *event) */ static int __hw_perf_event_init(struct perf_event *event) { - struct perf_event_attr *attr = &event->attr; - struct hw_perf_event *hwc = &event->hw; - u64 config; int err; if (!x86_pmu_initialized()) @@ -482,15 +481,24 @@ static int __hw_perf_event_init(struct perf_event *event) event->destroy = hw_perf_event_destroy; - hwc->idx = -1; - hwc->last_cpu = -1; - hwc->last_tag = ~0ULL; + event->hw.idx = -1; + event->hw.last_cpu = -1; + event->hw.last_tag = ~0ULL; /* Processor specifics */ err = x86_pmu.hw_config(event); if (err) return err; + return x86_setup_perfctr(event); +} + +static int x86_setup_perfctr(struct perf_event *event) +{ + struct perf_event_attr *attr = &event->attr; + struct hw_perf_event *hwc = &event->hw; + u64 config; + if (!hwc->sample_period) { hwc->sample_period = x86_pmu.max_period; hwc->last_period = hwc->sample_period; -- cgit v1.2.3-59-g8ed1b From c1726f343b3bfc2ee037e191907c632a31903021 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 13 Apr 2010 22:23:11 +0200 Subject: perf, x86: Move x86_setup_perfctr() Move x86_setup_perfctr(), no other changes made. Signed-off-by: Robert Richter Signed-off-by: Peter Zijlstra LKML-Reference: <1271190201-25705-3-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 120 +++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 61 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 801441a54245..3d3bceb9e830 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -426,7 +426,65 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event_attr *attr) return 0; } -static int x86_setup_perfctr(struct perf_event *event); +static int x86_setup_perfctr(struct perf_event *event) +{ + struct perf_event_attr *attr = &event->attr; + struct hw_perf_event *hwc = &event->hw; + u64 config; + + if (!hwc->sample_period) { + hwc->sample_period = x86_pmu.max_period; + hwc->last_period = hwc->sample_period; + atomic64_set(&hwc->period_left, hwc->sample_period); + } else { + /* + * If we have a PMU initialized but no APIC + * interrupts, we cannot sample hardware + * events (user-space has to fall back and + * sample via a hrtimer based software event): + */ + if (!x86_pmu.apic) + return -EOPNOTSUPP; + } + + if (attr->type == PERF_TYPE_RAW) + return 0; + + if (attr->type == PERF_TYPE_HW_CACHE) + return set_ext_hw_attr(hwc, attr); + + if (attr->config >= x86_pmu.max_events) + return -EINVAL; + + /* + * The generic map: + */ + config = x86_pmu.event_map(attr->config); + + if (config == 0) + return -ENOENT; + + if (config == -1LL) + return -EINVAL; + + /* + * Branch tracing: + */ + if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && + (hwc->sample_period == 1)) { + /* BTS is not supported by this architecture. */ + if (!x86_pmu.bts) + return -EOPNOTSUPP; + + /* BTS is currently only allowed for user-mode. */ + if (!attr->exclude_kernel) + return -EOPNOTSUPP; + } + + hwc->config |= config; + + return 0; +} static int x86_pmu_hw_config(struct perf_event *event) { @@ -493,66 +551,6 @@ static int __hw_perf_event_init(struct perf_event *event) return x86_setup_perfctr(event); } -static int x86_setup_perfctr(struct perf_event *event) -{ - struct perf_event_attr *attr = &event->attr; - struct hw_perf_event *hwc = &event->hw; - u64 config; - - if (!hwc->sample_period) { - hwc->sample_period = x86_pmu.max_period; - hwc->last_period = hwc->sample_period; - atomic64_set(&hwc->period_left, hwc->sample_period); - } else { - /* - * If we have a PMU initialized but no APIC - * interrupts, we cannot sample hardware - * events (user-space has to fall back and - * sample via a hrtimer based software event): - */ - if (!x86_pmu.apic) - return -EOPNOTSUPP; - } - - if (attr->type == PERF_TYPE_RAW) - return 0; - - if (attr->type == PERF_TYPE_HW_CACHE) - return set_ext_hw_attr(hwc, attr); - - if (attr->config >= x86_pmu.max_events) - return -EINVAL; - - /* - * The generic map: - */ - config = x86_pmu.event_map(attr->config); - - if (config == 0) - return -ENOENT; - - if (config == -1LL) - return -EINVAL; - - /* - * Branch tracing: - */ - if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && - (hwc->sample_period == 1)) { - /* BTS is not supported by this architecture. */ - if (!x86_pmu.bts) - return -EOPNOTSUPP; - - /* BTS is currently only allowed for user-mode. */ - if (!attr->exclude_kernel) - return -EOPNOTSUPP; - } - - hwc->config |= config; - - return 0; -} - static void x86_pmu_disable_all(void) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); -- cgit v1.2.3-59-g8ed1b From 9d0fcba67e47ff398a6fa86476d4884d472dc98a Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 13 Apr 2010 22:23:12 +0200 Subject: perf, x86: Call x86_setup_perfctr() from .hw_config() The perfctr setup calls are in the corresponding .hw_config() functions now. This makes it possible to introduce config functions for other pmu events that are not perfctr specific. Also, all of a sudden the code looks much nicer. Signed-off-by: Robert Richter Signed-off-by: Peter Zijlstra LKML-Reference: <1271190201-25705-4-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 9 ++------- arch/x86/kernel/cpu/perf_event_p4.c | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 3d3bceb9e830..c2c1e10f7b03 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -505,7 +505,7 @@ static int x86_pmu_hw_config(struct perf_event *event) if (event->attr.type == PERF_TYPE_RAW) event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK; - return 0; + return x86_setup_perfctr(event); } /* @@ -543,12 +543,7 @@ static int __hw_perf_event_init(struct perf_event *event) event->hw.last_cpu = -1; event->hw.last_tag = ~0ULL; - /* Processor specifics */ - err = x86_pmu.hw_config(event); - if (err) - return err; - - return x86_setup_perfctr(event); + return x86_pmu.hw_config(event); } static void x86_pmu_disable_all(void) diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 15367cce66bd..9e002054cb5f 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -455,7 +455,7 @@ static int p4_hw_config(struct perf_event *event) (p4_config_pack_escr(P4_ESCR_MASK_HT) | p4_config_pack_cccr(P4_CCCR_MASK_HT)); - return 0; + return x86_setup_perfctr(event); } static inline void p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc) -- cgit v1.2.3-59-g8ed1b From 31fa58af57c41d2912debf62d47d5811062411f1 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 13 Apr 2010 22:23:14 +0200 Subject: perf, x86: Pass enable bit mask to __x86_pmu_enable_event() To reuse this function for events with different enable bit masks, this mask is part of the function's argument list now. The function will be used later to control ibs events too. Signed-off-by: Robert Richter Signed-off-by: Peter Zijlstra LKML-Reference: <1271190201-25705-6-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 9 +++++---- arch/x86/kernel/cpu/perf_event_intel.c | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index c2c1e10f7b03..4e218d7ac852 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -844,10 +844,10 @@ void hw_perf_enable(void) x86_pmu.enable_all(added); } -static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc) +static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, + u64 enable_mask) { - wrmsrl(hwc->config_base + hwc->idx, - hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE); + wrmsrl(hwc->config_base + hwc->idx, hwc->config | enable_mask); } static inline void x86_pmu_disable_event(struct perf_event *event) @@ -919,7 +919,8 @@ static void x86_pmu_enable_event(struct perf_event *event) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); if (cpuc->enabled) - __x86_pmu_enable_event(&event->hw); + __x86_pmu_enable_event(&event->hw, + ARCH_PERFMON_EVENTSEL_ENABLE); } /* diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index a099df96f916..a4b56ac425cb 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -513,7 +513,8 @@ static void intel_pmu_nhm_enable_all(int added) if (!event) continue; - __x86_pmu_enable_event(&event->hw); + __x86_pmu_enable_event(&event->hw, + ARCH_PERFMON_EVENTSEL_ENABLE); } } intel_pmu_enable_all(added); @@ -617,7 +618,7 @@ static void intel_pmu_enable_event(struct perf_event *event) if (unlikely(event->attr.precise)) intel_pmu_pebs_enable(event); - __x86_pmu_enable_event(hwc); + __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE); } /* -- cgit v1.2.3-59-g8ed1b From a1f2b70a942b8d858a0ab02567da3999b60a99b2 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 13 Apr 2010 22:23:15 +0200 Subject: perf, x86: Use weight instead of cmask in for_each_event_constraint() There may exist constraints with a cmask set to zero. In this case for_each_event_constraint() will not work properly. Now weight is used instead of the cmask for loop exit detection. Weight is always a value other than zero since the default contains the HWEIGHT from the counter mask and in other cases a value of zero does not fit too. This is in preparation of ibs event constraints that wont have a cmask. Signed-off-by: Robert Richter Signed-off-by: Peter Zijlstra LKML-Reference: <1271190201-25705-7-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 4e218d7ac852..4a3f1f2b9b91 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -170,7 +170,7 @@ struct cpu_hw_events { EVENT_CONSTRAINT(0, 0, 0) #define for_each_event_constraint(e, c) \ - for ((e) = (c); (e)->cmask; (e)++) + for ((e) = (c); (e)->weight; (e)++) union perf_capabilities { struct { -- cgit v1.2.3-59-g8ed1b From 1e9a6d8d44cb6dcd2799b36ceb23007e6a423bfe Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 4 May 2010 16:30:21 +0200 Subject: perf, x86: Remove PEBS SAMPLE_RAW support Its broken, we really should get PERF_SAMPLE_REGS sorted. Signed-off-by: Peter Zijlstra LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index ec8b2e12e104..080b9b065bdd 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -459,7 +459,6 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) struct perf_event *event = cpuc->events[0]; /* PMC0 only */ struct pebs_record_core *at, *top; struct perf_sample_data data; - struct perf_raw_record raw; struct pt_regs regs; int n; @@ -499,12 +498,6 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) perf_sample_data_init(&data, 0); data.period = event->hw.last_period; - if (event->attr.sample_type & PERF_SAMPLE_RAW) { - raw.size = x86_pmu.pebs_record_size; - raw.data = at; - data.raw = &raw; - } - /* * We use the interrupt regs as a base because the PEBS record * does not contain a full regs set, specifically it seems to @@ -536,7 +529,6 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) struct pebs_record_nhm *at, *top; struct perf_sample_data data; struct perf_event *event = NULL; - struct perf_raw_record raw; struct pt_regs regs; u64 status = 0; int bit, n; @@ -585,12 +577,6 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) perf_sample_data_init(&data, 0); data.period = event->hw.last_period; - if (event->attr.sample_type & PERF_SAMPLE_RAW) { - raw.size = x86_pmu.pebs_record_size; - raw.data = at; - data.raw = &raw; - } - /* * See the comment in intel_pmu_drain_pebs_core() */ -- cgit v1.2.3-59-g8ed1b From 2b0b5c6fe9b383f3cf35a0a6371c9d577bd523ff Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 8 Apr 2010 23:03:20 +0200 Subject: perf, x86: Consolidate some code repetition Remove some duplicated logic. Signed-off-by: Peter Zijlstra LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 97 ++++++++++++++----------------- 1 file changed, 44 insertions(+), 53 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 080b9b065bdd..35056f715e9e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -452,14 +452,54 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) static int intel_pmu_save_and_restart(struct perf_event *event); +static void __intel_pmu_pebs_event(struct perf_event *event, + struct pt_regs *iregs, void *__pebs) +{ + /* + * We cast to pebs_record_core since that is a subset of + * both formats and we don't use the other fields in this + * routine. + */ + struct pebs_record_core *pebs = __pebs; + struct perf_sample_data data; + struct pt_regs regs; + + if (!intel_pmu_save_and_restart(event)) + return; + + perf_sample_data_init(&data, 0); + data.period = event->hw.last_period; + + /* + * We use the interrupt regs as a base because the PEBS record + * does not contain a full regs set, specifically it seems to + * lack segment descriptors, which get used by things like + * user_mode(). + * + * In the simple case fix up only the IP and BP,SP regs, for + * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly. + * A possible PERF_SAMPLE_REGS will have to transfer all regs. + */ + regs = *iregs; + regs.ip = pebs->ip; + regs.bp = pebs->bp; + regs.sp = pebs->sp; + + if (intel_pmu_pebs_fixup_ip(regs)) + regs.flags |= PERF_EFLAGS_EXACT; + else + regs.flags &= ~PERF_EFLAGS_EXACT; + + if (perf_event_overflow(event, 1, &data, ®s)) + x86_pmu_stop(event); +} + static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct debug_store *ds = cpuc->ds; struct perf_event *event = cpuc->events[0]; /* PMC0 only */ struct pebs_record_core *at, *top; - struct perf_sample_data data; - struct pt_regs regs; int n; if (!ds || !x86_pmu.pebs) @@ -485,9 +525,6 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) if (n <= 0) return; - if (!intel_pmu_save_and_restart(event)) - return; - /* * Should not happen, we program the threshold at 1 and do not * set a reset value. @@ -495,31 +532,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) WARN_ON_ONCE(n > 1); at += n - 1; - perf_sample_data_init(&data, 0); - data.period = event->hw.last_period; - - /* - * We use the interrupt regs as a base because the PEBS record - * does not contain a full regs set, specifically it seems to - * lack segment descriptors, which get used by things like - * user_mode(). - * - * In the simple case fix up only the IP and BP,SP regs, for - * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly. - * A possible PERF_SAMPLE_REGS will have to transfer all regs. - */ - regs = *iregs; - regs.ip = at->ip; - regs.bp = at->bp; - regs.sp = at->sp; - - if (intel_pmu_pebs_fixup_ip(®s)) - regs.flags |= PERF_EFLAGS_EXACT; - else - regs.flags &= ~PERF_EFLAGS_EXACT; - - if (perf_event_overflow(event, 1, &data, ®s)) - x86_pmu_stop(event); + __intel_pmu_pebs_event(event, iregs, at); } static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) @@ -527,9 +540,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct debug_store *ds = cpuc->ds; struct pebs_record_nhm *at, *top; - struct perf_sample_data data; struct perf_event *event = NULL; - struct pt_regs regs; u64 status = 0; int bit, n; @@ -571,27 +582,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) if (!event || bit >= MAX_PEBS_EVENTS) continue; - if (!intel_pmu_save_and_restart(event)) - continue; - - perf_sample_data_init(&data, 0); - data.period = event->hw.last_period; - - /* - * See the comment in intel_pmu_drain_pebs_core() - */ - regs = *iregs; - regs.ip = at->ip; - regs.bp = at->bp; - regs.sp = at->sp; - - if (intel_pmu_pebs_fixup_ip(®s)) - regs.flags |= PERF_EFLAGS_EXACT; - else - regs.flags &= ~PERF_EFLAGS_EXACT; - - if (perf_event_overflow(event, 1, &data, ®s)) - x86_pmu_stop(event); + __intel_pmu_pebs_event(event, iregs, at); } } -- cgit v1.2.3-59-g8ed1b From ab608344bcbde4f55ec4cd911b686b0ce3eae076 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 8 Apr 2010 23:03:20 +0200 Subject: perf, x86: Improve the PEBS ABI Rename perf_event_attr::precise to perf_event_attr::precise_ip and widen it to 2 bits. This new field describes the required precision of the PERF_SAMPLE_IP field: 0 - SAMPLE_IP can have arbitrary skid 1 - SAMPLE_IP must have constant skid 2 - SAMPLE_IP requested to have 0 skid 3 - SAMPLE_IP must have 0 skid And modify the Intel PEBS code accordingly. The PEBS implementation now supports up to precise_ip == 2, where we perform the IP fixup. Also s/PERF_RECORD_MISC_EXACT/&_IP/ to clarify its meaning, this bit should be set for each PERF_SAMPLE_IP field known to match the actual instruction triggering the event. This new scheme allows for a PEBS mode that uses the buffer for more than a single event. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Stephane Eranian LKML-Reference: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 17 ++++++++++++++++- arch/x86/kernel/cpu/perf_event_intel.c | 4 ++-- arch/x86/kernel/cpu/perf_event_intel_ds.c | 12 ++++++------ include/linux/perf_event.h | 23 +++++++++++++++++++---- tools/perf/builtin-top.c | 2 +- tools/perf/util/parse-events.c | 25 ++++++++++++++++--------- 6 files changed, 60 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 4a3f1f2b9b91..27fa9eeed024 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -488,6 +488,21 @@ static int x86_setup_perfctr(struct perf_event *event) static int x86_pmu_hw_config(struct perf_event *event) { + if (event->attr.precise_ip) { + int precise = 0; + + /* Support for constant skid */ + if (x86_pmu.pebs) + precise++; + + /* Support for IP fixup */ + if (x86_pmu.lbr_nr) + precise++; + + if (event->attr.precise_ip > precise) + return -EOPNOTSUPP; + } + /* * Generate PMC IRQs: * (keep 'enabled' bit clear for now) @@ -1780,7 +1795,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs) } if (regs->flags & PERF_EFLAGS_EXACT) - misc |= PERF_RECORD_MISC_EXACT; + misc |= PERF_RECORD_MISC_EXACT_IP; return misc; } diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index a4b56ac425cb..fdbc652d3feb 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -563,7 +563,7 @@ static void intel_pmu_disable_event(struct perf_event *event) x86_pmu_disable_event(event); - if (unlikely(event->attr.precise)) + if (unlikely(event->attr.precise_ip)) intel_pmu_pebs_disable(event); } @@ -615,7 +615,7 @@ static void intel_pmu_enable_event(struct perf_event *event) return; } - if (unlikely(event->attr.precise)) + if (unlikely(event->attr.precise_ip)) intel_pmu_pebs_enable(event); __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE); diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 35056f715e9e..18018d1311cd 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -307,7 +307,7 @@ intel_pebs_constraints(struct perf_event *event) { struct event_constraint *c; - if (!event->attr.precise) + if (!event->attr.precise_ip) return NULL; if (x86_pmu.pebs_constraints) { @@ -330,7 +330,7 @@ static void intel_pmu_pebs_enable(struct perf_event *event) cpuc->pebs_enabled |= 1ULL << hwc->idx; WARN_ON_ONCE(cpuc->enabled); - if (x86_pmu.intel_cap.pebs_trap) + if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1) intel_pmu_lbr_enable(event); } @@ -345,7 +345,7 @@ static void intel_pmu_pebs_disable(struct perf_event *event) hwc->config |= ARCH_PERFMON_EVENTSEL_INT; - if (x86_pmu.intel_cap.pebs_trap) + if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1) intel_pmu_lbr_disable(event); } @@ -485,7 +485,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event, regs.bp = pebs->bp; regs.sp = pebs->sp; - if (intel_pmu_pebs_fixup_ip(regs)) + if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(®s)) regs.flags |= PERF_EFLAGS_EXACT; else regs.flags &= ~PERF_EFLAGS_EXACT; @@ -518,7 +518,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) WARN_ON_ONCE(!event); - if (!event->attr.precise) + if (!event->attr.precise_ip) return; n = top - at; @@ -570,7 +570,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) WARN_ON_ONCE(!event); - if (!event->attr.precise) + if (!event->attr.precise_ip) continue; if (__test_and_set_bit(bit, (unsigned long *)&status)) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 6be4a0f9137c..23cd0057a681 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -203,9 +203,19 @@ struct perf_event_attr { enable_on_exec : 1, /* next exec enables */ task : 1, /* trace fork/exit */ watermark : 1, /* wakeup_watermark */ - precise : 1, /* OoO invariant counter */ - - __reserved_1 : 48; + /* + * precise_ip: + * + * 0 - SAMPLE_IP can have arbitrary skid + * 1 - SAMPLE_IP must have constant skid + * 2 - SAMPLE_IP requested to have 0 skid + * 3 - SAMPLE_IP must have 0 skid + * + * See also PERF_RECORD_MISC_EXACT_IP + */ + precise_ip : 2, /* skid constraint */ + + __reserved_1 : 47; union { __u32 wakeup_events; /* wakeup every n events */ @@ -296,7 +306,12 @@ struct perf_event_mmap_page { #define PERF_RECORD_MISC_GUEST_KERNEL (4 << 0) #define PERF_RECORD_MISC_GUEST_USER (5 << 0) -#define PERF_RECORD_MISC_EXACT (1 << 14) +/* + * Indicates that the content of PERF_SAMPLE_IP points to + * the actual instruction that triggered the event. See also + * perf_event_attr::precise_ip. + */ +#define PERF_RECORD_MISC_EXACT_IP (1 << 14) /* * Reserve the last bit to indicate some extended misc field */ diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 3de397764cb3..ed9b5b6905fa 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1021,7 +1021,7 @@ static void event__process_sample(const event_t *self, return; } - if (self->header.misc & PERF_RECORD_MISC_EXACT) + if (self->header.misc & PERF_RECORD_MISC_EXACT_IP) exact_samples++; if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 || diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index bc8b7e614207..ae7f5917935c 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -654,10 +654,6 @@ parse_raw_event(const char **strp, struct perf_event_attr *attr) return EVT_FAILED; n = hex2u64(str + 1, &config); if (n > 0) { - if (str[n+1] == 'p') { - attr->precise = 1; - n++; - } *strp = str + n + 1; attr->type = PERF_TYPE_RAW; attr->config = config; @@ -692,19 +688,29 @@ static enum event_result parse_event_modifier(const char **strp, struct perf_event_attr *attr) { const char *str = *strp; - int eu = 1, ek = 1, eh = 1; + int exclude = 0; + int eu = 0, ek = 0, eh = 0, precise = 0; if (*str++ != ':') return 0; while (*str) { - if (*str == 'u') + if (*str == 'u') { + if (!exclude) + exclude = eu = ek = eh = 1; eu = 0; - else if (*str == 'k') + } else if (*str == 'k') { + if (!exclude) + exclude = eu = ek = eh = 1; ek = 0; - else if (*str == 'h') + } else if (*str == 'h') { + if (!exclude) + exclude = eu = ek = eh = 1; eh = 0; - else + } else if (*str == 'p') { + precise++; + } else break; + ++str; } if (str >= *strp + 2) { @@ -712,6 +718,7 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr) attr->exclude_user = eu; attr->exclude_kernel = ek; attr->exclude_hv = eh; + attr->precise_ip = precise; return 1; } return 0; -- cgit v1.2.3-59-g8ed1b From 4d1c52b02d977d884abb21d0bbaba6b5d6bc8374 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Fri, 23 Apr 2010 13:56:12 +0800 Subject: perf, x86: implement group scheduling transactional APIs Convert to the transactional PMU API and remove the duplication of group_sched_in(). Reviewed-by: Stephane Eranian Signed-off-by: Lin Ming Signed-off-by: Peter Zijlstra Cc: David Miller Cc: Paul Mackerras LKML-Reference: <1272002172.5707.61.camel@minggr.sh.intel.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 180 +++++++++++++++------------------------ 1 file changed, 67 insertions(+), 113 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 27fa9eeed024..fd4db0db3708 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -110,6 +110,8 @@ struct cpu_hw_events { u64 tags[X86_PMC_IDX_MAX]; struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ + unsigned int group_flag; + /* * Intel DebugStore bits */ @@ -961,6 +963,14 @@ static int x86_pmu_enable(struct perf_event *event) if (n < 0) return n; + /* + * If group events scheduling transaction was started, + * skip the schedulability test here, it will be peformed + * at commit time(->commit_txn) as a whole + */ + if (cpuc->group_flag & PERF_EVENT_TXN_STARTED) + goto out; + ret = x86_pmu.schedule_events(cpuc, n, assign); if (ret) return ret; @@ -970,6 +980,7 @@ static int x86_pmu_enable(struct perf_event *event) */ memcpy(cpuc->assign, assign, n*sizeof(int)); +out: cpuc->n_events = n; cpuc->n_added += n - n0; @@ -1227,119 +1238,6 @@ x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) return &unconstrained; } -static int x86_event_sched_in(struct perf_event *event, - struct perf_cpu_context *cpuctx) -{ - int ret = 0; - - event->state = PERF_EVENT_STATE_ACTIVE; - event->oncpu = smp_processor_id(); - event->tstamp_running += event->ctx->time - event->tstamp_stopped; - - if (!is_x86_event(event)) - ret = event->pmu->enable(event); - - if (!ret && !is_software_event(event)) - cpuctx->active_oncpu++; - - if (!ret && event->attr.exclusive) - cpuctx->exclusive = 1; - - return ret; -} - -static void x86_event_sched_out(struct perf_event *event, - struct perf_cpu_context *cpuctx) -{ - event->state = PERF_EVENT_STATE_INACTIVE; - event->oncpu = -1; - - if (!is_x86_event(event)) - event->pmu->disable(event); - - event->tstamp_running -= event->ctx->time - event->tstamp_stopped; - - if (!is_software_event(event)) - cpuctx->active_oncpu--; - - if (event->attr.exclusive || !cpuctx->active_oncpu) - cpuctx->exclusive = 0; -} - -/* - * Called to enable a whole group of events. - * Returns 1 if the group was enabled, or -EAGAIN if it could not be. - * Assumes the caller has disabled interrupts and has - * frozen the PMU with hw_perf_save_disable. - * - * called with PMU disabled. If successful and return value 1, - * then guaranteed to call perf_enable() and hw_perf_enable() - */ -int hw_perf_group_sched_in(struct perf_event *leader, - struct perf_cpu_context *cpuctx, - struct perf_event_context *ctx) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct perf_event *sub; - int assign[X86_PMC_IDX_MAX]; - int n0, n1, ret; - - if (!x86_pmu_initialized()) - return 0; - - /* n0 = total number of events */ - n0 = collect_events(cpuc, leader, true); - if (n0 < 0) - return n0; - - ret = x86_pmu.schedule_events(cpuc, n0, assign); - if (ret) - return ret; - - ret = x86_event_sched_in(leader, cpuctx); - if (ret) - return ret; - - n1 = 1; - list_for_each_entry(sub, &leader->sibling_list, group_entry) { - if (sub->state > PERF_EVENT_STATE_OFF) { - ret = x86_event_sched_in(sub, cpuctx); - if (ret) - goto undo; - ++n1; - } - } - /* - * copy new assignment, now we know it is possible - * will be used by hw_perf_enable() - */ - memcpy(cpuc->assign, assign, n0*sizeof(int)); - - cpuc->n_events = n0; - cpuc->n_added += n1; - ctx->nr_active += n1; - - /* - * 1 means successful and events are active - * This is not quite true because we defer - * actual activation until hw_perf_enable() but - * this way we* ensure caller won't try to enable - * individual events - */ - return 1; -undo: - x86_event_sched_out(leader, cpuctx); - n0 = 1; - list_for_each_entry(sub, &leader->sibling_list, group_entry) { - if (sub->state == PERF_EVENT_STATE_ACTIVE) { - x86_event_sched_out(sub, cpuctx); - if (++n0 == n1) - break; - } - } - return ret; -} - #include "perf_event_amd.c" #include "perf_event_p6.c" #include "perf_event_p4.c" @@ -1471,6 +1369,59 @@ static inline void x86_pmu_read(struct perf_event *event) x86_perf_event_update(event); } +/* + * Start group events scheduling transaction + * Set the flag to make pmu::enable() not perform the + * schedulability test, it will be performed at commit time + */ +static void x86_pmu_start_txn(const struct pmu *pmu) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + + cpuc->group_flag |= PERF_EVENT_TXN_STARTED; +} + +/* + * Stop group events scheduling transaction + * Clear the flag and pmu::enable() will perform the + * schedulability test. + */ +static void x86_pmu_cancel_txn(const struct pmu *pmu) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + + cpuc->group_flag &= ~PERF_EVENT_TXN_STARTED; +} + +/* + * Commit group events scheduling transaction + * Perform the group schedulability test as a whole + * Return 0 if success + */ +static int x86_pmu_commit_txn(const struct pmu *pmu) +{ + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + int assign[X86_PMC_IDX_MAX]; + int n, ret; + + n = cpuc->n_events; + + if (!x86_pmu_initialized()) + return -EAGAIN; + + ret = x86_pmu.schedule_events(cpuc, n, assign); + if (ret) + return ret; + + /* + * copy new assignment, now we know it is possible + * will be used by hw_perf_enable() + */ + memcpy(cpuc->assign, assign, n*sizeof(int)); + + return 0; +} + static const struct pmu pmu = { .enable = x86_pmu_enable, .disable = x86_pmu_disable, @@ -1478,6 +1429,9 @@ static const struct pmu pmu = { .stop = x86_pmu_stop, .read = x86_pmu_read, .unthrottle = x86_pmu_unthrottle, + .start_txn = x86_pmu_start_txn, + .cancel_txn = x86_pmu_cancel_txn, + .commit_txn = x86_pmu_commit_txn, }; /* -- cgit v1.2.3-59-g8ed1b From e0e33280fedcfa9dd70a54085c4d44d9d53b788f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 7 May 2010 02:55:33 -0700 Subject: Revert "microblaze: Kill NET_SKB_PAD and NET_IP_ALIGN overrides." This reverts commit 39e0786d3cf39c6d2f47b4818ae2da8b8ebc9ce2. On request from microblaze developers, they are going to handle this differently. Signed-off-by: David S. Miller --- arch/microblaze/include/asm/system.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h index b1e2f0710098..48c4f0335e3f 100644 --- a/arch/microblaze/include/asm/system.h +++ b/arch/microblaze/include/asm/system.h @@ -97,4 +97,14 @@ extern struct dentry *of_debugfs_root; #define arch_align_stack(x) (x) +/* + * MicroBlaze doesn't handle unaligned accesses in hardware. + * + * Based on this we force the IP header alignment in network drivers. + * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining + * cacheline alignment of buffers. + */ +#define NET_IP_ALIGN 2 +#define NET_SKB_PAD L1_CACHE_BYTES + #endif /* _ASM_MICROBLAZE_SYSTEM_H */ -- cgit v1.2.3-59-g8ed1b From c4806174c516d26bf4a72db1789cfc96e4950d07 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 7 May 2010 10:21:39 +0900 Subject: ARM: S3C2412: DMA: Remove I2S FIFO address The S3C DMA API doesn't make use of hw_addr.to/from and also the FIFO addresses are provided from the I2S drivers. So these fields are redundant. This patch removes the hw_addr.to/from fields for I2S and the inclusion of header, paving way for the header to be moved closer to the I2S controller drivers. Signed-off-by: Jassi Brar Acked-by: Ben Dooks Signed-off-by: Mark Brown --- arch/arm/mach-s3c2412/dma.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c index e880524904eb..7abecfca0b7e 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c2412/dma.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -119,13 +118,11 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = { .name = "i2s-sdi", .channels = MAP(S3C2412_DMAREQSEL_I2SRX), .channels_rx = MAP(S3C2412_DMAREQSEL_I2SRX), - .hw_addr.from = S3C2410_PA_IIS + S3C2412_IISRXD, }, [DMACH_I2S_OUT] = { .name = "i2s-sdo", .channels = MAP(S3C2412_DMAREQSEL_I2STX), .channels_rx = MAP(S3C2412_DMAREQSEL_I2STX), - .hw_addr.to = S3C2410_PA_IIS + S3C2412_IISTXD, }, [DMACH_USB_EP1] = { .name = "usb-ep1", -- cgit v1.2.3-59-g8ed1b From 1252fa3154fae1f9624ea40cbbf0ea5e21319013 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Fri, 7 May 2010 12:09:52 -0700 Subject: Revert "arm: msm: add oprofile pmu support" This reverts commit ee3c454b8da04815c1884ed85fe89d2d131c0e51. As request by Russell King. Signed-off-by: Daniel Walker --- arch/arm/kernel/pmu.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c index 4f0eb4c2a72c..a124312e343f 100644 --- a/arch/arm/kernel/pmu.c +++ b/arch/arm/kernel/pmu.c @@ -44,8 +44,6 @@ static const int irqs[] = { IRQ_IOP33X_CORE_PMU, #elif defined(CONFIG_ARCH_PXA) IRQ_PMU, -#elif defined(CONFIG_ARCH_MSM_ARM11) - INT_ARM11_PMU, #endif }; -- cgit v1.2.3-59-g8ed1b From 2b107d93635616db0c3f893c8cc2e6d5cd8d77b2 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Fri, 7 May 2010 14:59:45 -0700 Subject: x86: Avoid check hlt for newer cpus Check hlt instruction was targeted for some older CPUs. It is an expensive operation in that it takes 4 ticks to break out the check. We can avoid such check completely for newer x86 cpus (family >= 5). [ hpa: corrected family > 5 to family >= 5 ] Signed-off-by: Jacob Pan LKML-Reference: <1273269585-14346-1-git-send-email-jacob.jun.pan@linux.intel.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/bugs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 01a265212395..c39576cb3018 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -86,7 +86,7 @@ static void __init check_fpu(void) static void __init check_hlt(void) { - if (paravirt_enabled()) + if (boot_cpu_data.x86 >= 5 || paravirt_enabled()) return; printk(KERN_INFO "Checking 'hlt' instruction... "); -- cgit v1.2.3-59-g8ed1b From 9fa02317429449e8176c9bb6da3ac00eb14d52d3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 7 May 2010 16:55:41 -0700 Subject: x86, HyperV: fix up the license to mshyperv.c This should have been GPLv2 only, we cut and pasted from the wrong file originally, sorry. Also removed some unneeded boilerplate license code, we all know where to find the GPLv2, and that there's no warranty as that is implicit from the license. Cc: Ky Srinivasan Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman LKML-Reference: <20100507235541.GA15448@kroah.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mshyperv.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 2443b61cdb17..a58d8e64fc7c 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -6,18 +6,7 @@ * * 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, GOOD TITLE or - * NON INFRINGEMENT. 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 St, Fifth Floor, Boston, MA 02110-1301 USA. + * the Free Software Foundation; version 2 of the License. * */ -- cgit v1.2.3-59-g8ed1b From e08cae4181af9483b04ecfac48f01c8e5a5f27bf Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 7 May 2010 16:57:28 -0700 Subject: x86: Clean up the hypervisor layer Clean up the hypervisor layer and the hypervisor drivers, using an ops structure instead of an enumeration with if statements. The identity of the hypervisor, if needed, can be tested by testing the pointer value in x86_hyper. The MS-HyperV private state is moved into a normal global variable (it's per-system state, not per-CPU state). Being a normal bss variable, it will be left at all zero on non-HyperV platforms, and so can generally be tested for HyperV-specific features without additional qualification. Signed-off-by: H. Peter Anvin Acked-by: Greg KH Cc: Hank Janssen Cc: Alok Kataria Cc: Ky Srinivasan LKML-Reference: <4BE49778.6060800@zytor.com> --- arch/x86/include/asm/hyperv.h | 5 ++-- arch/x86/include/asm/hypervisor.h | 27 +++++++++++++++++-- arch/x86/include/asm/mshyperv.h | 15 ++++++++--- arch/x86/include/asm/processor.h | 7 ----- arch/x86/include/asm/vmware.h | 27 ------------------- arch/x86/kernel/cpu/hypervisor.c | 56 ++++++++++++++++++++++++--------------- arch/x86/kernel/cpu/mshyperv.c | 51 +++++++++++++++++------------------ arch/x86/kernel/cpu/vmware.c | 36 ++++++++++++++----------- 8 files changed, 117 insertions(+), 107 deletions(-) delete mode 100644 arch/x86/include/asm/vmware.h (limited to 'arch') diff --git a/arch/x86/include/asm/hyperv.h b/arch/x86/include/asm/hyperv.h index 46040473e122..5df477ac3af7 100644 --- a/arch/x86/include/asm/hyperv.h +++ b/arch/x86/include/asm/hyperv.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_KVM_HYPERV_H -#define _ASM_X86_KVM_HYPERV_H +#ifndef _ASM_X86_HYPERV_H +#define _ASM_X86_HYPERV_H #include @@ -16,6 +16,7 @@ #define HYPERV_HYPERVISOR_PRESENT_BIT 0x80000000 #define HYPERV_CPUID_MIN 0x40000005 +#define HYPERV_CPUID_MAX 0x4000ffff /* * Feature identification. EAX indicates which features are available diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h index b78c0941e422..70abda7058c8 100644 --- a/arch/x86/include/asm/hypervisor.h +++ b/arch/x86/include/asm/hypervisor.h @@ -17,10 +17,33 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * */ -#ifndef ASM_X86__HYPERVISOR_H -#define ASM_X86__HYPERVISOR_H +#ifndef _ASM_X86_HYPERVISOR_H +#define _ASM_X86_HYPERVISOR_H extern void init_hypervisor(struct cpuinfo_x86 *c); extern void init_hypervisor_platform(void); +/* + * x86 hypervisor information + */ +struct hypervisor_x86 { + /* Hypervisor name */ + const char *name; + + /* Detection routine */ + bool (*detect)(void); + + /* Adjust CPU feature bits (run once per CPU) */ + void (*set_cpu_features)(struct cpuinfo_x86 *); + + /* Platform setup (run once per boot) */ + void (*init_platform)(void); +}; + +extern const struct hypervisor_x86 *x86_hyper; + +/* Recognized hypervisors */ +extern const struct hypervisor_x86 x86_hyper_vmware; +extern const struct hypervisor_x86 x86_hyper_ms_hyperv; + #endif diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 6cd8101d1344..79ce5685ab64 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -1,7 +1,14 @@ -#ifndef ASM_X86__MSHYPER_H -#define ASM_X86__MSHYPER_H +#ifndef _ASM_X86_MSHYPER_H +#define _ASM_X86_MSHYPER_H -int ms_hyperv_platform(void); -void __cpuinit ms_hyperv_set_feature_bits(struct cpuinfo_x86 *c); +#include +#include + +struct ms_hyperv_info { + u32 features; + u32 hints; +}; + +extern struct ms_hyperv_info ms_hyperv; #endif diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 597c041bd124..e4f1dfb2d05b 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -113,9 +113,6 @@ struct cpuinfo_x86 { /* Index into per_cpu list: */ u16 cpu_index; #endif - unsigned int x86_hyper_vendor; - /* The layout of this field is hypervisor specific */ - unsigned int x86_hyper_features; } __attribute__((__aligned__(SMP_CACHE_BYTES))); #define X86_VENDOR_INTEL 0 @@ -129,10 +126,6 @@ struct cpuinfo_x86 { #define X86_VENDOR_UNKNOWN 0xff -#define X86_HYPER_VENDOR_NONE 0 -#define X86_HYPER_VENDOR_VMWARE 1 -#define X86_HYPER_VENDOR_MSFT 2 - /* * capabilities of CPUs */ diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h deleted file mode 100644 index e49ed6d2fd4e..000000000000 --- a/arch/x86/include/asm/vmware.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2008, VMware, Inc. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. 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 St, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ -#ifndef ASM_X86__VMWARE_H -#define ASM_X86__VMWARE_H - -extern void vmware_platform_setup(void); -extern int vmware_platform(void); -extern void vmware_set_feature_bits(struct cpuinfo_x86 *c); - -#endif diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index de3f4e0ce8eb..87381759d3cb 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c @@ -22,40 +22,52 @@ */ #include -#include -#include #include -static inline void __cpuinit -detect_hypervisor_vendor(struct cpuinfo_x86 *c) +/* + * Hypervisor detect order. This is specified explicitly here because + * some hypervisors might implement compatibility modes for other + * hypervisors and therefore need to be detected in specific sequence. + */ +static const __initconst struct hypervisor_x86 * const hypervisors[] = { - if (vmware_platform()) - c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE; - else if (ms_hyperv_platform()) - c->x86_hyper_vendor = X86_HYPER_VENDOR_MSFT; - else - c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE; -} + &x86_hyper_vmware, + &x86_hyper_ms_hyperv, +}; -static inline void __cpuinit -hypervisor_set_feature_bits(struct cpuinfo_x86 *c) +const struct hypervisor_x86 *x86_hyper; + +static inline void __init +detect_hypervisor_vendor(void) { - if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) - vmware_set_feature_bits(c); - else if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_MSFT) - ms_hyperv_set_feature_bits(c); - return; + const struct hypervisor_x86 *h, * const *p; + + for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) { + h = *p; + if (h->detect()) { + x86_hyper = h; + printk(KERN_INFO "Hypervisor detected: %s\n", h->name); + break; + } + } } void __cpuinit init_hypervisor(struct cpuinfo_x86 *c) { - detect_hypervisor_vendor(c); - hypervisor_set_feature_bits(c); + if (x86_hyper && x86_hyper->set_cpu_features) + x86_hyper->set_cpu_features(c); } void __init init_hypervisor_platform(void) { + + detect_hypervisor_vendor(); + + if (!x86_hyper) + return; + init_hypervisor(&boot_cpu_data); - if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) - vmware_platform_setup(); + + if (x86_hyper->init_platform) + x86_hyper->init_platform(); } diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index a58d8e64fc7c..5969c3ee3186 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -12,45 +12,42 @@ #include #include +#include #include #include +struct ms_hyperv_info ms_hyperv; -int ms_hyperv_platform(void) +static bool __init ms_hyperv_platform(void) { - u32 eax, ebx, ecx, edx; - char hyp_signature[13]; + u32 eax; + u32 hyp_signature[3]; - cpuid(1, &eax, &ebx, &ecx, &edx); - if (!(ecx & HYPERV_HYPERVISOR_PRESENT_BIT)) - return 0; + if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) + return false; - cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, &eax, &ebx, &ecx, &edx); - *(u32 *)(hyp_signature + 0) = ebx; - *(u32 *)(hyp_signature + 4) = ecx; - *(u32 *)(hyp_signature + 8) = edx; + cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, + &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); - if ((eax < HYPERV_CPUID_MIN) || (memcmp("Microsoft Hv", hyp_signature, 12))) - return 0; - return 1; + return eax >= HYPERV_CPUID_MIN && + eax <= HYPERV_CPUID_MAX && + !memcmp("Microsoft Hv", hyp_signature, 12); } -void __cpuinit ms_hyperv_set_feature_bits(struct cpuinfo_x86 *c) +static void __init ms_hyperv_init_platform(void) { - u32 eax, ebx, ecx, edx; - - c->x86_hyper_features = 0; /* - * Extract the features, recommendations etc. - * The first 9 bits will be used to track hypervisor features. - * The next 6 bits will be used to track the hypervisor - * recommendations. + * Extract the features and hints */ - cpuid(HYPERV_CPUID_FEATURES, &eax, &ebx, &ecx, &edx); - c->x86_hyper_features |= (eax & 0x1ff); + ms_hyperv.features = cpuid_eax(HYPERV_CPUID_FEATURES); + ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO); - cpuid(HYPERV_CPUID_ENLIGHTMENT_INFO, &eax, &ebx, &ecx, &edx); - c->x86_hyper_features |= ((eax & 0x3f) << 9); - printk(KERN_INFO "Detected HyperV with features: %x\n", - c->x86_hyper_features); + printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n", + ms_hyperv.features, ms_hyperv.hints); } + +const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { + .name = "Microsoft HyperV", + .detect = ms_hyperv_platform, + .init_platform = ms_hyperv_init_platform, +}; diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 1cbed97b59cf..46a5b5d3ba5e 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -23,8 +23,8 @@ #include #include -#include #include +#include #define CPUID_VMWARE_INFO_LEAF 0x40000000 #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 @@ -64,7 +64,7 @@ static unsigned long vmware_get_tsc_khz(void) return tsc_hz; } -void __init vmware_platform_setup(void) +static void __init vmware_platform_setup(void) { uint32_t eax, ebx, ecx, edx; @@ -82,24 +82,21 @@ void __init vmware_platform_setup(void) * serial key should be enough, as this will always have a VMware * specific string when running under VMware hypervisor. */ -int vmware_platform(void) +static bool __init vmware_platform(void) { if (cpu_has_hypervisor) { - unsigned int eax, ebx, ecx, edx; - char hyper_vendor_id[13]; - - cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &ebx, &ecx, &edx); - memcpy(hyper_vendor_id + 0, &ebx, 4); - memcpy(hyper_vendor_id + 4, &ecx, 4); - memcpy(hyper_vendor_id + 8, &edx, 4); - hyper_vendor_id[12] = '\0'; - if (!strcmp(hyper_vendor_id, "VMwareVMware")) - return 1; + unsigned int eax; + unsigned int hyper_vendor_id[3]; + + cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &hyper_vendor_id[0], + &hyper_vendor_id[1], &hyper_vendor_id[2]); + if (!memcmp(hyper_vendor_id, "VMwareVMware", 12)) + return true; } else if (dmi_available && dmi_name_in_serial("VMware") && __vmware_platform()) - return 1; + return true; - return 0; + return false; } /* @@ -114,8 +111,15 @@ int vmware_platform(void) * so that the kernel could just trust the hypervisor with providing a * reliable virtual TSC that is suitable for timekeeping. */ -void __cpuinit vmware_set_feature_bits(struct cpuinfo_x86 *c) +static void __cpuinit vmware_set_cpu_features(struct cpuinfo_x86 *c) { set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE); } + +const __refconst struct hypervisor_x86 x86_hyper_vmware = { + .name = "VMware", + .detect = vmware_platform, + .set_cpu_features = vmware_set_cpu_features, + .init_platform = vmware_platform_setup, +}; -- cgit v1.2.3-59-g8ed1b From de902d967feb96f2dfddfbe9dbd69dc22fd5ebcb Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 8 May 2010 15:39:52 +0400 Subject: x86, perf: P4 PMU -- configure predefined events If an event is not RAW we should not exit p4_hw_config early but call x86_setup_perfctr as well. Signed-off-by: Cyrill Gorcunov Cc: Peter Zijlstra Cc: Frederic Weisbecker Cc: Lin Ming Cc: Robert Richter Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_p4.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 9e002054cb5f..b1f532d1d36f 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -439,21 +439,20 @@ static int p4_hw_config(struct perf_event *event) if (p4_ht_active() && p4_ht_thread(cpu)) event->hw.config = p4_set_ht_bit(event->hw.config); - if (event->attr.type != PERF_TYPE_RAW) - return 0; - - /* - * We don't control raw events so it's up to the caller - * to pass sane values (and we don't count the thread number - * on HT machine but allow HT-compatible specifics to be - * passed on) - * - * XXX: HT wide things should check perf_paranoid_cpu() && - * CAP_SYS_ADMIN - */ - event->hw.config |= event->attr.config & - (p4_config_pack_escr(P4_ESCR_MASK_HT) | - p4_config_pack_cccr(P4_CCCR_MASK_HT)); + if (event->attr.type == PERF_TYPE_RAW) { + /* + * We don't control raw events so it's up to the caller + * to pass sane values (and we don't count the thread number + * on HT machine but allow HT-compatible specifics to be + * passed on) + * + * XXX: HT wide things should check perf_paranoid_cpu() && + * CAP_SYS_ADMIN + */ + event->hw.config |= event->attr.config & + (p4_config_pack_escr(P4_ESCR_MASK_HT) | + p4_config_pack_cccr(P4_CCCR_MASK_HT)); + } return x86_setup_perfctr(event); } -- cgit v1.2.3-59-g8ed1b From 137351e0feeb9f25d99488ee1afc1c79f5499a9a Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 8 May 2010 15:25:52 +0400 Subject: x86, perf: P4 PMU -- protect sensible procedures from preemption Steven reported: | | I'm getting: | | Pid: 3477, comm: perf Not tainted 2.6.34-rc6 #2727 | Call Trace: | [] debug_smp_processor_id+0xd5/0xf0 | [] p4_hw_config+0x2b/0x15c | [] ? trace_hardirqs_on_caller+0x12b/0x14f | [] hw_perf_event_init+0x468/0x7be | [] ? debug_mutex_init+0x31/0x3c | [] T.850+0x273/0x42e | [] sys_perf_event_open+0x23e/0x3f1 | [] ? sysret_check+0x2e/0x69 | [] system_call_fastpath+0x16/0x1b | | When running perf record in latest tip/perf/core | Due to the fact that p4 counters are shared between HT threads we synthetically divide the whole set of counters into two non-intersected subsets. And while we're "borrowing" counters from these subsets we should not be preempted (well, strictly speaking in p4_hw_config we just pre-set reference to the subset which allow to save some cycles in schedule routine if it happens on the same cpu). So use get_cpu/put_cpu pair. Also p4_pmu_schedule_events should use smp_processor_id rather than raw_ version. This allow us to catch up preemption issue (if there will ever be). Reported-by: Steven Rostedt Tested-by: Steven Rostedt Signed-off-by: Cyrill Gorcunov Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Frederic Weisbecker Cc: Lin Ming LKML-Reference: <20100508112716.963478928@openvz.org> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_p4.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index b1f532d1d36f..ca40180c41d4 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -421,7 +421,8 @@ static u64 p4_pmu_event_map(int hw_event) static int p4_hw_config(struct perf_event *event) { - int cpu = raw_smp_processor_id(); + int cpu = get_cpu(); + int rc = 0; u32 escr, cccr; /* @@ -454,7 +455,10 @@ static int p4_hw_config(struct perf_event *event) p4_config_pack_cccr(P4_CCCR_MASK_HT)); } - return x86_setup_perfctr(event); + rc = x86_setup_perfctr(event); + put_cpu(); + + return rc; } static inline void p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc) -- cgit v1.2.3-59-g8ed1b From 3f51b7119d052827dbb0e40c966acdf2bdc6f47f Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 8 May 2010 15:25:53 +0400 Subject: x86, perf: P4 PMU -- Get rid of redundant check for array index The caller already has done such a check. And it was wrong anyway, it had to be '>=' rather than '>' Signed-off-by: Cyrill Gorcunov Cc: Peter Zijlstra Cc: Frederic Weisbecker Cc: Lin Ming LKML-Reference: <20100508112717.130386882@openvz.org> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_p4.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index ca40180c41d4..b8c2d379eea6 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -406,11 +406,6 @@ static u64 p4_pmu_event_map(int hw_event) unsigned int esel; u64 config; - if (hw_event > ARRAY_SIZE(p4_general_events)) { - printk_once(KERN_ERR "P4 PMU: Bad index: %i\n", hw_event); - return 0; - } - config = p4_general_events[hw_event]; bind = p4_config_get_bind(config); esel = P4_OPCODE_ESEL(bind->opcode); -- cgit v1.2.3-59-g8ed1b From c7993165ef0c1d636ca05f4787739f8414584e6d Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 8 May 2010 15:25:54 +0400 Subject: x86, perf: P4 PMU -- check for proper event index in RAW events RAW events are special and we should be ready for user passing in insane event index values. Signed-off-by: Cyrill Gorcunov Cc: Peter Zijlstra Cc: Frederic Weisbecker Cc: Lin Ming LKML-Reference: <20100508112717.315897547@openvz.org> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_p4.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index b8c2d379eea6..a603930271f3 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -418,6 +418,7 @@ static int p4_hw_config(struct perf_event *event) { int cpu = get_cpu(); int rc = 0; + unsigned int evnt; u32 escr, cccr; /* @@ -436,6 +437,14 @@ static int p4_hw_config(struct perf_event *event) event->hw.config = p4_set_ht_bit(event->hw.config); if (event->attr.type == PERF_TYPE_RAW) { + + /* user data may have out-of-bound event index */ + evnt = p4_config_unpack_event(event->attr.config); + if (evnt >= ARRAY_SIZE(p4_event_bind_map)) { + rc = -EINVAL; + goto out; + } + /* * We don't control raw events so it's up to the caller * to pass sane values (and we don't count the thread number @@ -451,8 +460,8 @@ static int p4_hw_config(struct perf_event *event) } rc = x86_setup_perfctr(event); +out: put_cpu(); - return rc; } -- cgit v1.2.3-59-g8ed1b From 96f6e775b58687d85ee33004d414419b5ec34106 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 9 May 2010 01:10:34 -0700 Subject: x86, hypervisor: Export the x86_hyper* symbols Export x86_hyper and the related specific structures, allowing for hypervisor identification by modules. Signed-off-by: H. Peter Anvin Cc: Greg KH Cc: Hank Janssen Cc: Alok Kataria Cc: Ky Srinivasan Cc: Dmitry Torokhov LKML-Reference: <4BE49778.6060800@zytor.com> --- arch/x86/kernel/cpu/hypervisor.c | 1 + arch/x86/kernel/cpu/mshyperv.c | 1 + arch/x86/kernel/cpu/vmware.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index 87381759d3cb..4afb5a2130ed 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c @@ -36,6 +36,7 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] = }; const struct hypervisor_x86 *x86_hyper; +EXPORT_SYMBOL(x86_hyper); static inline void __init detect_hypervisor_vendor(void) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 5969c3ee3186..0f1371724c86 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -51,3 +51,4 @@ const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { .detect = ms_hyperv_platform, .init_platform = ms_hyperv_init_platform, }; +EXPORT_SYMBOL(x86_hyper_ms_hyperv); diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 265b432f6e64..b9d1ff588445 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -99,7 +99,6 @@ static bool __init vmware_platform(void) return false; } -EXPORT_SYMBOL(vmware_platform); /* * VMware hypervisor takes care of exporting a reliable TSC to the guest. @@ -125,3 +124,4 @@ const __refconst struct hypervisor_x86 x86_hyper_vmware = { .set_cpu_features = vmware_set_cpu_features, .init_platform = vmware_platform_setup, }; +EXPORT_SYMBOL(x86_hyper_vmware); -- cgit v1.2.3-59-g8ed1b From 7cfdee9f6791fe9ec288e75ee746790ebf3b6c3b Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Wed, 19 Aug 2009 16:31:03 +0300 Subject: ARM: S3C2416: Add S3C2416-specific registers definitions Add macros for S3C2416 SoC support. Signed-off-by: Yauhen Kharuzhy [ben-linux@fluff.org: removed files that need changing] [ben-linux@fluff.org: Fix S3C2416_GPH0_TXD0 definition] Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/dma.h | 2 +- arch/arm/mach-s3c2410/include/mach/irqs.h | 22 ++++++++++++- arch/arm/mach-s3c2410/include/mach/regs-dsc.h | 36 ++++++++++++++++++++++ arch/arm/mach-s3c2410/include/mach/regs-gpio.h | 28 +++++++++++++++++ arch/arm/mach-s3c2410/include/mach/regs-irq.h | 10 ++++++ .../mach-s3c2410/include/mach/regs-s3c2416-mem.h | 30 ++++++++++++++++++ arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h | 24 +++++++++++++++ 7 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h create mode 100644 arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index 08ac5f96c012..cf68136cc668 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -54,7 +54,7 @@ enum dma_ch { #define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ /* we have 4 dma channels */ -#ifndef CONFIG_CPU_S3C2443 +#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416) #define S3C_DMA_CHANNELS (4) #else #define S3C_DMA_CHANNELS (6) diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h index 6c12c6312ad8..c1b8ec07bf45 100644 --- a/arch/arm/mach-s3c2410/include/mach/irqs.h +++ b/arch/arm/mach-s3c2410/include/mach/irqs.h @@ -115,6 +115,26 @@ #define IRQ_S3C2412_SDI S3C2410_IRQSUB(13) #define IRQ_S3C2412_CF S3C2410_IRQSUB(14) + +#define IRQ_S3C2416_EINT8t15 S3C2410_IRQ(5) +#define IRQ_S3C2416_DMA S3C2410_IRQ(17) +#define IRQ_S3C2416_UART3 S3C2410_IRQ(18) +#define IRQ_S3C2416_SDI1 S3C2410_IRQ(20) +#define IRQ_S3C2416_SDI0 S3C2410_IRQ(21) + +#define IRQ_S3C2416_LCD2 S3C2410_IRQSUB(15) +#define IRQ_S3C2416_LCD3 S3C2410_IRQSUB(16) +#define IRQ_S3C2416_LCD4 S3C2410_IRQSUB(17) +#define IRQ_S3C2416_DMA0 S3C2410_IRQSUB(18) +#define IRQ_S3C2416_DMA1 S3C2410_IRQSUB(19) +#define IRQ_S3C2416_DMA2 S3C2410_IRQSUB(20) +#define IRQ_S3C2416_DMA3 S3C2410_IRQSUB(21) +#define IRQ_S3C2416_DMA4 S3C2410_IRQSUB(22) +#define IRQ_S3C2416_DMA5 S3C2410_IRQSUB(23) +#define IRQ_S32416_WDT S3C2410_IRQSUB(27) +#define IRQ_S32416_AC97 S3C2410_IRQSUB(28) + + /* extra irqs for s3c2440 */ #define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */ @@ -152,7 +172,7 @@ #define IRQ_S3C2443_WDT S3C2410_IRQSUB(27) #define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28) -#ifdef CONFIG_CPU_S3C2443 +#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) #define NR_IRQS (IRQ_S3C2443_AC97+1) #else #define NR_IRQS (IRQ_S3C2440_AC97+1) diff --git a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h index 3c3853cd3cf7..98fd4a05587c 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h @@ -19,6 +19,42 @@ #define S3C2412_DSC1 S3C2410_GPIOREG(0xe0) #endif +#if defined(CONFIG_CPU_S3C2416) +#define S3C2416_DSC0 S3C2410_GPIOREG(0xc0) +#define S3C2416_DSC1 S3C2410_GPIOREG(0xc4) +#define S3C2416_DSC2 S3C2410_GPIOREG(0xc8) +#define S3C2416_DSC3 S3C2410_GPIOREG(0x110) + +#define S3C2416_SELECT_DSC0 (0 << 30) +#define S3C2416_SELECT_DSC1 (1 << 30) +#define S3C2416_SELECT_DSC2 (2 << 30) +#define S3C2416_SELECT_DSC3 (3 << 30) + +#define S3C2416_DSC_GETSHIFT(x) (x & 30) + +#define S3C2416_DSC0_CF (S3C2416_SELECT_DSC0 | 28) +#define S3C2416_DSC0_CF_5mA (0 << 28) +#define S3C2416_DSC0_CF_10mA (1 << 28) +#define S3C2416_DSC0_CF_15mA (2 << 28) +#define S3C2416_DSC0_CF_21mA (3 << 28) +#define S3C2416_DSC0_CF_MASK (3 << 28) + +#define S3C2416_DSC0_nRBE (S3C2416_SELECT_DSC0 | 26) +#define S3C2416_DSC0_nRBE_5mA (0 << 26) +#define S3C2416_DSC0_nRBE_10mA (1 << 26) +#define S3C2416_DSC0_nRBE_15mA (2 << 26) +#define S3C2416_DSC0_nRBE_21mA (3 << 26) +#define S3C2416_DSC0_nRBE_MASK (3 << 26) + +#define S3C2416_DSC0_nROE (S3C2416_SELECT_DSC0 | 24) +#define S3C2416_DSC0_nROE_5mA (0 << 24) +#define S3C2416_DSC0_nROE_10mA (1 << 24) +#define S3C2416_DSC0_nROE_15mA (2 << 24) +#define S3C2416_DSC0_nROE_21mA (3 << 24) +#define S3C2416_DSC0_nROE_MASK (3 << 24) + +#endif + #if defined(CONFIG_CPU_S3C244X) #define S3C2440_DSC0 S3C2410_GPIOREG(0xc4) diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h index 821b966bf05a..a6384239eddf 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h @@ -610,29 +610,50 @@ #define S3C2410_GPHUP S3C2410_GPIOREG(0x78) #define S3C2410_GPH0_nCTS0 (0x02 << 0) +#define S3C2416_GPH0_TXD0 (0x02 << 0) #define S3C2410_GPH1_nRTS0 (0x02 << 2) +#define S3C2416_GPH1_RXD0 (0x02 << 2) #define S3C2410_GPH2_TXD0 (0x02 << 4) +#define S3C2416_GPH2_TXD1 (0x02 << 4) #define S3C2410_GPH3_RXD0 (0x02 << 6) +#define S3C2416_GPH3_RXD1 (0x02 << 6) #define S3C2410_GPH4_TXD1 (0x02 << 8) +#define S3C2416_GPH4_TXD2 (0x02 << 8) #define S3C2410_GPH5_RXD1 (0x02 << 10) +#define S3C2416_GPH5_RXD2 (0x02 << 10) #define S3C2410_GPH6_TXD2 (0x02 << 12) +#define S3C2416_GPH6_TXD3 (0x02 << 12) #define S3C2410_GPH6_nRTS1 (0x03 << 12) +#define S3C2416_GPH6_nRTS2 (0x03 << 12) #define S3C2410_GPH7_RXD2 (0x02 << 14) +#define S3C2416_GPH7_RXD3 (0x02 << 14) #define S3C2410_GPH7_nCTS1 (0x03 << 14) +#define S3C2416_GPH7_nCTS2 (0x03 << 14) #define S3C2410_GPH8_UCLK (0x02 << 16) +#define S3C2416_GPH8_nCTS0 (0x02 << 16) #define S3C2410_GPH9_CLKOUT0 (0x02 << 18) #define S3C2442_GPH9_nSPICS0 (0x03 << 18) +#define S3C2416_GPH9_nRTS0 (0x02 << 18) #define S3C2410_GPH10_CLKOUT1 (0x02 << 20) +#define S3C2416_GPH10_nCTS1 (0x02 << 20) + +#define S3C2416_GPH11_nRTS1 (0x02 << 22) + +#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24) + +#define S3C2416_GPH13_CLKOUT0 (0x02 << 26) + +#define S3C2416_GPH14_CLKOUT1 (0x02 << 28) /* The S3C2412 and S3C2413 move the GPJ register set to after * GPH, which means all registers after 0x80 are now offset by 0x10 @@ -703,6 +724,7 @@ #define S3C2412_MISCCR_CLK1_CLKsrc (0<<8) #define S3C2410_MISCCR_USBSUSPND0 (1<<12) +#define S3C2416_MISCCR_SEL_SUSPND (1<<12) #define S3C2410_MISCCR_USBSUSPND1 (1<<13) #define S3C2410_MISCCR_nRSTCON (1<<16) @@ -712,6 +734,9 @@ #define S3C2410_MISCCR_nEN_SCLKE (1<<19) /* not 2412 */ #define S3C2410_MISCCR_SDSLEEP (7<<17) +#define S3C2416_MISCCR_FLT_I2C (1<<24) +#define S3C2416_MISCCR_HSSPI_EN2 (1<<31) + /* external interrupt control... */ /* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7 * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15 @@ -779,8 +804,11 @@ #define S3C2410_GSTATUS1_IDMASK (0xffff0000) #define S3C2410_GSTATUS1_2410 (0x32410000) #define S3C2410_GSTATUS1_2412 (0x32412001) +#define S3C2410_GSTATUS1_2416 (0x32416003) #define S3C2410_GSTATUS1_2440 (0x32440000) #define S3C2410_GSTATUS1_2442 (0x32440aaa) +/* some 2416 CPUs report this value also */ +#define S3C2410_GSTATUS1_2450 (0x32450003) #define S3C2410_GSTATUS2_WTRESET (1<<2) #define S3C2410_GSTATUS2_OFFRESET (1<<1) diff --git a/arch/arm/mach-s3c2410/include/mach/regs-irq.h b/arch/arm/mach-s3c2410/include/mach/regs-irq.h index de86ee8812bd..0f07ba30b1fb 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-irq.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-irq.h @@ -27,6 +27,16 @@ #define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018) #define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C) +#define S3C2416_PRIORITY_MODE1 S3C2410_IRQREG(0x030) +#define S3C2416_PRIORITY_UPDATE1 S3C2410_IRQREG(0x034) +#define S3C2416_SRCPND2 S3C2410_IRQREG(0x040) +#define S3C2416_INTMOD2 S3C2410_IRQREG(0x044) +#define S3C2416_INTMSK2 S3C2410_IRQREG(0x048) +#define S3C2416_INTPND2 S3C2410_IRQREG(0x050) +#define S3C2416_INTOFFSET2 S3C2410_IRQREG(0x054) +#define S3C2416_PRIORITY_MODE2 S3C2410_IRQREG(0x070) +#define S3C2416_PRIORITY_UPDATE2 S3C2410_IRQREG(0x074) + /* mask: 0=enable, 1=disable * 1 bit EINT, 4=EINT4, 23=EINT23 * EINT0,1,2,3 are not handled here. diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h new file mode 100644 index 000000000000..2f31b74974af --- /dev/null +++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h @@ -0,0 +1,30 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h + * + * Copyright (c) 2009 Yauhen Kharuzhy , + * as part of OpenInkpot project + * Copyright (c) 2009 Promwad Innovation Company + * Yauhen Kharuzhy + * + * 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. + * + * S3C2416 memory register definitions +*/ + +#ifndef __ASM_ARM_REGS_S3C2416_MEM +#define __ASM_ARM_REGS_S3C2416_MEM + +#ifndef S3C2416_MEMREG +#define S3C2416_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) +#endif + +#define S3C2416_BANKCFG S3C2416_MEMREG(0x00) +#define S3C2416_BANKCON1 S3C2416_MEMREG(0x04) +#define S3C2416_BANKCON2 S3C2416_MEMREG(0x08) +#define S3C2416_BANKCON3 S3C2416_MEMREG(0x0C) + +#define S3C2416_REFRESH S3C2416_MEMREG(0x10) +#define S3C2416_TIMEOUT S3C2416_MEMREG(0x14) + +#endif /* __ASM_ARM_REGS_S3C2416_MEM */ diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h new file mode 100644 index 000000000000..e443167efb87 --- /dev/null +++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h @@ -0,0 +1,24 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h + * + * Copyright (c) 2009 Yauhen Kharuzhy , + * as part of OpenInkpot project + * Copyright (c) 2009 Promwad Innovation Company + * Yauhen Kharuzhy + * + * 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. + * + * S3C2416 specific register definitions +*/ + +#ifndef __ASM_ARCH_REGS_S3C2416_H +#define __ASM_ARCH_REGS_S3C2416_H "s3c2416" + +#define S3C2416_SWRST (S3C24XX_VA_CLKPWR + 0x44) +#define S3C2416_SWRST_RESET (0x533C2416) + +/* see regs-power.h for the other registers in the power block. */ + +#endif /* __ASM_ARCH_REGS_S3C2416_H */ + -- cgit v1.2.3-59-g8ed1b From e561aacc70716ff59b9359ba8f010609ee757241 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 28 Apr 2010 18:10:02 +0900 Subject: ARM: SAMSUNG: Move S3C6400 PLL code to for re-use The S3C6400 EPLL code matches the S3C2416 and compatible SoCs, so move it from mach-s3c64xx into for easy reuse. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/include/mach/pll.h | 35 ++---------------- arch/arm/plat-samsung/include/plat/pll6553x.h | 51 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 32 deletions(-) create mode 100644 arch/arm/plat-samsung/include/plat/pll6553x.h (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/include/mach/pll.h b/arch/arm/mach-s3c64xx/include/mach/pll.h index 90bbd72fdc4e..5ef0bb698ee0 100644 --- a/arch/arm/mach-s3c64xx/include/mach/pll.h +++ b/arch/arm/mach-s3c64xx/include/mach/pll.h @@ -20,6 +20,7 @@ #define S3C6400_PLL_SDIV_SHIFT (0) #include +#include static inline unsigned long s3c6400_get_pll(unsigned long baseclk, u32 pllcon) @@ -37,38 +38,8 @@ static inline unsigned long s3c6400_get_pll(unsigned long baseclk, return (unsigned long)fvco; } -#define S3C6400_EPLL_MDIV_MASK ((1 << (23-16)) - 1) -#define S3C6400_EPLL_PDIV_MASK ((1 << (13-8)) - 1) -#define S3C6400_EPLL_SDIV_MASK ((1 << (2-0)) - 1) -#define S3C6400_EPLL_MDIV_SHIFT (16) -#define S3C6400_EPLL_PDIV_SHIFT (8) -#define S3C6400_EPLL_SDIV_SHIFT (0) -#define S3C6400_EPLL_KDIV_MASK (0xffff) - static inline unsigned long s3c6400_get_epll(unsigned long baseclk) { - unsigned long result; - u32 epll0 = __raw_readl(S3C_EPLL_CON0); - u32 epll1 = __raw_readl(S3C_EPLL_CON1); - u32 mdiv, pdiv, sdiv, kdiv; - u64 tmp; - - mdiv = (epll0 >> S3C6400_EPLL_MDIV_SHIFT) & S3C6400_EPLL_MDIV_MASK; - pdiv = (epll0 >> S3C6400_EPLL_PDIV_SHIFT) & S3C6400_EPLL_PDIV_MASK; - sdiv = (epll0 >> S3C6400_EPLL_SDIV_SHIFT) & S3C6400_EPLL_SDIV_MASK; - kdiv = epll1 & S3C6400_EPLL_KDIV_MASK; - - /* We need to multiple baseclk by mdiv (the integer part) and kdiv - * which is in 2^16ths, so shift mdiv up (does not overflow) and - * add kdiv before multiplying. The use of tmp is to avoid any - * overflows before shifting bac down into result when multipling - * by the mdiv and kdiv pair. - */ - - tmp = baseclk; - tmp *= (mdiv << 16) + kdiv; - do_div(tmp, (pdiv << sdiv)); - result = tmp >> 16; - - return result; + return s3c_get_pll6553x(baseclk, __raw_readl(S3C_EPLL_CON0), + __raw_readl(S3C_EPLL_CON1)); } diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h new file mode 100644 index 000000000000..b8b7e1d884f8 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/pll6553x.h @@ -0,0 +1,51 @@ +/* arch/arm/plat-samsung/include/plat/pll6553x.h + * partially from arch/arm/mach-s3c64xx/include/mach/pll.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * Samsung PLL6553x PLL code + * + * 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. +*/ + +/* S3C6400 and compatible (S3C2416, etc.) EPLL code */ + +#define PLL6553X_MDIV_MASK ((1 << (23-16)) - 1) +#define PLL6553X_PDIV_MASK ((1 << (13-8)) - 1) +#define PLL6553X_SDIV_MASK ((1 << (2-0)) - 1) +#define PLL6553X_MDIV_SHIFT (16) +#define PLL6553X_PDIV_SHIFT (8) +#define PLL6553X_SDIV_SHIFT (0) +#define PLL6553X_KDIV_MASK (0xffff) + +static inline unsigned long s3c_get_pll6553x(unsigned long baseclk, + u32 pll0, u32 pll1) +{ + unsigned long result; + u32 mdiv, pdiv, sdiv, kdiv; + u64 tmp; + + mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK; + pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK; + sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK; + kdiv = pll1 & PLL6553X_KDIV_MASK; + + /* We need to multiple baseclk by mdiv (the integer part) and kdiv + * which is in 2^16ths, so shift mdiv up (does not overflow) and + * add kdiv before multiplying. The use of tmp is to avoid any + * overflows before shifting bac down into result when multipling + * by the mdiv and kdiv pair. + */ + + tmp = baseclk; + tmp *= (mdiv << 16) + kdiv; + do_div(tmp, (pdiv << sdiv)); + result = tmp >> 16; + + return result; +} -- cgit v1.2.3-59-g8ed1b From 4e04691bc600b53f6aab63404e58fae3bdf8e310 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 28 Apr 2010 12:58:13 +0900 Subject: ARM: SAMSUNG: Add s3c_disable_clocks() and tidy init+disable usage Add s3c_disable_clocks() and change the clock registration code to use the s3c_register_clocks() followed by s3c_disable_clocks() instead of the loops it was using. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2443/clock.c | 27 ++++----------------------- arch/arm/plat-s3c24xx/s3c2410-clock.c | 15 +++------------ arch/arm/plat-samsung/clock.c | 15 +++++++++++++++ arch/arm/plat-samsung/include/plat/clock.h | 1 + 4 files changed, 23 insertions(+), 35 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 62cd4eaee01b..76d8d66247c3 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -492,7 +492,7 @@ static struct clk clk_prediv = { /* standard clock definitions */ -static struct clk init_clocks_disable[] = { +static struct clk init_clocks_off[] = { { .name = "nand", .id = -1, @@ -761,9 +761,7 @@ void __init_or_cpufreq s3c2443_setup_clocks(void) void __init s3c2443_init_clocks(int xtal) { - struct clk *clkp; unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); - int ret; int ptr; /* s3c2443 parents h and p clocks from prediv */ @@ -774,15 +772,7 @@ void __init s3c2443_init_clocks(int xtal) s3c2443_setup_clocks(); s3c2443_clk_initparents(); - for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { - clkp = clks[ptr]; - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - } + s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_register_clksrc(clksrcs[ptr], 1); @@ -819,17 +809,8 @@ void __init s3c2443_init_clocks(int xtal) /* install (and disable) the clocks we do not need immediately */ - clkp = init_clocks_disable; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - - (clkp->enable)(clkp, 0); - } + s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_pwmclk_init(); } diff --git a/arch/arm/plat-s3c24xx/s3c2410-clock.c b/arch/arm/plat-s3c24xx/s3c2410-clock.c index b61bdb793734..9ecc5d913679 100644 --- a/arch/arm/plat-s3c24xx/s3c2410-clock.c +++ b/arch/arm/plat-s3c24xx/s3c2410-clock.c @@ -87,7 +87,7 @@ static int s3c2410_upll_enable(struct clk *clk, int enable) /* standard clock definitions */ -static struct clk init_clocks_disable[] = { +static struct clk init_clocks_off[] = { { .name = "nand", .id = -1, @@ -249,17 +249,8 @@ int __init s3c2410_baseclk_add(void) /* install (and disable) the clocks we do not need immediately */ - clkp = init_clocks_disable; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - - s3c2410_clkcon_enable(clkp, 0); - } + s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); /* show the clock-slow value */ diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 1b25c9d8c403..8bf79f3efdfb 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c @@ -376,6 +376,21 @@ void __init s3c_register_clocks(struct clk *clkp, int nr_clks) } } +/** + * s3c_disable_clocks() - disable an array of clocks + * @clkp: Pointer to the first clock in the array. + * @nr_clks: Number of clocks to register. + * + * for internal use only at initialisation time. disable the clocks in the + * @clkp array. + */ + +void __init s3c_disable_clocks(struct clk *clkp, int nr_clks) +{ + for (; nr_clks > 0; nr_clks--, clkp++) + (clkp->enable)(clkp, 0); +} + /* initalise all the clocks */ int __init s3c24xx_register_baseclocks(unsigned long xtal) diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h index 60b62692ac7a..12caf48a6bdc 100644 --- a/arch/arm/plat-samsung/include/plat/clock.h +++ b/arch/arm/plat-samsung/include/plat/clock.h @@ -91,6 +91,7 @@ extern int s3c24xx_register_clock(struct clk *clk); extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks); extern void s3c_register_clocks(struct clk *clk, int nr_clks); +extern void s3c_disable_clocks(struct clk *clkp, int nr_clks); extern int s3c24xx_register_baseclocks(unsigned long xtal); -- cgit v1.2.3-59-g8ed1b From f1290a49c5496521360a3e40d8bc766aceee65e5 Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Wed, 28 Apr 2010 18:09:01 +0900 Subject: ARM: S3C2416: Add arch support Add arch/arm/mach-s3c2416 for support of the Samsung S3C2416 SoC. This patch adds support of the S3C2416 SoC, clocks, timers, and initial IRQ support (without support of secondary set of registers). Signed-off-by: Yauhen Kharuzhy [ben-linux@fluff.org: removed files to be reworked, fixed conflicts] [ben-linux@fluff.org: use s3c2443 reset instead of specific reset code] Signed-off-by: Ben Dooks --- arch/arm/Kconfig | 3 +- arch/arm/Makefile | 2 +- arch/arm/mach-s3c2412/Kconfig | 3 +- arch/arm/mach-s3c2416/Kconfig | 25 +++ arch/arm/mach-s3c2416/Makefile | 18 ++ arch/arm/mach-s3c2416/irq.c | 254 +++++++++++++++++++++++++++ arch/arm/mach-s3c2416/s3c2416.c | 115 ++++++++++++ arch/arm/plat-s3c24xx/cpu.c | 13 ++ arch/arm/plat-s3c24xx/include/plat/s3c2416.h | 31 ++++ arch/arm/plat-samsung/include/plat/cpu.h | 1 + 10 files changed, 462 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-s3c2416/Kconfig create mode 100644 arch/arm/mach-s3c2416/Makefile create mode 100644 arch/arm/mach-s3c2416/irq.c create mode 100644 arch/arm/mach-s3c2416/s3c2416.c create mode 100644 arch/arm/plat-s3c24xx/include/plat/s3c2416.h (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 92622eb5cc0d..6785c33908bf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -647,7 +647,7 @@ config ARCH_SA1100 Support for StrongARM 11x0 based boards. config ARCH_S3C2410 - bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443" + bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443" select GENERIC_GPIO select ARCH_HAS_CPUFREQ select HAVE_CLK @@ -892,6 +892,7 @@ if ARCH_S3C2410 source "arch/arm/mach-s3c2400/Kconfig" source "arch/arm/mach-s3c2410/Kconfig" source "arch/arm/mach-s3c2412/Kconfig" +source "arch/arm/mach-s3c2416/Kconfig" source "arch/arm/mach-s3c2440/Kconfig" source "arch/arm/mach-s3c2443/Kconfig" endif diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ed820e737a8a..15947397e12a 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -160,7 +160,7 @@ machine-$(CONFIG_ARCH_PNX4008) := pnx4008 machine-$(CONFIG_ARCH_PXA) := pxa machine-$(CONFIG_ARCH_REALVIEW) := realview machine-$(CONFIG_ARCH_RPC) := rpc -machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2443 +machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443 machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx machine-$(CONFIG_ARCH_S5P6440) := s5p6440 diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig index 9a8c0657ae50..cef6a65637bd 100644 --- a/arch/arm/mach-s3c2412/Kconfig +++ b/arch/arm/mach-s3c2412/Kconfig @@ -16,7 +16,8 @@ config CPU_S3C2412 config CPU_S3C2412_ONLY bool depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \ - !CPU_S3C2440 && !CPU_S3C2442 && !CPU_S3C2443 && CPU_S3C2412 + !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \ + !CPU_S3C2443 && CPU_S3C2412 default y if CPU_S3C2412 config S3C2412_DMA diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig new file mode 100644 index 000000000000..cc320f6b7372 --- /dev/null +++ b/arch/arm/mach-s3c2416/Kconfig @@ -0,0 +1,25 @@ +# arch/arm/mach-s3c2416/Kconfig +# +# Copyright 2009 Yauhen Kharuzhy +# +# Licensed under GPLv2 + +config CPU_S3C2416 + bool + depends on ARCH_S3C2410 + select CPU_ARM926T + select S3C2416_DMA if S3C2410_DMA + select CPU_LLSERIAL_S3C2440 + help + Support for the S3C2416 SoC from the S3C24XX line + +config S3C2416_DMA + bool + depends on CPU_S3C2416 + help + Internal config node for S3C2416 DMA support + +menu "S3C2416 Machines" + + +endmenu diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile new file mode 100644 index 000000000000..34bb70d44d50 --- /dev/null +++ b/arch/arm/mach-s3c2416/Makefile @@ -0,0 +1,18 @@ +# arch/arm/mach-s3c2416/Makefile +# +# Copyright 2009 Yauhen Kharuzhy +# +# Licensed under GPLv2 + +obj-y := +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_CPU_S3C2416) += s3c2416.o +obj-$(CONFIG_CPU_S3C2416) += irq.o + +#obj-$(CONFIG_S3C2416_DMA) += dma.o + +# Machine support + diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c new file mode 100644 index 000000000000..89f521d59d06 --- /dev/null +++ b/arch/arm/mach-s3c2416/irq.c @@ -0,0 +1,254 @@ +/* linux/arch/arm/mach-s3c2416/irq.c + * + * Copyright (c) 2009 Yauhen Kharuzhy , + * as part of OpenInkpot project + * Copyright (c) 2009 Promwad Innovation Company + * Yauhen Kharuzhy + * + * 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 +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) + +static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len) +{ + unsigned int subsrc, submsk; + unsigned int end; + + /* read the current pending interrupts, and the mask + * for what it is available */ + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + subsrc &= ~submsk; + subsrc >>= (irq - S3C2410_IRQSUB(0)); + subsrc &= (1 << len)-1; + + end = len + irq; + + for (; irq < end && subsrc; irq++) { + if (subsrc & 1) + generic_handle_irq(irq); + + subsrc >>= 1; + } +} + +/* WDT/AC97 sub interrupts */ + +static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc) +{ + s3c2416_irq_demux(IRQ_S3C2443_WDT, 4); +} + +#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0)) +#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97) + +static void s3c2416_irq_wdtac97_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97); +} + +static void s3c2416_irq_wdtac97_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_WDTAC97); +} + +static void s3c2416_irq_wdtac97_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97); +} + +static struct irq_chip s3c2416_irq_wdtac97 = { + .mask = s3c2416_irq_wdtac97_mask, + .unmask = s3c2416_irq_wdtac97_unmask, + .ack = s3c2416_irq_wdtac97_ack, +}; + + +/* LCD sub interrupts */ + +static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc) +{ + s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4); +} + +#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) +#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4) + +static void s3c2416_irq_lcd_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD); +} + +static void s3c2416_irq_lcd_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_LCD); +} + +static void s3c2416_irq_lcd_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD); +} + +static struct irq_chip s3c2416_irq_lcd = { + .mask = s3c2416_irq_lcd_mask, + .unmask = s3c2416_irq_lcd_unmask, + .ack = s3c2416_irq_lcd_ack, +}; + + +/* DMA sub interrupts */ + +static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc) +{ + s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6); +} + +#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0)) +#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5) + + +static void s3c2416_irq_dma_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA); +} + +static void s3c2416_irq_dma_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_DMA); +} + +static void s3c2416_irq_dma_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA); +} + +static struct irq_chip s3c2416_irq_dma = { + .mask = s3c2416_irq_dma_mask, + .unmask = s3c2416_irq_dma_unmask, + .ack = s3c2416_irq_dma_ack, +}; + + +/* UART3 sub interrupts */ + +static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc) +{ + s3c2416_irq_demux(IRQ_S3C2443_UART3, 3); +} + +#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0)) +#define SUBMSK_UART3 (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0))) + + +static void s3c2416_irq_uart3_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3); +} + +static void s3c2416_irq_uart3_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_UART3); +} + +static void s3c2416_irq_uart3_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3); +} + +static struct irq_chip s3c2416_irq_uart3 = { + .mask = s3c2416_irq_uart3_mask, + .unmask = s3c2416_irq_uart3_unmask, + .ack = s3c2416_irq_uart3_ack, +}; + + +/* IRQ initialisation code */ + +static int __init s3c2416_add_sub(unsigned int base, + void (*demux)(unsigned int, + struct irq_desc *), + struct irq_chip *chip, + unsigned int start, unsigned int end) +{ + unsigned int irqno; + + set_irq_chip(base, &s3c_irq_level_chip); + set_irq_handler(base, handle_level_irq); + set_irq_chained_handler(base, demux); + + for (irqno = start; irqno <= end; irqno++) { + set_irq_chip(irqno, chip); + set_irq_handler(irqno, handle_level_irq); + set_irq_flags(irqno, IRQF_VALID); + } + + return 0; +} + +static int __init s3c2416_irq_add(struct sys_device *sysdev) +{ + printk(KERN_INFO "S3C2416: IRQ Support\n"); + + s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd, + IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4); + + s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma, + &s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5); + + s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3, + &s3c2416_irq_uart3, + IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3); + + s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97, + &s3c2416_irq_wdtac97, + IRQ_S3C2443_WDT, IRQ_S3C2443_AC97); + + return 0; +} + +static struct sysdev_driver s3c2416_irq_driver = { + .add = s3c2416_irq_add, +}; + +static int __init s3c2416_irq_init(void) +{ + return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_irq_driver); +} + +arch_initcall(s3c2416_irq_init); + diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c new file mode 100644 index 000000000000..6165dc7010fe --- /dev/null +++ b/arch/arm/mach-s3c2416/s3c2416.c @@ -0,0 +1,115 @@ +/* linux/arch/arm/mach-s3c2416/s3c2416.c + * + * Copyright (c) 2009 Yauhen Kharuzhy , + * as part of OpenInkpot project + * Copyright (c) 2009 Promwad Innovation Company + * Yauhen Kharuzhy + * + * Samsung S3C2416 Mobile CPU support + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +static struct map_desc s3c2416_iodesc[] __initdata = { + IODESC_ENT(WATCHDOG), + IODESC_ENT(CLKPWR), + IODESC_ENT(TIMER), +}; + +struct sysdev_class s3c2416_sysclass = { + .name = "s3c2416-core", +}; + +static struct sys_device s3c2416_sysdev = { + .cls = &s3c2416_sysclass, +}; + +static void s3c2416_hard_reset(void) +{ + __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST); +} + +int __init s3c2416_init(void) +{ + printk(KERN_INFO "S3C2416: Initializing architecture\n"); + + s3c24xx_reset_hook = s3c2416_hard_reset; + /* s3c24xx_idle = s3c2416_idle; */ + + /* change WDT IRQ number */ + s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT; + s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT; + + return sysdev_register(&s3c2416_sysdev); +} + +void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no); + + s3c_device_nand.name = "s3c2416-nand"; +} + +/* s3c2416_map_io + * + * register the standard cpu IO areas, and any passed in from the + * machine specific initialisation. + */ + +void __init s3c2416_map_io(void) +{ + iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc)); +} + +/* need to register class before we actually register the device, and + * we also need to ensure that it has been initialised before any of the + * drivers even try to use it (even if not on an s3c2416 based system) + * as a driver which may support both 2443 and 2440 may try and use it. +*/ + +static int __init s3c2416_core_init(void) +{ + return sysdev_class_register(&s3c2416_sysclass); +} + +core_initcall(s3c2416_core_init); diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 9ca64df35bf6..494f4f3a9332 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -57,6 +58,7 @@ static const char name_s3c2400[] = "S3C2400"; static const char name_s3c2410[] = "S3C2410"; static const char name_s3c2412[] = "S3C2412"; +static const char name_s3c2416[] = "S3C2416"; static const char name_s3c2440[] = "S3C2440"; static const char name_s3c2442[] = "S3C2442"; static const char name_s3c2442b[] = "S3C2442B"; @@ -137,6 +139,15 @@ static struct cpu_table cpu_ids[] __initdata = { .init = s3c2412_init, .name = name_s3c2412, }, + { /* a strange version of the s3c2416 */ + .idcode = 0x32450003, + .idmask = 0xffffffff, + .map_io = s3c2416_map_io, + .init_clocks = s3c2416_init_clocks, + .init_uarts = s3c2416_init_uarts, + .init = s3c2416_init, + .name = name_s3c2416, + }, { .idcode = 0x32443001, .idmask = 0xffffffff, @@ -172,6 +183,8 @@ static unsigned long s3c24xx_read_idcode_v5(void) { #if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) return __raw_readl(S3C2412_GSTATUS1); +#elif defined(CONFIG_CPU_S3C2416) + return __raw_readl(S3C24XX_GSTATUS1); #else return 1UL; /* don't look like an 2400 */ #endif diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2416.h b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h new file mode 100644 index 000000000000..dc3c0907d221 --- /dev/null +++ b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h @@ -0,0 +1,31 @@ +/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h + * + * Copyright (c) 2009 Yauhen Kharuzhy + * + * Header file for s3c2416 cpu support + * + * 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. +*/ + +#ifdef CONFIG_CPU_S3C2416 + +struct s3c2410_uartcfg; + +extern int s3c2416_init(void); + +extern void s3c2416_map_io(void); + +extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no); + +extern void s3c2416_init_clocks(int xtal); + +extern int s3c2416_baseclk_add(void); + +#else +#define s3c2416_init_clocks NULL +#define s3c2416_init_uarts NULL +#define s3c2416_map_io NULL +#define s3c2416_init NULL +#endif diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index d316b4a579f4..5dbeb7991e60 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -73,6 +73,7 @@ extern struct sys_timer s3c24xx_timer; extern struct sysdev_class s3c2410_sysclass; extern struct sysdev_class s3c2410a_sysclass; extern struct sysdev_class s3c2412_sysclass; +extern struct sysdev_class s3c2416_sysclass; extern struct sysdev_class s3c2440_sysclass; extern struct sysdev_class s3c2442_sysclass; extern struct sysdev_class s3c2443_sysclass; -- cgit v1.2.3-59-g8ed1b From d24131470f3def698683144cf1e81ee0f4f9c0b8 Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Wed, 19 Aug 2009 16:31:07 +0300 Subject: ARM: S3C2416: Add initial support of SMDK2416 Add support of SMDK2416 development board. Signed-off-by: Yauhen Kharuzhy Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2416/Kconfig | 6 ++ arch/arm/mach-s3c2416/Makefile | 1 + arch/arm/mach-s3c2416/mach-smdk2416.c | 144 ++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 arch/arm/mach-s3c2416/mach-smdk2416.c (limited to 'arch') diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index cc320f6b7372..528f27348b68 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig @@ -21,5 +21,11 @@ config S3C2416_DMA menu "S3C2416 Machines" +config MACH_SMDK2416 + bool "SMDK2416" + select CPU_S3C2416 + select S3C_DEV_HSMMC + help + Say Y here if you are using an SMDK2416 endmenu diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile index 34bb70d44d50..9183e81037ca 100644 --- a/arch/arm/mach-s3c2416/Makefile +++ b/arch/arm/mach-s3c2416/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_CPU_S3C2416) += irq.o # Machine support +obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c new file mode 100644 index 000000000000..8c9aed69d415 --- /dev/null +++ b/arch/arm/mach-s3c2416/mach-smdk2416.c @@ -0,0 +1,144 @@ +/* linux/arch/arm/mach-s3c2416/mach-hanlin_v3c.c + * + * Copyright (c) 2009 Yauhen Kharuzhy , + * as part of OpenInkpot project + * Copyright (c) 2009 Promwad Innovation Company + * Yauhen Kharuzhy + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +static struct map_desc smdk2416_iodesc[] __initdata = { + /* ISA IO Space map (memory space selected by A24) */ + + { + .virtual = (u32)S3C24XX_VA_ISA_WORD, + .pfn = __phys_to_pfn(S3C2410_CS2), + .length = 0x10000, + .type = MT_DEVICE, + }, { + .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000, + .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)), + .length = SZ_4M, + .type = MT_DEVICE, + }, { + .virtual = (u32)S3C24XX_VA_ISA_BYTE, + .pfn = __phys_to_pfn(S3C2410_CS2), + .length = 0x10000, + .type = MT_DEVICE, + }, { + .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000, + .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)), + .length = SZ_4M, + .type = MT_DEVICE, + } +}; + +#define UCON (S3C2410_UCON_DEFAULT | \ + S3C2440_UCON_PCLK | \ + S3C2443_UCON_RXERR_IRQEN) + +#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) + +#define UFCON (S3C2410_UFCON_RXTRIG8 | \ + S3C2410_UFCON_FIFOMODE | \ + S3C2440_UFCON_TXTRIG16) + +static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + /* IR port */ + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON | 0x50, + .ufcon = UFCON, + } +}; + +static struct platform_device *smdk2416_devices[] __initdata = { + &s3c_device_wdt, + &s3c_device_i2c0, + &s3c_device_hsmmc0, +}; + +static void __init smdk2416_map_io(void) +{ + + s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc)); + s3c24xx_init_clocks(12000000); + s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs)); + +} + +static void __init smdk2416_machine_init(void) +{ + s3c_i2c0_set_platdata(NULL); + + platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices)); + smdk_machine_init(); +} + +MACHINE_START(SMDK2416, "SMDK2416") + /* Maintainer: Yauhen Kharuzhy */ + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + + .init_irq = s3c24xx_init_irq, + .map_io = smdk2416_map_io, + .init_machine = smdk2416_machine_init, + .timer = &s3c24xx_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From d11a7d7100123d178821f82ecc11ba2d9d6e97c8 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 28 Apr 2010 18:00:07 +0900 Subject: ARM: S3C24XX: Identify S3C2416 if S3C2412/S3C2413 built in Extend the ARMv5 ID code to deal with S3C2416 being built with S3C2412/S3C2413 enabled, as these have their ID registers in a different place. Signed-off-by: Ben Dooks --- arch/arm/plat-s3c24xx/cpu.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 494f4f3a9332..32db85651af0 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c @@ -181,10 +181,18 @@ static struct map_desc s3c_iodesc[] __initdata = { static unsigned long s3c24xx_read_idcode_v5(void) { +#if defined(CONFIG_CPU_S3C2416) + /* s3c2416 is v5, with S3C24XX_GSTATUS1 instead of S3C2412_GSTATUS1 */ + + u32 gs = __raw_readl(S3C24XX_GSTATUS1); + + /* test for s3c2416 or similar device */ + if ((gs >> 16) == 0x3245) + return gs; +#endif + #if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) return __raw_readl(S3C2412_GSTATUS1); -#elif defined(CONFIG_CPU_S3C2416) - return __raw_readl(S3C24XX_GSTATUS1); #else return 1UL; /* don't look like an 2400 */ #endif -- cgit v1.2.3-59-g8ed1b From af337f3e633a198034a99450416257ddf2307497 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 28 Apr 2010 18:03:57 +0900 Subject: ARM: S3C2443: Move parts of the clock code to common clock file To share code with some of the newer parts such as the S3C2416, move parts of arch/arm/mach-s3c2443/clock.c to a common file called arch/arm/plat-s3c24xx/s3c2443-clock.c. Update the build configuration to deal with this new file. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2443/Kconfig | 1 + arch/arm/mach-s3c2443/clock.c | 452 +------------------------ arch/arm/plat-s3c24xx/Kconfig | 6 + arch/arm/plat-s3c24xx/Makefile | 1 + arch/arm/plat-s3c24xx/include/plat/s3c2443.h | 19 ++ arch/arm/plat-s3c24xx/s3c2443-clock.c | 472 +++++++++++++++++++++++++++ 6 files changed, 505 insertions(+), 446 deletions(-) create mode 100644 arch/arm/plat-s3c24xx/s3c2443-clock.c (limited to 'arch') diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig index 698140af247c..4fef723126fa 100644 --- a/arch/arm/mach-s3c2443/Kconfig +++ b/arch/arm/mach-s3c2443/Kconfig @@ -8,6 +8,7 @@ config CPU_S3C2443 select S3C2443_DMA if S3C2410_DMA select CPU_LLSERIAL_S3C2440 select SAMSUNG_CLKSRC + select S3C2443_CLOCK help Support for the S3C2443 SoC from the S3C24XX line diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 76d8d66247c3..83b1aa63d778 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -21,6 +21,7 @@ */ #include + #include #include #include @@ -54,111 +55,13 @@ * set the correct muxing at initialisation */ -static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable) -{ - u32 ctrlbit = clk->ctrlbit; - u32 con = __raw_readl(reg); - - if (enable) - con |= ctrlbit; - else - con &= ~ctrlbit; - - __raw_writel(con, reg); - return 0; -} - -static int s3c2443_clkcon_enable_h(struct clk *clk, int enable) -{ - return s3c2443_gate(S3C2443_HCLKCON, clk, enable); -} - -static int s3c2443_clkcon_enable_p(struct clk *clk, int enable) -{ - return s3c2443_gate(S3C2443_PCLKCON, clk, enable); -} - -static int s3c2443_clkcon_enable_s(struct clk *clk, int enable) -{ - return s3c2443_gate(S3C2443_SCLKCON, clk, enable); -} - /* clock selections */ -/* mpllref is a direct descendant of clk_xtal by default, but it is not - * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as - * such directly equating the two source clocks is impossible. - */ -static struct clk clk_mpllref = { - .name = "mpllref", - .parent = &clk_xtal, - .id = -1, -}; - static struct clk clk_i2s_ext = { .name = "i2s-ext", .id = -1, }; -static struct clk *clk_epllref_sources[] = { - [0] = &clk_mpllref, - [1] = &clk_mpllref, - [2] = &clk_xtal, - [3] = &clk_ext, -}; - -static struct clksrc_clk clk_epllref = { - .clk = { - .name = "epllref", - .id = -1, - }, - .sources = &(struct clksrc_sources) { - .sources = clk_epllref_sources, - .nr_sources = ARRAY_SIZE(clk_epllref_sources), - }, - .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 }, -}; - -static unsigned long s3c2443_getrate_mdivclk(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2443_CLKDIV0); - - div &= S3C2443_CLKDIV0_EXTDIV_MASK; - div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */ - - return parent_rate / (div + 1); -} - -static struct clk clk_mdivclk = { - .name = "mdivclk", - .parent = &clk_mpllref, - .id = -1, - .ops = &(struct clk_ops) { - .get_rate = s3c2443_getrate_mdivclk, - }, -}; - -static struct clk *clk_msysclk_sources[] = { - [0] = &clk_mpllref, - [1] = &clk_mpll, - [2] = &clk_mdivclk, - [3] = &clk_mpllref, -}; - -static struct clksrc_clk clk_msysclk = { - .clk = { - .name = "msysclk", - .parent = &clk_xtal, - .id = -1, - }, - .sources = &(struct clksrc_sources) { - .sources = clk_msysclk_sources, - .nr_sources = ARRAY_SIZE(clk_msysclk_sources), - }, - .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 }, -}; - /* armdiv * * this clock is sourced from msysclk and can have a number of @@ -266,44 +169,6 @@ static struct clksrc_clk clk_arm = { .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 }, }; -/* esysclk - * - * this is sourced from either the EPLL or the EPLLref clock -*/ - -static struct clk *clk_sysclk_sources[] = { - [0] = &clk_epllref.clk, - [1] = &clk_epll, -}; - -static struct clksrc_clk clk_esysclk = { - .clk = { - .name = "esysclk", - .parent = &clk_epll, - .id = -1, - }, - .sources = &(struct clksrc_sources) { - .sources = clk_sysclk_sources, - .nr_sources = ARRAY_SIZE(clk_sysclk_sources), - }, - .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 }, -}; - -/* uartclk - * - * UART baud-rate clock sourced from esysclk via a divisor -*/ - -static struct clksrc_clk clk_uart = { - .clk = { - .name = "uartclk", - .id = -1, - .parent = &clk_esysclk.clk, - }, - .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 }, -}; - - /* hsspi * * high-speed spi clock, sourced from esysclk @@ -320,21 +185,6 @@ static struct clksrc_clk clk_hsspi = { .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 }, }; -/* usbhost - * - * usb host bus-clock, usually 48MHz to provide USB bus clock timing -*/ - -static struct clksrc_clk clk_usb_bus_host = { - .clk = { - .name = "usb-bus-host-parent", - .id = -1, - .parent = &clk_esysclk.clk, - .ctrlbit = S3C2443_SCLKCON_USBHOST, - .enable = s3c2443_clkcon_enable_s, - }, - .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 }, -}; /* clk_hsmcc_div * @@ -433,88 +283,15 @@ static struct clksrc_clk clk_i2s = { .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 }, }; -/* cam-if - * - * camera interface bus-clock, divided down from esysclk -*/ - -static struct clksrc_clk clk_cam = { - .clk = { - .name = "camif-upll", /* same as 2440 name */ - .id = -1, - .parent = &clk_esysclk.clk, - .ctrlbit = S3C2443_SCLKCON_CAMCLK, - .enable = s3c2443_clkcon_enable_s, - }, - .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 }, -}; - -/* display-if - * - * display interface clock, divided from esysclk -*/ - -static struct clksrc_clk clk_display = { - .clk = { - .name = "display-if", - .id = -1, - .parent = &clk_esysclk.clk, - .ctrlbit = S3C2443_SCLKCON_DISPCLK, - .enable = s3c2443_clkcon_enable_s, - }, - .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 }, -}; - -/* prediv - * - * this divides the msysclk down to pass to h/p/etc. - */ - -static unsigned long s3c2443_prediv_getrate(struct clk *clk) -{ - unsigned long rate = clk_get_rate(clk->parent); - unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); - - clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK; - clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT; - - return rate / (clkdiv0 + 1); -} - -static struct clk clk_prediv = { - .name = "prediv", - .id = -1, - .parent = &clk_msysclk.clk, - .ops = &(struct clk_ops) { - .get_rate = s3c2443_prediv_getrate, - }, -}; - /* standard clock definitions */ static struct clk init_clocks_off[] = { { - .name = "nand", - .id = -1, - .parent = &clk_h, - }, { .name = "sdi", .id = -1, .parent = &clk_p, .enable = s3c2443_clkcon_enable_p, .ctrlbit = S3C2443_PCLKCON_SDI, - }, { - .name = "adc", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_ADC, - }, { - .name = "i2c", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_IIC, }, { .name = "iis", .id = -1, @@ -537,179 +314,12 @@ static struct clk init_clocks_off[] = { }; static struct clk init_clocks[] = { - { - .name = "dma", - .id = 0, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA0, - }, { - .name = "dma", - .id = 1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA1, - }, { - .name = "dma", - .id = 2, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA2, - }, { - .name = "dma", - .id = 3, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA3, - }, { - .name = "dma", - .id = 4, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA4, - }, { - .name = "dma", - .id = 5, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_DMA5, - }, { - .name = "lcd", - .id = -1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_LCDC, - }, { - .name = "gpio", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_GPIO, - }, { - .name = "usb-host", - .id = -1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_USBH, - }, { - .name = "usb-device", - .id = -1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_USBD, - }, { - .name = "hsmmc", - .id = -1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_HSMMC, - }, { - .name = "cfc", - .id = -1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_CFC, - }, { - .name = "ssmc", - .id = -1, - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_SSMC, - }, { - .name = "timers", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_PWMT, - }, { - .name = "uart", - .id = 0, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_UART0, - }, { - .name = "uart", - .id = 1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_UART1, - }, { - .name = "uart", - .id = 2, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_UART2, - }, { - .name = "uart", - .id = 3, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_UART3, - }, { - .name = "rtc", - .id = -1, - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_RTC, - }, { - .name = "watchdog", - .id = -1, - .parent = &clk_p, - .ctrlbit = S3C2443_PCLKCON_WDT, - }, { - .name = "usb-bus-host", - .id = -1, - .parent = &clk_usb_bus_host.clk, - }, { - .name = "ac97", - .id = -1, - .parent = &clk_p, - .ctrlbit = S3C2443_PCLKCON_AC97, - } }; -/* clocks to add where we need to check their parentage */ - -static struct clksrc_clk __initdata *init_list[] = { - &clk_epllref, /* should be first */ - &clk_esysclk, - &clk_msysclk, - &clk_arm, - &clk_i2s_eplldiv, - &clk_i2s, - &clk_cam, - &clk_uart, - &clk_display, - &clk_hsmmc_div, - &clk_usb_bus_host, -}; - -static void __init s3c2443_clk_initparents(void) -{ - int ptr; - - for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++) - s3c_set_clksrc(init_list[ptr], true); -} - -static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) -{ - clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; - - return clkcon0 + 1; -} - /* clocks to add straight away */ static struct clksrc_clk *clksrcs[] __initdata = { - &clk_usb_bus_host, - &clk_epllref, - &clk_esysclk, - &clk_msysclk, &clk_arm, - &clk_uart, - &clk_display, - &clk_cam, &clk_i2s_eplldiv, &clk_i2s, &clk_hsspi, @@ -717,46 +327,13 @@ static struct clksrc_clk *clksrcs[] __initdata = { }; static struct clk *clks[] __initdata = { - &clk_ext, - &clk_epll, - &clk_usb_bus, - &clk_mpllref, &clk_hsmmc, &clk_armdiv, - &clk_prediv, }; void __init_or_cpufreq s3c2443_setup_clocks(void) { - unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON); - unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); - struct clk *xtal_clk; - unsigned long xtal; - unsigned long pll; - unsigned long fclk; - unsigned long hclk; - unsigned long pclk; - - xtal_clk = clk_get(NULL, "xtal"); - xtal = clk_get_rate(xtal_clk); - clk_put(xtal_clk); - - pll = s3c2443_get_mpll(mpllcon, xtal); - clk_msysclk.clk.rate = pll; - - fclk = pll / s3c2443_fclk_div(clkdiv0); - hclk = s3c2443_prediv_getrate(&clk_prediv); - hclk /= s3c2443_get_hdiv(clkdiv0); - pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); - - s3c24xx_setup_clocks(fclk, hclk, pclk); - - printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", - (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on", - print_mhz(pll), print_mhz(fclk), - print_mhz(hclk), print_mhz(pclk)); - - s3c24xx_setup_clocks(fclk, hclk, pclk); + s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div); } void __init s3c2443_init_clocks(int xtal) @@ -764,35 +341,18 @@ void __init s3c2443_init_clocks(int xtal) unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); int ptr; - /* s3c2443 parents h and p clocks from prediv */ - clk_h.parent = &clk_prediv; - clk_p.parent = &clk_prediv; + clk_epll.rate = s3c2443_get_epll(epllcon, xtal); + clk_epll.parent = &clk_epllref.clk; + + s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div); - s3c24xx_register_baseclocks(xtal); s3c2443_setup_clocks(); - s3c2443_clk_initparents(); s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_register_clksrc(clksrcs[ptr], 1); - clk_epll.rate = s3c2443_get_epll(epllcon, xtal); - clk_epll.parent = &clk_epllref.clk; - clk_usb_bus.parent = &clk_usb_bus_host.clk; - - /* ensure usb bus clock is within correct rate of 48MHz */ - - if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) { - printk(KERN_INFO "Warning: USB host bus not at 48MHz\n"); - clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000); - } - - printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n", - (epllcon & S3C2443_PLLCON_OFF) ? "off":"on", - print_mhz(clk_get_rate(&clk_epll)), - print_mhz(clk_get_rate(&clk_usb_bus))); - /* register clocks from clock array */ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index a830fad6f89e..3ce8f010b3c6 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig @@ -45,6 +45,12 @@ config S3C2410_CLOCK Clock code for the S3C2410, and similar processors which is currently includes the S3C2410, S3C2440, S3C2442. +config S3C2443_CLOCK + bool + help + Clock code for the S3C2443 and similar processors, which includes + the S3C2416 and S3C2450. + config S3C24XX_DCLK bool help diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index c2237c41141f..44aea8868f89 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += irq-pm.o obj-$(CONFIG_PM) += sleep.o obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o +obj-$(CONFIG_S3C2443_CLOCK) += s3c2443-clock.o obj-$(CONFIG_S3C2410_DMA) += dma.o obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h index 815b107ed890..a19715feb798 100644 --- a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h +++ b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h @@ -30,3 +30,22 @@ extern int s3c2443_baseclk_add(void); #define s3c2443_map_io NULL #define s3c2443_init NULL #endif + +/* common code used by s3c2443 and others. + * note, not to be used outside of arch/arm/mach-s3c* */ + +struct clk; /* some files don't need clk.h otherwise */ + +typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base); +typedef unsigned int (*fdiv_fn)(unsigned long clkcon0); + +extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv); +extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv); + +extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable); +extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable); +extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable); + +extern struct clksrc_clk clk_epllref; +extern struct clksrc_clk clk_esysclk; +extern struct clksrc_clk clk_msysclk; diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c new file mode 100644 index 000000000000..461f070eb62d --- /dev/null +++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c @@ -0,0 +1,472 @@ +/* linux/arch/arm/plat-s3c24xx/s3c2443-clock.c + * + * Copyright (c) 2007, 2010 Simtec Electronics + * Ben Dooks + * + * S3C2443 Clock control suport - common code + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + + +static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable) +{ + u32 ctrlbit = clk->ctrlbit; + u32 con = __raw_readl(reg); + + if (enable) + con |= ctrlbit; + else + con &= ~ctrlbit; + + __raw_writel(con, reg); + return 0; +} + +int s3c2443_clkcon_enable_h(struct clk *clk, int enable) +{ + return s3c2443_gate(S3C2443_HCLKCON, clk, enable); +} + +int s3c2443_clkcon_enable_p(struct clk *clk, int enable) +{ + return s3c2443_gate(S3C2443_PCLKCON, clk, enable); +} + +int s3c2443_clkcon_enable_s(struct clk *clk, int enable) +{ + return s3c2443_gate(S3C2443_SCLKCON, clk, enable); +} + +/* mpllref is a direct descendant of clk_xtal by default, but it is not + * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as + * such directly equating the two source clocks is impossible. + */ +struct clk clk_mpllref = { + .name = "mpllref", + .parent = &clk_xtal, + .id = -1, +}; + +static struct clk *clk_epllref_sources[] = { + [0] = &clk_mpllref, + [1] = &clk_mpllref, + [2] = &clk_xtal, + [3] = &clk_ext, +}; + +struct clksrc_clk clk_epllref = { + .clk = { + .name = "epllref", + .id = -1, + }, + .sources = &(struct clksrc_sources) { + .sources = clk_epllref_sources, + .nr_sources = ARRAY_SIZE(clk_epllref_sources), + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 }, +}; + +/* esysclk + * + * this is sourced from either the EPLL or the EPLLref clock +*/ + +static struct clk *clk_sysclk_sources[] = { + [0] = &clk_epllref.clk, + [1] = &clk_epll, +}; + +struct clksrc_clk clk_esysclk = { + .clk = { + .name = "esysclk", + .parent = &clk_epll, + .id = -1, + }, + .sources = &(struct clksrc_sources) { + .sources = clk_sysclk_sources, + .nr_sources = ARRAY_SIZE(clk_sysclk_sources), + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 }, +}; + +static unsigned long s3c2443_getrate_mdivclk(struct clk *clk) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long div = __raw_readl(S3C2443_CLKDIV0); + + div &= S3C2443_CLKDIV0_EXTDIV_MASK; + div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */ + + return parent_rate / (div + 1); +} + +static struct clk clk_mdivclk = { + .name = "mdivclk", + .parent = &clk_mpllref, + .id = -1, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_getrate_mdivclk, + }, +}; + +static struct clk *clk_msysclk_sources[] = { + [0] = &clk_mpllref, + [1] = &clk_mpll, + [2] = &clk_mdivclk, + [3] = &clk_mpllref, +}; + +struct clksrc_clk clk_msysclk = { + .clk = { + .name = "msysclk", + .parent = &clk_xtal, + .id = -1, + }, + .sources = &(struct clksrc_sources) { + .sources = clk_msysclk_sources, + .nr_sources = ARRAY_SIZE(clk_msysclk_sources), + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 }, +}; + +/* prediv + * + * this divides the msysclk down to pass to h/p/etc. + */ + +static unsigned long s3c2443_prediv_getrate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); + + clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK; + clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT; + + return rate / (clkdiv0 + 1); +} + +static struct clk clk_prediv = { + .name = "prediv", + .id = -1, + .parent = &clk_msysclk.clk, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_prediv_getrate, + }, +}; + +/* usbhost + * + * usb host bus-clock, usually 48MHz to provide USB bus clock timing +*/ + +static struct clksrc_clk clk_usb_bus_host = { + .clk = { + .name = "usb-bus-host-parent", + .id = -1, + .parent = &clk_esysclk.clk, + .ctrlbit = S3C2443_SCLKCON_USBHOST, + .enable = s3c2443_clkcon_enable_s, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 }, +}; + +/* common clksrc clocks */ + +static struct clksrc_clk clksrc_clks[] = { + { + /* ART baud-rate clock sourced from esysclk via a divisor */ + .clk = { + .name = "uartclk", + .id = -1, + .parent = &clk_esysclk.clk, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 }, + }, { + /* camera interface bus-clock, divided down from esysclk */ + .clk = { + .name = "camif-upll", /* same as 2440 name */ + .id = -1, + .parent = &clk_esysclk.clk, + .ctrlbit = S3C2443_SCLKCON_CAMCLK, + .enable = s3c2443_clkcon_enable_s, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 }, + }, { + .clk = { + .name = "display-if", + .id = -1, + .parent = &clk_esysclk.clk, + .ctrlbit = S3C2443_SCLKCON_DISPCLK, + .enable = s3c2443_clkcon_enable_s, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 }, + }, +}; + + +static struct clk init_clocks_off[] = { + { + .name = "adc", + .id = -1, + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_ADC, + }, { + .name = "i2c", + .id = -1, + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_IIC, + } +}; + +static struct clk init_clocks[] = { + { + .name = "dma", + .id = 0, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA0, + }, { + .name = "dma", + .id = 1, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA1, + }, { + .name = "dma", + .id = 2, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA2, + }, { + .name = "dma", + .id = 3, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA3, + }, { + .name = "dma", + .id = 4, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA4, + }, { + .name = "dma", + .id = 5, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA5, + }, { + .name = "hsmmc", + .id = 0, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_HSMMC, + }, { + .name = "gpio", + .id = -1, + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_GPIO, + }, { + .name = "usb-host", + .id = -1, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_USBH, + }, { + .name = "usb-device", + .id = -1, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_USBD, + }, { + .name = "lcd", + .id = -1, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_LCDC, + + }, { + .name = "timers", + .id = -1, + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_PWMT, + }, { + .name = "cfc", + .id = -1, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_CFC, + }, { + .name = "ssmc", + .id = -1, + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_SSMC, + }, { + .name = "uart", + .id = 0, + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_UART0, + }, { + .name = "uart", + .id = 1, + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_UART1, + }, { + .name = "uart", + .id = 2, + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_UART2, + }, { + .name = "uart", + .id = 3, + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_UART3, + }, { + .name = "rtc", + .id = -1, + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_RTC, + }, { + .name = "watchdog", + .id = -1, + .parent = &clk_p, + .ctrlbit = S3C2443_PCLKCON_WDT, + }, { + .name = "ac97", + .id = -1, + .parent = &clk_p, + .ctrlbit = S3C2443_PCLKCON_AC97, + }, { + .name = "nand", + .id = -1, + .parent = &clk_h, + }, { + .name = "usb-bus-host", + .id = -1, + .parent = &clk_usb_bus_host.clk, + } +}; + +static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) +{ + clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; + + return clkcon0 + 1; +} + +/* EPLLCON compatible enough to get on/off information */ + +void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll, + fdiv_fn get_fdiv) +{ + unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); + unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON); + unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); + struct clk *xtal_clk; + unsigned long xtal; + unsigned long pll; + unsigned long fclk; + unsigned long hclk; + unsigned long pclk; + int ptr; + + xtal_clk = clk_get(NULL, "xtal"); + xtal = clk_get_rate(xtal_clk); + clk_put(xtal_clk); + + pll = get_mpll(mpllcon, xtal); + clk_msysclk.clk.rate = pll; + + fclk = pll / get_fdiv(clkdiv0); + hclk = s3c2443_prediv_getrate(&clk_prediv); + hclk /= s3c2443_get_hdiv(clkdiv0); + pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); + + s3c24xx_setup_clocks(fclk, hclk, pclk); + + printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", + (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on", + print_mhz(pll), print_mhz(fclk), + print_mhz(hclk), print_mhz(pclk)); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++) + s3c_set_clksrc(&clksrc_clks[ptr], true); + + /* ensure usb bus clock is within correct rate of 48MHz */ + + if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) { + printk(KERN_INFO "Warning: USB host bus not at 48MHz\n"); + clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000); + } + + printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n", + (epllcon & S3C2443_PLLCON_OFF) ? "off":"on", + print_mhz(clk_get_rate(&clk_epll)), + print_mhz(clk_get_rate(&clk_usb_bus))); +} + +static struct clk *clks[] __initdata = { + &clk_prediv, + &clk_mpllref, + &clk_mdivclk, + &clk_ext, + &clk_epll, + &clk_usb_bus, +}; + +static struct clksrc_clk *clksrcs[] __initdata = { + &clk_usb_bus_host, + &clk_epllref, + &clk_esysclk, + &clk_msysclk, +}; + +void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, + fdiv_fn get_fdiv) +{ + int ptr; + + /* s3c2443 parents h and p clocks from prediv */ + clk_h.parent = &clk_prediv; + clk_p.parent = &clk_prediv; + + clk_usb_bus.parent = &clk_usb_bus_host.clk; + clk_epll.parent = &clk_epllref.clk; + + s3c24xx_register_baseclocks(xtal); + s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_register_clksrc(clksrcs[ptr], 1); + + s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks)); + s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + + /* See s3c2443/etc notes on disabling clocks at init time */ + s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + + s3c2443_common_setup_clocks(get_mpll, get_fdiv); +} -- cgit v1.2.3-59-g8ed1b From 8d6f8658305db969981f64a22296b487ef2f1148 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 30 Apr 2010 11:12:58 +0900 Subject: ARM: S3C2416: Add basic clock support Add basic clock support for the PLLs, HSMMC channels and PWM clocks. This is enough to get a basic system up and running. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/regs-clock.h | 2 + arch/arm/mach-s3c2416/Kconfig | 2 + arch/arm/mach-s3c2416/Makefile | 2 +- arch/arm/mach-s3c2416/clock.c | 135 ++++++++++++++++++++++++ arch/arm/plat-s3c24xx/include/plat/pll.h | 25 +++++ 5 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-s3c2416/clock.c (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/regs-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-clock.h index 9a0d169be137..3415b60082d7 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-clock.h @@ -161,4 +161,6 @@ #endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */ +#define S3C2416_CLKDIV2 S3C2410_CLKREG(0x28) + #endif /* __ASM_ARM_REGS_CLOCK */ diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index 528f27348b68..677f963ee49e 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig @@ -10,6 +10,8 @@ config CPU_S3C2416 select CPU_ARM926T select S3C2416_DMA if S3C2410_DMA select CPU_LLSERIAL_S3C2440 + select SAMSUNG_CLKSRC + select S3C2443_CLOCK help Support for the S3C2416 SoC from the S3C24XX line diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile index 9183e81037ca..6c12c7bf40ad 100644 --- a/arch/arm/mach-s3c2416/Makefile +++ b/arch/arm/mach-s3c2416/Makefile @@ -9,7 +9,7 @@ obj-m := obj-n := obj- := -obj-$(CONFIG_CPU_S3C2416) += s3c2416.o +obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o obj-$(CONFIG_CPU_S3C2416) += irq.o #obj-$(CONFIG_S3C2416_DMA) += dma.o diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c new file mode 100644 index 000000000000..7ccf5a2a2bfc --- /dev/null +++ b/arch/arm/mach-s3c2416/clock.c @@ -0,0 +1,135 @@ +/* linux/arch/arm/mach-s3c2416/clock.c + * + * Copyright (c) 2010 Simtec Electronics + * Copyright (c) 2010 Ben Dooks + * + * S3C2416 Clock control support + * + * 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. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +static unsigned int armdiv[8] = { + [0] = 1, + [1] = 2, + [2] = 3, + [3] = 4, + [5] = 6, + [7] = 8, +}; + +/* ID to hardware numbering, 0 is HSMMC1, 1 is HSMMC0 */ +static struct clksrc_clk hsmmc_div[] = { + [0] = { + .clk = { + .name = "hsmmc-div", + .id = 1, + .parent = &clk_esysclk.clk, + }, + .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 }, + }, + [1] = { + .clk = { + .name = "hsmmc-div", + .id = 0, + .parent = &clk_esysclk.clk, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 }, + }, +}; + +static struct clksrc_clk hsmmc_mux[] = { + [0] = { + .clk = { + .id = 1, + .name = "hsmmc-if", + .ctrlbit = (1 << 6), + .enable = s3c2443_clkcon_enable_s, + }, + .sources = &(struct clksrc_sources) { + .nr_sources = 2, + .sources = (struct clk *[]) { + [0] = &hsmmc_div[0].clk, + [1] = NULL, /* to fix */ + }, + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 }, + }, + [1] = { + .clk = { + .id = 0, + .name = "hsmmc-if", + .ctrlbit = (1 << 12), + .enable = s3c2443_clkcon_enable_s, + }, + .sources = &(struct clksrc_sources) { + .nr_sources = 2, + .sources = (struct clk *[]) { + [0] = &hsmmc_div[1].clk, + [1] = NULL, /* to fix */ + }, + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 }, + }, +}; + + +static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0) +{ + clkcon0 &= 7 << S3C2443_CLKDIV0_ARMDIV_SHIFT; + + return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; +} + +void __init_or_cpufreq s3c2416_setup_clocks(void) +{ + s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div); +} + + +static struct clksrc_clk *clksrcs[] __initdata = { + &hsmmc_div[0], + &hsmmc_div[1], + &hsmmc_mux[0], + &hsmmc_mux[1], +}; + +void __init s3c2416_init_clocks(int xtal) +{ + u32 epllcon = __raw_readl(S3C2443_EPLLCON); + u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4); + int ptr; + + /* s3c2416 EPLL compatible with s3c64xx */ + clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1); + + clk_epll.parent = &clk_epllref.clk; + + s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_register_clksrc(clksrcs[ptr], 1); + + s3c_pwmclk_init(); + +} diff --git a/arch/arm/plat-s3c24xx/include/plat/pll.h b/arch/arm/plat-s3c24xx/include/plat/pll.h index 7ea8bffa7a9c..005729a1077a 100644 --- a/arch/arm/plat-s3c24xx/include/plat/pll.h +++ b/arch/arm/plat-s3c24xx/include/plat/pll.h @@ -35,3 +35,28 @@ s3c24xx_get_pll(unsigned int pllval, unsigned int baseclk) return (unsigned int)fvco; } + +#define S3C2416_PLL_M_SHIFT (14) +#define S3C2416_PLL_P_SHIFT (5) +#define S3C2416_PLL_S_MASK (7) +#define S3C2416_PLL_M_MASK ((1 << 10) - 1) +#define S3C2416_PLL_P_MASK (63) + +static inline unsigned int +s3c2416_get_pll(unsigned int pllval, unsigned int baseclk) +{ + unsigned int m, p, s; + uint64_t fvco; + + m = pllval >> S3C2416_PLL_M_SHIFT; + p = pllval >> S3C2416_PLL_P_SHIFT; + + s = pllval & S3C2416_PLL_S_MASK; + m &= S3C2416_PLL_M_MASK; + p &= S3C2416_PLL_P_MASK; + + fvco = (uint64_t)baseclk * m; + do_div(fvco, (p << s)); + + return (unsigned int)fvco; +} -- cgit v1.2.3-59-g8ed1b From c140c98ac161ad270a768126431e36a22f86f6b3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 29 Apr 2010 18:59:43 +0900 Subject: ARM: S3C2416: Add support for second HSMMC channel Add support for the second HSMMC channel on the S3C2416. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/irqs.h | 3 +++ arch/arm/mach-s3c2410/include/mach/map.h | 5 +++-- arch/arm/mach-s3c2416/Kconfig | 1 + arch/arm/mach-s3c2416/mach-smdk2416.c | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h index c1b8ec07bf45..877c15e1b154 100644 --- a/arch/arm/mach-s3c2410/include/mach/irqs.h +++ b/arch/arm/mach-s3c2410/include/mach/irqs.h @@ -150,7 +150,10 @@ #define IRQ_S3C2443_HSMMC S3C2410_IRQ(20) /* IRQ_SDI */ #define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */ +#define IRQ_S3C2416_HSMMC0 S3C2410_IRQ(21) /* S3C2416/S3C2450 */ + #define IRQ_HSMMC0 IRQ_S3C2443_HSMMC +#define IRQ_HSMMC1 IRQ_S3C2416_HSMMC0 #define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14) #define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15) diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h index b049e61460b6..f07d68066d7e 100644 --- a/arch/arm/mach-s3c2410/include/mach/map.h +++ b/arch/arm/mach-s3c2410/include/mach/map.h @@ -63,9 +63,9 @@ #define S3C2440_PA_AC97 (0x5B000000) #define S3C2440_SZ_AC97 SZ_1M -/* S3C2443 High-speed SD/MMC */ +/* S3C2443/S3C2416 High-speed SD/MMC */ #define S3C2443_PA_HSMMC (0x4A800000) -#define S3C2443_SZ_HSMMC (256) +#define S3C2416_PA_HSMMC0 (0x4AC00000) /* S3C2412 memory and IO controls */ #define S3C2412_PA_SSMC (0x4F000000) @@ -110,6 +110,7 @@ #define S3C_PA_UART S3C24XX_PA_UART #define S3C_PA_USBHOST S3C2410_PA_USBHOST #define S3C_PA_HSMMC0 S3C2443_PA_HSMMC +#define S3C_PA_HSMMC1 S3C2416_PA_HSMMC0 #define S3C_PA_NAND S3C24XX_PA_NAND #endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index 677f963ee49e..a1308d45b94f 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig @@ -27,6 +27,7 @@ config MACH_SMDK2416 bool "SMDK2416" select CPU_S3C2416 select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 help Say Y here if you are using an SMDK2416 diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c index 8c9aed69d415..a51973c7334c 100644 --- a/arch/arm/mach-s3c2416/mach-smdk2416.c +++ b/arch/arm/mach-s3c2416/mach-smdk2416.c @@ -112,6 +112,7 @@ static struct platform_device *smdk2416_devices[] __initdata = { &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_hsmmc0, + &s3c_device_hsmmc1, }; static void __init smdk2416_map_io(void) -- cgit v1.2.3-59-g8ed1b From a6e1ec7f69950864ff8d992da6d929b1444f7cb3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 30 Apr 2010 10:59:42 +0900 Subject: ARM: S3C2416: Add support for OHCI on SMDK2416 Add device definition and ensure that the host port is powered up at start time. Full power control can be added at a later date. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2416/mach-smdk2416.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c index a51973c7334c..99d24c44f30f 100644 --- a/arch/arm/mach-s3c2416/mach-smdk2416.c +++ b/arch/arm/mach-s3c2416/mach-smdk2416.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -110,6 +111,7 @@ static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = { static struct platform_device *smdk2416_devices[] __initdata = { &s3c_device_wdt, + &s3c_device_ohci, &s3c_device_i2c0, &s3c_device_hsmmc0, &s3c_device_hsmmc1, @@ -128,6 +130,9 @@ static void __init smdk2416_machine_init(void) { s3c_i2c0_set_platdata(NULL); + gpio_request(S3C2410_GPB(4), "USBHost Power"); + gpio_direction_output(S3C2410_GPB(4), 1); + platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices)); smdk_machine_init(); } -- cgit v1.2.3-59-g8ed1b From e12ef7f02ed56af4f84a5743fa268901c52729bf Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 3 May 2010 16:44:35 +0900 Subject: ARM: S3C2416: Use s3c2440 style i2c controller The s3c2416 i2c controllers are compatible with the s3c2440 style i2c block, so change the device name appropriately. Signed-off-by: Ben Dooks y --- arch/arm/mach-s3c2416/s3c2416.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c index 6165dc7010fe..ad5a63a40d6e 100644 --- a/arch/arm/mach-s3c2416/s3c2416.c +++ b/arch/arm/mach-s3c2416/s3c2416.c @@ -50,6 +50,8 @@ #include #include +#include + static struct map_desc s3c2416_iodesc[] __initdata = { IODESC_ENT(WATCHDOG), IODESC_ENT(CLKPWR), @@ -80,6 +82,10 @@ int __init s3c2416_init(void) s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT; s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT; + /* the i2c devices are directly compatible with s3c2440 */ + s3c_i2c0_setname("s3c2440-i2c"); + s3c_i2c1_setname("s3c2440-i2c"); + return sysdev_register(&s3c2416_sysdev); } -- cgit v1.2.3-59-g8ed1b From eb90de4a2d2880f0037d2b2ba85a3e857a898b40 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 30 Apr 2010 19:48:02 +0900 Subject: ARM: S3C2413: Update GPIO pull-up support Ensure the right get/set pull code is selected and assigned to the GPIO core. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2416/Kconfig | 1 + arch/arm/mach-s3c2416/s3c2416.c | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index a1308d45b94f..6d077b24d190 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig @@ -10,6 +10,7 @@ config CPU_S3C2416 select CPU_ARM926T select S3C2416_DMA if S3C2410_DMA select CPU_LLSERIAL_S3C2440 + select S3C_GPIO_PULL_UPDOWN select SAMSUNG_CLKSRC select S3C2443_CLOCK help diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c index ad5a63a40d6e..3bff05745d0b 100644 --- a/arch/arm/mach-s3c2416/s3c2416.c +++ b/arch/arm/mach-s3c2416/s3c2416.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,9 @@ #include #include +#include +#include +#include #include #include #include @@ -104,6 +108,9 @@ void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no) void __init s3c2416_map_io(void) { + s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown; + s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown; + iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc)); } -- cgit v1.2.3-59-g8ed1b From 63b1f51b2405573d47bf5b9ab6e7cd5c697d3dcc Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 30 Apr 2010 16:32:26 +0900 Subject: ARM: SAMSUNG: Update S3C2416 entry with S3C2450 These devices are so similar that they share the same SoC ID code, so note this. Signed-off-by: Ben Dooks --- arch/arm/Kconfig | 6 +++++- arch/arm/mach-s3c2416/Kconfig | 3 +++ arch/arm/plat-s3c24xx/cpu.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6785c33908bf..3f8718fc4050 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -647,7 +647,7 @@ config ARCH_SA1100 Support for StrongARM 11x0 based boards. config ARCH_S3C2410 - bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443" + bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450" select GENERIC_GPIO select ARCH_HAS_CPUFREQ select HAVE_CLK @@ -656,6 +656,10 @@ config ARCH_S3C2410 BAST (), the IPAQ 1940 or the Samsung SMDK2410 development board (and derivatives). + Note, the S3C2416 and the S3C2450 are so close that they even share + the same SoC ID code. This means that there is no seperate machine + directory (no arch/arm/mach-s3c2450) as the S3C2416 was first. + config ARCH_S3C64XX bool "Samsung S3C64XX" select PLAT_SAMSUNG diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index 6d077b24d190..29103a6047de 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig @@ -4,6 +4,9 @@ # # Licensed under GPLv2 +# note, this also supports the S3C2450 which is so similar it has the same +# ID code as the S3C2416. + config CPU_S3C2416 bool depends on ARCH_S3C2410 diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 32db85651af0..76d0858c3cbb 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c @@ -58,7 +58,7 @@ static const char name_s3c2400[] = "S3C2400"; static const char name_s3c2410[] = "S3C2410"; static const char name_s3c2412[] = "S3C2412"; -static const char name_s3c2416[] = "S3C2416"; +static const char name_s3c2416[] = "S3C2416/S3C2450"; static const char name_s3c2440[] = "S3C2440"; static const char name_s3c2442[] = "S3C2442"; static const char name_s3c2442b[] = "S3C2442B"; -- cgit v1.2.3-59-g8ed1b From 3998d095354d2a3062bdaa821ef07a1e1c82873c Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 9 May 2010 22:46:54 -0700 Subject: x86, hypervisor: add missing EXPORT_SYMBOL() needs to be included; fixes modular builds of the VMware balloon driver, and any future modular drivers which depends on the hypervisor. Reported-by: Ingo Molnar Signed-off-by: H. Peter Anvin Cc: Greg KH Cc: Hank Janssen Cc: Alok Kataria Cc: Ky Srinivasan Cc: Dmitry Torokhov LKML-Reference: <4BE49778.6060800@zytor.com> --- arch/x86/kernel/cpu/hypervisor.c | 1 + arch/x86/kernel/cpu/mshyperv.c | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index 4afb5a2130ed..dd531cc56a8f 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c @@ -21,6 +21,7 @@ * */ +#include #include #include diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 0f1371724c86..16f41bbe46b6 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 19d8f84f86af867abee174be8bf1e4941a59143d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 10 May 2010 15:39:05 +0900 Subject: sh: enable LMB region setup via machvec. This plugs in a memory init callback in the machvec to permit boards to wire up various bits of memory directly in to LMB. A generic machvec implementation is provided that simply wraps around the normal Kconfig-derived memory start/size. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io_generic.h | 1 + arch/sh/include/asm/machvec.h | 2 ++ arch/sh/include/asm/mmzone.h | 1 - arch/sh/kernel/machvec.c | 1 + arch/sh/kernel/setup.c | 26 +++++++++++++------------- arch/sh/mm/init.c | 8 +++++++- 6 files changed, 24 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/io_generic.h b/arch/sh/include/asm/io_generic.h index 1e5d375f55dc..491df93cbf8e 100644 --- a/arch/sh/include/asm/io_generic.h +++ b/arch/sh/include/asm/io_generic.h @@ -38,5 +38,6 @@ void IO_CONCAT(__IO_PREFIX,iounmap)(void *addr); void __iomem *IO_CONCAT(__IO_PREFIX,ioport_map)(unsigned long addr, unsigned int size); void IO_CONCAT(__IO_PREFIX,ioport_unmap)(void __iomem *addr); +void IO_CONCAT(__IO_PREFIX,mem_init)(void); #undef __IO_PREFIX diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h index 9c30955630ff..bc0218cb72e1 100644 --- a/arch/sh/include/asm/machvec.h +++ b/arch/sh/include/asm/machvec.h @@ -49,6 +49,8 @@ struct sh_machine_vector { int (*mv_clk_init)(void); int (*mv_mode_pins)(void); + + void (*mv_mem_init)(void); }; extern struct sh_machine_vector sh_mv; diff --git a/arch/sh/include/asm/mmzone.h b/arch/sh/include/asm/mmzone.h index 7f5363b29ba0..94f04b2f4fb1 100644 --- a/arch/sh/include/asm/mmzone.h +++ b/arch/sh/include/asm/mmzone.h @@ -42,7 +42,6 @@ setup_bootmem_node(int nid, unsigned long start, unsigned long end) void __init plat_mem_setup(void); /* arch/sh/kernel/setup.c */ -void __init setup_bootmem_allocator(unsigned long start_pfn); void __init __add_active_range(unsigned int nid, unsigned long start_pfn, unsigned long end_pfn); diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c index 1652340ba3f2..85cfaf916fdc 100644 --- a/arch/sh/kernel/machvec.c +++ b/arch/sh/kernel/machvec.c @@ -131,6 +131,7 @@ void __init sh_mv_setup(void) mv_set(ioport_unmap); mv_set(irq_demux); mv_set(mode_pins); + mv_set(mem_init); if (!sh_mv.mv_nr_irqs) sh_mv.mv_nr_irqs = NR_IRQS; diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index e3f0da7b865d..2c9ab2842765 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -4,7 +4,7 @@ * This file handles the architecture-dependent parts of initialization * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2002 - 2010 Paul Mundt */ #include #include @@ -41,6 +41,7 @@ #include #include #include +#include /* * Initialize loops_per_jiffy as 10000000 (1000MIPS). @@ -247,7 +248,7 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn, add_active_range(nid, start_pfn, end_pfn); } -void __init setup_bootmem_allocator(unsigned long free_pfn) +void __init do_init_bootmem(void) { unsigned long bootmap_size; unsigned long bootmap_pages, bootmem_paddr; @@ -298,12 +299,9 @@ void __init setup_bootmem_allocator(unsigned long free_pfn) sparse_memory_present_with_active_regions(0); } -#ifndef CONFIG_NEED_MULTIPLE_NODES static void __init setup_memory(void) { unsigned long start_pfn; - u64 base = min_low_pfn << PAGE_SHIFT; - u64 size = (max_low_pfn << PAGE_SHIFT) - base; /* * Partially used pages are not usable - thus @@ -311,8 +309,6 @@ static void __init setup_memory(void) */ start_pfn = PFN_UP(__pa(_end)); - lmb_add(base, size); - /* * Reserve the kernel text and * Reserve the bootmem bitmap. We do this in two steps (first step @@ -333,11 +329,9 @@ static void __init setup_memory(void) lmb_analyze(); lmb_dump_all(); - setup_bootmem_allocator(start_pfn); + do_init_bootmem(); + plat_mem_setup(); } -#else -extern void __init setup_memory(void); -#endif /* * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by @@ -358,7 +352,11 @@ static int __init parse_elfcorehdr(char *arg) early_param("elfcorehdr", parse_elfcorehdr); #endif -void __init __attribute__ ((weak)) plat_early_device_setup(void) +void __init __weak plat_early_device_setup(void) +{ +} + +void __init __weak plat_mem_setup(void) { } @@ -426,7 +424,10 @@ void __init setup_arch(char **cmdline_p) /* Let earlyprintk output early console messages */ early_platform_driver_probe("earlyprintk", 1, 1); + lmb_init(); + sh_mv_setup(); + sh_mv.mv_mem_init(); /* * Find the highest page frame number we have available @@ -442,7 +443,6 @@ void __init setup_arch(char **cmdline_p) nodes_clear(node_online_map); pmb_init(); - lmb_init(); setup_memory(); sparse_init(); diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index c505de61a5ca..9c5400b02f43 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -2,7 +2,7 @@ * linux/arch/sh/mm/init.c * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2002 - 2010 Paul Mundt * * Based on linux/arch/i386/mm/init.c: * Copyright (C) 1995 Linus Torvalds @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,11 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD]; +void __init generic_mem_init(void) +{ + lmb_add(__MEMORY_START, __MEMORY_SIZE); +} + #ifdef CONFIG_MMU static pte_t *__get_pte_phys(unsigned long addr) { -- cgit v1.2.3-59-g8ed1b From a8cd4561ea176f51e9f4707873ca4eff8fd5ee70 Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Mon, 10 May 2010 14:51:19 +0530 Subject: fix "seperate" typos in comments s/seperate/separate Signed-off-by: Anand Gadiyar Signed-off-by: Jiri Kosina --- Documentation/filesystems/logfs.txt | 8 ++++---- arch/arm/mach-s3c2443/clock.c | 2 +- arch/arm/plat-samsung/include/plat/gpio-core.h | 2 +- drivers/usb/host/ehci-omap.c | 2 +- fs/logfs/dir.c | 2 +- fs/logfs/logfs.h | 2 +- fs/logfs/logfs_abi.h | 10 +++++----- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/Documentation/filesystems/logfs.txt b/Documentation/filesystems/logfs.txt index e64c94ba401a..bca42c22a143 100644 --- a/Documentation/filesystems/logfs.txt +++ b/Documentation/filesystems/logfs.txt @@ -59,7 +59,7 @@ Levels ------ Garbage collection (GC) may fail if all data is written -indiscriminately. One requirement of GC is that data is seperated +indiscriminately. One requirement of GC is that data is separated roughly according to the distance between the tree root and the data. Effectively that means all file data is on level 0, indirect blocks are on levels 1, 2, 3 4 or 5 for 1x, 2x, 3x, 4x or 5x indirect blocks, @@ -67,7 +67,7 @@ respectively. Inode file data is on level 6 for the inodes and 7-11 for indirect blocks. Each segment contains objects of a single level only. As a result, -each level requires its own seperate segment to be open for writing. +each level requires its own separate segment to be open for writing. Inode File ---------- @@ -106,9 +106,9 @@ Vim --- By cleverly predicting the life time of data, it is possible to -seperate long-living data from short-living data and thereby reduce +separate long-living data from short-living data and thereby reduce the GC overhead later. Each type of distinc life expectency (vim) can -have a seperate segment open for writing. Each (level, vim) tupel can +have a separate segment open for writing. Each (level, vim) tupel can be open just once. If an open segment with unknown vim is encountered at mount time, it is closed and ignored henceforth. diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 62cd4eaee01b..8a55e78f7090 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -391,7 +391,7 @@ static struct clk clk_hsmmc = { /* i2s_eplldiv * - * This clock is the output from the I2S divisor of ESYSCLK, and is seperate + * This clock is the output from the I2S divisor of ESYSCLK, and is separate * from the mux that comes after it (cannot merge into one single clock) */ diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h index 49ff406a7066..16643e3029fc 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-core.h +++ b/arch/arm/plat-samsung/include/plat/gpio-core.h @@ -97,7 +97,7 @@ extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip); * others = Special functions (dependant on bank) * * Note, since the code to deal with the case where there are two control - * registers instead of one, we do not have a seperate set of function + * registers instead of one, we do not have a separate set of function * (samsung_gpiolib_add_4bit2_chips)for each case. */ extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip, diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index a67a0030dd57..bed6de342ecc 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -181,7 +181,7 @@ struct ehci_hcd_omap { void __iomem *ehci_base; /* Regulators for USB PHYs. - * Each PHY can have a seperate regulator. + * Each PHY can have a separate regulator. */ struct regulator *regulator[OMAP3_HS_USB_PORTS]; }; diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 2396a85c0f55..72d1893ddd36 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c @@ -12,7 +12,7 @@ * Atomic dir operations * * Directory operations are by default not atomic. Dentries and Inodes are - * created/removed/altered in seperate operations. Therefore we need to do + * created/removed/altered in separate operations. Therefore we need to do * a small amount of journaling. * * Create, link, mkdir, mknod and symlink all share the same function to do diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index 0a3df1a0c936..9028d7f83bbd 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h @@ -704,7 +704,7 @@ static inline gc_level_t expand_level(u64 ino, level_t __level) u8 level = (__force u8)__level; if (ino == LOGFS_INO_MASTER) { - /* ifile has seperate areas */ + /* ifile has separate areas */ level += LOGFS_MAX_LEVELS; } return (__force gc_level_t)level; diff --git a/fs/logfs/logfs_abi.h b/fs/logfs/logfs_abi.h index f674725663fe..ae960519c54a 100644 --- a/fs/logfs/logfs_abi.h +++ b/fs/logfs/logfs_abi.h @@ -50,9 +50,9 @@ static inline void check_##type(void) \ * 12 - gc recycled blocks, long-lived data * 13 - replacement blocks, short-lived data * - * Levels 1-11 are necessary for robust gc operations and help seperate + * Levels 1-11 are necessary for robust gc operations and help separate * short-lived metadata from longer-lived file data. In the future, - * file data should get seperated into several segments based on simple + * file data should get separated into several segments based on simple * heuristics. Old data recycled during gc operation is expected to be * long-lived. New data is of uncertain life expectancy. New data * used to replace older blocks in existing files is expected to be @@ -117,7 +117,7 @@ static inline void check_##type(void) \ #define pure_ofs(ofs) (ofs & ~LOGFS_FULLY_POPULATED) /* - * LogFS needs to seperate data into levels. Each level is defined as the + * LogFS needs to separate data into levels. Each level is defined as the * maximal possible distance from the master inode (inode of the inode file). * Data blocks reside on level 0, 1x indirect block on level 1, etc. * Inodes reside on level 6, indirect blocks for the inode file on levels 7-11. @@ -204,7 +204,7 @@ SIZE_CHECK(logfs_segment_header, LOGFS_SEGMENT_HEADERSIZE); * @ds_crc: crc32 of structure starting with the next field * @ds_ifile_levels: maximum number of levels for ifile * @ds_iblock_levels: maximum number of levels for regular files - * @ds_data_levels: number of seperate levels for data + * @ds_data_levels: number of separate levels for data * @pad0: reserved, must be 0 * @ds_feature_incompat: incompatible filesystem features * @ds_feature_ro_compat: read-only compatible filesystem features @@ -456,7 +456,7 @@ enum logfs_vim { * @vim: life expectancy of data * * "Areas" are segments currently being used for writing. There is at least - * one area per GC level. Several may be used to seperate long-living from + * one area per GC level. Several may be used to separate long-living from * short-living data. If an area with unknown vim is encountered, it can * simply be closed. * The write buffer immediately follow this header. -- cgit v1.2.3-59-g8ed1b From 5e2ff328c0668794ff408a4632f5b8a62827571f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 10 May 2010 20:17:25 +0900 Subject: sh: rework memory limits to work with LMB. This reworks the memory limit handling to tie in through the available LMB infrastructure. This requires a bit of reordering as we need to have all of the LMB reservations taken care of prior to establishing the limits. While we're at it, the crash kernel reservation semantics are reworked so that we allocate from the bottom up and reduce the risk of having to disable the memory limit due to a clash with the crash kernel reservation. Signed-off-by: Paul Mundt --- arch/sh/include/asm/page.h | 2 +- arch/sh/kernel/machine_kexec.c | 20 ++++++++++---- arch/sh/kernel/setup.c | 63 +++++++++++++++++------------------------- 3 files changed, 40 insertions(+), 45 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 0152c040f6c3..fb703d120d09 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -49,7 +49,7 @@ extern unsigned long shm_align_mask; extern unsigned long max_low_pfn, min_low_pfn; -extern unsigned long memory_start, memory_end; +extern unsigned long memory_start, memory_end, memory_limit; static inline unsigned long pages_do_alias(unsigned long addr1, unsigned long addr2) diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index f0f049caa6e2..7f68fc0e89e8 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -169,7 +169,8 @@ void __init reserve_crashkernel(void) crash_size = PAGE_ALIGN(crashk_res.end - crashk_res.start + 1); if (!crashk_res.start) { - crashk_res.start = lmb_alloc(crash_size, PAGE_SIZE); + unsigned long max = lmb_end_of_DRAM() - memory_limit; + crashk_res.start = __lmb_alloc_base(crash_size, PAGE_SIZE, max); if (!crashk_res.start) { pr_err("crashkernel allocation failed\n"); goto disable; @@ -183,15 +184,22 @@ void __init reserve_crashkernel(void) } } - pr_info("Reserving %ldMB of memory at %ldMB " + crashk_res.end = crashk_res.start + crash_size - 1; + + /* + * Crash kernel trumps memory limit + */ + if ((lmb_end_of_DRAM() - memory_limit) <= crashk_res.end) { + memory_limit = 0; + pr_info("Disabled memory limit for crashkernel\n"); + } + + pr_info("Reserving %ldMB of memory at 0x%08lx " "for crashkernel (System RAM: %ldMB)\n", (unsigned long)(crash_size >> 20), - (unsigned long)(crashk_res.start >> 20), + (unsigned long)(crashk_res.start), (unsigned long)(lmb_phys_mem_size() >> 20)); - crashk_res.end = crashk_res.start + crash_size - 1; - insert_resource(&iomem_resource, &crashk_res); - return; disable: diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 2c9ab2842765..f6a2db12ad78 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -95,6 +95,7 @@ unsigned long memory_start; EXPORT_SYMBOL(memory_start); unsigned long memory_end = 0; EXPORT_SYMBOL(memory_end); +unsigned long memory_limit = 0; static struct resource mem_resources[MAX_NUMNODES]; @@ -102,21 +103,12 @@ int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; static int __init early_parse_mem(char *p) { - unsigned long size; + if (!p) + return 1; - memory_start = (unsigned long)__va(__MEMORY_START); - size = memparse(p, &p); - - if (size > __MEMORY_SIZE) { - printk(KERN_ERR - "Using mem= to increase the size of kernel memory " - "is not allowed.\n" - " Recompile the kernel with the correct value for " - "CONFIG_MEMORY_SIZE.\n"); - return 0; - } + memory_limit = PAGE_ALIGN(memparse(p, &p)); - memory_end = memory_start + size; + pr_notice("Memory limited to %ldMB\n", memory_limit >> 20); return 0; } @@ -252,7 +244,7 @@ void __init do_init_bootmem(void) { unsigned long bootmap_size; unsigned long bootmap_pages, bootmem_paddr; - u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT; + u64 total_pages = lmb_phys_mem_size() >> PAGE_SHIFT; int i; bootmap_pages = bootmem_bootmap_pages(total_pages); @@ -276,12 +268,6 @@ void __init do_init_bootmem(void) __add_active_range(0, start_pfn, end_pfn); } - /* - * Handle additional early reservations - */ - check_for_initrd(); - reserve_crashkernel(); - /* * Add all physical memory to the bootmem map and mark each * area as present. @@ -299,7 +285,7 @@ void __init do_init_bootmem(void) sparse_memory_present_with_active_regions(0); } -static void __init setup_memory(void) +static void __init early_reserve_mem(void) { unsigned long start_pfn; @@ -326,11 +312,11 @@ static void __init setup_memory(void) if (CONFIG_ZERO_PAGE_OFFSET != 0) lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET); - lmb_analyze(); - lmb_dump_all(); - - do_init_bootmem(); - plat_mem_setup(); + /* + * Handle additional early reservations + */ + check_for_initrd(); + reserve_crashkernel(); } /* @@ -397,10 +383,6 @@ void __init setup_arch(char **cmdline_p) bss_resource.start = virt_to_phys(__bss_start); bss_resource.end = virt_to_phys(_ebss)-1; - memory_start = (unsigned long)__va(__MEMORY_START); - if (!memory_end) - memory_end = memory_start + __MEMORY_SIZE; - #ifdef CONFIG_CMDLINE_OVERWRITE strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); #else @@ -417,8 +399,6 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); - uncached_init(); - plat_early_device_setup(); /* Let earlyprintk output early console messages */ @@ -429,21 +409,28 @@ void __init setup_arch(char **cmdline_p) sh_mv_setup(); sh_mv.mv_mem_init(); - /* - * Find the highest page frame number we have available - */ - max_pfn = PFN_DOWN(__pa(memory_end)); + early_reserve_mem(); + + lmb_enforce_memory_limit(memory_limit); + lmb_analyze(); + + lmb_dump_all(); /* * Determine low and high memory ranges: */ - max_low_pfn = max_pfn; + max_low_pfn = max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; min_low_pfn = __MEMORY_START >> PAGE_SHIFT; nodes_clear(node_online_map); + memory_start = (unsigned long)__va(__MEMORY_START); + memory_end = memory_start + (memory_limit ?: lmb_phys_mem_size()); + + uncached_init(); pmb_init(); - setup_memory(); + do_init_bootmem(); + plat_mem_setup(); sparse_init(); #ifdef CONFIG_DUMMY_CONSOLE -- cgit v1.2.3-59-g8ed1b From c9ad488289144ae5ef53b012e15895ef1f5e4bb6 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 6 May 2010 11:45:45 +0300 Subject: x86: Eliminate TS_XSAVE The fpu code currently uses current->thread_info->status & TS_XSAVE as a way to distinguish between XSAVE capable processors and older processors. The decision is not really task specific; instead we use the task status to avoid a global memory reference - the value should be the same across all threads. Eliminate this tie-in into the task structure by using an alternative instruction keyed off the XSAVE cpu feature; this results in shorter and faster code, without introducing a global memory reference. [ hpa: in the future, this probably should use an asm jmp ] Signed-off-by: Avi Kivity Acked-by: Suresh Siddha LKML-Reference: <1273135546-29690-2-git-send-email-avi@redhat.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/i387.h | 20 ++++++++++++++++---- arch/x86/include/asm/thread_info.h | 1 - arch/x86/kernel/cpu/common.c | 5 +---- arch/x86/kernel/i387.c | 5 +---- arch/x86/kernel/xsave.c | 6 +++--- 5 files changed, 21 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index da2930924501..a301a6825c3a 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h @@ -56,6 +56,18 @@ extern int restore_i387_xstate_ia32(void __user *buf); #define X87_FSW_ES (1 << 7) /* Exception Summary */ +static inline bool use_xsave(void) +{ + u8 has_xsave; + + alternative_io("mov $0, %0", + "mov $1, %0", + X86_FEATURE_XSAVE, + "=g"(has_xsave)); + + return has_xsave; +} + #ifdef CONFIG_X86_64 /* Ignore delayed exceptions from user space */ @@ -99,7 +111,7 @@ static inline void clear_fpu_state(struct task_struct *tsk) /* * xsave header may indicate the init state of the FP. */ - if ((task_thread_info(tsk)->status & TS_XSAVE) && + if (use_xsave() && !(xstate->xsave_hdr.xstate_bv & XSTATE_FP)) return; @@ -164,7 +176,7 @@ static inline void fxsave(struct task_struct *tsk) static inline void __save_init_fpu(struct task_struct *tsk) { - if (task_thread_info(tsk)->status & TS_XSAVE) + if (use_xsave()) xsave(tsk); else fxsave(tsk); @@ -218,7 +230,7 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx) */ static inline void __save_init_fpu(struct task_struct *tsk) { - if (task_thread_info(tsk)->status & TS_XSAVE) { + if (use_xsave()) { struct xsave_struct *xstate = &tsk->thread.xstate->xsave; struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave; @@ -266,7 +278,7 @@ end: static inline int restore_fpu_checking(struct task_struct *tsk) { - if (task_thread_info(tsk)->status & TS_XSAVE) + if (use_xsave()) return xrstor_checking(&tsk->thread.xstate->xsave); else return fxrstor_checking(&tsk->thread.xstate->fxsave); diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index e0d28901e969..e9e341505ab3 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -244,7 +244,6 @@ static inline struct thread_info *current_thread_info(void) #define TS_POLLING 0x0004 /* true if in idle loop and not sleeping */ #define TS_RESTORE_SIGMASK 0x0008 /* restore signal mask in do_signal() */ -#define TS_XSAVE 0x0010 /* Use xsave/xrstor */ #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 4868e4a951ee..c1c00d0b1692 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1243,10 +1243,7 @@ void __cpuinit cpu_init(void) /* * Force FPU initialization: */ - if (cpu_has_xsave) - current_thread_info()->status = TS_XSAVE; - else - current_thread_info()->status = 0; + current_thread_info()->status = 0; clear_used_math(); mxcsr_feature_mask_init(); diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 54c31c285488..14ca1dc7a703 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -102,10 +102,7 @@ void __cpuinit fpu_init(void) mxcsr_feature_mask_init(); /* clean state in init */ - if (cpu_has_xsave) - current_thread_info()->status = TS_XSAVE; - else - current_thread_info()->status = 0; + current_thread_info()->status = 0; clear_used_math(); } #endif /* CONFIG_X86_64 */ diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 782c3a362ec6..c1b0a11033a2 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c @@ -99,7 +99,7 @@ int save_i387_xstate(void __user *buf) if (err) return err; - if (task_thread_info(tsk)->status & TS_XSAVE) + if (use_xsave()) err = xsave_user(buf); else err = fxsave_user(buf); @@ -116,7 +116,7 @@ int save_i387_xstate(void __user *buf) clear_used_math(); /* trigger finit */ - if (task_thread_info(tsk)->status & TS_XSAVE) { + if (use_xsave()) { struct _fpstate __user *fx = buf; struct _xstate __user *x = buf; u64 xstate_bv; @@ -225,7 +225,7 @@ int restore_i387_xstate(void __user *buf) clts(); task_thread_info(current)->status |= TS_USEDFPU; } - if (task_thread_info(tsk)->status & TS_XSAVE) + if (use_xsave()) err = restore_user_xstate(buf); else err = fxrstor_checking((__force struct i387_fxsave_struct *) -- cgit v1.2.3-59-g8ed1b From 86603283326c9e95e5ad4e9fdddeec93cac5d9ad Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 6 May 2010 11:45:46 +0300 Subject: x86: Introduce 'struct fpu' and related API Currently all fpu state access is through tsk->thread.xstate. Since we wish to generalize fpu access to non-task contexts, wrap the state in a new 'struct fpu' and convert existing access to use an fpu API. Signal frame handlers are not converted to the API since they will remain task context only things. Signed-off-by: Avi Kivity Acked-by: Suresh Siddha LKML-Reference: <1273135546-29690-3-git-send-email-avi@redhat.com> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/i387.h | 115 +++++++++++++++++++++++++++++---------- arch/x86/include/asm/processor.h | 6 +- arch/x86/include/asm/xsave.h | 7 ++- arch/x86/kernel/i387.c | 102 +++++++++++++++++----------------- arch/x86/kernel/process.c | 21 +++---- arch/x86/kernel/process_32.c | 2 +- arch/x86/kernel/process_64.c | 2 +- arch/x86/kernel/xsave.c | 2 +- arch/x86/math-emu/fpu_aux.c | 6 +- 9 files changed, 160 insertions(+), 103 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index a301a6825c3a..1a8cca33b736 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -103,10 +104,10 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx) values. The kernel data segment can be sometimes 0 and sometimes new user value. Both should be ok. Use the PDA as safe address because it should be already in L1. */ -static inline void clear_fpu_state(struct task_struct *tsk) +static inline void fpu_clear(struct fpu *fpu) { - struct xsave_struct *xstate = &tsk->thread.xstate->xsave; - struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave; + struct xsave_struct *xstate = &fpu->state->xsave; + struct i387_fxsave_struct *fx = &fpu->state->fxsave; /* * xsave header may indicate the init state of the FP. @@ -123,6 +124,11 @@ static inline void clear_fpu_state(struct task_struct *tsk) X86_FEATURE_FXSAVE_LEAK); } +static inline void clear_fpu_state(struct task_struct *tsk) +{ + fpu_clear(&tsk->thread.fpu); +} + static inline int fxsave_user(struct i387_fxsave_struct __user *fx) { int err; @@ -147,7 +153,7 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx) return err; } -static inline void fxsave(struct task_struct *tsk) +static inline void fpu_fxsave(struct fpu *fpu) { /* Using "rex64; fxsave %0" is broken because, if the memory operand uses any extended registers for addressing, a second REX prefix @@ -157,42 +163,45 @@ static inline void fxsave(struct task_struct *tsk) /* Using "fxsaveq %0" would be the ideal choice, but is only supported starting with gas 2.16. */ __asm__ __volatile__("fxsaveq %0" - : "=m" (tsk->thread.xstate->fxsave)); + : "=m" (fpu->state->fxsave)); #elif 0 /* Using, as a workaround, the properly prefixed form below isn't accepted by any binutils version so far released, complaining that the same type of prefix is used twice if an extended register is needed for addressing (fix submitted to mainline 2005-11-21). */ __asm__ __volatile__("rex64/fxsave %0" - : "=m" (tsk->thread.xstate->fxsave)); + : "=m" (fpu->state->fxsave)); #else /* This, however, we can work around by forcing the compiler to select an addressing mode that doesn't require extended registers. */ __asm__ __volatile__("rex64/fxsave (%1)" - : "=m" (tsk->thread.xstate->fxsave) - : "cdaSDb" (&tsk->thread.xstate->fxsave)); + : "=m" (fpu->state->fxsave) + : "cdaSDb" (&fpu->state->fxsave)); #endif } -static inline void __save_init_fpu(struct task_struct *tsk) +static inline void fpu_save_init(struct fpu *fpu) { if (use_xsave()) - xsave(tsk); + fpu_xsave(fpu); else - fxsave(tsk); + fpu_fxsave(fpu); - clear_fpu_state(tsk); + fpu_clear(fpu); +} + +static inline void __save_init_fpu(struct task_struct *tsk) +{ + fpu_save_init(&tsk->thread.fpu); task_thread_info(tsk)->status &= ~TS_USEDFPU; } #else /* CONFIG_X86_32 */ #ifdef CONFIG_MATH_EMULATION -extern void finit_task(struct task_struct *tsk); +extern void finit_soft_fpu(struct i387_soft_struct *soft); #else -static inline void finit_task(struct task_struct *tsk) -{ -} +static inline void finit_soft_fpu(struct i387_soft_struct *soft) {} #endif static inline void tolerant_fwait(void) @@ -228,13 +237,13 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx) /* * These must be called with preempt disabled */ -static inline void __save_init_fpu(struct task_struct *tsk) +static inline void fpu_save_init(struct fpu *fpu) { if (use_xsave()) { - struct xsave_struct *xstate = &tsk->thread.xstate->xsave; - struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave; + struct xsave_struct *xstate = &fpu->state->xsave; + struct i387_fxsave_struct *fx = &fpu->state->fxsave; - xsave(tsk); + fpu_xsave(fpu); /* * xsave header may indicate the init state of the FP. @@ -258,8 +267,8 @@ static inline void __save_init_fpu(struct task_struct *tsk) "fxsave %[fx]\n" "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", X86_FEATURE_FXSR, - [fx] "m" (tsk->thread.xstate->fxsave), - [fsw] "m" (tsk->thread.xstate->fxsave.swd) : "memory"); + [fx] "m" (fpu->state->fxsave), + [fsw] "m" (fpu->state->fxsave.swd) : "memory"); clear_state: /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception is pending. Clear the x87 state here by setting it to fixed @@ -271,17 +280,34 @@ clear_state: X86_FEATURE_FXSAVE_LEAK, [addr] "m" (safe_address)); end: + ; +} + +static inline void __save_init_fpu(struct task_struct *tsk) +{ + fpu_save_init(&tsk->thread.fpu); task_thread_info(tsk)->status &= ~TS_USEDFPU; } + #endif /* CONFIG_X86_64 */ -static inline int restore_fpu_checking(struct task_struct *tsk) +static inline int fpu_fxrstor_checking(struct fpu *fpu) +{ + return fxrstor_checking(&fpu->state->fxsave); +} + +static inline int fpu_restore_checking(struct fpu *fpu) { if (use_xsave()) - return xrstor_checking(&tsk->thread.xstate->xsave); + return fpu_xrstor_checking(fpu); else - return fxrstor_checking(&tsk->thread.xstate->fxsave); + return fpu_fxrstor_checking(fpu); +} + +static inline int restore_fpu_checking(struct task_struct *tsk) +{ + return fpu_restore_checking(&tsk->thread.fpu); } /* @@ -409,30 +435,59 @@ static inline void clear_fpu(struct task_struct *tsk) static inline unsigned short get_fpu_cwd(struct task_struct *tsk) { if (cpu_has_fxsr) { - return tsk->thread.xstate->fxsave.cwd; + return tsk->thread.fpu.state->fxsave.cwd; } else { - return (unsigned short)tsk->thread.xstate->fsave.cwd; + return (unsigned short)tsk->thread.fpu.state->fsave.cwd; } } static inline unsigned short get_fpu_swd(struct task_struct *tsk) { if (cpu_has_fxsr) { - return tsk->thread.xstate->fxsave.swd; + return tsk->thread.fpu.state->fxsave.swd; } else { - return (unsigned short)tsk->thread.xstate->fsave.swd; + return (unsigned short)tsk->thread.fpu.state->fsave.swd; } } static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk) { if (cpu_has_xmm) { - return tsk->thread.xstate->fxsave.mxcsr; + return tsk->thread.fpu.state->fxsave.mxcsr; } else { return MXCSR_DEFAULT; } } +static bool fpu_allocated(struct fpu *fpu) +{ + return fpu->state != NULL; +} + +static inline int fpu_alloc(struct fpu *fpu) +{ + if (fpu_allocated(fpu)) + return 0; + fpu->state = kmem_cache_alloc(task_xstate_cachep, GFP_KERNEL); + if (!fpu->state) + return -ENOMEM; + WARN_ON((unsigned long)fpu->state & 15); + return 0; +} + +static inline void fpu_free(struct fpu *fpu) +{ + if (fpu->state) { + kmem_cache_free(task_xstate_cachep, fpu->state); + fpu->state = NULL; + } +} + +static inline void fpu_copy(struct fpu *dst, struct fpu *src) +{ + memcpy(dst->state, src->state, xstate_size); +} + #endif /* __ASSEMBLY__ */ #define PSHUFB_XMM5_XMM0 .byte 0x66, 0x0f, 0x38, 0x00, 0xc5 diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index b753ea59703a..b684f587647c 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -380,6 +380,10 @@ union thread_xstate { struct xsave_struct xsave; }; +struct fpu { + union thread_xstate *state; +}; + #ifdef CONFIG_X86_64 DECLARE_PER_CPU(struct orig_ist, orig_ist); @@ -457,7 +461,7 @@ struct thread_struct { unsigned long trap_no; unsigned long error_code; /* floating point and extended processor state */ - union thread_xstate *xstate; + struct fpu fpu; #ifdef CONFIG_X86_32 /* Virtual 86 mode info */ struct vm86_struct __user *vm86_info; diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index ddc04ccad03b..2c4390cae228 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h @@ -37,8 +37,9 @@ extern int check_for_xstate(struct i387_fxsave_struct __user *buf, void __user *fpstate, struct _fpx_sw_bytes *sw); -static inline int xrstor_checking(struct xsave_struct *fx) +static inline int fpu_xrstor_checking(struct fpu *fpu) { + struct xsave_struct *fx = &fpu->state->xsave; int err; asm volatile("1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n\t" @@ -110,12 +111,12 @@ static inline void xrstor_state(struct xsave_struct *fx, u64 mask) : "memory"); } -static inline void xsave(struct task_struct *tsk) +static inline void fpu_xsave(struct fpu *fpu) { /* This, however, we can work around by forcing the compiler to select an addressing mode that doesn't require extended registers. */ __asm__ __volatile__(".byte " REX_PREFIX "0x0f,0xae,0x27" - : : "D" (&(tsk->thread.xstate->xsave)), + : : "D" (&(fpu->state->xsave)), "a" (-1), "d"(-1) : "memory"); } #endif diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 14ca1dc7a703..86cef6b32253 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -107,57 +107,57 @@ void __cpuinit fpu_init(void) } #endif /* CONFIG_X86_64 */ -/* - * The _current_ task is using the FPU for the first time - * so initialize it and set the mxcsr to its default - * value at reset if we support XMM instructions and then - * remeber the current task has used the FPU. - */ -int init_fpu(struct task_struct *tsk) +static void fpu_finit(struct fpu *fpu) { - if (tsk_used_math(tsk)) { - if (HAVE_HWFP && tsk == current) - unlazy_fpu(tsk); - return 0; - } - - /* - * Memory allocation at the first usage of the FPU and other state. - */ - if (!tsk->thread.xstate) { - tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep, - GFP_KERNEL); - if (!tsk->thread.xstate) - return -ENOMEM; - } - #ifdef CONFIG_X86_32 if (!HAVE_HWFP) { - memset(tsk->thread.xstate, 0, xstate_size); - finit_task(tsk); - set_stopped_child_used_math(tsk); - return 0; + finit_soft_fpu(&fpu->state->soft); + return; } #endif if (cpu_has_fxsr) { - struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave; + struct i387_fxsave_struct *fx = &fpu->state->fxsave; memset(fx, 0, xstate_size); fx->cwd = 0x37f; if (cpu_has_xmm) fx->mxcsr = MXCSR_DEFAULT; } else { - struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave; + struct i387_fsave_struct *fp = &fpu->state->fsave; memset(fp, 0, xstate_size); fp->cwd = 0xffff037fu; fp->swd = 0xffff0000u; fp->twd = 0xffffffffu; fp->fos = 0xffff0000u; } +} + +/* + * The _current_ task is using the FPU for the first time + * so initialize it and set the mxcsr to its default + * value at reset if we support XMM instructions and then + * remeber the current task has used the FPU. + */ +int init_fpu(struct task_struct *tsk) +{ + int ret; + + if (tsk_used_math(tsk)) { + if (HAVE_HWFP && tsk == current) + unlazy_fpu(tsk); + return 0; + } + /* - * Only the device not available exception or ptrace can call init_fpu. + * Memory allocation at the first usage of the FPU and other state. */ + ret = fpu_alloc(&tsk->thread.fpu); + if (ret) + return ret; + + fpu_finit(&tsk->thread.fpu); + set_stopped_child_used_math(tsk); return 0; } @@ -191,7 +191,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset, return ret; return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.xstate->fxsave, 0, -1); + &target->thread.fpu.state->fxsave, 0, -1); } int xfpregs_set(struct task_struct *target, const struct user_regset *regset, @@ -208,19 +208,19 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, return ret; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.xstate->fxsave, 0, -1); + &target->thread.fpu.state->fxsave, 0, -1); /* * mxcsr reserved bits must be masked to zero for security reasons. */ - target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask; + target->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask; /* * update the header bits in the xsave header, indicating the * presence of FP and SSE state. */ if (cpu_has_xsave) - target->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE; + target->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE; return ret; } @@ -243,14 +243,14 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset, * memory layout in the thread struct, so that we can copy the entire * xstateregs to the user using one user_regset_copyout(). */ - memcpy(&target->thread.xstate->fxsave.sw_reserved, + memcpy(&target->thread.fpu.state->fxsave.sw_reserved, xstate_fx_sw_bytes, sizeof(xstate_fx_sw_bytes)); /* * Copy the xstate memory layout. */ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.xstate->xsave, 0, -1); + &target->thread.fpu.state->xsave, 0, -1); return ret; } @@ -269,14 +269,14 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, return ret; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.xstate->xsave, 0, -1); + &target->thread.fpu.state->xsave, 0, -1); /* * mxcsr reserved bits must be masked to zero for security reasons. */ - target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask; + target->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask; - xsave_hdr = &target->thread.xstate->xsave.xsave_hdr; + xsave_hdr = &target->thread.fpu.state->xsave.xsave_hdr; xsave_hdr->xstate_bv &= pcntxt_mask; /* @@ -362,7 +362,7 @@ static inline u32 twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave) static void convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk) { - struct i387_fxsave_struct *fxsave = &tsk->thread.xstate->fxsave; + struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave; struct _fpreg *to = (struct _fpreg *) &env->st_space[0]; struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0]; int i; @@ -402,7 +402,7 @@ static void convert_to_fxsr(struct task_struct *tsk, const struct user_i387_ia32_struct *env) { - struct i387_fxsave_struct *fxsave = &tsk->thread.xstate->fxsave; + struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave; struct _fpreg *from = (struct _fpreg *) &env->st_space[0]; struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0]; int i; @@ -442,7 +442,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset, if (!cpu_has_fxsr) { return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.xstate->fsave, 0, + &target->thread.fpu.state->fsave, 0, -1); } @@ -472,7 +472,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, if (!cpu_has_fxsr) { return user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.xstate->fsave, 0, -1); + &target->thread.fpu.state->fsave, 0, -1); } if (pos > 0 || count < sizeof(env)) @@ -487,7 +487,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, * presence of FP. */ if (cpu_has_xsave) - target->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FP; + target->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FP; return ret; } @@ -498,7 +498,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf) { struct task_struct *tsk = current; - struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave; + struct i387_fsave_struct *fp = &tsk->thread.fpu.state->fsave; fp->status = fp->swd; if (__copy_to_user(buf, fp, sizeof(struct i387_fsave_struct))) @@ -509,7 +509,7 @@ static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf) static int save_i387_fxsave(struct _fpstate_ia32 __user *buf) { struct task_struct *tsk = current; - struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave; + struct i387_fxsave_struct *fx = &tsk->thread.fpu.state->fxsave; struct user_i387_ia32_struct env; int err = 0; @@ -544,7 +544,7 @@ static int save_i387_xsave(void __user *buf) * header as well as change any contents in the memory layout. * xrestore as part of sigreturn will capture all the changes. */ - tsk->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE; + tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE; if (save_i387_fxsave(fx) < 0) return -1; @@ -596,7 +596,7 @@ static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf) { struct task_struct *tsk = current; - return __copy_from_user(&tsk->thread.xstate->fsave, buf, + return __copy_from_user(&tsk->thread.fpu.state->fsave, buf, sizeof(struct i387_fsave_struct)); } @@ -607,10 +607,10 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf, struct user_i387_ia32_struct env; int err; - err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0], + err = __copy_from_user(&tsk->thread.fpu.state->fxsave, &buf->_fxsr_env[0], size); /* mxcsr reserved bits must be masked to zero for security reasons */ - tsk->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask; + tsk->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask; if (err || __copy_from_user(&env, buf, sizeof(env))) return 1; convert_to_fxsr(tsk, &env); @@ -626,7 +626,7 @@ static int restore_i387_xsave(void __user *buf) struct i387_fxsave_struct __user *fx = (struct i387_fxsave_struct __user *) &fx_user->_fxsr_env[0]; struct xsave_hdr_struct *xsave_hdr = - ¤t->thread.xstate->xsave.xsave_hdr; + ¤t->thread.fpu.state->xsave.xsave_hdr; u64 mask; int err; diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 28ad9f4d8b94..f18fd9c15247 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -32,25 +32,22 @@ struct kmem_cache *task_xstate_cachep; int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) { + int ret; + *dst = *src; - if (src->thread.xstate) { - dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep, - GFP_KERNEL); - if (!dst->thread.xstate) - return -ENOMEM; - WARN_ON((unsigned long)dst->thread.xstate & 15); - memcpy(dst->thread.xstate, src->thread.xstate, xstate_size); + if (fpu_allocated(&src->thread.fpu)) { + memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu)); + ret = fpu_alloc(&dst->thread.fpu); + if (ret) + return ret; + fpu_copy(&dst->thread.fpu, &src->thread.fpu); } return 0; } void free_thread_xstate(struct task_struct *tsk) { - if (tsk->thread.xstate) { - kmem_cache_free(task_xstate_cachep, tsk->thread.xstate); - tsk->thread.xstate = NULL; - } - + fpu_free(&tsk->thread.fpu); WARN(tsk->thread.ds_ctx, "leaking DS context\n"); } diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index f6c62667e30c..0a7a4f5bbaa9 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -317,7 +317,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) /* we're going to use this soon, after a few expensive things */ if (preload_fpu) - prefetch(next->xstate); + prefetch(next->fpu.state); /* * Reload esp0. diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 17cb3295cbf7..979215f51985 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -396,7 +396,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) /* we're going to use this soon, after a few expensive things */ if (preload_fpu) - prefetch(next->xstate); + prefetch(next->fpu.state); /* * Reload esp0, LDT and the page table pointer: diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index c1b0a11033a2..37e68fc5e24a 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c @@ -109,7 +109,7 @@ int save_i387_xstate(void __user *buf) task_thread_info(tsk)->status &= ~TS_USEDFPU; stts(); } else { - if (__copy_to_user(buf, &tsk->thread.xstate->fxsave, + if (__copy_to_user(buf, &tsk->thread.fpu.state->fxsave, xstate_size)) return -1; } diff --git a/arch/x86/math-emu/fpu_aux.c b/arch/x86/math-emu/fpu_aux.c index aa0987088774..62797f930511 100644 --- a/arch/x86/math-emu/fpu_aux.c +++ b/arch/x86/math-emu/fpu_aux.c @@ -30,10 +30,10 @@ static void fclex(void) } /* Needs to be externally visible */ -void finit_task(struct task_struct *tsk) +void finit_soft_fpu(struct i387_soft_struct *soft) { - struct i387_soft_struct *soft = &tsk->thread.xstate->soft; struct address *oaddr, *iaddr; + memset(soft, 0, sizeof(*soft)); soft->cwd = 0x037f; soft->swd = 0; soft->ftop = 0; /* We don't keep top in the status word internally. */ @@ -52,7 +52,7 @@ void finit_task(struct task_struct *tsk) void finit(void) { - finit_task(current); + finit_task(¤t->thread.fpu); } /* -- cgit v1.2.3-59-g8ed1b From c3f8978ea332cd4be88e12574452a025892ac9af Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 10 May 2010 13:37:16 -0700 Subject: x86, fpu: Unbreak FPU emulation Unbreak FPU emulation, broken by checkin 86603283326c9e95e5ad4e9fdddeec93cac5d9ad: x86: Introduce 'struct fpu' and related API Signed-off-by: H. Peter Anvin Cc: Avi Kivity Cc: Suresh Siddha LKML-Reference: <1273135546-29690-3-git-send-email-avi@redhat.com> --- arch/x86/math-emu/fpu_aux.c | 2 +- arch/x86/math-emu/fpu_entry.c | 4 ++-- arch/x86/math-emu/fpu_system.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/math-emu/fpu_aux.c b/arch/x86/math-emu/fpu_aux.c index 62797f930511..dc8adad10a2f 100644 --- a/arch/x86/math-emu/fpu_aux.c +++ b/arch/x86/math-emu/fpu_aux.c @@ -52,7 +52,7 @@ void finit_soft_fpu(struct i387_soft_struct *soft) void finit(void) { - finit_task(¤t->thread.fpu); + finit_soft_fpu(¤t->thread.fpu.state->soft); } /* diff --git a/arch/x86/math-emu/fpu_entry.c b/arch/x86/math-emu/fpu_entry.c index 5d87f586f8d7..7718541541d4 100644 --- a/arch/x86/math-emu/fpu_entry.c +++ b/arch/x86/math-emu/fpu_entry.c @@ -681,7 +681,7 @@ int fpregs_soft_set(struct task_struct *target, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { - struct i387_soft_struct *s387 = &target->thread.xstate->soft; + struct i387_soft_struct *s387 = &target->thread.fpu.state->soft; void *space = s387->st_space; int ret; int offset, other, i, tags, regnr, tag, newtop; @@ -733,7 +733,7 @@ int fpregs_soft_get(struct task_struct *target, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { - struct i387_soft_struct *s387 = &target->thread.xstate->soft; + struct i387_soft_struct *s387 = &target->thread.fpu.state->soft; const void *space = s387->st_space; int ret; int offset = (S387->ftop & 7) * 10, other = 80 - offset; diff --git a/arch/x86/math-emu/fpu_system.h b/arch/x86/math-emu/fpu_system.h index 50fa0ec2c8a5..2c614410a5f3 100644 --- a/arch/x86/math-emu/fpu_system.h +++ b/arch/x86/math-emu/fpu_system.h @@ -31,7 +31,7 @@ #define SEG_EXPAND_DOWN(s) (((s).b & ((1 << 11) | (1 << 10))) \ == (1 << 10)) -#define I387 (current->thread.xstate) +#define I387 (current->thread.fpu.state) #define FPU_info (I387->soft.info) #define FPU_CS (*(unsigned short *) &(FPU_info->regs->cs)) -- cgit v1.2.3-59-g8ed1b From dce8bf4e115aa44d590802ce3554e926840c9042 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 10 May 2010 13:41:41 -0700 Subject: x86, fpu: Use the proper asm constraint in use_xsave() The proper constraint for a receiving 8-bit variable is "=qm", not "=g" which equals "=rim"; even though the "i" will never match, bugs can and do happen due to the difference between "q" and "r". Signed-off-by: H. Peter Anvin Cc: Avi Kivity Cc: Suresh Siddha LKML-Reference: <1273135546-29690-2-git-send-email-avi@redhat.com> --- arch/x86/include/asm/i387.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index 1a8cca33b736..8002e9ce25fc 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h @@ -64,7 +64,7 @@ static inline bool use_xsave(void) alternative_io("mov $0, %0", "mov $1, %0", X86_FEATURE_XSAVE, - "=g"(has_xsave)); + "=qm" (has_xsave)); return has_xsave; } -- cgit v1.2.3-59-g8ed1b From b227358d333426abe47211b5be1fb69c0f74955f Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 10 May 2010 14:29:14 -0700 Subject: OMAP2/3: Add V4L2 DSS driver support in device.c Add V4L2 DSS driver support in device.c Signed-off-by: Vaibhav Hiremath Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/devices.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 2271b9bd1f50..10f3a3c58cc0 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -786,6 +786,33 @@ static inline void omap_hdq_init(void) static inline void omap_hdq_init(void) {} #endif +/*---------------------------------------------------------------------------*/ + +#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \ + defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE) +#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) +static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = { +}; +#else +static struct resource omap_vout_resource[2] = { +}; +#endif + +static struct platform_device omap_vout_device = { + .name = "omap_vout", + .num_resources = ARRAY_SIZE(omap_vout_resource), + .resource = &omap_vout_resource[0], + .id = -1, +}; +static void omap_init_vout(void) +{ + if (platform_device_register(&omap_vout_device) < 0) + printk(KERN_ERR "Unable to register OMAP-VOUT device\n"); +} +#else +static inline void omap_init_vout(void) {} +#endif + /*-------------------------------------------------------------------------*/ static int __init omap2_init_devices(void) @@ -800,6 +827,7 @@ static int __init omap2_init_devices(void) omap_hdq_init(); omap_init_sti(); omap_init_sha1_md5(); + omap_init_vout(); return 0; } -- cgit v1.2.3-59-g8ed1b From ce60d4d5d50a5454768faa522da98aa5f8070bd0 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 19 Apr 2010 23:53:07 +0200 Subject: uml: i386: Avoid redefinition of NR_syscalls The i386 subarch happens to pull in original NR_syscalls. Maybe we can make that work for all host arch, but for now just avoid the clash by using an all-upper-case name. CC arch/um/kernel/skas/syscall.o/data/linux-2.6/arch/um/kernel/skas/syscall.c:13:1: warning: "NR_syscalls" redefined In file included from /data/linux-2.6/arch/x86/include/asm/unistd.h:3, from /data/linux-2.6/arch/um/sys-i386/shared/sysdep/syscalls.h:6, from /data/linux-2.6/arch/um/kernel/skas/syscall.c:10: /data/linux-2.6/arch/x86/include/asm/unistd_32.h:349:1: warning: this is the location of the previous definition Signed-off-by: Jan Kiszka Signed-off-by: Jiri Kosina --- arch/um/kernel/skas/syscall.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index 4e3b820bd2be..f5173e1ec3ac 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c @@ -10,7 +10,7 @@ #include "sysdep/syscalls.h" extern int syscall_table_size; -#define NR_syscalls (syscall_table_size / sizeof(void *)) +#define NR_SYSCALLS (syscall_table_size / sizeof(void *)) void handle_syscall(struct uml_pt_regs *r) { @@ -30,7 +30,7 @@ void handle_syscall(struct uml_pt_regs *r) * in case it's a compiler bug. */ syscall = UPT_SYSCALL_NR(r); - if ((syscall >= NR_syscalls) || (syscall < 0)) + if ((syscall >= NR_SYSCALLS) || (syscall < 0)) result = -ENOSYS; else result = EXECUTE_SYSCALL(syscall, regs); -- cgit v1.2.3-59-g8ed1b From 474b62f573360947e2740458bde3778d420e1b40 Mon Sep 17 00:00:00 2001 From: Jongpill Lee Date: Fri, 19 Mar 2010 15:33:12 +0900 Subject: ARM: S5P6440: Bug fix on PWM Timer This patch fixes return value in below functions - pwm_cfg_src_is_tclk - tcfg_to_divisor - pwm_tdiv_has_div1 - pwm_tdiv_div_bits And this patch changes Copyright ordering, and addes 'based on' information. Signed-off-by: Jongpill Lee Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/include/mach/pwm-clock.h | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/include/mach/pwm-clock.h b/arch/arm/mach-s5p6440/include/mach/pwm-clock.h index c4bb7c555477..6a2a02fdf12a 100644 --- a/arch/arm/mach-s5p6440/include/mach/pwm-clock.h +++ b/arch/arm/mach-s5p6440/include/mach/pwm-clock.h @@ -1,11 +1,14 @@ /* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * Ben Dooks * http://armlinux.simtec.co.uk/ * - * Copyright 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h * * S5P6440 - pwm clock and timer support * @@ -14,16 +17,19 @@ * published by the Free Software Foundation. */ +#ifndef __ASM_ARCH_PWMCLK_H +#define __ASM_ARCH_PWMCLK_H __FILE__ + /** * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk - * @cfg: The timer TCFG1 register bits shifted down to 0. + * @tcfg: The timer TCFG1 register bits shifted down to 0. * * Return true if the given configuration from TCFG1 is a TCLK instead * any of the TDIV clocks. */ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) { - return tcfg == S3C2410_TCFG1_MUX_TCLK; + return 0; } /** @@ -35,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) */ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) { - return 1 << (1 + tcfg1); + return 1 << tcfg1; } /** @@ -45,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) */ static inline unsigned int pwm_tdiv_has_div1(void) { - return 0; + return 1; } /** @@ -56,7 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void) */ static inline unsigned long pwm_tdiv_div_bits(unsigned int div) { - return ilog2(div) - 1; + return ilog2(div); } -#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK +#define S3C_TCFG1_MUX_TCLK 0 + +#endif /* __ASM_ARCH_PWMCLK_H */ -- cgit v1.2.3-59-g8ed1b From dcd897dba163e746cd98d8290c5a18dc47157c64 Mon Sep 17 00:00:00 2001 From: Jongpill Lee Date: Fri, 19 Mar 2010 15:33:22 +0900 Subject: ARM: S5P6442: Bug fix on PWM Timer This patch fixes return value in below functions - pwm_cfg_src_is_tclk - tcfg_to_divisor - pwm_tdiv_has_div1 - pwm_tdiv_div_bits And this patch changes Copyright ordering. Signed-off-by: Jongpill Lee Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6442/include/mach/pwm-clock.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6442/include/mach/pwm-clock.h b/arch/arm/mach-s5p6442/include/mach/pwm-clock.h index 15e8525da0f1..2724b37def31 100644 --- a/arch/arm/mach-s5p6442/include/mach/pwm-clock.h +++ b/arch/arm/mach-s5p6442/include/mach/pwm-clock.h @@ -1,13 +1,14 @@ /* linux/arch/arm/mach-s5p6442/include/mach/pwm-clock.h * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * Ben Dooks * http://armlinux.simtec.co.uk/ * - * Copyright 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h + * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h * * S5P6442 - pwm clock and timer support * @@ -21,14 +22,14 @@ /** * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk - * @cfg: The timer TCFG1 register bits shifted down to 0. + * @tcfg: The timer TCFG1 register bits shifted down to 0. * * Return true if the given configuration from TCFG1 is a TCLK instead * any of the TDIV clocks. */ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) { - return tcfg == S3C2410_TCFG1_MUX_TCLK; + return tcfg == S3C64XX_TCFG1_MUX_TCLK; } /** @@ -40,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) */ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) { - return 1 << (1 + tcfg1); + return 1 << tcfg1; } /** @@ -50,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) */ static inline unsigned int pwm_tdiv_has_div1(void) { - return 0; + return 1; } /** @@ -61,9 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void) */ static inline unsigned long pwm_tdiv_div_bits(unsigned int div) { - return ilog2(div) - 1; + return ilog2(div); } -#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK +#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK #endif /* __ASM_ARCH_PWMCLK_H */ -- cgit v1.2.3-59-g8ed1b From b78232da3f85950a207bbcb64db46fd95b581465 Mon Sep 17 00:00:00 2001 From: Jongpill Lee Date: Fri, 19 Mar 2010 15:33:31 +0900 Subject: ARM: S5PV210: Bug fix on PWM Timer This patch fixes return value in below functions - pwm_cfg_src_is_tclk - tcfg_to_divisor - pwm_tdiv_has_div1 - pwm_tdiv_div_bits And this patch changes Copyright ordering. Signed-off-by: Jongpill Lee Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/include/mach/pwm-clock.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/include/mach/pwm-clock.h b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h index 69027fea987a..f8a9f1b330e0 100644 --- a/arch/arm/mach-s5pv210/include/mach/pwm-clock.h +++ b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h @@ -1,13 +1,14 @@ /* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * Ben Dooks * http://armlinux.simtec.co.uk/ * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h + * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h * * S5PV210 - pwm clock and timer support * @@ -21,14 +22,14 @@ /** * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk - * @cfg: The timer TCFG1 register bits shifted down to 0. + * @tcfg: The timer TCFG1 register bits shifted down to 0. * * Return true if the given configuration from TCFG1 is a TCLK instead * any of the TDIV clocks. */ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) { - return tcfg == S3C2410_TCFG1_MUX_TCLK; + return tcfg == S3C64XX_TCFG1_MUX_TCLK; } /** @@ -40,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) */ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) { - return 1 << (1 + tcfg1); + return 1 << tcfg1; } /** @@ -50,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) */ static inline unsigned int pwm_tdiv_has_div1(void) { - return 0; + return 1; } /** @@ -61,9 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void) */ static inline unsigned long pwm_tdiv_div_bits(unsigned int div) { - return ilog2(div) - 1; + return ilog2(div); } -#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK +#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK #endif /* __ASM_ARCH_PWMCLK_H */ -- cgit v1.2.3-59-g8ed1b From f001d5b28bc583c85281a9ce315ac16970201eae Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 19 Apr 2010 20:05:08 +0900 Subject: ARM: S5P: Add USB External Crystal clock definition Add USB external crystal clock definition Xusbxti to common S5P clock code. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/plat-s5p/clock.c | 5 +++++ arch/arm/plat-s5p/include/plat/s5p-clock.h | 1 + 2 files changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index aa96e335073b..3fef951445dc 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c @@ -33,6 +33,11 @@ struct clk clk_ext_xtal_mux = { .id = -1, }; +struct clk clk_xusbxti = { + .name = "xusbxti", + .id = -1, +}; + static struct clk s5p_clk_27m = { .name = "clk_27m", .id = -1, diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h index 56fb8b414d41..a476a9f14697 100644 --- a/arch/arm/plat-s5p/include/plat/s5p-clock.h +++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h @@ -23,6 +23,7 @@ #define clk_fin_vpll clk_ext_xtal_mux extern struct clk clk_ext_xtal_mux; +extern struct clk clk_xusbxti; extern struct clk clk_48m; extern struct clk clk_fout_apll; extern struct clk clk_fout_mpll; -- cgit v1.2.3-59-g8ed1b From f3d51e13fea901729fef15bf1c32ca004d45476e Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 May 2010 14:01:02 +0000 Subject: sh: hwblk index rework Rework the sh7722/sh7723/sh7724 hwblk code to use the hwblk id as index in the mstp clock array. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/hwblk.h | 2 +- arch/sh/kernel/cpu/hwblk.c | 5 +++++ arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 4 ++-- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 14 +++++++------- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 16 ++++++++-------- 5 files changed, 23 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/hwblk.h b/arch/sh/include/asm/hwblk.h index 5d3ccae4202b..4984d291ee0b 100644 --- a/arch/sh/include/asm/hwblk.h +++ b/arch/sh/include/asm/hwblk.h @@ -59,7 +59,7 @@ void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt); /* allow clocks to enable and disable hardware blocks */ #define SH_HWBLK_CLK(_name, _id, _parent, _hwblk, _flags) \ -{ \ +[_hwblk] = { \ .name = _name, \ .id = _id, \ .parent = _parent, \ diff --git a/arch/sh/kernel/cpu/hwblk.c b/arch/sh/kernel/cpu/hwblk.c index 67a1e811cfe8..3e985aae5d91 100644 --- a/arch/sh/kernel/cpu/hwblk.c +++ b/arch/sh/kernel/cpu/hwblk.c @@ -146,6 +146,11 @@ int __init sh_hwblk_clk_register(struct clk *clks, int nr) for (k = 0; !ret && (k < nr); k++) { clkp = clks + k; + + /* skip over clocks using hwblk 0 (HWBLK_UNKNOWN) */ + if (!clkp->arch_flags) + continue; + clkp->ops = &sh_hwblk_clk_ops; ret |= clk_register(clkp); } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 107b200e78bd..e5b6f47ea8b0 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -157,7 +157,7 @@ struct clk div6_clks[] = { #define B_CLK &div4_clks[DIV4_B] #define U_CLK &div4_clks[DIV4_U] -static struct clk mstp_clks[] = { +static struct clk mstp_clks[HWBLK_NR] = { SH_HWBLK_CLK("uram0", -1, U_CLK, HWBLK_URAM, CLK_ENABLE_ON_INIT), SH_HWBLK_CLK("xymem0", -1, B_CLK, HWBLK_XYMEM, CLK_ENABLE_ON_INIT), SH_HWBLK_CLK("tmu_fck", -1, P_CLK, HWBLK_TMU, 0), @@ -213,7 +213,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); if (!ret) - ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks)); + ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index fc86c88223f4..390bdb5cabc5 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -218,32 +218,32 @@ static struct clk_lookup lookups[] = { /* TMU0 */ .dev_id = "sh_tmu.0", .con_id = "tmu_fck", - .clk = &mstp_clks[11], /* tmu012_fck */ + .clk = &mstp_clks[HWBLK_TMU0], }, { /* TMU1 */ .dev_id = "sh_tmu.1", .con_id = "tmu_fck", - .clk = &mstp_clks[11], + .clk = &mstp_clks[HWBLK_TMU0], }, { /* TMU2 */ .dev_id = "sh_tmu.2", .con_id = "tmu_fck", - .clk = &mstp_clks[11], + .clk = &mstp_clks[HWBLK_TMU0], }, { /* TMU3 */ .dev_id = "sh_tmu.3", .con_id = "tmu_fck", - .clk = &mstp_clks[15], /* tmu345_fck */ + .clk = &mstp_clks[HWBLK_TMU1], }, { /* TMU4 */ .dev_id = "sh_tmu.4", .con_id = "tmu_fck", - .clk = &mstp_clks[15], + .clk = &mstp_clks[HWBLK_TMU1], }, { /* TMU5 */ .dev_id = "sh_tmu.5", .con_id = "tmu_fck", - .clk = &mstp_clks[15], + .clk = &mstp_clks[HWBLK_TMU1], }, }; @@ -277,7 +277,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); if (!ret) - ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks)); + ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR); return ret; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index f1583a23b3a5..c5d4891d38a4 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -178,7 +178,7 @@ struct clk div6_clks[] = { #define I_CLK (&div4_clks[DIV4_I]) #define SH_CLK (&div4_clks[DIV4_SH]) -static struct clk mstp_clks[] = { +static struct clk mstp_clks[HWBLK_NR] = { SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT), SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT), SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT), @@ -240,32 +240,32 @@ static struct clk_lookup lookups[] = { /* TMU0 */ .dev_id = "sh_tmu.0", .con_id = "tmu_fck", - .clk = &mstp_clks[12], /* tmu012_fck */ + .clk = &mstp_clks[HWBLK_TMU0], }, { /* TMU1 */ .dev_id = "sh_tmu.1", .con_id = "tmu_fck", - .clk = &mstp_clks[12], + .clk = &mstp_clks[HWBLK_TMU0], }, { /* TMU2 */ .dev_id = "sh_tmu.2", .con_id = "tmu_fck", - .clk = &mstp_clks[12], + .clk = &mstp_clks[HWBLK_TMU0], }, { /* TMU3 */ .dev_id = "sh_tmu.3", .con_id = "tmu_fck", - .clk = &mstp_clks[16], /* tmu345_fck */ + .clk = &mstp_clks[HWBLK_TMU1], }, { /* TMU4 */ .dev_id = "sh_tmu.4", .con_id = "tmu_fck", - .clk = &mstp_clks[16], + .clk = &mstp_clks[HWBLK_TMU1], }, { /* TMU5 */ .dev_id = "sh_tmu.5", .con_id = "tmu_fck", - .clk = &mstp_clks[16], + .clk = &mstp_clks[HWBLK_TMU1], }, }; @@ -291,7 +291,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); if (!ret) - ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks)); + ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR); return ret; } -- cgit v1.2.3-59-g8ed1b From e4e06697977bf6731d940ab1bd84e16cb53c3ae3 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 May 2010 14:01:12 +0000 Subject: sh: scif and tmu clkdev changes Modify sh7722/sh7723/sh7724 to use clkdev for TMU and SCIF clock lookups. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 43 +++++++++++++++++++++++++++++++--- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 42 ++++++++++++++++++++++++++++----- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 42 ++++++++++++++++++++++++++++----- 3 files changed, 112 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index e5b6f47ea8b0..ed57c631b09a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -164,9 +165,9 @@ static struct clk mstp_clks[HWBLK_NR] = { SH_HWBLK_CLK("cmt_fck", -1, R_CLK, HWBLK_CMT, 0), SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0), SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0), - SH_HWBLK_CLK("sci_fck", 0, P_CLK, HWBLK_SCIF0, 0), - SH_HWBLK_CLK("sci_fck", 1, P_CLK, HWBLK_SCIF1, 0), - SH_HWBLK_CLK("sci_fck", 2, P_CLK, HWBLK_SCIF2, 0), + SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF0, 0), + SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF1, 0), + SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF2, 0), SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0), SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0), @@ -185,6 +186,40 @@ static struct clk mstp_clks[HWBLK_NR] = { SH_HWBLK_CLK("lcdc0", -1, P_CLK, HWBLK_LCDC, 0), }; +static struct clk_lookup lookups[] = { + { + /* TMU0 */ + .dev_id = "sh_tmu.0", + .con_id = "tmu_fck", + .clk = &mstp_clks[HWBLK_TMU], + }, { + /* TMU1 */ + .dev_id = "sh_tmu.1", + .con_id = "tmu_fck", + .clk = &mstp_clks[HWBLK_TMU], + }, { + /* TMU2 */ + .dev_id = "sh_tmu.2", + .con_id = "tmu_fck", + .clk = &mstp_clks[HWBLK_TMU], + }, { + /* SCIF0 */ + .dev_id = "sh-sci.0", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF0], + }, { + /* SCIF1 */ + .dev_id = "sh-sci.1", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF1], + }, { + /* SCIF2 */ + .dev_id = "sh-sci.2", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF2], + }, +}; + int __init arch_clk_init(void) { int k, ret = 0; @@ -198,6 +233,8 @@ int __init arch_clk_init(void) for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) ret = clk_register(main_clks[k]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + if (!ret) ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 390bdb5cabc5..d92d7cddd099 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -179,12 +179,12 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0), SH_HWBLK_CLK("tmu345_fck", -1, P_CLK, HWBLK_TMU1, 0), SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0), - SH_HWBLK_CLK("sci_fck", 0, P_CLK, HWBLK_SCIF0, 0), - SH_HWBLK_CLK("sci_fck", 1, P_CLK, HWBLK_SCIF1, 0), - SH_HWBLK_CLK("sci_fck", 2, P_CLK, HWBLK_SCIF2, 0), - SH_HWBLK_CLK("sci_fck", 3, B_CLK, HWBLK_SCIF3, 0), - SH_HWBLK_CLK("sci_fck", 4, B_CLK, HWBLK_SCIF4, 0), - SH_HWBLK_CLK("sci_fck", 5, B_CLK, HWBLK_SCIF5, 0), + SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF0, 0), + SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF1, 0), + SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF2, 0), + SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF3, 0), + SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF4, 0), + SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF5, 0), SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0), SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0), SH_HWBLK_CLK("meram0", -1, SH_CLK, HWBLK_MERAM, 0), @@ -244,6 +244,36 @@ static struct clk_lookup lookups[] = { .dev_id = "sh_tmu.5", .con_id = "tmu_fck", .clk = &mstp_clks[HWBLK_TMU1], + }, { + /* SCIF0 */ + .dev_id = "sh-sci.0", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF0], + }, { + /* SCIF1 */ + .dev_id = "sh-sci.1", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF1], + }, { + /* SCIF2 */ + .dev_id = "sh-sci.2", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF2], + }, { + /* SCIF3 */ + .dev_id = "sh-sci.3", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF3], + }, { + /* SCIF4 */ + .dev_id = "sh-sci.4", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF4], + }, { + /* SCIF5 */ + .dev_id = "sh-sci.5", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF5], }, }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index c5d4891d38a4..0c2aa34c7847 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -196,12 +196,12 @@ static struct clk mstp_clks[HWBLK_NR] = { SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0), SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0), SH_HWBLK_CLK("tmu345_fck", -1, P_CLK, HWBLK_TMU1, 0), - SH_HWBLK_CLK("sci_fck", 0, P_CLK, HWBLK_SCIF0, 0), - SH_HWBLK_CLK("sci_fck", 1, P_CLK, HWBLK_SCIF1, 0), - SH_HWBLK_CLK("sci_fck", 2, P_CLK, HWBLK_SCIF2, 0), - SH_HWBLK_CLK("sci_fck", 3, B_CLK, HWBLK_SCIF3, 0), - SH_HWBLK_CLK("sci_fck", 4, B_CLK, HWBLK_SCIF4, 0), - SH_HWBLK_CLK("sci_fck", 5, B_CLK, HWBLK_SCIF5, 0), + SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF0, 0), + SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF1, 0), + SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF2, 0), + SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF3, 0), + SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF4, 0), + SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF5, 0), SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0), SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0), @@ -266,6 +266,36 @@ static struct clk_lookup lookups[] = { .dev_id = "sh_tmu.5", .con_id = "tmu_fck", .clk = &mstp_clks[HWBLK_TMU1], + }, { + /* SCIF0 */ + .dev_id = "sh-sci.0", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF0], + }, { + /* SCIF1 */ + .dev_id = "sh-sci.1", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF1], + }, { + /* SCIF2 */ + .dev_id = "sh-sci.2", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF2], + }, { + /* SCIF3 */ + .dev_id = "sh-sci.3", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF3], + }, { + /* SCIF4 */ + .dev_id = "sh-sci.4", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF4], + }, { + /* SCIF5 */ + .dev_id = "sh-sci.5", + .con_id = "sci_fck", + .clk = &mstp_clks[HWBLK_SCIF5], }, }; -- cgit v1.2.3-59-g8ed1b From fd30401b07fdcf21e4be87fd276d1b2c84d712a3 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 May 2010 14:01:22 +0000 Subject: sh: tie in hwblk clocks using clkdev Use clkdev for lookup of hwblk clocks on sh7722/sh7723/sh7724. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 25 ++++++++++++++++- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 48 ++++++++++++++++++++++++++++++-- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 50 +++++++++++++++++++++++++++++++++- 3 files changed, 119 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index ed57c631b09a..2a122e0d3983 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -186,7 +186,12 @@ static struct clk mstp_clks[HWBLK_NR] = { SH_HWBLK_CLK("lcdc0", -1, P_CLK, HWBLK_LCDC, 0), }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + static struct clk_lookup lookups[] = { + /* MSTP clocks */ + CLKDEV_CON_ID("uram0", &mstp_clks[HWBLK_URAM]), + CLKDEV_CON_ID("xymem0", &mstp_clks[HWBLK_XYMEM]), { /* TMU0 */ .dev_id = "sh_tmu.0", @@ -202,7 +207,11 @@ static struct clk_lookup lookups[] = { .dev_id = "sh_tmu.2", .con_id = "tmu_fck", .clk = &mstp_clks[HWBLK_TMU], - }, { + }, + CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]), + CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]), + CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]), + { /* SCIF0 */ .dev_id = "sh-sci.0", .con_id = "sci_fck", @@ -218,6 +227,20 @@ static struct clk_lookup lookups[] = { .con_id = "sci_fck", .clk = &mstp_clks[HWBLK_SCIF2], }, + CLKDEV_CON_ID("i2c0", &mstp_clks[HWBLK_IIC]), + CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]), + CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI]), + CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]), + CLKDEV_CON_ID("usbf0", &mstp_clks[HWBLK_USBF]), + CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]), + CLKDEV_CON_ID("siu0", &mstp_clks[HWBLK_SIU]), + CLKDEV_CON_ID("vou0", &mstp_clks[HWBLK_VOU]), + CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]), + CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]), + CLKDEV_CON_ID("ceu0", &mstp_clks[HWBLK_CEU]), + CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU]), + CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]), + CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]), }; int __init arch_clk_init(void) diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index d92d7cddd099..36e17dc27b0a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -213,7 +213,21 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0), }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + static struct clk_lookup lookups[] = { + /* MSTP clocks */ + CLKDEV_CON_ID("tlb0", &mstp_clks[HWBLK_TLB]), + CLKDEV_CON_ID("ic0", &mstp_clks[HWBLK_IC]), + CLKDEV_CON_ID("oc0", &mstp_clks[HWBLK_OC]), + CLKDEV_CON_ID("l2c0", &mstp_clks[HWBLK_L2C]), + CLKDEV_CON_ID("ilmem0", &mstp_clks[HWBLK_ILMEM]), + CLKDEV_CON_ID("fpu0", &mstp_clks[HWBLK_FPU]), + CLKDEV_CON_ID("intc0", &mstp_clks[HWBLK_INTC]), + CLKDEV_CON_ID("dmac0", &mstp_clks[HWBLK_DMAC0]), + CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]), + CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]), + CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]), { /* TMU0 */ .dev_id = "sh_tmu.0", @@ -229,7 +243,11 @@ static struct clk_lookup lookups[] = { .dev_id = "sh_tmu.2", .con_id = "tmu_fck", .clk = &mstp_clks[HWBLK_TMU0], - }, { + }, + CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]), + CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]), + CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]), + { /* TMU3 */ .dev_id = "sh_tmu.3", .con_id = "tmu_fck", @@ -244,7 +262,9 @@ static struct clk_lookup lookups[] = { .dev_id = "sh_tmu.5", .con_id = "tmu_fck", .clk = &mstp_clks[HWBLK_TMU1], - }, { + }, + CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]), + { /* SCIF0 */ .dev_id = "sh-sci.0", .con_id = "sci_fck", @@ -275,6 +295,30 @@ static struct clk_lookup lookups[] = { .con_id = "sci_fck", .clk = &mstp_clks[HWBLK_SCIF5], }, + CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]), + CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]), + CLKDEV_CON_ID("meram0", &mstp_clks[HWBLK_MERAM]), + CLKDEV_CON_ID("i2c0", &mstp_clks[HWBLK_IIC]), + CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]), + CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]), + CLKDEV_CON_ID("adc0", &mstp_clks[HWBLK_ADC]), + CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]), + CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]), + CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]), + CLKDEV_CON_ID("icb0", &mstp_clks[HWBLK_ICB]), + CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI0]), + CLKDEV_CON_ID("sdhi1", &mstp_clks[HWBLK_SDHI1]), + CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]), + CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB]), + CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]), + CLKDEV_CON_ID("siu0", &mstp_clks[HWBLK_SIU]), + CLKDEV_CON_ID("veu1", &mstp_clks[HWBLK_VEU2H1]), + CLKDEV_CON_ID("vou0", &mstp_clks[HWBLK_VOU]), + CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]), + CLKDEV_CON_ID("ceu0", &mstp_clks[HWBLK_CEU]), + CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU2H0]), + CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]), + CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]), }; int __init arch_clk_init(void) diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 0c2aa34c7847..fe59f34a6e00 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -235,7 +235,22 @@ static struct clk mstp_clks[HWBLK_NR] = { SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0), }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + static struct clk_lookup lookups[] = { + /* MSTP clocks */ + CLKDEV_CON_ID("tlb0", &mstp_clks[HWBLK_TLB]), + CLKDEV_CON_ID("ic0", &mstp_clks[HWBLK_IC]), + CLKDEV_CON_ID("oc0", &mstp_clks[HWBLK_OC]), + CLKDEV_CON_ID("rs0", &mstp_clks[HWBLK_RSMEM]), + CLKDEV_CON_ID("ilmem0", &mstp_clks[HWBLK_ILMEM]), + CLKDEV_CON_ID("l2c0", &mstp_clks[HWBLK_L2C]), + CLKDEV_CON_ID("fpu0", &mstp_clks[HWBLK_FPU]), + CLKDEV_CON_ID("intc0", &mstp_clks[HWBLK_INTC]), + CLKDEV_CON_ID("dmac0", &mstp_clks[HWBLK_DMAC0]), + CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]), + CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]), + CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]), { /* TMU0 */ .dev_id = "sh_tmu.0", @@ -256,7 +271,11 @@ static struct clk_lookup lookups[] = { .dev_id = "sh_tmu.3", .con_id = "tmu_fck", .clk = &mstp_clks[HWBLK_TMU1], - }, { + }, + CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]), + CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]), + CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]), + { /* TMU4 */ .dev_id = "sh_tmu.4", .con_id = "tmu_fck", @@ -297,6 +316,35 @@ static struct clk_lookup lookups[] = { .con_id = "sci_fck", .clk = &mstp_clks[HWBLK_SCIF5], }, + CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]), + CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]), + CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]), + CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]), + CLKDEV_CON_ID("i2c0", &mstp_clks[HWBLK_IIC0]), + CLKDEV_CON_ID("i2c1", &mstp_clks[HWBLK_IIC1]), + CLKDEV_CON_ID("mmc0", &mstp_clks[HWBLK_MMC]), + CLKDEV_CON_ID("eth0", &mstp_clks[HWBLK_ETHER]), + CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]), + CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]), + CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]), + CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]), + CLKDEV_CON_ID("usb1", &mstp_clks[HWBLK_USB1]), + CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB0]), + CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]), + CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI0]), + CLKDEV_CON_ID("sdhi1", &mstp_clks[HWBLK_SDHI1]), + CLKDEV_CON_ID("veu1", &mstp_clks[HWBLK_VEU1]), + CLKDEV_CON_ID("ceu1", &mstp_clks[HWBLK_CEU1]), + CLKDEV_CON_ID("beu1", &mstp_clks[HWBLK_BEU1]), + CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]), + CLKDEV_CON_ID("spu0", &mstp_clks[HWBLK_SPU]), + CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]), + CLKDEV_CON_ID("vou0", &mstp_clks[HWBLK_VOU]), + CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU0]), + CLKDEV_CON_ID("ceu0", &mstp_clks[HWBLK_CEU0]), + CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU0]), + CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]), + CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]), }; int __init arch_clk_init(void) -- cgit v1.2.3-59-g8ed1b From d97432f1014c73bbace9eb1e67742c1bcab0c3cd Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 May 2010 14:01:34 +0000 Subject: sh: allow registering clocks without name Modify the SuperH clock code to support struct clk with NULL as name. Such clocks will not be hooked up to debugfs. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 9ded1bc29260..073f4ffe956a 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -415,7 +415,7 @@ struct clk *clk_get(struct device *dev, const char *id) mutex_lock(&clock_list_sem); list_for_each_entry(p, &clock_list, node) { - if (p->id == idno && + if (p->name && p->id == idno && strcmp(id, p->name) == 0 && try_module_get(p->owner)) { clk = p; goto found; @@ -423,7 +423,8 @@ struct clk *clk_get(struct device *dev, const char *id) } list_for_each_entry(p, &clock_list, node) { - if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + if (p->name && + strcmp(id, p->name) == 0 && try_module_get(p->owner)) { clk = p; break; } @@ -594,7 +595,7 @@ static int clk_debugfs_register(struct clk *c) return err; } - if (!c->dentry) { + if (!c->dentry && c->name) { err = clk_debugfs_register_one(c); if (err) return err; -- cgit v1.2.3-59-g8ed1b From 08134c3c629bf128245f721391b96a858d88e997 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 May 2010 14:01:44 +0000 Subject: sh: get rid of hwblk clock names Remove the clock name from sh7722/sh7723/sh7724 hwblk clocks. Lookup is handled by clkdev. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/hwblk.h | 12 ++-- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 55 ++++++++-------- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 105 ++++++++++++++---------------- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 114 ++++++++++++++++----------------- 4 files changed, 133 insertions(+), 153 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/hwblk.h b/arch/sh/include/asm/hwblk.h index 4984d291ee0b..855e945c6199 100644 --- a/arch/sh/include/asm/hwblk.h +++ b/arch/sh/include/asm/hwblk.h @@ -58,13 +58,11 @@ void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt); void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt); /* allow clocks to enable and disable hardware blocks */ -#define SH_HWBLK_CLK(_name, _id, _parent, _hwblk, _flags) \ -[_hwblk] = { \ - .name = _name, \ - .id = _id, \ - .parent = _parent, \ - .arch_flags = _hwblk, \ - .flags = _flags, \ +#define SH_HWBLK_CLK(_hwblk, _parent, _flags) \ +[_hwblk] = { \ + .parent = _parent, \ + .arch_flags = _hwblk, \ + .flags = _flags, \ } int sh_hwblk_clk_register(struct clk *clks, int nr); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 2a122e0d3983..151bc3e219ac 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -153,37 +153,32 @@ struct clk div6_clks[] = { SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), }; -#define R_CLK &r_clk -#define P_CLK &div4_clks[DIV4_P] -#define B_CLK &div4_clks[DIV4_B] -#define U_CLK &div4_clks[DIV4_U] - static struct clk mstp_clks[HWBLK_NR] = { - SH_HWBLK_CLK("uram0", -1, U_CLK, HWBLK_URAM, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("xymem0", -1, B_CLK, HWBLK_XYMEM, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("tmu_fck", -1, P_CLK, HWBLK_TMU, 0), - SH_HWBLK_CLK("cmt_fck", -1, R_CLK, HWBLK_CMT, 0), - SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0), - SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0), - SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF0, 0), - SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF1, 0), - SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF2, 0), - - SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0), - SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0), - - SH_HWBLK_CLK("sdhi0", -1, P_CLK, HWBLK_SDHI, 0), - SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0), - SH_HWBLK_CLK("usbf0", -1, P_CLK, HWBLK_USBF, 0), - SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0), - SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0), - SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0), - SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, 0), - SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0), - SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0), - SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU, 0), - SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0), - SH_HWBLK_CLK("lcdc0", -1, P_CLK, HWBLK_LCDC, 0), + SH_HWBLK_CLK(HWBLK_URAM, &div4_clks[DIV4_U], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_XYMEM, &div4_clks[DIV4_B], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_TMU, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_CMT, &r_clk, 0), + SH_HWBLK_CLK(HWBLK_RWDT, &r_clk, 0), + SH_HWBLK_CLK(HWBLK_FLCTL, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF0, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF1, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF2, &div4_clks[DIV4_P], 0), + + SH_HWBLK_CLK(HWBLK_IIC, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_RTC, &r_clk, 0), + + SH_HWBLK_CLK(HWBLK_SDHI, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_KEYSC, &r_clk, 0), + SH_HWBLK_CLK(HWBLK_USBF, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_2DG, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SIU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VOU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_JPU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_BEU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_CEU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VEU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VPU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_P], 0), }; #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 36e17dc27b0a..b4331854f57b 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -153,64 +153,57 @@ struct clk div6_clks[] = { SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), }; -#define R_CLK (&r_clk) -#define P_CLK (&div4_clks[DIV4_P]) -#define B_CLK (&div4_clks[DIV4_B]) -#define U_CLK (&div4_clks[DIV4_U]) -#define I_CLK (&div4_clks[DIV4_I]) -#define SH_CLK (&div4_clks[DIV4_SH]) - static struct clk mstp_clks[] = { /* See page 60 of Datasheet V1.0: Overview -> Block Diagram */ - SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("intc0", -1, I_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0), - SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0), - SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0), - SH_HWBLK_CLK("tmu012_fck", -1, P_CLK, HWBLK_TMU0, 0), - SH_HWBLK_CLK("cmt_fck", -1, R_CLK, HWBLK_CMT, 0), - SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0), - SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0), - SH_HWBLK_CLK("tmu345_fck", -1, P_CLK, HWBLK_TMU1, 0), - SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0), - SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF0, 0), - SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF1, 0), - SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF2, 0), - SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF3, 0), - SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF4, 0), - SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF5, 0), - SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0), - SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0), - SH_HWBLK_CLK("meram0", -1, SH_CLK, HWBLK_MERAM, 0), - - SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0), - SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0), - - SH_HWBLK_CLK("atapi0", -1, SH_CLK, HWBLK_ATAPI, 0), - SH_HWBLK_CLK("adc0", -1, P_CLK, HWBLK_ADC, 0), - SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0), - SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0), - SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0), - SH_HWBLK_CLK("icb0", -1, B_CLK, HWBLK_ICB, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0), - SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0), - SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0), - SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB, 0), - SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0), - SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0), - SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU2H1, 0), - SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0), - SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0), - SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0), - SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU2H0, 0), - SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0), - SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0), + SH_HWBLK_CLK(HWBLK_TLB, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_IC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_OC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_L2C, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_ILMEM, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_FPU, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_INTC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_DMAC0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SHYWAY, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_HUDI, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_UBC, &div4_clks[DIV4_I], 0), + SH_HWBLK_CLK(HWBLK_TMU0, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_CMT, &r_clk, 0), + SH_HWBLK_CLK(HWBLK_RWDT, &r_clk, 0), + SH_HWBLK_CLK(HWBLK_DMAC1, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_TMU1, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_FLCTL, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF0, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF1, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF2, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF3, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SCIF4, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SCIF5, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_MSIOF0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_MSIOF1, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_MERAM, &div4_clks[DIV4_SH], 0), + + SH_HWBLK_CLK(HWBLK_IIC, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_RTC, &r_clk, 0), + + SH_HWBLK_CLK(HWBLK_ATAPI, &div4_clks[DIV4_SH], 0), + SH_HWBLK_CLK(HWBLK_ADC, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_TPU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_IRDA, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_TSIF, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_ICB, &div4_clks[DIV4_B], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_SDHI0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SDHI1, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_KEYSC, &r_clk, 0), + SH_HWBLK_CLK(HWBLK_USB, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_2DG, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SIU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VEU2H1, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VOU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_BEU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_CEU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VEU2H0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VPU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_B], 0), }; #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index fe59f34a6e00..6f3d400f2f20 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -172,67 +172,61 @@ struct clk div6_clks[] = { SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT), }; -#define R_CLK (&r_clk) -#define P_CLK (&div4_clks[DIV4_P]) -#define B_CLK (&div4_clks[DIV4_B]) -#define I_CLK (&div4_clks[DIV4_I]) -#define SH_CLK (&div4_clks[DIV4_SH]) - static struct clk mstp_clks[HWBLK_NR] = { - SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("rs0", -1, B_CLK, HWBLK_RSMEM, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("intc0", -1, P_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0), - SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0), - SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0), - SH_HWBLK_CLK("tmu012_fck", -1, P_CLK, HWBLK_TMU0, 0), - SH_HWBLK_CLK("cmt_fck", -1, R_CLK, HWBLK_CMT, 0), - SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0), - SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0), - SH_HWBLK_CLK("tmu345_fck", -1, P_CLK, HWBLK_TMU1, 0), - SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF0, 0), - SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF1, 0), - SH_HWBLK_CLK("sci_fck", -1, P_CLK, HWBLK_SCIF2, 0), - SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF3, 0), - SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF4, 0), - SH_HWBLK_CLK("sci_fck", -1, B_CLK, HWBLK_SCIF5, 0), - SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0), - SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0), - - SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0), - SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0), - SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC0, 0), - SH_HWBLK_CLK("i2c1", -1, P_CLK, HWBLK_IIC1, 0), - - SH_HWBLK_CLK("mmc0", -1, B_CLK, HWBLK_MMC, 0), - SH_HWBLK_CLK("eth0", -1, B_CLK, HWBLK_ETHER, 0), - SH_HWBLK_CLK("atapi0", -1, B_CLK, HWBLK_ATAPI, 0), - SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0), - SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0), - SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0), - SH_HWBLK_CLK("usb1", -1, B_CLK, HWBLK_USB1, 0), - SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB0, 0), - SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0), - SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0), - SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0), - SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU1, 0), - SH_HWBLK_CLK("ceu1", -1, B_CLK, HWBLK_CEU1, 0), - SH_HWBLK_CLK("beu1", -1, B_CLK, HWBLK_BEU1, 0), - SH_HWBLK_CLK("2ddmac0", -1, SH_CLK, HWBLK_2DDMAC, 0), - SH_HWBLK_CLK("spu0", -1, B_CLK, HWBLK_SPU, 0), - SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, 0), - SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0), - SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU0, 0), - SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU0, 0), - SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU0, 0), - SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0), - SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0), + SH_HWBLK_CLK(HWBLK_TLB, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_IC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_OC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_RSMEM, &div4_clks[DIV4_B], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_ILMEM, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_L2C, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_FPU, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_INTC, &div4_clks[DIV4_P], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_DMAC0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SHYWAY, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK(HWBLK_HUDI, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_UBC, &div4_clks[DIV4_I], 0), + SH_HWBLK_CLK(HWBLK_TMU0, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_CMT, &r_clk, 0), + SH_HWBLK_CLK(HWBLK_RWDT, &r_clk, 0), + SH_HWBLK_CLK(HWBLK_DMAC1, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_TMU1, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF0, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF1, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF2, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_SCIF3, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SCIF4, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SCIF5, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_MSIOF0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_MSIOF1, &div4_clks[DIV4_B], 0), + + SH_HWBLK_CLK(HWBLK_KEYSC, &r_clk, 0), + SH_HWBLK_CLK(HWBLK_RTC, &r_clk, 0), + SH_HWBLK_CLK(HWBLK_IIC0, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_IIC1, &div4_clks[DIV4_P], 0), + + SH_HWBLK_CLK(HWBLK_MMC, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_ETHER, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_ATAPI, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_TPU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_IRDA, &div4_clks[DIV4_P], 0), + SH_HWBLK_CLK(HWBLK_TSIF, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_USB1, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_USB0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_2DG, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SDHI0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_SDHI1, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VEU1, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_CEU1, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_BEU1, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_2DDMAC, &div4_clks[DIV4_SH], 0), + SH_HWBLK_CLK(HWBLK_SPU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_JPU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VOU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_BEU0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_CEU0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VEU0, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_VPU, &div4_clks[DIV4_B], 0), + SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_B], 0), }; #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } -- cgit v1.2.3-59-g8ed1b From 098ec49b684313cbd2ba1e24db61cfda9788ff73 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 May 2010 14:01:55 +0000 Subject: sh: tie in div6 clocks using clkdev Use clkdev for div6 lookup on SH-Mobile processors: sh7343/sh7366/sh7722/sh7723/sh7724 Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 18 +++++++++++++++--- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 18 +++++++++++++++--- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 11 ++++++++--- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 11 ++++++++--- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 26 +++++++++++++++++++------- 5 files changed, 65 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index a63cdcaee0b2..9e4992a08e51 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -21,6 +21,7 @@ #include #include #include +#include #include /* SH7343 registers */ @@ -135,8 +136,10 @@ struct clk div4_clks[DIV4_NR] = { [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0), }; -struct clk div6_clks[] = { - SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), +enum { DIV6_V, DIV6_NR }; + +struct clk div6_clks[DIV6_NR] = { + [DIV6_V] = SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), }; #define MSTP(_str, _parent, _reg, _bit, _flags) \ @@ -189,6 +192,13 @@ static struct clk mstp_clks[] = { MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0), }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* DIV6 clocks */ + CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), +}; + int __init arch_clk_init(void) { int k, ret = 0; @@ -202,11 +212,13 @@ int __init arch_clk_init(void) for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) ret = clk_register(main_clks[k]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + if (!ret) ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); if (!ret) - ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); + ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks)); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index f99db94cf8fb..4eeeb240823e 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -21,6 +21,7 @@ #include #include #include +#include #include /* SH7366 registers */ @@ -138,8 +139,10 @@ struct clk div4_clks[DIV4_NR] = { [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0), }; -struct clk div6_clks[] = { - SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), +enum { DIV6_V, DIV6_NR }; + +struct clk div6_clks[DIV6_NR] = { + [DIV6_V] = SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), }; #define MSTP(_str, _parent, _reg, _bit, _flags) \ @@ -189,6 +192,13 @@ static struct clk mstp_clks[] = { MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0), }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* DIV6 clocks */ + CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), +}; + int __init arch_clk_init(void) { int k, ret = 0; @@ -202,11 +212,13 @@ int __init arch_clk_init(void) for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) ret = clk_register(main_clks[k]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + if (!ret) ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); if (!ret) - ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); + ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks)); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 151bc3e219ac..d8a7ad8a83b3 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -149,8 +149,10 @@ struct clk div4_reparent_clks[DIV4_REPARENT_NR] = { [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0), }; -struct clk div6_clks[] = { - SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), +enum { DIV6_V, DIV6_NR }; + +struct clk div6_clks[DIV6_NR] = { + [DIV6_V] = SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), }; static struct clk mstp_clks[HWBLK_NR] = { @@ -184,6 +186,9 @@ static struct clk mstp_clks[HWBLK_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* DIV6 clocks */ + CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), + /* MSTP clocks */ CLKDEV_CON_ID("uram0", &mstp_clks[HWBLK_URAM]), CLKDEV_CON_ID("xymem0", &mstp_clks[HWBLK_XYMEM]), @@ -265,7 +270,7 @@ int __init arch_clk_init(void) DIV4_REPARENT_NR, &div4_table); if (!ret) - ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); + ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index b4331854f57b..edb2414896b1 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -149,8 +149,10 @@ struct clk div4_reparent_clks[DIV4_REPARENT_NR] = { [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0), [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0), }; -struct clk div6_clks[] = { - SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), +enum { DIV6_V, DIV6_NR }; + +struct clk div6_clks[DIV6_NR] = { + [DIV6_V] = SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), }; static struct clk mstp_clks[] = { @@ -209,6 +211,9 @@ static struct clk mstp_clks[] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* DIV6 clocks */ + CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), + /* MSTP clocks */ CLKDEV_CON_ID("tlb0", &mstp_clks[HWBLK_TLB]), CLKDEV_CON_ID("ic0", &mstp_clks[HWBLK_IC]), @@ -341,7 +346,7 @@ int __init arch_clk_init(void) DIV4_REPARENT_NR, &div4_table); if (!ret) - ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); + ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 6f3d400f2f20..ad57c007b05c 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -164,12 +164,17 @@ struct clk div4_clks[DIV4_NR] = { [DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT), }; -struct clk div6_clks[] = { - SH_CLK_DIV6("video_clk", &div3_clk, VCLKCR, 0), - SH_CLK_DIV6("fsia_clk", &div3_clk, FCLKACR, 0), - SH_CLK_DIV6("fsib_clk", &div3_clk, FCLKBCR, 0), - SH_CLK_DIV6("irda_clk", &div3_clk, IRDACLKCR, 0), - SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT), +enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR }; + +#define DIV6(_str, _reg, _flags) \ + SH_CLK_DIV6(_str, &div3_clk, _reg, _flags) + +struct clk div6_clks[DIV6_NR] = { + [DIV6_V] = DIV6("video_clk", VCLKCR, 0), + [DIV6_FA] = DIV6("fsia_clk", FCLKACR, 0), + [DIV6_FB] = DIV6("fsib_clk", FCLKBCR, 0), + [DIV6_I] = DIV6("irda_clk", IRDACLKCR, 0), + [DIV6_S] = DIV6("spu_clk", SPUCLKCR, CLK_ENABLE_ON_INIT), }; static struct clk mstp_clks[HWBLK_NR] = { @@ -232,6 +237,13 @@ static struct clk mstp_clks[HWBLK_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* DIV6 clocks */ + CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), + CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]), + CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FB]), + CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]), + CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]), + /* MSTP clocks */ CLKDEV_CON_ID("tlb0", &mstp_clks[HWBLK_TLB]), CLKDEV_CON_ID("ic0", &mstp_clks[HWBLK_IC]), @@ -360,7 +372,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); if (!ret) - ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); + ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR); -- cgit v1.2.3-59-g8ed1b From 9e1985e13d42b4b66af94637346849565174309d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 May 2010 14:02:09 +0000 Subject: sh: get rid of div6 clock names Get rid of div6 clock names on sh7343/sh7366/sh7722/sh7723/sh7724 Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 11 +++++------ arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 2 +- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 13 +++++-------- 6 files changed, 14 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 4b19179230fe..405a12c09960 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -151,12 +151,11 @@ int sh_clk_div4_enable_register(struct clk *clks, int nr, int sh_clk_div4_reparent_register(struct clk *clks, int nr, struct clk_div4_table *table); -#define SH_CLK_DIV6(_name, _parent, _reg, _flags) \ -{ \ - .name = _name, \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_reg, \ - .flags = _flags, \ +#define SH_CLK_DIV6(_parent, _reg, _flags) \ +{ \ + .parent = _parent, \ + .enable_reg = (void __iomem *)_reg, \ + .flags = _flags, \ } int sh_clk_div6_register(struct clk *clks, int nr); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index 9e4992a08e51..a066c438b404 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -139,7 +139,7 @@ struct clk div4_clks[DIV4_NR] = { enum { DIV6_V, DIV6_NR }; struct clk div6_clks[DIV6_NR] = { - [DIV6_V] = SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), + [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0), }; #define MSTP(_str, _parent, _reg, _bit, _flags) \ diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 4eeeb240823e..44cc5a0965d9 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -142,7 +142,7 @@ struct clk div4_clks[DIV4_NR] = { enum { DIV6_V, DIV6_NR }; struct clk div6_clks[DIV6_NR] = { - [DIV6_V] = SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), + [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0), }; #define MSTP(_str, _parent, _reg, _bit, _flags) \ diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index d8a7ad8a83b3..2798ceaa648f 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -152,7 +152,7 @@ struct clk div4_reparent_clks[DIV4_REPARENT_NR] = { enum { DIV6_V, DIV6_NR }; struct clk div6_clks[DIV6_NR] = { - [DIV6_V] = SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), + [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0), }; static struct clk mstp_clks[HWBLK_NR] = { diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index edb2414896b1..500715f78142 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -152,7 +152,7 @@ struct clk div4_reparent_clks[DIV4_REPARENT_NR] = { enum { DIV6_V, DIV6_NR }; struct clk div6_clks[DIV6_NR] = { - [DIV6_V] = SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), + [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0), }; static struct clk mstp_clks[] = { diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index ad57c007b05c..2bbff53fcd87 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -166,15 +166,12 @@ struct clk div4_clks[DIV4_NR] = { enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR }; -#define DIV6(_str, _reg, _flags) \ - SH_CLK_DIV6(_str, &div3_clk, _reg, _flags) - struct clk div6_clks[DIV6_NR] = { - [DIV6_V] = DIV6("video_clk", VCLKCR, 0), - [DIV6_FA] = DIV6("fsia_clk", FCLKACR, 0), - [DIV6_FB] = DIV6("fsib_clk", FCLKBCR, 0), - [DIV6_I] = DIV6("irda_clk", IRDACLKCR, 0), - [DIV6_S] = DIV6("spu_clk", SPUCLKCR, CLK_ENABLE_ON_INIT), + [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0), + [DIV6_FA] = SH_CLK_DIV6(&div3_clk, FCLKACR, 0), + [DIV6_FB] = SH_CLK_DIV6(&div3_clk, FCLKBCR, 0), + [DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0), + [DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT), }; static struct clk mstp_clks[HWBLK_NR] = { -- cgit v1.2.3-59-g8ed1b From 4f615d575c17195f975cf8314be54f362d859a3f Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Mon, 10 May 2010 14:50:55 +0300 Subject: sh: clkfwk: Use debugfs_remove_recursive() for rewinding Rewinding each debugfs entries to unregister if an error happens. Based on the commit ca4caa4e1d45f9542fa54263974d0ef637157b4a Signed-off-by: Hiroshi DOYU Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 073f4ffe956a..a725c7feb747 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -621,7 +621,7 @@ static int __init clk_debugfs_init(void) } return 0; err_out: - debugfs_remove(clk_debugfs_root); /* REVISIT: Cleanup correctly */ + debugfs_remove_recursive(clk_debugfs_root); return err; } late_initcall(clk_debugfs_init); -- cgit v1.2.3-59-g8ed1b From 4bc277ac9cae60e11fe2e557e4ea4acb56d3dc9a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 11 May 2010 13:32:19 +0900 Subject: sh: bootmem refactoring. This reworks much of the bootmem setup and initialization code allowing us to get rid of duplicate work between the NUMA and non-NUMA cases. The end result is that we end up with a much more flexible interface for supporting more complex topologies (fake NUMA, highmem, etc, etc.) which is entirely LMB backed. This is an incremental step for more NUMA work as well as gradually enabling migration off of bootmem entirely. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmzone.h | 2 + arch/sh/include/asm/setup.h | 1 + arch/sh/kernel/setup.c | 143 ++----------------------------------- arch/sh/mm/init.c | 165 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 169 insertions(+), 142 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/mmzone.h b/arch/sh/include/asm/mmzone.h index 94f04b2f4fb1..8887baff5eff 100644 --- a/arch/sh/include/asm/mmzone.h +++ b/arch/sh/include/asm/mmzone.h @@ -44,6 +44,8 @@ void __init plat_mem_setup(void); /* arch/sh/kernel/setup.c */ void __init __add_active_range(unsigned int nid, unsigned long start_pfn, unsigned long end_pfn); +/* arch/sh/mm/init.c */ +void __init allocate_pgdat(unsigned int nid); #endif /* __KERNEL__ */ #endif /* __ASM_SH_MMZONE_H */ diff --git a/arch/sh/include/asm/setup.h b/arch/sh/include/asm/setup.h index 4758325bb24a..01fa17a3d759 100644 --- a/arch/sh/include/asm/setup.h +++ b/arch/sh/include/asm/setup.h @@ -19,6 +19,7 @@ #define COMMAND_LINE ((char *) (PARAM+0x100)) void sh_mv_setup(void); +void check_for_initrd(void); #endif /* __KERNEL__ */ diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index f6a2db12ad78..61404ed01449 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -114,31 +114,7 @@ static int __init early_parse_mem(char *p) } early_param("mem", early_parse_mem); -/* - * Register fully available low RAM pages with the bootmem allocator. - */ -static void __init register_bootmem_low_pages(void) -{ - unsigned long curr_pfn, last_pfn, pages; - - /* - * We are rounding up the start address of usable memory: - */ - curr_pfn = PFN_UP(__MEMORY_START); - - /* - * ... and at the end of the usable range downwards: - */ - last_pfn = PFN_DOWN(__pa(memory_end)); - - if (last_pfn > max_low_pfn) - last_pfn = max_low_pfn; - - pages = last_pfn - curr_pfn; - free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages)); -} - -static void __init check_for_initrd(void) +void __init check_for_initrd(void) { #ifdef CONFIG_BLK_DEV_INITRD unsigned long start, end; @@ -240,85 +216,6 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn, add_active_range(nid, start_pfn, end_pfn); } -void __init do_init_bootmem(void) -{ - unsigned long bootmap_size; - unsigned long bootmap_pages, bootmem_paddr; - u64 total_pages = lmb_phys_mem_size() >> PAGE_SHIFT; - int i; - - bootmap_pages = bootmem_bootmap_pages(total_pages); - - bootmem_paddr = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE); - - /* - * Find a proper area for the bootmem bitmap. After this - * bootstrap step all allocations (until the page allocator - * is intact) must be done via bootmem_alloc(). - */ - bootmap_size = init_bootmem_node(NODE_DATA(0), - bootmem_paddr >> PAGE_SHIFT, - min_low_pfn, max_low_pfn); - - /* Add active regions with valid PFNs. */ - for (i = 0; i < lmb.memory.cnt; i++) { - unsigned long start_pfn, end_pfn; - start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; - end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); - __add_active_range(0, start_pfn, end_pfn); - } - - /* - * Add all physical memory to the bootmem map and mark each - * area as present. - */ - register_bootmem_low_pages(); - - /* Reserve the sections we're already using. */ - for (i = 0; i < lmb.reserved.cnt; i++) - reserve_bootmem(lmb.reserved.region[i].base, - lmb_size_bytes(&lmb.reserved, i), - BOOTMEM_DEFAULT); - - node_set_online(0); - - sparse_memory_present_with_active_regions(0); -} - -static void __init early_reserve_mem(void) -{ - unsigned long start_pfn; - - /* - * Partially used pages are not usable - thus - * we are rounding upwards: - */ - start_pfn = PFN_UP(__pa(_end)); - - /* - * Reserve the kernel text and - * Reserve the bootmem bitmap. We do this in two steps (first step - * was init_bootmem()), because this catches the (definitely buggy) - * case of us accidentally initializing the bootmem allocator with - * an invalid RAM area. - */ - lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET, - (PFN_PHYS(start_pfn) + PAGE_SIZE - 1) - - (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET)); - - /* - * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET. - */ - if (CONFIG_ZERO_PAGE_OFFSET != 0) - lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET); - - /* - * Handle additional early reservations - */ - check_for_initrd(); - reserve_crashkernel(); -} - /* * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by * is_kdump_kernel() to determine if we are booting after a panic. Hence @@ -342,10 +239,6 @@ void __init __weak plat_early_device_setup(void) { } -void __init __weak plat_mem_setup(void) -{ -} - void __init setup_arch(char **cmdline_p) { enable_mmu(); @@ -401,44 +294,16 @@ void __init setup_arch(char **cmdline_p) plat_early_device_setup(); - /* Let earlyprintk output early console messages */ - early_platform_driver_probe("earlyprintk", 1, 1); - - lmb_init(); - sh_mv_setup(); - sh_mv.mv_mem_init(); - - early_reserve_mem(); - lmb_enforce_memory_limit(memory_limit); - lmb_analyze(); - - lmb_dump_all(); - - /* - * Determine low and high memory ranges: - */ - max_low_pfn = max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; - min_low_pfn = __MEMORY_START >> PAGE_SHIFT; - - nodes_clear(node_online_map); - - memory_start = (unsigned long)__va(__MEMORY_START); - memory_end = memory_start + (memory_limit ?: lmb_phys_mem_size()); + /* Let earlyprintk output early console messages */ + early_platform_driver_probe("earlyprintk", 1, 1); - uncached_init(); - pmb_init(); - do_init_bootmem(); - plat_mem_setup(); - sparse_init(); + paging_init(); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif - paging_init(); - - ioremap_fixed_init(); /* Perform the machine specific initialisation */ if (likely(sh_mv.mv_setup)) diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 9c5400b02f43..7f3cb5254abb 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -17,11 +17,14 @@ #include #include #include +#include #include #include +#include #include #include #include +#include #include #include @@ -33,6 +36,11 @@ void __init generic_mem_init(void) lmb_add(__MEMORY_START, __MEMORY_SIZE); } +void __init __weak plat_mem_setup(void) +{ + /* Nothing to see here, move along. */ +} + #ifdef CONFIG_MMU static pte_t *__get_pte_phys(unsigned long addr) { @@ -158,15 +166,166 @@ void __init page_table_range_init(unsigned long start, unsigned long end, } #endif /* CONFIG_MMU */ -/* - * paging_init() sets up the page tables - */ +void __init allocate_pgdat(unsigned int nid) +{ + unsigned long start_pfn, end_pfn; +#ifdef CONFIG_NEED_MULTIPLE_NODES + unsigned long phys; +#endif + + get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); + +#ifdef CONFIG_NEED_MULTIPLE_NODES + phys = __lmb_alloc_base(sizeof(struct pglist_data), + SMP_CACHE_BYTES, end_pfn << PAGE_SHIFT); + /* Retry with all of system memory */ + if (!phys) + phys = __lmb_alloc_base(sizeof(struct pglist_data), + SMP_CACHE_BYTES, lmb_end_of_DRAM()); + if (!phys) + panic("Can't allocate pgdat for node %d\n", nid); + + NODE_DATA(nid) = __va(phys); + memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); + + NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; +#endif + + NODE_DATA(nid)->node_start_pfn = start_pfn; + NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; +} + +static void __init bootmem_init_one_node(unsigned int nid) +{ + unsigned long total_pages, paddr; + unsigned long end_pfn; + struct pglist_data *p; + int i; + + p = NODE_DATA(nid); + + /* Nothing to do.. */ + if (!p->node_spanned_pages) + return; + + end_pfn = p->node_start_pfn + p->node_spanned_pages; + + total_pages = bootmem_bootmap_pages(p->node_spanned_pages); + + paddr = lmb_alloc(total_pages << PAGE_SHIFT, PAGE_SIZE); + if (!paddr) + panic("Can't allocate bootmap for nid[%d]\n", nid); + + init_bootmem_node(p, paddr >> PAGE_SHIFT, p->node_start_pfn, end_pfn); + + free_bootmem_with_active_regions(nid, end_pfn); + + /* + * XXX Handle initial reservations for the system memory node + * only for the moment, we'll refactor this later for handling + * reservations in other nodes. + */ + if (nid == 0) { + /* Reserve the sections we're already using. */ + for (i = 0; i < lmb.reserved.cnt; i++) + reserve_bootmem(lmb.reserved.region[i].base, + lmb_size_bytes(&lmb.reserved, i), + BOOTMEM_DEFAULT); + } + + sparse_memory_present_with_active_regions(nid); +} + +static void __init do_init_bootmem(void) +{ + int i; + + /* Add active regions with valid PFNs. */ + for (i = 0; i < lmb.memory.cnt; i++) { + unsigned long start_pfn, end_pfn; + start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; + end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); + __add_active_range(0, start_pfn, end_pfn); + } + + /* All of system RAM sits in node 0 for the non-NUMA case */ + allocate_pgdat(0); + node_set_online(0); + + plat_mem_setup(); + + for_each_online_node(i) + bootmem_init_one_node(i); + + sparse_init(); +} + +static void __init early_reserve_mem(void) +{ + unsigned long start_pfn; + + /* + * Partially used pages are not usable - thus + * we are rounding upwards: + */ + start_pfn = PFN_UP(__pa(_end)); + + /* + * Reserve the kernel text and Reserve the bootmem bitmap. We do + * this in two steps (first step was init_bootmem()), because + * this catches the (definitely buggy) case of us accidentally + * initializing the bootmem allocator with an invalid RAM area. + */ + lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET, + (PFN_PHYS(start_pfn) + PAGE_SIZE - 1) - + (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET)); + + /* + * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET. + */ + if (CONFIG_ZERO_PAGE_OFFSET != 0) + lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET); + + /* + * Handle additional early reservations + */ + check_for_initrd(); + reserve_crashkernel(); +} + void __init paging_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES]; unsigned long vaddr, end; int nid; + lmb_init(); + + sh_mv.mv_mem_init(); + + early_reserve_mem(); + + lmb_enforce_memory_limit(memory_limit); + lmb_analyze(); + + lmb_dump_all(); + + /* + * Determine low and high memory ranges: + */ + max_low_pfn = max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; + min_low_pfn = __MEMORY_START >> PAGE_SHIFT; + + nodes_clear(node_online_map); + + memory_start = (unsigned long)__va(__MEMORY_START); + memory_end = memory_start + (memory_limit ?: lmb_phys_mem_size()); + + uncached_init(); + pmb_init(); + do_init_bootmem(); + ioremap_fixed_init(); + /* We don't need to map the kernel through the TLB, as * it is permanatly mapped using P1. So clear the * entire pgd. */ -- cgit v1.2.3-59-g8ed1b From dfbca89987b74c34d9b1a2414b0e5ccee65347e0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 11 May 2010 13:50:29 +0900 Subject: sh: Reject small mappings for PMB bolting. The minimum section size for the PMB is 16M, so just always error out early if the specified size is too small. This permits us to unconditionally call in to pmb_bolt_mapping() with variable sizes without wasting a TLB and cache flush for the range. Signed-off-by: Paul Mundt --- arch/sh/mm/pmb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index e9f5384f3f1c..18623ba751b3 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -341,6 +341,8 @@ int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys, unsigned long flags, pmb_flags; int i, mapped; + if (size < SZ_16M) + return -EINVAL; if (!pmb_addr_valid(vaddr, size)) return -EFAULT; if (pmb_mapping_exists(vaddr, phys, size)) -- cgit v1.2.3-59-g8ed1b From 21823259a70b7a2a21eea1d48c25a6f38896dd11 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 11 May 2010 13:52:50 +0900 Subject: sh: Ensure active regions have a backing PMB entry. In the NUMA or memory hot-add case where system memory has been partitioned up, we immediately run in to a situation where the existing PMB entry doesn't cover the new range (primarily as a result of the entry size being shrunk to match the node size early in the initialization). In order to fix this up it's necessary to preload a PMB mapping for the new range prior to activation in order to circumvent reset by MMU. Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 61404ed01449..57bd93838f15 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -191,13 +191,18 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn, unsigned long end_pfn) { struct resource *res = &mem_resources[nid]; + unsigned long start, end; WARN_ON(res->name); /* max one active range per node for now */ + start = start_pfn << PAGE_SHIFT; + end = end_pfn << PAGE_SHIFT; + res->name = "System RAM"; - res->start = start_pfn << PAGE_SHIFT; - res->end = (end_pfn << PAGE_SHIFT) - 1; + res->start = start; + res->end = end - 1; res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (request_resource(&iomem_resource, res)) { pr_err("unable to request memory_resource 0x%lx 0x%lx\n", start_pfn, end_pfn); @@ -213,6 +218,14 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn, request_resource(res, &data_resource); request_resource(res, &bss_resource); + /* + * Also make sure that there is a PMB mapping that covers this + * range before we attempt to activate it, to avoid reset by MMU. + * We can hit this path with NUMA or memory hot-add. + */ + pmb_bolt_mapping((unsigned long)__va(start), start, end - start, + PAGE_KERNEL); + add_active_range(nid, start_pfn, end_pfn); } -- cgit v1.2.3-59-g8ed1b From 4b478ee2a1251d99813a90afeb0f809b3a8b04fb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 11 May 2010 15:24:04 +0900 Subject: sh: All SH-X3 cores support NUMA and SMP, update Kconfig. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index c2325bd48fd3..67ca505901ff 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -236,6 +236,8 @@ config CPU_SHX2 config CPU_SHX3 bool select DMA_COHERENT + select SYS_SUPPORTS_SMP + select SYS_SUPPORTS_NUMA config ARCH_SHMOBILE bool @@ -452,18 +454,12 @@ config CPU_SUBTYPE_SH7786 select CPU_SH4A select CPU_SHX3 select CPU_HAS_PTEAEX - select ARCH_SPARSEMEM_ENABLE - select SYS_SUPPORTS_NUMA - select SYS_SUPPORTS_SMP select GENERIC_CLOCKEVENTS_BROADCAST if SMP config CPU_SUBTYPE_SHX3 bool "Support SH-X3 processor" select CPU_SH4A select CPU_SHX3 - select ARCH_SPARSEMEM_ENABLE - select SYS_SUPPORTS_NUMA - select SYS_SUPPORTS_SMP select GENERIC_CLOCKEVENTS_BROADCAST if SMP # SH4AL-DSP Processor Support -- cgit v1.2.3-59-g8ed1b From fcef85c0c122f90f57f2f3ef0caeaf6404d6e8f3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 6 May 2010 15:42:23 +0900 Subject: ARM: SAMSUNG: Add spinlock locking to GPIO banks Add locking to each GPIO bank to allow for SMP capable code to use the gpiolib functions. See the gpio-core.h header file for more information. Signed-off-by: Ben Dooks --- arch/arm/plat-samsung/gpio-config.c | 12 ++++++------ arch/arm/plat-samsung/gpio.c | 15 +++++++++------ arch/arm/plat-samsung/include/plat/gpio-core.h | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index 3282db360fa8..a76eef533392 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c @@ -33,9 +33,9 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) offset = pin - chip->chip.base; - local_irq_save(flags); + s3c_gpio_lock(chip, flags); ret = s3c_gpio_do_setcfg(chip, offset, config); - local_irq_restore(flags); + s3c_gpio_unlock(chip, flags); return ret; } @@ -51,9 +51,9 @@ unsigned s3c_gpio_getcfg(unsigned int pin) if (chip) { offset = pin - chip->chip.base; - local_irq_save(flags); + s3c_gpio_lock(chip, flags); ret = s3c_gpio_do_getcfg(chip, offset); - local_irq_restore(flags); + s3c_gpio_unlock(chip, flags); } return ret; @@ -72,9 +72,9 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) offset = pin - chip->chip.base; - local_irq_save(flags); + s3c_gpio_lock(chip, flags); ret = s3c_gpio_do_setpull(chip, offset, pull); - local_irq_restore(flags); + s3c_gpio_unlock(chip, flags); return ret; } diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c index 28d2ab8a08db..b83a83351cea 100644 --- a/arch/arm/plat-samsung/gpio.c +++ b/arch/arm/plat-samsung/gpio.c @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -52,14 +53,14 @@ static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset) unsigned long flags; unsigned long con; - local_irq_save(flags); + s3c_gpio_lock(ourchip, flags); con = __raw_readl(base + 0x00); con &= ~(3 << (offset * 2)); __raw_writel(con, base + 0x00); - local_irq_restore(flags); + s3c_gpio_unlock(ourchip, flags); return 0; } @@ -72,7 +73,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip, unsigned long dat; unsigned long con; - local_irq_save(flags); + s3c_gpio_lock(ourchip, flags); dat = __raw_readl(base + 0x04); dat &= ~(1 << offset); @@ -87,7 +88,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip, __raw_writel(con, base + 0x00); __raw_writel(dat, base + 0x04); - local_irq_restore(flags); + s3c_gpio_unlock(ourchip, flags); return 0; } @@ -99,7 +100,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip, unsigned long flags; unsigned long dat; - local_irq_save(flags); + s3c_gpio_lock(ourchip, flags); dat = __raw_readl(base + 0x04); dat &= ~(1 << offset); @@ -107,7 +108,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip, dat |= 1 << offset; __raw_writel(dat, base + 0x04); - local_irq_restore(flags); + s3c_gpio_unlock(ourchip, flags); } static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset) @@ -131,6 +132,8 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip) BUG_ON(!gc->label); BUG_ON(!gc->ngpio); + spin_lock_init(&chip->lock); + if (!gc->direction_input) gc->direction_input = s3c_gpiolib_input; if (!gc->direction_output) diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h index f0584f26d493..f3a68d1a07b9 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-core.h +++ b/arch/arm/plat-samsung/include/plat/gpio-core.h @@ -44,16 +44,26 @@ struct s3c_gpio_cfg; * @chip: The chip structure to be exported via gpiolib. * @base: The base pointer to the gpio configuration registers. * @config: special function and pull-resistor control information. + * @lock: Lock for exclusive access to this gpio bank. * @pm_save: Save information for suspend/resume support. * * This wrapper provides the necessary information for the Samsung * specific gpios being registered with gpiolib. + * + * The lock protects each gpio bank from multiple access of the shared + * configuration registers, or from reading of data whilst another thread + * is writing to the register set. + * + * Each chip has its own lock to avoid any contention between different + * CPU cores trying to get one lock for different GPIO banks, where each + * bank of GPIO has its own register space and configuration registers. */ struct s3c_gpio_chip { struct gpio_chip chip; struct s3c_gpio_cfg *config; struct s3c_gpio_pm *pm; void __iomem *base; + spinlock_t lock; #ifdef CONFIG_PM u32 pm_save[4]; #endif @@ -138,3 +148,7 @@ extern struct s3c_gpio_pm s3c_gpio_pm_4bit; #define __gpio_pm(x) NULL #endif /* CONFIG_PM */ + +/* locking wrappers to deal with multiple access to the same gpio bank */ +#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl) +#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl) -- cgit v1.2.3-59-g8ed1b From 8e6d5573af55435160d329f6ae3fe16a0abbdaec Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Sat, 8 May 2010 20:28:41 +1000 Subject: perf, powerpc: Implement group scheduling transactional APIs [paulus@samba.org: Set cpuhw->event[i]->hw.config in power_pmu_commit_txn.] Signed-off-by: Lin Ming Signed-off-by: Paul Mackerras Signed-off-by: Peter Zijlstra LKML-Reference: <20100508102841.GA10650@brick.ozlabs.ibm.com> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_event.c | 129 +++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 61 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index 08460a2e9f41..43b83c35cf54 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c @@ -35,6 +35,9 @@ struct cpu_hw_events { u64 alternatives[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES]; unsigned long amasks[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES]; unsigned long avalues[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES]; + + unsigned int group_flag; + int n_txn_start; }; DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); @@ -718,66 +721,6 @@ static int collect_events(struct perf_event *group, int max_count, return n; } -static void event_sched_in(struct perf_event *event) -{ - event->state = PERF_EVENT_STATE_ACTIVE; - event->oncpu = smp_processor_id(); - event->tstamp_running += event->ctx->time - event->tstamp_stopped; - if (is_software_event(event)) - event->pmu->enable(event); -} - -/* - * Called to enable a whole group of events. - * Returns 1 if the group was enabled, or -EAGAIN if it could not be. - * Assumes the caller has disabled interrupts and has - * frozen the PMU with hw_perf_save_disable. - */ -int hw_perf_group_sched_in(struct perf_event *group_leader, - struct perf_cpu_context *cpuctx, - struct perf_event_context *ctx) -{ - struct cpu_hw_events *cpuhw; - long i, n, n0; - struct perf_event *sub; - - if (!ppmu) - return 0; - cpuhw = &__get_cpu_var(cpu_hw_events); - n0 = cpuhw->n_events; - n = collect_events(group_leader, ppmu->n_counter - n0, - &cpuhw->event[n0], &cpuhw->events[n0], - &cpuhw->flags[n0]); - if (n < 0) - return -EAGAIN; - if (check_excludes(cpuhw->event, cpuhw->flags, n0, n)) - return -EAGAIN; - i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n + n0); - if (i < 0) - return -EAGAIN; - cpuhw->n_events = n0 + n; - cpuhw->n_added += n; - - /* - * OK, this group can go on; update event states etc., - * and enable any software events - */ - for (i = n0; i < n0 + n; ++i) - cpuhw->event[i]->hw.config = cpuhw->events[i]; - cpuctx->active_oncpu += n; - n = 1; - event_sched_in(group_leader); - list_for_each_entry(sub, &group_leader->sibling_list, group_entry) { - if (sub->state != PERF_EVENT_STATE_OFF) { - event_sched_in(sub); - ++n; - } - } - ctx->nr_active += n; - - return 1; -} - /* * Add a event to the PMU. * If all events are not already frozen, then we disable and @@ -805,12 +748,22 @@ static int power_pmu_enable(struct perf_event *event) cpuhw->event[n0] = event; cpuhw->events[n0] = event->hw.config; cpuhw->flags[n0] = event->hw.event_base; + + /* + * If group events scheduling transaction was started, + * skip the schedulability test here, it will be peformed + * at commit time(->commit_txn) as a whole + */ + if (cpuhw->group_flag & PERF_EVENT_TXN_STARTED) + goto nocheck; + if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1)) goto out; if (power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n0 + 1)) goto out; - event->hw.config = cpuhw->events[n0]; + +nocheck: ++cpuhw->n_events; ++cpuhw->n_added; @@ -896,11 +849,65 @@ static void power_pmu_unthrottle(struct perf_event *event) local_irq_restore(flags); } +/* + * Start group events scheduling transaction + * Set the flag to make pmu::enable() not perform the + * schedulability test, it will be performed at commit time + */ +void power_pmu_start_txn(const struct pmu *pmu) +{ + struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + + cpuhw->group_flag |= PERF_EVENT_TXN_STARTED; + cpuhw->n_txn_start = cpuhw->n_events; +} + +/* + * Stop group events scheduling transaction + * Clear the flag and pmu::enable() will perform the + * schedulability test. + */ +void power_pmu_cancel_txn(const struct pmu *pmu) +{ + struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + + cpuhw->group_flag &= ~PERF_EVENT_TXN_STARTED; +} + +/* + * Commit group events scheduling transaction + * Perform the group schedulability test as a whole + * Return 0 if success + */ +int power_pmu_commit_txn(const struct pmu *pmu) +{ + struct cpu_hw_events *cpuhw; + long i, n; + + if (!ppmu) + return -EAGAIN; + cpuhw = &__get_cpu_var(cpu_hw_events); + n = cpuhw->n_events; + if (check_excludes(cpuhw->event, cpuhw->flags, 0, n)) + return -EAGAIN; + i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n); + if (i < 0) + return -EAGAIN; + + for (i = cpuhw->n_txn_start; i < n; ++i) + cpuhw->event[i]->hw.config = cpuhw->events[i]; + + return 0; +} + struct pmu power_pmu = { .enable = power_pmu_enable, .disable = power_pmu_disable, .read = power_pmu_read, .unthrottle = power_pmu_unthrottle, + .start_txn = power_pmu_start_txn, + .cancel_txn = power_pmu_cancel_txn, + .commit_txn = power_pmu_commit_txn, }; /* -- cgit v1.2.3-59-g8ed1b From a52357259680fe5368c2fabf5949209e231f2aa2 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Tue, 11 May 2010 17:12:33 +0200 Subject: x86/amd-iommu: Add amd_iommu=off command line option This patch adds a command line option to tell the AMD IOMMU driver to not initialize any IOMMU it finds. Signed-off-by: Joerg Roedel --- Documentation/kernel-parameters.txt | 2 ++ arch/x86/kernel/amd_iommu_init.c | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 839b21b0699a..0c6c56076d19 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -324,6 +324,8 @@ and is between 256 and 4096 characters. It is defined in the file they are unmapped. Otherwise they are flushed before they will be reused, which is a lot of faster + off - do not initialize any AMD IOMMU found in + the system amijoy.map= [HW,JOY] Amiga joystick support Map of devices attached to JOY0DAT and JOY1DAT diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 6360abf993d4..3bacb4d0844c 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -120,6 +120,7 @@ struct ivmd_header { bool amd_iommu_dump; static int __initdata amd_iommu_detected; +static bool __initdata amd_iommu_disabled; u16 amd_iommu_last_bdf; /* largest PCI device id we have to handle */ @@ -1372,6 +1373,9 @@ void __init amd_iommu_detect(void) if (no_iommu || (iommu_detected && !gart_iommu_aperture)) return; + if (amd_iommu_disabled) + return; + if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) { iommu_detected = 1; amd_iommu_detected = 1; @@ -1401,6 +1405,8 @@ static int __init parse_amd_iommu_options(char *str) for (; *str; ++str) { if (strncmp(str, "fullflush", 9) == 0) amd_iommu_unmap_flush = true; + if (strncmp(str, "off", 3) == 0) + amd_iommu_disabled = true; } return 1; -- cgit v1.2.3-59-g8ed1b From 639b91a364fafea24fc1d2e8853c12ce45d4ceea Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 15 Mar 2010 22:39:27 +0800 Subject: [ARM] pxa: remove now un-used corgi_ssp.c and corgi_lcd.c The only use of corgi_ssp.c is corgi_ts.c, which is now deprecated and removed. Remove corgi_ssp.c and corgi_lcd.c and their relevant function declarations and data structures. Signed-off-by: Eric Miao Cc: Richard Purdie Cc: Pavel Machek --- Documentation/feature-removal-schedule.txt | 12 -- arch/arm/mach-pxa/Kconfig | 9 - arch/arm/mach-pxa/Makefile | 1 - arch/arm/mach-pxa/corgi_lcd.c | 288 ----------------------------- arch/arm/mach-pxa/corgi_ssp.c | 274 --------------------------- arch/arm/mach-pxa/include/mach/corgi.h | 1 - arch/arm/mach-pxa/sharpsl.h | 23 --- 7 files changed, 608 deletions(-) delete mode 100644 arch/arm/mach-pxa/corgi_lcd.c delete mode 100644 arch/arm/mach-pxa/corgi_ssp.c (limited to 'arch') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 05df0b7514b6..6237d74be86d 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -531,18 +531,6 @@ Who: Eric Miao ---------------------------- -What: corgi_ssp and corgi_ts driver -When: 2.6.35 -Files: arch/arm/mach-pxa/corgi_ssp.c, drivers/input/touchscreen/corgi_ts.c -Why: The corgi touchscreen is now deprecated in favour of the generic - ads7846.c driver. The noise reduction technique used in corgi_ts.c, - that's to wait till vsync before ADC sampling, is also integrated into - ads7846 driver now. Provided that the original driver is not generic - and is difficult to maintain, it will be removed later. -Who: Eric Miao - ----------------------------- - What: capifs When: February 2011 Files: drivers/isdn/capi/capifs.* diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 5b6ee46fa7f6..089579fda6c5 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -461,15 +461,6 @@ config SHARPSL_PM_MAX1111 select HWMON select SENSORS_MAX1111 -config CORGI_SSP_DEPRECATED - bool - select PXA_SSP - select PXA_SSP_LEGACY - help - This option will include corgi_ssp.c and corgi_lcd.c - that corgi_ts.c and other legacy drivers (corgi_bl.c - and sharpsl_pm.c) may depend on. - config MACH_POODLE bool "Enable Sharp SL-5600 (Poodle) Support" depends on PXA_SHARPSL diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 86bc87b7f2dd..a83aff386fba 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -80,7 +80,6 @@ obj-$(CONFIG_MACH_PALMLD) += palmld.o obj-$(CONFIG_PALM_TREO) += palmtreo.o obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o sharpsl_pm.o corgi_pm.o obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o sharpsl_pm.o spitz_pm.o -obj-$(CONFIG_CORGI_SSP_DEPRECATED) += corgi_ssp.o corgi_lcd.o obj-$(CONFIG_MACH_POODLE) += poodle.o obj-$(CONFIG_MACH_TOSA) += tosa.o obj-$(CONFIG_MACH_ICONTROL) += icontrol.o mxm8x10.o diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c deleted file mode 100644 index d9b96319d498..000000000000 --- a/arch/arm/mach-pxa/corgi_lcd.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/corgi_lcd.c - * - * Corgi/Spitz LCD Specific Code - * - * Copyright (C) 2005 Richard Purdie - * - * Connectivity: - * Corgi - LCD to ATI Imageon w100 (Wallaby) - * Spitz - LCD to PXA Framebuffer - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "generic.h" - -/* Register Addresses */ -#define RESCTL_ADRS 0x00 -#define PHACTRL_ADRS 0x01 -#define DUTYCTRL_ADRS 0x02 -#define POWERREG0_ADRS 0x03 -#define POWERREG1_ADRS 0x04 -#define GPOR3_ADRS 0x05 -#define PICTRL_ADRS 0x06 -#define POLCTRL_ADRS 0x07 - -/* Register Bit Definitions */ -#define RESCTL_QVGA 0x01 -#define RESCTL_VGA 0x00 - -#define POWER1_VW_ON 0x01 /* VW Supply FET ON */ -#define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */ -#define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */ - -#define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */ -#define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */ -#define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */ - -#define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */ -#define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */ -#define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */ -#define POWER0_COM_ON 0x08 /* COM Power Supply ON */ -#define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */ - -#define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */ -#define POWER0_COM_OFF 0x00 /* COM Power Supply OFF */ -#define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */ - -#define PICTRL_INIT_STATE 0x01 -#define PICTRL_INIOFF 0x02 -#define PICTRL_POWER_DOWN 0x04 -#define PICTRL_COM_SIGNAL_OFF 0x08 -#define PICTRL_DAC_SIGNAL_OFF 0x10 - -#define POLCTRL_SYNC_POL_FALL 0x01 -#define POLCTRL_EN_POL_FALL 0x02 -#define POLCTRL_DATA_POL_FALL 0x04 -#define POLCTRL_SYNC_ACT_H 0x08 -#define POLCTRL_EN_ACT_L 0x10 - -#define POLCTRL_SYNC_POL_RISE 0x00 -#define POLCTRL_EN_POL_RISE 0x00 -#define POLCTRL_DATA_POL_RISE 0x00 -#define POLCTRL_SYNC_ACT_L 0x00 -#define POLCTRL_EN_ACT_H 0x00 - -#define PHACTRL_PHASE_MANUAL 0x01 -#define DEFAULT_PHAD_QVGA (9) -#define DEFAULT_COMADJ (125) - -/* - * This is only a psuedo I2C interface. We can't use the standard kernel - * routines as the interface is write only. We just assume the data is acked... - */ -static void lcdtg_ssp_i2c_send(u8 data) -{ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, data); - udelay(10); -} - -static void lcdtg_i2c_send_bit(u8 data) -{ - lcdtg_ssp_i2c_send(data); - lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK); - lcdtg_ssp_i2c_send(data); -} - -static void lcdtg_i2c_send_start(u8 base) -{ - lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT); - lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK); - lcdtg_ssp_i2c_send(base); -} - -static void lcdtg_i2c_send_stop(u8 base) -{ - lcdtg_ssp_i2c_send(base); - lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK); - lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT); -} - -static void lcdtg_i2c_send_byte(u8 base, u8 data) -{ - int i; - for (i = 0; i < 8; i++) { - if (data & 0x80) - lcdtg_i2c_send_bit(base | POWER0_COM_DOUT); - else - lcdtg_i2c_send_bit(base); - data <<= 1; - } -} - -static void lcdtg_i2c_wait_ack(u8 base) -{ - lcdtg_i2c_send_bit(base); -} - -static void lcdtg_set_common_voltage(u8 base_data, u8 data) -{ - /* Set Common Voltage to M62332FP via I2C */ - lcdtg_i2c_send_start(base_data); - lcdtg_i2c_send_byte(base_data, 0x9c); - lcdtg_i2c_wait_ack(base_data); - lcdtg_i2c_send_byte(base_data, 0x00); - lcdtg_i2c_wait_ack(base_data); - lcdtg_i2c_send_byte(base_data, data); - lcdtg_i2c_wait_ack(base_data); - lcdtg_i2c_send_stop(base_data); -} - -/* Set Phase Adjust */ -static void lcdtg_set_phadadj(int mode) -{ - int adj; - switch(mode) { - case 480: - case 640: - /* Setting for VGA */ - adj = sharpsl_param.phadadj; - if (adj < 0) { - adj = PHACTRL_PHASE_MANUAL; - } else { - adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL; - } - break; - case 240: - case 320: - default: - /* Setting for QVGA */ - adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL; - break; - } - - corgi_ssp_lcdtg_send(PHACTRL_ADRS, adj); -} - -static int lcd_inited; - -void corgi_lcdtg_hw_init(int mode) -{ - if (!lcd_inited) { - int comadj; - - /* Initialize Internal Logic & Port */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE - | PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF); - - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF - | POWER0_COM_OFF | POWER0_VCC5_OFF); - - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF); - - /* VDD(+8V), SVSS(-4V) ON */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON); - mdelay(3); - - /* DAC ON */ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON - | POWER0_COM_OFF | POWER0_VCC5_OFF); - - /* INIB = H, INI = L */ - /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF); - - /* Set Common Voltage */ - comadj = sharpsl_param.comadj; - if (comadj < 0) - comadj = DEFAULT_COMADJ; - lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj); - - /* VCC5 ON, DAC ON */ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON | - POWER0_COM_OFF | POWER0_VCC5_ON); - - /* GVSS(-8V) ON, VDD ON */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON); - mdelay(2); - - /* COM SIGNAL ON (PICTL[3] = L) */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE); - - /* COM ON, DAC ON, VCC5_ON */ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON - | POWER0_COM_ON | POWER0_VCC5_ON); - - /* VW ON, GVSS ON, VDD ON */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON); - - /* Signals output enable */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, 0); - - /* Set Phase Adjust */ - lcdtg_set_phadadj(mode); - - /* Initialize for Input Signals from ATI */ - corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE - | POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H); - udelay(1000); - - lcd_inited=1; - } else { - lcdtg_set_phadadj(mode); - } - - switch(mode) { - case 480: - case 640: - /* Set Lcd Resolution (VGA) */ - corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_VGA); - break; - case 240: - case 320: - default: - /* Set Lcd Resolution (QVGA) */ - corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_QVGA); - break; - } -} - -void corgi_lcdtg_suspend(void) -{ - /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */ - mdelay(34); - - /* (1)VW OFF */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON); - - /* (2)COM OFF */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF); - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON); - - /* (3)Set Common Voltage Bias 0V */ - lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0); - - /* (4)GVSS OFF */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON); - - /* (5)VCC5 OFF */ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF); - - /* (6)Set PDWN, INIOFF, DACOFF */ - corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF | - PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF); - - /* (7)DAC OFF */ - corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF); - - /* (8)VDD OFF */ - corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF); - - lcd_inited = 0; -} - diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c deleted file mode 100644 index 9347254f8bcf..000000000000 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * SSP control code for Sharp Corgi devices - * - * Copyright (c) 2004-2005 Richard Purdie - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "sharpsl.h" - -static DEFINE_SPINLOCK(corgi_ssp_lock); -static struct ssp_dev corgi_ssp_dev; -static struct ssp_state corgi_ssp_state; -static struct corgissp_machinfo *ssp_machinfo; - -/* - * There are three devices connected to the SSP interface: - * 1. A touchscreen controller (TI ADS7846 compatible) - * 2. An LCD controller (with some Backlight functionality) - * 3. A battery monitoring IC (Maxim MAX1111) - * - * Each device uses a different speed/mode of communication. - * - * The touchscreen is very sensitive and the most frequently used - * so the port is left configured for this. - * - * Devices are selected using Chip Selects on GPIOs. - */ - -/* - * ADS7846 Routines - */ -unsigned long corgi_ssp_ads7846_putget(ulong data) -{ - unsigned long flag; - u32 ret = 0; - - spin_lock_irqsave(&corgi_ssp_lock, flag); - if (ssp_machinfo->cs_ads7846 >= 0) - GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); - - ssp_write_word(&corgi_ssp_dev,data); - ssp_read_word(&corgi_ssp_dev, &ret); - - if (ssp_machinfo->cs_ads7846 >= 0) - GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); - spin_unlock_irqrestore(&corgi_ssp_lock, flag); - - return ret; -} - -/* - * NOTE: These functions should always be called in interrupt context - * and use the _lock and _unlock functions. They are very time sensitive. - */ -void corgi_ssp_ads7846_lock(void) -{ - spin_lock(&corgi_ssp_lock); - if (ssp_machinfo->cs_ads7846 >= 0) - GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); -} - -void corgi_ssp_ads7846_unlock(void) -{ - if (ssp_machinfo->cs_ads7846 >= 0) - GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); - spin_unlock(&corgi_ssp_lock); -} - -void corgi_ssp_ads7846_put(ulong data) -{ - ssp_write_word(&corgi_ssp_dev,data); -} - -unsigned long corgi_ssp_ads7846_get(void) -{ - u32 ret = 0; - ssp_read_word(&corgi_ssp_dev, &ret); - return ret; -} - -EXPORT_SYMBOL(corgi_ssp_ads7846_putget); -EXPORT_SYMBOL(corgi_ssp_ads7846_lock); -EXPORT_SYMBOL(corgi_ssp_ads7846_unlock); -EXPORT_SYMBOL(corgi_ssp_ads7846_put); -EXPORT_SYMBOL(corgi_ssp_ads7846_get); - - -/* - * LCD/Backlight Routines - */ -unsigned long corgi_ssp_dac_put(ulong data) -{ - unsigned long flag, sscr1 = SSCR1_SPH; - u32 tmp; - - spin_lock_irqsave(&corgi_ssp_lock, flag); - - if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) - sscr1 = 0; - - ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon)); - ssp_enable(&corgi_ssp_dev); - - if (ssp_machinfo->cs_lcdcon >= 0) - GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); - ssp_write_word(&corgi_ssp_dev,data); - /* Read null data back from device to prevent SSP overflow */ - ssp_read_word(&corgi_ssp_dev, &tmp); - if (ssp_machinfo->cs_lcdcon >= 0) - GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); - - ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); - ssp_enable(&corgi_ssp_dev); - - spin_unlock_irqrestore(&corgi_ssp_lock, flag); - - return 0; -} - -void corgi_ssp_lcdtg_send(u8 adrs, u8 data) -{ - corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f)); -} - -void corgi_ssp_blduty_set(int duty) -{ - corgi_ssp_lcdtg_send(0x02,duty); -} - -EXPORT_SYMBOL(corgi_ssp_lcdtg_send); -EXPORT_SYMBOL(corgi_ssp_blduty_set); - -/* - * Max1111 Routines - */ -int corgi_ssp_max1111_get(ulong data) -{ - unsigned long flag; - long voltage = 0, voltage1 = 0, voltage2 = 0; - - spin_lock_irqsave(&corgi_ssp_lock, flag); - if (ssp_machinfo->cs_max1111 >= 0) - GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); - ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111)); - ssp_enable(&corgi_ssp_dev); - - udelay(1); - - /* TB1/RB1 */ - ssp_write_word(&corgi_ssp_dev,data); - ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */ - - /* TB12/RB2 */ - ssp_write_word(&corgi_ssp_dev,0); - ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); - - /* TB13/RB3*/ - ssp_write_word(&corgi_ssp_dev,0); - ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2); - - ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); - ssp_enable(&corgi_ssp_dev); - if (ssp_machinfo->cs_max1111 >= 0) - GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); - spin_unlock_irqrestore(&corgi_ssp_lock, flag); - - if (voltage1 & 0xc0 || voltage2 & 0x3f) - voltage = -1; - else - voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03); - - return voltage; -} - -EXPORT_SYMBOL(corgi_ssp_max1111_get); - -/* - * Support Routines - */ - -void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo) -{ - ssp_machinfo = machinfo; -} - -static int __devinit corgi_ssp_probe(struct platform_device *dev) -{ - int ret; - - /* Chip Select - Disable All */ - if (ssp_machinfo->cs_lcdcon >= 0) - pxa_gpio_mode(ssp_machinfo->cs_lcdcon | GPIO_OUT | GPIO_DFLT_HIGH); - if (ssp_machinfo->cs_max1111 >= 0) - pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH); - if (ssp_machinfo->cs_ads7846 >= 0) - pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH); - - ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0); - - if (ret) - printk(KERN_ERR "Unable to register SSP handler!\n"); - else { - ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); - ssp_enable(&corgi_ssp_dev); - } - - return ret; -} - -static int corgi_ssp_remove(struct platform_device *dev) -{ - ssp_exit(&corgi_ssp_dev); - return 0; -} - -static int corgi_ssp_suspend(struct platform_device *dev, pm_message_t state) -{ - ssp_flush(&corgi_ssp_dev); - ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state); - - return 0; -} - -static int corgi_ssp_resume(struct platform_device *dev) -{ - if (ssp_machinfo->cs_lcdcon >= 0) - GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ - if (ssp_machinfo->cs_max1111 >= 0) - GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ - if (ssp_machinfo->cs_ads7846 >= 0) - GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ - ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state); - ssp_enable(&corgi_ssp_dev); - - return 0; -} - -static struct platform_driver corgissp_driver = { - .probe = corgi_ssp_probe, - .remove = corgi_ssp_remove, - .suspend = corgi_ssp_suspend, - .resume = corgi_ssp_resume, - .driver = { - .name = "corgi-ssp", - }, -}; - -int __init corgi_ssp_init(void) -{ - return platform_driver_register(&corgissp_driver); -} - -arch_initcall(corgi_ssp_init); diff --git a/arch/arm/mach-pxa/include/mach/corgi.h b/arch/arm/mach-pxa/include/mach/corgi.h index 7239281788de..585970ef08ce 100644 --- a/arch/arm/mach-pxa/include/mach/corgi.h +++ b/arch/arm/mach-pxa/include/mach/corgi.h @@ -113,7 +113,6 @@ * Shared data structures */ extern struct platform_device corgiscoop_device; -extern struct platform_device corgissp_device; #endif /* __ASM_ARCH_CORGI_H */ diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h index 1439785d3979..0cc1203c5bef 100644 --- a/arch/arm/mach-pxa/sharpsl.h +++ b/arch/arm/mach-pxa/sharpsl.h @@ -9,29 +9,6 @@ #include -/* - * SharpSL SSP Driver - */ -struct corgissp_machinfo { - int port; - int cs_lcdcon; - int cs_ads7846; - int cs_max1111; - int clk_lcdcon; - int clk_ads7846; - int clk_max1111; -}; - -void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo); - - -/* - * SharpSL/Corgi LCD Driver - */ -void corgi_lcdtg_suspend(void); -void corgi_lcdtg_hw_init(int mode); - - /* * SharpSL Battery/PM Driver */ -- cgit v1.2.3-59-g8ed1b From 793ffb9ed3179906760874689a99d4863d76914e Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 16 Mar 2010 14:44:05 +0800 Subject: [ARM] pxa: remove the now legacy SSP API Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 5 - arch/arm/mach-pxa/include/mach/ssp.h | 35 ----- arch/arm/mach-pxa/ssp.c | 286 ----------------------------------- 3 files changed, 326 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 089579fda6c5..8f7eb12776a9 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -653,11 +653,6 @@ config PXA_SSP help Enable support for PXA2xx SSP ports -config PXA_SSP_LEGACY - bool - help - Support of legacy SSP API - config TOSA_BT tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" depends on MACH_TOSA diff --git a/arch/arm/mach-pxa/include/mach/ssp.h b/arch/arm/mach-pxa/include/mach/ssp.h index be1be5b6db51..8470a73d18b9 100644 --- a/arch/arm/mach-pxa/include/mach/ssp.h +++ b/arch/arm/mach-pxa/include/mach/ssp.h @@ -46,41 +46,6 @@ struct ssp_device { int drcmr_tx; }; -#ifdef CONFIG_PXA_SSP_LEGACY -/* - * SSP initialisation flags - */ -#define SSP_NO_IRQ 0x1 /* don't register an irq handler in SSP driver */ - -struct ssp_state { - u32 cr0; - u32 cr1; - u32 to; - u32 psp; -}; - -struct ssp_dev { - struct ssp_device *ssp; - u32 port; - u32 mode; - u32 flags; - u32 psp_flags; - u32 speed; - int irq; -}; - -int ssp_write_word(struct ssp_dev *dev, u32 data); -int ssp_read_word(struct ssp_dev *dev, u32 *data); -int ssp_flush(struct ssp_dev *dev); -void ssp_enable(struct ssp_dev *dev); -void ssp_disable(struct ssp_dev *dev); -void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp); -void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp); -int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags); -int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed); -void ssp_exit(struct ssp_dev *dev); -#endif /* CONFIG_PXA_SSP_LEGACY */ - /** * ssp_write_reg - Write to a SSP register * diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c index a81d6dbf662d..6e7df7af61e1 100644 --- a/arch/arm/mach-pxa/ssp.c +++ b/arch/arm/mach-pxa/ssp.c @@ -35,278 +35,6 @@ #include #include -#ifdef CONFIG_PXA_SSP_LEGACY - -#define TIMEOUT 100000 - -static irqreturn_t ssp_interrupt(int irq, void *dev_id) -{ - struct ssp_dev *dev = dev_id; - struct ssp_device *ssp = dev->ssp; - unsigned int status; - - status = __raw_readl(ssp->mmio_base + SSSR); - __raw_writel(status, ssp->mmio_base + SSSR); - - if (status & SSSR_ROR) - printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port); - - if (status & SSSR_TUR) - printk(KERN_WARNING "SSP(%d): transmitter underrun\n", dev->port); - - if (status & SSSR_BCE) - printk(KERN_WARNING "SSP(%d): bit count error\n", dev->port); - - return IRQ_HANDLED; -} - -/** - * ssp_write_word - write a word to the SSP port - * @data: 32-bit, MSB justified data to write. - * - * Wait for a free entry in the SSP transmit FIFO, and write a data - * word to the SSP port. - * - * The caller is expected to perform the necessary locking. - * - * Returns: - * %-ETIMEDOUT timeout occurred - * 0 success - */ -int ssp_write_word(struct ssp_dev *dev, u32 data) -{ - struct ssp_device *ssp = dev->ssp; - int timeout = TIMEOUT; - - while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_TNF)) { - if (!--timeout) - return -ETIMEDOUT; - cpu_relax(); - } - - __raw_writel(data, ssp->mmio_base + SSDR); - - return 0; -} - -/** - * ssp_read_word - read a word from the SSP port - * - * Wait for a data word in the SSP receive FIFO, and return the - * received data. Data is LSB justified. - * - * Note: Currently, if data is not expected to be received, this - * function will wait for ever. - * - * The caller is expected to perform the necessary locking. - * - * Returns: - * %-ETIMEDOUT timeout occurred - * 32-bit data success - */ -int ssp_read_word(struct ssp_dev *dev, u32 *data) -{ - struct ssp_device *ssp = dev->ssp; - int timeout = TIMEOUT; - - while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE)) { - if (!--timeout) - return -ETIMEDOUT; - cpu_relax(); - } - - *data = __raw_readl(ssp->mmio_base + SSDR); - return 0; -} - -/** - * ssp_flush - flush the transmit and receive FIFOs - * - * Wait for the SSP to idle, and ensure that the receive FIFO - * is empty. - * - * The caller is expected to perform the necessary locking. - */ -int ssp_flush(struct ssp_dev *dev) -{ - struct ssp_device *ssp = dev->ssp; - int timeout = TIMEOUT * 2; - - /* ensure TX FIFO is empty instead of not full */ - if (cpu_is_pxa3xx()) { - while (__raw_readl(ssp->mmio_base + SSSR) & 0xf00) { - if (!--timeout) - return -ETIMEDOUT; - cpu_relax(); - } - timeout = TIMEOUT * 2; - } - - do { - while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE) { - if (!--timeout) - return -ETIMEDOUT; - (void)__raw_readl(ssp->mmio_base + SSDR); - } - if (!--timeout) - return -ETIMEDOUT; - } while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_BSY); - - return 0; -} - -/** - * ssp_enable - enable the SSP port - * - * Turn on the SSP port. - */ -void ssp_enable(struct ssp_dev *dev) -{ - struct ssp_device *ssp = dev->ssp; - uint32_t sscr0; - - sscr0 = __raw_readl(ssp->mmio_base + SSCR0); - sscr0 |= SSCR0_SSE; - __raw_writel(sscr0, ssp->mmio_base + SSCR0); -} - -/** - * ssp_disable - shut down the SSP port - * - * Turn off the SSP port, optionally powering it down. - */ -void ssp_disable(struct ssp_dev *dev) -{ - struct ssp_device *ssp = dev->ssp; - uint32_t sscr0; - - sscr0 = __raw_readl(ssp->mmio_base + SSCR0); - sscr0 &= ~SSCR0_SSE; - __raw_writel(sscr0, ssp->mmio_base + SSCR0); -} - -/** - * ssp_save_state - save the SSP configuration - * @ssp: pointer to structure to save SSP configuration - * - * Save the configured SSP state for suspend. - */ -void ssp_save_state(struct ssp_dev *dev, struct ssp_state *state) -{ - struct ssp_device *ssp = dev->ssp; - - state->cr0 = __raw_readl(ssp->mmio_base + SSCR0); - state->cr1 = __raw_readl(ssp->mmio_base + SSCR1); - state->to = __raw_readl(ssp->mmio_base + SSTO); - state->psp = __raw_readl(ssp->mmio_base + SSPSP); - - ssp_disable(dev); -} - -/** - * ssp_restore_state - restore a previously saved SSP configuration - * @ssp: pointer to configuration saved by ssp_save_state - * - * Restore the SSP configuration saved previously by ssp_save_state. - */ -void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *state) -{ - struct ssp_device *ssp = dev->ssp; - uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE; - - __raw_writel(sssr, ssp->mmio_base + SSSR); - - __raw_writel(state->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0); - __raw_writel(state->cr1, ssp->mmio_base + SSCR1); - __raw_writel(state->to, ssp->mmio_base + SSTO); - __raw_writel(state->psp, ssp->mmio_base + SSPSP); - __raw_writel(state->cr0, ssp->mmio_base + SSCR0); -} - -/** - * ssp_config - configure SSP port settings - * @mode: port operating mode - * @flags: port config flags - * @psp_flags: port PSP config flags - * @speed: port speed - * - * Port MUST be disabled by ssp_disable before making any config changes. - */ -int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed) -{ - struct ssp_device *ssp = dev->ssp; - - dev->mode = mode; - dev->flags = flags; - dev->psp_flags = psp_flags; - dev->speed = speed; - - /* set up port type, speed, port settings */ - __raw_writel((dev->speed | dev->mode), ssp->mmio_base + SSCR0); - __raw_writel(dev->flags, ssp->mmio_base + SSCR1); - __raw_writel(dev->psp_flags, ssp->mmio_base + SSPSP); - - return 0; -} - -/** - * ssp_init - setup the SSP port - * - * initialise and claim resources for the SSP port. - * - * Returns: - * %-ENODEV if the SSP port is unavailable - * %-EBUSY if the resources are already in use - * %0 on success - */ -int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags) -{ - struct ssp_device *ssp; - int ret; - - ssp = ssp_request(port, "SSP"); - if (ssp == NULL) - return -ENODEV; - - dev->ssp = ssp; - dev->port = port; - - /* do we need to get irq */ - if (!(init_flags & SSP_NO_IRQ)) { - ret = request_irq(ssp->irq, ssp_interrupt, - 0, "SSP", dev); - if (ret) - goto out_region; - dev->irq = ssp->irq; - } else - dev->irq = NO_IRQ; - - /* turn on SSP port clock */ - clk_enable(ssp->clk); - return 0; - -out_region: - ssp_free(ssp); - return ret; -} - -/** - * ssp_exit - undo the effects of ssp_init - * - * release and free resources for the SSP port. - */ -void ssp_exit(struct ssp_dev *dev) -{ - struct ssp_device *ssp = dev->ssp; - - ssp_disable(dev); - if (dev->irq != NO_IRQ) - free_irq(dev->irq, dev); - clk_disable(ssp->clk); - ssp_free(ssp); -} -#endif /* CONFIG_PXA_SSP_LEGACY */ - static DEFINE_MUTEX(ssp_lock); static LIST_HEAD(ssp_list); @@ -491,20 +219,6 @@ static void __exit pxa_ssp_exit(void) arch_initcall(pxa_ssp_init); module_exit(pxa_ssp_exit); -#ifdef CONFIG_PXA_SSP_LEGACY -EXPORT_SYMBOL(ssp_write_word); -EXPORT_SYMBOL(ssp_read_word); -EXPORT_SYMBOL(ssp_flush); -EXPORT_SYMBOL(ssp_enable); -EXPORT_SYMBOL(ssp_disable); -EXPORT_SYMBOL(ssp_save_state); -EXPORT_SYMBOL(ssp_restore_state); -EXPORT_SYMBOL(ssp_init); -EXPORT_SYMBOL(ssp_exit); -EXPORT_SYMBOL(ssp_config); -#endif - MODULE_DESCRIPTION("PXA SSP driver"); MODULE_AUTHOR("Liam Girdwood"); MODULE_LICENSE("GPL"); - -- cgit v1.2.3-59-g8ed1b From c9840daa70fbb8f6031fcd1f254a3da49a41ea7b Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 16 Mar 2010 16:48:01 +0800 Subject: [ARM] pxa: correct SSCR0_SCR to support multiple SoCs The previous definitions of SSCR0_SCR and SSCR0_SerClkDiv() prevented them being used simultaneously when supporting multiple PXA SoCs, esp. in drivers/spi/pxa2xx_spi.c, make them correct. The change from SSCR0_SerClkDiv(2) to SSCR0_SCR(2), will make the result a little bit different in pxa2xx_spi_probe(), however, since that's only used as a default initialization value, it's acceptable. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/regs-ssp.h | 9 +-------- drivers/spi/pxa2xx_spi.c | 14 +++++++------- 2 files changed, 8 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/include/mach/regs-ssp.h b/arch/arm/mach-pxa/include/mach/regs-ssp.h index 6a2ed35acd59..dd15dc35a240 100644 --- a/arch/arm/mach-pxa/include/mach/regs-ssp.h +++ b/arch/arm/mach-pxa/include/mach/regs-ssp.h @@ -33,14 +33,7 @@ #define SSCR0_National (0x2 << 4) /* National Microwire */ #define SSCR0_ECS (1 << 6) /* External clock select */ #define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ - -#if defined(CONFIG_PXA25x) -#define SSCR0_SCR (0x0000ff00) /* Serial Clock Rate (mask) */ -#define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */ -#elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) -#define SSCR0_SCR (0x000fff00) /* Serial Clock Rate (mask) */ -#define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */ -#endif +#define SSCR0_SCR(x) ((x) << 8) /* Serial Clock Rate (mask) */ #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #define SSCR0_EDSS (1 << 20) /* Extended data size select */ diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 36828358a4d8..35d4e5cdb631 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -1318,14 +1318,14 @@ static int setup(struct spi_device *spi) /* NOTE: PXA25x_SSP _could_ use external clocking ... */ if (drv_data->ssp_type != PXA25x_SSP) dev_dbg(&spi->dev, "%ld Hz actual, %s\n", - clk_get_rate(ssp->clk) - / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), - chip->enable_dma ? "DMA" : "PIO"); + clk_get_rate(ssp->clk) + / (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)), + chip->enable_dma ? "DMA" : "PIO"); else dev_dbg(&spi->dev, "%ld Hz actual, %s\n", - clk_get_rate(ssp->clk) / 2 - / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), - chip->enable_dma ? "DMA" : "PIO"); + clk_get_rate(ssp->clk) / 2 + / (1 + ((chip->cr0 & SSCR0_SCR(0x0ff)) >> 8)), + chip->enable_dma ? "DMA" : "PIO"); if (spi->bits_per_word <= 8) { chip->n_bytes = 1; @@ -1558,7 +1558,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) | SSCR1_TxTresh(TX_THRESH_DFLT), drv_data->ioaddr); - write_SSCR0(SSCR0_SerClkDiv(2) + write_SSCR0(SSCR0_SCR(2) | SSCR0_Motorola | SSCR0_DataSize(8), drv_data->ioaddr); -- cgit v1.2.3-59-g8ed1b From 83f2889643d8efbc7fe925afbaa114e775699d7c Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 16 Mar 2010 17:03:20 +0800 Subject: [ARM] pxa: merge regs-ssp.h into ssp.h No need to separate them as they should be together from the begining. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/regs-ssp.h | 127 ------------------------------ arch/arm/mach-pxa/include/mach/ssp.h | 122 ++++++++++++++++++++++++++++ arch/arm/mach-pxa/ssp.c | 1 - drivers/spi/pxa2xx_spi.c | 1 - sound/soc/pxa/pxa-ssp.c | 1 - 5 files changed, 122 insertions(+), 130 deletions(-) delete mode 100644 arch/arm/mach-pxa/include/mach/regs-ssp.h (limited to 'arch') diff --git a/arch/arm/mach-pxa/include/mach/regs-ssp.h b/arch/arm/mach-pxa/include/mach/regs-ssp.h deleted file mode 100644 index dd15dc35a240..000000000000 --- a/arch/arm/mach-pxa/include/mach/regs-ssp.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef __ASM_ARCH_REGS_SSP_H -#define __ASM_ARCH_REGS_SSP_H - -/* - * SSP Serial Port Registers - * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different. - * PXA255, PXA26x and PXA27x have extra ports, registers and bits. - */ - -#define SSCR0 (0x00) /* SSP Control Register 0 */ -#define SSCR1 (0x04) /* SSP Control Register 1 */ -#define SSSR (0x08) /* SSP Status Register */ -#define SSITR (0x0C) /* SSP Interrupt Test Register */ -#define SSDR (0x10) /* SSP Data Write/Data Read Register */ - -#define SSTO (0x28) /* SSP Time Out Register */ -#define SSPSP (0x2C) /* SSP Programmable Serial Protocol */ -#define SSTSA (0x30) /* SSP Tx Timeslot Active */ -#define SSRSA (0x34) /* SSP Rx Timeslot Active */ -#define SSTSS (0x38) /* SSP Timeslot Status */ -#define SSACD (0x3C) /* SSP Audio Clock Divider */ - -#if defined(CONFIG_PXA3xx) -#define SSACDD (0x40) /* SSP Audio Clock Dither Divider */ -#endif - -/* Common PXA2xx bits first */ -#define SSCR0_DSS (0x0000000f) /* Data Size Select (mask) */ -#define SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..16] */ -#define SSCR0_FRF (0x00000030) /* FRame Format (mask) */ -#define SSCR0_Motorola (0x0 << 4) /* Motorola's Serial Peripheral Interface (SPI) */ -#define SSCR0_TI (0x1 << 4) /* Texas Instruments' Synchronous Serial Protocol (SSP) */ -#define SSCR0_National (0x2 << 4) /* National Microwire */ -#define SSCR0_ECS (1 << 6) /* External clock select */ -#define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ -#define SSCR0_SCR(x) ((x) << 8) /* Serial Clock Rate (mask) */ - -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) -#define SSCR0_EDSS (1 << 20) /* Extended data size select */ -#define SSCR0_NCS (1 << 21) /* Network clock select */ -#define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */ -#define SSCR0_TUM (1 << 23) /* Transmit FIFO underrun interrupt mask */ -#define SSCR0_FRDC (0x07000000) /* Frame rate divider control (mask) */ -#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */ -#define SSCR0_ACS (1 << 30) /* Audio clock select */ -#define SSCR0_MOD (1 << 31) /* Mode (normal or network) */ -#endif - -#if defined(CONFIG_PXA3xx) -#define SSCR0_FPCKE (1 << 29) /* FIFO packing enable */ -#endif - -#define SSCR1_RIE (1 << 0) /* Receive FIFO Interrupt Enable */ -#define SSCR1_TIE (1 << 1) /* Transmit FIFO Interrupt Enable */ -#define SSCR1_LBM (1 << 2) /* Loop-Back Mode */ -#define SSCR1_SPO (1 << 3) /* Motorola SPI SSPSCLK polarity setting */ -#define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ -#define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ -#define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ -#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ -#define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ -#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ - -#define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ -#define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ -#define SSSR_BSY (1 << 4) /* SSP Busy */ -#define SSSR_TFS (1 << 5) /* Transmit FIFO Service Request */ -#define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ -#define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ - -#define SSCR0_TIM (1 << 23) /* Transmit FIFO Under Run Interrupt Mask */ -#define SSCR0_RIM (1 << 22) /* Receive FIFO Over Run interrupt Mask */ -#define SSCR0_NCS (1 << 21) /* Network Clock Select */ -#define SSCR0_EDSS (1 << 20) /* Extended Data Size Select */ - -/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ -#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ -#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ -#define SSCR1_TTELP (1 << 31) /* TXD Tristate Enable Last Phase */ -#define SSCR1_TTE (1 << 30) /* TXD Tristate Enable */ -#define SSCR1_EBCEI (1 << 29) /* Enable Bit Count Error interrupt */ -#define SSCR1_SCFR (1 << 28) /* Slave Clock free Running */ -#define SSCR1_ECRA (1 << 27) /* Enable Clock Request A */ -#define SSCR1_ECRB (1 << 26) /* Enable Clock request B */ -#define SSCR1_SCLKDIR (1 << 25) /* Serial Bit Rate Clock Direction */ -#define SSCR1_SFRMDIR (1 << 24) /* Frame Direction */ -#define SSCR1_RWOT (1 << 23) /* Receive Without Transmit */ -#define SSCR1_TRAIL (1 << 22) /* Trailing Byte */ -#define SSCR1_TSRE (1 << 21) /* Transmit Service Request Enable */ -#define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */ -#define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */ -#define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */ -#define SSCR1_IFS (1 << 16) /* Invert Frame Signal */ -#define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */ -#define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */ - -#define SSSR_BCE (1 << 23) /* Bit Count Error */ -#define SSSR_CSS (1 << 22) /* Clock Synchronisation Status */ -#define SSSR_TUR (1 << 21) /* Transmit FIFO Under Run */ -#define SSSR_EOC (1 << 20) /* End Of Chain */ -#define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */ -#define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */ - -#if defined(CONFIG_PXA3xx) -#define SSPSP_EDMYSTOP(x) ((x) << 28) /* Extended Dummy Stop */ -#define SSPSP_EDMYSTRT(x) ((x) << 26) /* Extended Dummy Start */ -#endif - -#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ -#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */ -#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */ -#define SSPSP_SFRMDLY(x) ((x) << 9) /* Serial Frame Delay */ -#define SSPSP_DMYSTRT(x) ((x) << 7) /* Dummy Start */ -#define SSPSP_STRTDLY(x) ((x) << 4) /* Start Delay */ -#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */ -#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */ -#define SSPSP_SCMODE(x) ((x) << 0) /* Serial Bit Rate Clock Mode */ - -#define SSACD_SCDB (1 << 3) /* SSPSYSCLK Divider Bypass */ -#define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */ -#define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */ -#if defined(CONFIG_PXA3xx) -#define SSACD_SCDX8 (1 << 7) /* SYSCLK division ratio select */ -#endif - - -#endif /* __ASM_ARCH_REGS_SSP_H */ diff --git a/arch/arm/mach-pxa/include/mach/ssp.h b/arch/arm/mach-pxa/include/mach/ssp.h index 8470a73d18b9..4c4ce62390d0 100644 --- a/arch/arm/mach-pxa/include/mach/ssp.h +++ b/arch/arm/mach-pxa/include/mach/ssp.h @@ -22,6 +22,128 @@ #include #include +/* + * SSP Serial Port Registers + * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different. + * PXA255, PXA26x and PXA27x have extra ports, registers and bits. + */ + +#define SSCR0 (0x00) /* SSP Control Register 0 */ +#define SSCR1 (0x04) /* SSP Control Register 1 */ +#define SSSR (0x08) /* SSP Status Register */ +#define SSITR (0x0C) /* SSP Interrupt Test Register */ +#define SSDR (0x10) /* SSP Data Write/Data Read Register */ + +#define SSTO (0x28) /* SSP Time Out Register */ +#define SSPSP (0x2C) /* SSP Programmable Serial Protocol */ +#define SSTSA (0x30) /* SSP Tx Timeslot Active */ +#define SSRSA (0x34) /* SSP Rx Timeslot Active */ +#define SSTSS (0x38) /* SSP Timeslot Status */ +#define SSACD (0x3C) /* SSP Audio Clock Divider */ + +#if defined(CONFIG_PXA3xx) +#define SSACDD (0x40) /* SSP Audio Clock Dither Divider */ +#endif + +/* Common PXA2xx bits first */ +#define SSCR0_DSS (0x0000000f) /* Data Size Select (mask) */ +#define SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..16] */ +#define SSCR0_FRF (0x00000030) /* FRame Format (mask) */ +#define SSCR0_Motorola (0x0 << 4) /* Motorola's Serial Peripheral Interface (SPI) */ +#define SSCR0_TI (0x1 << 4) /* Texas Instruments' Synchronous Serial Protocol (SSP) */ +#define SSCR0_National (0x2 << 4) /* National Microwire */ +#define SSCR0_ECS (1 << 6) /* External clock select */ +#define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ +#define SSCR0_SCR(x) ((x) << 8) /* Serial Clock Rate (mask) */ + +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) +#define SSCR0_EDSS (1 << 20) /* Extended data size select */ +#define SSCR0_NCS (1 << 21) /* Network clock select */ +#define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */ +#define SSCR0_TUM (1 << 23) /* Transmit FIFO underrun interrupt mask */ +#define SSCR0_FRDC (0x07000000) /* Frame rate divider control (mask) */ +#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */ +#define SSCR0_ACS (1 << 30) /* Audio clock select */ +#define SSCR0_MOD (1 << 31) /* Mode (normal or network) */ +#endif + +#if defined(CONFIG_PXA3xx) +#define SSCR0_FPCKE (1 << 29) /* FIFO packing enable */ +#endif + +#define SSCR1_RIE (1 << 0) /* Receive FIFO Interrupt Enable */ +#define SSCR1_TIE (1 << 1) /* Transmit FIFO Interrupt Enable */ +#define SSCR1_LBM (1 << 2) /* Loop-Back Mode */ +#define SSCR1_SPO (1 << 3) /* Motorola SPI SSPSCLK polarity setting */ +#define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ +#define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ +#define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ +#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ +#define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ +#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ + +#define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ +#define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ +#define SSSR_BSY (1 << 4) /* SSP Busy */ +#define SSSR_TFS (1 << 5) /* Transmit FIFO Service Request */ +#define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ +#define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ + +#define SSCR0_TIM (1 << 23) /* Transmit FIFO Under Run Interrupt Mask */ +#define SSCR0_RIM (1 << 22) /* Receive FIFO Over Run interrupt Mask */ +#define SSCR0_NCS (1 << 21) /* Network Clock Select */ +#define SSCR0_EDSS (1 << 20) /* Extended Data Size Select */ + +/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ +#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ +#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ +#define SSCR1_TTELP (1 << 31) /* TXD Tristate Enable Last Phase */ +#define SSCR1_TTE (1 << 30) /* TXD Tristate Enable */ +#define SSCR1_EBCEI (1 << 29) /* Enable Bit Count Error interrupt */ +#define SSCR1_SCFR (1 << 28) /* Slave Clock free Running */ +#define SSCR1_ECRA (1 << 27) /* Enable Clock Request A */ +#define SSCR1_ECRB (1 << 26) /* Enable Clock request B */ +#define SSCR1_SCLKDIR (1 << 25) /* Serial Bit Rate Clock Direction */ +#define SSCR1_SFRMDIR (1 << 24) /* Frame Direction */ +#define SSCR1_RWOT (1 << 23) /* Receive Without Transmit */ +#define SSCR1_TRAIL (1 << 22) /* Trailing Byte */ +#define SSCR1_TSRE (1 << 21) /* Transmit Service Request Enable */ +#define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */ +#define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */ +#define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */ +#define SSCR1_IFS (1 << 16) /* Invert Frame Signal */ +#define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */ +#define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */ + +#define SSSR_BCE (1 << 23) /* Bit Count Error */ +#define SSSR_CSS (1 << 22) /* Clock Synchronisation Status */ +#define SSSR_TUR (1 << 21) /* Transmit FIFO Under Run */ +#define SSSR_EOC (1 << 20) /* End Of Chain */ +#define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */ +#define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */ + +#if defined(CONFIG_PXA3xx) +#define SSPSP_EDMYSTOP(x) ((x) << 28) /* Extended Dummy Stop */ +#define SSPSP_EDMYSTRT(x) ((x) << 26) /* Extended Dummy Start */ +#endif + +#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ +#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */ +#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */ +#define SSPSP_SFRMDLY(x) ((x) << 9) /* Serial Frame Delay */ +#define SSPSP_DMYSTRT(x) ((x) << 7) /* Dummy Start */ +#define SSPSP_STRTDLY(x) ((x) << 4) /* Start Delay */ +#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */ +#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */ +#define SSPSP_SCMODE(x) ((x) << 0) /* Serial Bit Rate Clock Mode */ + +#define SSACD_SCDB (1 << 3) /* SSPSYSCLK Divider Bypass */ +#define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */ +#define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */ +#if defined(CONFIG_PXA3xx) +#define SSACD_SCDX8 (1 << 7) /* SYSCLK division ratio select */ +#endif + enum pxa_ssp_type { SSP_UNDEFINED = 0, PXA25x_SSP, /* pxa 210, 250, 255, 26x */ diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c index 6e7df7af61e1..a9b2d3eb8f32 100644 --- a/arch/arm/mach-pxa/ssp.c +++ b/arch/arm/mach-pxa/ssp.c @@ -33,7 +33,6 @@ #include #include #include -#include static DEFINE_MUTEX(ssp_lock); static LIST_HEAD(ssp_list); diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 35d4e5cdb631..959e78bb2f04 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -36,7 +36,6 @@ #include #include -#include #include #include diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 544fd9566f4d..2e27962220ad 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -32,7 +32,6 @@ #include #include -#include #include #include -- cgit v1.2.3-59-g8ed1b From be1194cca55961b4dd98ea17fb24f0ffc6fa2213 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 16 Mar 2010 17:21:57 +0800 Subject: [ARM] pxa: remove unnecessary #include of Signed-off-by: Eric Miao --- arch/arm/mach-pxa/littleton.c | 1 - arch/arm/mach-pxa/poodle.c | 1 - arch/arm/mach-pxa/pxa3xx.c | 1 - 3 files changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index fa527b258d61..be727aeed217 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -41,7 +41,6 @@ #include #include -#include #include #include #include diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index d58a52415d75..48b10c783a28 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 4d7c03e72504..f544e58e1536 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3-59-g8ed1b From 54c39b420f017c546fb130a05c14bdb0a7910f98 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 16 Mar 2010 17:12:37 +0800 Subject: [ARM] pxa: move ssp into common plat-pxa Signed-off-by: Haojian Zhuang Acked-by: Mark Brown Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 5 - arch/arm/mach-pxa/Makefile | 1 - arch/arm/mach-pxa/include/mach/ssp.h | 196 ------------------------------ arch/arm/mach-pxa/poodle.c | 2 +- arch/arm/mach-pxa/ssp.c | 223 ----------------------------------- arch/arm/plat-pxa/Kconfig | 5 + arch/arm/plat-pxa/Makefile | 1 + arch/arm/plat-pxa/include/plat/ssp.h | 196 ++++++++++++++++++++++++++++++ arch/arm/plat-pxa/ssp.c | 223 +++++++++++++++++++++++++++++++++++ drivers/spi/pxa2xx_spi.c | 2 +- sound/soc/pxa/pxa-ssp.c | 2 +- 11 files changed, 428 insertions(+), 428 deletions(-) delete mode 100644 arch/arm/mach-pxa/include/mach/ssp.h delete mode 100644 arch/arm/mach-pxa/ssp.c create mode 100644 arch/arm/plat-pxa/include/plat/ssp.h create mode 100644 arch/arm/plat-pxa/ssp.c (limited to 'arch') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 8f7eb12776a9..6dd450a7dea6 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -648,11 +648,6 @@ config PXA_SHARP_Cxx00 help Enable common support for Sharp Cxx00 models -config PXA_SSP - tristate - help - Enable support for PXA2xx SSP ports - config TOSA_BT tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" depends on MACH_TOSA diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index a83aff386fba..cf57fb2f73d8 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -14,7 +14,6 @@ obj-$(CONFIG_PXA3xx) += cpufreq-pxa3xx.o endif # Generic drivers that other drivers may depend upon -obj-$(CONFIG_PXA_SSP) += ssp.o # SoC-specific code obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o diff --git a/arch/arm/mach-pxa/include/mach/ssp.h b/arch/arm/mach-pxa/include/mach/ssp.h deleted file mode 100644 index 4c4ce62390d0..000000000000 --- a/arch/arm/mach-pxa/include/mach/ssp.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * ssp.h - * - * Copyright (C) 2003 Russell King, 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 version 2 as - * published by the Free Software Foundation. - * - * This driver supports the following PXA CPU/SSP ports:- - * - * PXA250 SSP - * PXA255 SSP, NSSP - * PXA26x SSP, NSSP, ASSP - * PXA27x SSP1, SSP2, SSP3 - * PXA3xx SSP1, SSP2, SSP3, SSP4 - */ - -#ifndef __ASM_ARCH_SSP_H -#define __ASM_ARCH_SSP_H - -#include -#include - -/* - * SSP Serial Port Registers - * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different. - * PXA255, PXA26x and PXA27x have extra ports, registers and bits. - */ - -#define SSCR0 (0x00) /* SSP Control Register 0 */ -#define SSCR1 (0x04) /* SSP Control Register 1 */ -#define SSSR (0x08) /* SSP Status Register */ -#define SSITR (0x0C) /* SSP Interrupt Test Register */ -#define SSDR (0x10) /* SSP Data Write/Data Read Register */ - -#define SSTO (0x28) /* SSP Time Out Register */ -#define SSPSP (0x2C) /* SSP Programmable Serial Protocol */ -#define SSTSA (0x30) /* SSP Tx Timeslot Active */ -#define SSRSA (0x34) /* SSP Rx Timeslot Active */ -#define SSTSS (0x38) /* SSP Timeslot Status */ -#define SSACD (0x3C) /* SSP Audio Clock Divider */ - -#if defined(CONFIG_PXA3xx) -#define SSACDD (0x40) /* SSP Audio Clock Dither Divider */ -#endif - -/* Common PXA2xx bits first */ -#define SSCR0_DSS (0x0000000f) /* Data Size Select (mask) */ -#define SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..16] */ -#define SSCR0_FRF (0x00000030) /* FRame Format (mask) */ -#define SSCR0_Motorola (0x0 << 4) /* Motorola's Serial Peripheral Interface (SPI) */ -#define SSCR0_TI (0x1 << 4) /* Texas Instruments' Synchronous Serial Protocol (SSP) */ -#define SSCR0_National (0x2 << 4) /* National Microwire */ -#define SSCR0_ECS (1 << 6) /* External clock select */ -#define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ -#define SSCR0_SCR(x) ((x) << 8) /* Serial Clock Rate (mask) */ - -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) -#define SSCR0_EDSS (1 << 20) /* Extended data size select */ -#define SSCR0_NCS (1 << 21) /* Network clock select */ -#define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */ -#define SSCR0_TUM (1 << 23) /* Transmit FIFO underrun interrupt mask */ -#define SSCR0_FRDC (0x07000000) /* Frame rate divider control (mask) */ -#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */ -#define SSCR0_ACS (1 << 30) /* Audio clock select */ -#define SSCR0_MOD (1 << 31) /* Mode (normal or network) */ -#endif - -#if defined(CONFIG_PXA3xx) -#define SSCR0_FPCKE (1 << 29) /* FIFO packing enable */ -#endif - -#define SSCR1_RIE (1 << 0) /* Receive FIFO Interrupt Enable */ -#define SSCR1_TIE (1 << 1) /* Transmit FIFO Interrupt Enable */ -#define SSCR1_LBM (1 << 2) /* Loop-Back Mode */ -#define SSCR1_SPO (1 << 3) /* Motorola SPI SSPSCLK polarity setting */ -#define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ -#define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ -#define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ -#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ -#define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ -#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ - -#define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ -#define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ -#define SSSR_BSY (1 << 4) /* SSP Busy */ -#define SSSR_TFS (1 << 5) /* Transmit FIFO Service Request */ -#define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ -#define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ - -#define SSCR0_TIM (1 << 23) /* Transmit FIFO Under Run Interrupt Mask */ -#define SSCR0_RIM (1 << 22) /* Receive FIFO Over Run interrupt Mask */ -#define SSCR0_NCS (1 << 21) /* Network Clock Select */ -#define SSCR0_EDSS (1 << 20) /* Extended Data Size Select */ - -/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ -#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ -#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ -#define SSCR1_TTELP (1 << 31) /* TXD Tristate Enable Last Phase */ -#define SSCR1_TTE (1 << 30) /* TXD Tristate Enable */ -#define SSCR1_EBCEI (1 << 29) /* Enable Bit Count Error interrupt */ -#define SSCR1_SCFR (1 << 28) /* Slave Clock free Running */ -#define SSCR1_ECRA (1 << 27) /* Enable Clock Request A */ -#define SSCR1_ECRB (1 << 26) /* Enable Clock request B */ -#define SSCR1_SCLKDIR (1 << 25) /* Serial Bit Rate Clock Direction */ -#define SSCR1_SFRMDIR (1 << 24) /* Frame Direction */ -#define SSCR1_RWOT (1 << 23) /* Receive Without Transmit */ -#define SSCR1_TRAIL (1 << 22) /* Trailing Byte */ -#define SSCR1_TSRE (1 << 21) /* Transmit Service Request Enable */ -#define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */ -#define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */ -#define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */ -#define SSCR1_IFS (1 << 16) /* Invert Frame Signal */ -#define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */ -#define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */ - -#define SSSR_BCE (1 << 23) /* Bit Count Error */ -#define SSSR_CSS (1 << 22) /* Clock Synchronisation Status */ -#define SSSR_TUR (1 << 21) /* Transmit FIFO Under Run */ -#define SSSR_EOC (1 << 20) /* End Of Chain */ -#define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */ -#define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */ - -#if defined(CONFIG_PXA3xx) -#define SSPSP_EDMYSTOP(x) ((x) << 28) /* Extended Dummy Stop */ -#define SSPSP_EDMYSTRT(x) ((x) << 26) /* Extended Dummy Start */ -#endif - -#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ -#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */ -#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */ -#define SSPSP_SFRMDLY(x) ((x) << 9) /* Serial Frame Delay */ -#define SSPSP_DMYSTRT(x) ((x) << 7) /* Dummy Start */ -#define SSPSP_STRTDLY(x) ((x) << 4) /* Start Delay */ -#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */ -#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */ -#define SSPSP_SCMODE(x) ((x) << 0) /* Serial Bit Rate Clock Mode */ - -#define SSACD_SCDB (1 << 3) /* SSPSYSCLK Divider Bypass */ -#define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */ -#define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */ -#if defined(CONFIG_PXA3xx) -#define SSACD_SCDX8 (1 << 7) /* SYSCLK division ratio select */ -#endif - -enum pxa_ssp_type { - SSP_UNDEFINED = 0, - PXA25x_SSP, /* pxa 210, 250, 255, 26x */ - PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ - PXA27x_SSP, -}; - -struct ssp_device { - struct platform_device *pdev; - struct list_head node; - - struct clk *clk; - void __iomem *mmio_base; - unsigned long phys_base; - - const char *label; - int port_id; - int type; - int use_count; - int irq; - int drcmr_rx; - int drcmr_tx; -}; - -/** - * ssp_write_reg - Write to a SSP register - * - * @dev: SSP device to access - * @reg: Register to write to - * @val: Value to be written. - */ -static inline void ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val) -{ - __raw_writel(val, dev->mmio_base + reg); -} - -/** - * ssp_read_reg - Read from a SSP register - * - * @dev: SSP device to access - * @reg: Register to read from - */ -static inline u32 ssp_read_reg(struct ssp_device *dev, u32 reg) -{ - return __raw_readl(dev->mmio_base + reg); -} - -struct ssp_device *ssp_request(int port, const char *label); -void ssp_free(struct ssp_device *); -#endif /* __ASM_ARCH_SSP_H */ diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 48b10c783a28..dcb178807046 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -40,12 +40,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c deleted file mode 100644 index a9b2d3eb8f32..000000000000 --- a/arch/arm/mach-pxa/ssp.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/ssp.c - * - * based on linux/arch/arm/mach-sa1100/ssp.c by Russell King - * - * Copyright (C) 2003 Russell King. - * Copyright (C) 2003 Wolfson Microelectronics PLC - * - * 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. - * - * PXA2xx SSP driver. This provides the generic core for simple - * IO-based SSP applications and allows easy port setup for DMA access. - * - * Author: Liam Girdwood - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static DEFINE_MUTEX(ssp_lock); -static LIST_HEAD(ssp_list); - -struct ssp_device *ssp_request(int port, const char *label) -{ - struct ssp_device *ssp = NULL; - - mutex_lock(&ssp_lock); - - list_for_each_entry(ssp, &ssp_list, node) { - if (ssp->port_id == port && ssp->use_count == 0) { - ssp->use_count++; - ssp->label = label; - break; - } - } - - mutex_unlock(&ssp_lock); - - if (&ssp->node == &ssp_list) - return NULL; - - return ssp; -} -EXPORT_SYMBOL(ssp_request); - -void ssp_free(struct ssp_device *ssp) -{ - mutex_lock(&ssp_lock); - if (ssp->use_count) { - ssp->use_count--; - ssp->label = NULL; - } else - dev_err(&ssp->pdev->dev, "device already free\n"); - mutex_unlock(&ssp_lock); -} -EXPORT_SYMBOL(ssp_free); - -static int __devinit ssp_probe(struct platform_device *pdev) -{ - const struct platform_device_id *id = platform_get_device_id(pdev); - struct resource *res; - struct ssp_device *ssp; - int ret = 0; - - ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL); - if (ssp == NULL) { - dev_err(&pdev->dev, "failed to allocate memory"); - return -ENOMEM; - } - ssp->pdev = pdev; - - ssp->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(ssp->clk)) { - ret = PTR_ERR(ssp->clk); - goto err_free; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "no memory resource defined\n"); - ret = -ENODEV; - goto err_free_clk; - } - - res = request_mem_region(res->start, res->end - res->start + 1, - pdev->name); - if (res == NULL) { - dev_err(&pdev->dev, "failed to request memory resource\n"); - ret = -EBUSY; - goto err_free_clk; - } - - ssp->phys_base = res->start; - - ssp->mmio_base = ioremap(res->start, res->end - res->start + 1); - if (ssp->mmio_base == NULL) { - dev_err(&pdev->dev, "failed to ioremap() registers\n"); - ret = -ENODEV; - goto err_free_mem; - } - - ssp->irq = platform_get_irq(pdev, 0); - if (ssp->irq < 0) { - dev_err(&pdev->dev, "no IRQ resource defined\n"); - ret = -ENODEV; - goto err_free_io; - } - - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (res == NULL) { - dev_err(&pdev->dev, "no SSP RX DRCMR defined\n"); - ret = -ENODEV; - goto err_free_io; - } - ssp->drcmr_rx = res->start; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (res == NULL) { - dev_err(&pdev->dev, "no SSP TX DRCMR defined\n"); - ret = -ENODEV; - goto err_free_io; - } - ssp->drcmr_tx = res->start; - - /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id - * starts from 0, do a translation here - */ - ssp->port_id = pdev->id + 1; - ssp->use_count = 0; - ssp->type = (int)id->driver_data; - - mutex_lock(&ssp_lock); - list_add(&ssp->node, &ssp_list); - mutex_unlock(&ssp_lock); - - platform_set_drvdata(pdev, ssp); - return 0; - -err_free_io: - iounmap(ssp->mmio_base); -err_free_mem: - release_mem_region(res->start, res->end - res->start + 1); -err_free_clk: - clk_put(ssp->clk); -err_free: - kfree(ssp); - return ret; -} - -static int __devexit ssp_remove(struct platform_device *pdev) -{ - struct resource *res; - struct ssp_device *ssp; - - ssp = platform_get_drvdata(pdev); - if (ssp == NULL) - return -ENODEV; - - iounmap(ssp->mmio_base); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, res->end - res->start + 1); - - clk_put(ssp->clk); - - mutex_lock(&ssp_lock); - list_del(&ssp->node); - mutex_unlock(&ssp_lock); - - kfree(ssp); - return 0; -} - -static const struct platform_device_id ssp_id_table[] = { - { "pxa25x-ssp", PXA25x_SSP }, - { "pxa25x-nssp", PXA25x_NSSP }, - { "pxa27x-ssp", PXA27x_SSP }, - { }, -}; - -static struct platform_driver ssp_driver = { - .probe = ssp_probe, - .remove = __devexit_p(ssp_remove), - .driver = { - .owner = THIS_MODULE, - .name = "pxa2xx-ssp", - }, - .id_table = ssp_id_table, -}; - -static int __init pxa_ssp_init(void) -{ - return platform_driver_register(&ssp_driver); -} - -static void __exit pxa_ssp_exit(void) -{ - platform_driver_unregister(&ssp_driver); -} - -arch_initcall(pxa_ssp_init); -module_exit(pxa_ssp_exit); - -MODULE_DESCRIPTION("PXA SSP driver"); -MODULE_AUTHOR("Liam Girdwood"); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/plat-pxa/Kconfig b/arch/arm/plat-pxa/Kconfig index b158e98038ed..da53395a17c6 100644 --- a/arch/arm/plat-pxa/Kconfig +++ b/arch/arm/plat-pxa/Kconfig @@ -1,3 +1,8 @@ if PLAT_PXA +config PXA_SSP + tristate + help + Enable support for PXA2xx SSP ports + endif diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile index 0264bfb0ca4f..4aacdd12c9cc 100644 --- a/arch/arm/plat-pxa/Makefile +++ b/arch/arm/plat-pxa/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_PXA3xx) += mfp.o obj-$(CONFIG_ARCH_MMP) += mfp.o obj-$(CONFIG_HAVE_PWM) += pwm.o +obj-$(CONFIG_PXA_SSP) += ssp.o diff --git a/arch/arm/plat-pxa/include/plat/ssp.h b/arch/arm/plat-pxa/include/plat/ssp.h new file mode 100644 index 000000000000..4c4ce62390d0 --- /dev/null +++ b/arch/arm/plat-pxa/include/plat/ssp.h @@ -0,0 +1,196 @@ +/* + * ssp.h + * + * Copyright (C) 2003 Russell King, 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 version 2 as + * published by the Free Software Foundation. + * + * This driver supports the following PXA CPU/SSP ports:- + * + * PXA250 SSP + * PXA255 SSP, NSSP + * PXA26x SSP, NSSP, ASSP + * PXA27x SSP1, SSP2, SSP3 + * PXA3xx SSP1, SSP2, SSP3, SSP4 + */ + +#ifndef __ASM_ARCH_SSP_H +#define __ASM_ARCH_SSP_H + +#include +#include + +/* + * SSP Serial Port Registers + * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different. + * PXA255, PXA26x and PXA27x have extra ports, registers and bits. + */ + +#define SSCR0 (0x00) /* SSP Control Register 0 */ +#define SSCR1 (0x04) /* SSP Control Register 1 */ +#define SSSR (0x08) /* SSP Status Register */ +#define SSITR (0x0C) /* SSP Interrupt Test Register */ +#define SSDR (0x10) /* SSP Data Write/Data Read Register */ + +#define SSTO (0x28) /* SSP Time Out Register */ +#define SSPSP (0x2C) /* SSP Programmable Serial Protocol */ +#define SSTSA (0x30) /* SSP Tx Timeslot Active */ +#define SSRSA (0x34) /* SSP Rx Timeslot Active */ +#define SSTSS (0x38) /* SSP Timeslot Status */ +#define SSACD (0x3C) /* SSP Audio Clock Divider */ + +#if defined(CONFIG_PXA3xx) +#define SSACDD (0x40) /* SSP Audio Clock Dither Divider */ +#endif + +/* Common PXA2xx bits first */ +#define SSCR0_DSS (0x0000000f) /* Data Size Select (mask) */ +#define SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..16] */ +#define SSCR0_FRF (0x00000030) /* FRame Format (mask) */ +#define SSCR0_Motorola (0x0 << 4) /* Motorola's Serial Peripheral Interface (SPI) */ +#define SSCR0_TI (0x1 << 4) /* Texas Instruments' Synchronous Serial Protocol (SSP) */ +#define SSCR0_National (0x2 << 4) /* National Microwire */ +#define SSCR0_ECS (1 << 6) /* External clock select */ +#define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ +#define SSCR0_SCR(x) ((x) << 8) /* Serial Clock Rate (mask) */ + +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) +#define SSCR0_EDSS (1 << 20) /* Extended data size select */ +#define SSCR0_NCS (1 << 21) /* Network clock select */ +#define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */ +#define SSCR0_TUM (1 << 23) /* Transmit FIFO underrun interrupt mask */ +#define SSCR0_FRDC (0x07000000) /* Frame rate divider control (mask) */ +#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */ +#define SSCR0_ACS (1 << 30) /* Audio clock select */ +#define SSCR0_MOD (1 << 31) /* Mode (normal or network) */ +#endif + +#if defined(CONFIG_PXA3xx) +#define SSCR0_FPCKE (1 << 29) /* FIFO packing enable */ +#endif + +#define SSCR1_RIE (1 << 0) /* Receive FIFO Interrupt Enable */ +#define SSCR1_TIE (1 << 1) /* Transmit FIFO Interrupt Enable */ +#define SSCR1_LBM (1 << 2) /* Loop-Back Mode */ +#define SSCR1_SPO (1 << 3) /* Motorola SPI SSPSCLK polarity setting */ +#define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ +#define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ +#define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ +#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ +#define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ +#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ + +#define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ +#define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ +#define SSSR_BSY (1 << 4) /* SSP Busy */ +#define SSSR_TFS (1 << 5) /* Transmit FIFO Service Request */ +#define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ +#define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ + +#define SSCR0_TIM (1 << 23) /* Transmit FIFO Under Run Interrupt Mask */ +#define SSCR0_RIM (1 << 22) /* Receive FIFO Over Run interrupt Mask */ +#define SSCR0_NCS (1 << 21) /* Network Clock Select */ +#define SSCR0_EDSS (1 << 20) /* Extended Data Size Select */ + +/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ +#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ +#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ +#define SSCR1_TTELP (1 << 31) /* TXD Tristate Enable Last Phase */ +#define SSCR1_TTE (1 << 30) /* TXD Tristate Enable */ +#define SSCR1_EBCEI (1 << 29) /* Enable Bit Count Error interrupt */ +#define SSCR1_SCFR (1 << 28) /* Slave Clock free Running */ +#define SSCR1_ECRA (1 << 27) /* Enable Clock Request A */ +#define SSCR1_ECRB (1 << 26) /* Enable Clock request B */ +#define SSCR1_SCLKDIR (1 << 25) /* Serial Bit Rate Clock Direction */ +#define SSCR1_SFRMDIR (1 << 24) /* Frame Direction */ +#define SSCR1_RWOT (1 << 23) /* Receive Without Transmit */ +#define SSCR1_TRAIL (1 << 22) /* Trailing Byte */ +#define SSCR1_TSRE (1 << 21) /* Transmit Service Request Enable */ +#define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */ +#define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */ +#define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */ +#define SSCR1_IFS (1 << 16) /* Invert Frame Signal */ +#define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */ +#define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */ + +#define SSSR_BCE (1 << 23) /* Bit Count Error */ +#define SSSR_CSS (1 << 22) /* Clock Synchronisation Status */ +#define SSSR_TUR (1 << 21) /* Transmit FIFO Under Run */ +#define SSSR_EOC (1 << 20) /* End Of Chain */ +#define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */ +#define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */ + +#if defined(CONFIG_PXA3xx) +#define SSPSP_EDMYSTOP(x) ((x) << 28) /* Extended Dummy Stop */ +#define SSPSP_EDMYSTRT(x) ((x) << 26) /* Extended Dummy Start */ +#endif + +#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ +#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */ +#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */ +#define SSPSP_SFRMDLY(x) ((x) << 9) /* Serial Frame Delay */ +#define SSPSP_DMYSTRT(x) ((x) << 7) /* Dummy Start */ +#define SSPSP_STRTDLY(x) ((x) << 4) /* Start Delay */ +#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */ +#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */ +#define SSPSP_SCMODE(x) ((x) << 0) /* Serial Bit Rate Clock Mode */ + +#define SSACD_SCDB (1 << 3) /* SSPSYSCLK Divider Bypass */ +#define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */ +#define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */ +#if defined(CONFIG_PXA3xx) +#define SSACD_SCDX8 (1 << 7) /* SYSCLK division ratio select */ +#endif + +enum pxa_ssp_type { + SSP_UNDEFINED = 0, + PXA25x_SSP, /* pxa 210, 250, 255, 26x */ + PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ + PXA27x_SSP, +}; + +struct ssp_device { + struct platform_device *pdev; + struct list_head node; + + struct clk *clk; + void __iomem *mmio_base; + unsigned long phys_base; + + const char *label; + int port_id; + int type; + int use_count; + int irq; + int drcmr_rx; + int drcmr_tx; +}; + +/** + * ssp_write_reg - Write to a SSP register + * + * @dev: SSP device to access + * @reg: Register to write to + * @val: Value to be written. + */ +static inline void ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val) +{ + __raw_writel(val, dev->mmio_base + reg); +} + +/** + * ssp_read_reg - Read from a SSP register + * + * @dev: SSP device to access + * @reg: Register to read from + */ +static inline u32 ssp_read_reg(struct ssp_device *dev, u32 reg) +{ + return __raw_readl(dev->mmio_base + reg); +} + +struct ssp_device *ssp_request(int port, const char *label); +void ssp_free(struct ssp_device *); +#endif /* __ASM_ARCH_SSP_H */ diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c new file mode 100644 index 000000000000..5fe230178f0a --- /dev/null +++ b/arch/arm/plat-pxa/ssp.c @@ -0,0 +1,223 @@ +/* + * linux/arch/arm/mach-pxa/ssp.c + * + * based on linux/arch/arm/mach-sa1100/ssp.c by Russell King + * + * Copyright (C) 2003 Russell King. + * Copyright (C) 2003 Wolfson Microelectronics PLC + * + * 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. + * + * PXA2xx SSP driver. This provides the generic core for simple + * IO-based SSP applications and allows easy port setup for DMA access. + * + * Author: Liam Girdwood + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static DEFINE_MUTEX(ssp_lock); +static LIST_HEAD(ssp_list); + +struct ssp_device *ssp_request(int port, const char *label) +{ + struct ssp_device *ssp = NULL; + + mutex_lock(&ssp_lock); + + list_for_each_entry(ssp, &ssp_list, node) { + if (ssp->port_id == port && ssp->use_count == 0) { + ssp->use_count++; + ssp->label = label; + break; + } + } + + mutex_unlock(&ssp_lock); + + if (&ssp->node == &ssp_list) + return NULL; + + return ssp; +} +EXPORT_SYMBOL(ssp_request); + +void ssp_free(struct ssp_device *ssp) +{ + mutex_lock(&ssp_lock); + if (ssp->use_count) { + ssp->use_count--; + ssp->label = NULL; + } else + dev_err(&ssp->pdev->dev, "device already free\n"); + mutex_unlock(&ssp_lock); +} +EXPORT_SYMBOL(ssp_free); + +static int __devinit ssp_probe(struct platform_device *pdev) +{ + const struct platform_device_id *id = platform_get_device_id(pdev); + struct resource *res; + struct ssp_device *ssp; + int ret = 0; + + ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL); + if (ssp == NULL) { + dev_err(&pdev->dev, "failed to allocate memory"); + return -ENOMEM; + } + ssp->pdev = pdev; + + ssp->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(ssp->clk)) { + ret = PTR_ERR(ssp->clk); + goto err_free; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + ret = -ENODEV; + goto err_free_clk; + } + + res = request_mem_region(res->start, res->end - res->start + 1, + pdev->name); + if (res == NULL) { + dev_err(&pdev->dev, "failed to request memory resource\n"); + ret = -EBUSY; + goto err_free_clk; + } + + ssp->phys_base = res->start; + + ssp->mmio_base = ioremap(res->start, res->end - res->start + 1); + if (ssp->mmio_base == NULL) { + dev_err(&pdev->dev, "failed to ioremap() registers\n"); + ret = -ENODEV; + goto err_free_mem; + } + + ssp->irq = platform_get_irq(pdev, 0); + if (ssp->irq < 0) { + dev_err(&pdev->dev, "no IRQ resource defined\n"); + ret = -ENODEV; + goto err_free_io; + } + + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no SSP RX DRCMR defined\n"); + ret = -ENODEV; + goto err_free_io; + } + ssp->drcmr_rx = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (res == NULL) { + dev_err(&pdev->dev, "no SSP TX DRCMR defined\n"); + ret = -ENODEV; + goto err_free_io; + } + ssp->drcmr_tx = res->start; + + /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id + * starts from 0, do a translation here + */ + ssp->port_id = pdev->id + 1; + ssp->use_count = 0; + ssp->type = (int)id->driver_data; + + mutex_lock(&ssp_lock); + list_add(&ssp->node, &ssp_list); + mutex_unlock(&ssp_lock); + + platform_set_drvdata(pdev, ssp); + return 0; + +err_free_io: + iounmap(ssp->mmio_base); +err_free_mem: + release_mem_region(res->start, res->end - res->start + 1); +err_free_clk: + clk_put(ssp->clk); +err_free: + kfree(ssp); + return ret; +} + +static int __devexit ssp_remove(struct platform_device *pdev) +{ + struct resource *res; + struct ssp_device *ssp; + + ssp = platform_get_drvdata(pdev); + if (ssp == NULL) + return -ENODEV; + + iounmap(ssp->mmio_base); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, res->end - res->start + 1); + + clk_put(ssp->clk); + + mutex_lock(&ssp_lock); + list_del(&ssp->node); + mutex_unlock(&ssp_lock); + + kfree(ssp); + return 0; +} + +static const struct platform_device_id ssp_id_table[] = { + { "pxa25x-ssp", PXA25x_SSP }, + { "pxa25x-nssp", PXA25x_NSSP }, + { "pxa27x-ssp", PXA27x_SSP }, + { }, +}; + +static struct platform_driver ssp_driver = { + .probe = ssp_probe, + .remove = __devexit_p(ssp_remove), + .driver = { + .owner = THIS_MODULE, + .name = "pxa2xx-ssp", + }, + .id_table = ssp_id_table, +}; + +static int __init pxa_ssp_init(void) +{ + return platform_driver_register(&ssp_driver); +} + +static void __exit pxa_ssp_exit(void) +{ + platform_driver_unregister(&ssp_driver); +} + +arch_initcall(pxa_ssp_init); +module_exit(pxa_ssp_exit); + +MODULE_DESCRIPTION("PXA SSP driver"); +MODULE_AUTHOR("Liam Girdwood"); +MODULE_LICENSE("GPL"); diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 959e78bb2f04..50d6b780bc67 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -36,7 +36,7 @@ #include #include -#include +#include #include MODULE_AUTHOR("Stephen Street"); diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 2e27962220ad..6271a100f355 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include "pxa2xx-pcm.h" #include "pxa-ssp.h" -- cgit v1.2.3-59-g8ed1b From 866d091dcb043594626d4facf7c6fcffcc7c8d35 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 16 Mar 2010 17:30:15 +0800 Subject: [ARM] pxa: remove incorrect select PXA_SSP in Kconfig PXA_SSP is actually used by drivers like drivers/spi/pxa2xx_spi.c and sound/soc/pxa/pxa-ssp.c, not by boards. Remove those incorrect 'select' from Kconfig and make SOC_PXA_SSP to select. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 13 ------------- sound/soc/pxa/Kconfig | 1 + 2 files changed, 1 insertion(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 6dd450a7dea6..352dc4f3820c 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -19,7 +19,6 @@ config MACH_MAINSTONE config MACH_ZYLONITE bool select PXA3xx - select PXA_SSP select HAVE_PWM select PXA_HAVE_BOARD_IRQS @@ -39,7 +38,6 @@ config MACH_LITTLETON select PXA3xx select CPU_PXA300 select CPU_PXA310 - select PXA_SSP config MACH_TAVOREVB bool "PXA930 Evaluation Board (aka TavorEVB)" @@ -98,7 +96,6 @@ config MACH_ARMCORE select PXA27x select IWMMXT select PXA25x - select PXA_SSP config MACH_EM_X270 bool "CompuLab EM-x270 platform" @@ -161,7 +158,6 @@ config MACH_XCEP select MTD_CFI select MTD_CHAR select SMC91X - select PXA_SSP help PXA255 based Single Board Computer with SMC 91C111 ethernet chip and 64 MB of flash. Tuned for usage in Libera instruments for particle accelerators. @@ -180,7 +176,6 @@ config MACH_TRIZEPS4WL depends on TRIZEPS_PXA select TRIZEPS_PCMCIA select PXA27x - select PXA_SSP choice prompt "Select base board for Trizeps module" @@ -217,7 +212,6 @@ config MACH_PCM027 bool "Phytec phyCORE-PXA270 CPU module (PCM-027)" select PXA27x select IWMMXT - select PXA_SSP select PXA_HAVE_BOARD_IRQS config MACH_PCM990_BASEBOARD @@ -261,7 +255,6 @@ config MACH_H4700 bool "HP iPAQ hx4700" select PXA27x select IWMMXT - select PXA_SSP select HAVE_PWM select PXA_HAVE_BOARD_IRQS @@ -277,7 +270,6 @@ config MACH_MAGICIAN bool "Enable HTC Magician Support" select PXA27x select IWMMXT - select PXA_SSP select HAVE_PWM select PXA_HAVE_BOARD_IRQS @@ -431,13 +423,11 @@ config MACH_RAUMFELD_CONNECTOR bool "Raumfeld Connector" select PXA3xx select CPU_PXA300 - select PXA_SSP config MACH_RAUMFELD_SPEAKER bool "Raumfeld Speaker" select PXA3xx select CPU_PXA300 - select PXA_SSP config PXA_SHARPSL bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models" @@ -466,7 +456,6 @@ config MACH_POODLE depends on PXA_SHARPSL select PXA25x select SHARP_LOCOMO - select PXA_SSP select PXA_HAVE_BOARD_IRQS config MACH_CORGI @@ -636,14 +625,12 @@ config CPU_PXA950 config PXA_SHARP_C7xx bool - select PXA_SSP select SHARPSL_PM help Enable support for all Sharp C7xx models config PXA_SHARP_Cxx00 bool - select PXA_SSP select SHARPSL_PM help Enable common support for Sharp Cxx00 models diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 376e14a9c273..78e612100782 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -23,6 +23,7 @@ config SND_PXA2XX_SOC_I2S config SND_PXA_SOC_SSP tristate + select PXA_SSP config SND_PXA2XX_SOC_CORGI tristate "SoC Audio support for Sharp Zaurus SL-C7x0" -- cgit v1.2.3-59-g8ed1b From 004690f05244e1a41824cda7dc4feb7804964dc6 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Fri, 19 Mar 2010 11:52:39 -0400 Subject: [ARM] pxa: simplify ifdef in ssp.h Try to keep minimum ifdef in ssp.h. Some of the definitions are valid only to specific SoCs, and device drivers should be responsible to take care of these difference. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/plat-pxa/include/plat/ssp.h | 41 +++++++++++++----------------------- 1 file changed, 15 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-pxa/include/plat/ssp.h b/arch/arm/plat-pxa/include/plat/ssp.h index 4c4ce62390d0..74f70c7cc4f0 100644 --- a/arch/arm/plat-pxa/include/plat/ssp.h +++ b/arch/arm/plat-pxa/include/plat/ssp.h @@ -40,10 +40,7 @@ #define SSRSA (0x34) /* SSP Rx Timeslot Active */ #define SSTSS (0x38) /* SSP Timeslot Status */ #define SSACD (0x3C) /* SSP Audio Clock Divider */ - -#if defined(CONFIG_PXA3xx) #define SSACDD (0x40) /* SSP Audio Clock Dither Divider */ -#endif /* Common PXA2xx bits first */ #define SSCR0_DSS (0x0000000f) /* Data Size Select (mask) */ @@ -56,20 +53,17 @@ #define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ #define SSCR0_SCR(x) ((x) << 8) /* Serial Clock Rate (mask) */ -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) +/* PXA27x, PXA3xx */ #define SSCR0_EDSS (1 << 20) /* Extended data size select */ #define SSCR0_NCS (1 << 21) /* Network clock select */ #define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */ #define SSCR0_TUM (1 << 23) /* Transmit FIFO underrun interrupt mask */ #define SSCR0_FRDC (0x07000000) /* Frame rate divider control (mask) */ #define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */ +#define SSCR0_FPCKE (1 << 29) /* FIFO packing enable */ #define SSCR0_ACS (1 << 30) /* Audio clock select */ #define SSCR0_MOD (1 << 31) /* Mode (normal or network) */ -#endif -#if defined(CONFIG_PXA3xx) -#define SSCR0_FPCKE (1 << 29) /* FIFO packing enable */ -#endif #define SSCR1_RIE (1 << 0) /* Receive FIFO Interrupt Enable */ #define SSCR1_TIE (1 << 1) /* Transmit FIFO Interrupt Enable */ @@ -89,10 +83,6 @@ #define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ #define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ -#define SSCR0_TIM (1 << 23) /* Transmit FIFO Under Run Interrupt Mask */ -#define SSCR0_RIM (1 << 22) /* Receive FIFO Over Run interrupt Mask */ -#define SSCR0_NCS (1 << 21) /* Network Clock Select */ -#define SSCR0_EDSS (1 << 20) /* Extended Data Size Select */ /* extra bits in PXA255, PXA26x and PXA27x SSP ports */ #define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ @@ -122,27 +112,26 @@ #define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */ #define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */ -#if defined(CONFIG_PXA3xx) -#define SSPSP_EDMYSTOP(x) ((x) << 28) /* Extended Dummy Stop */ -#define SSPSP_EDMYSTRT(x) ((x) << 26) /* Extended Dummy Start */ -#endif -#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ -#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */ -#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */ -#define SSPSP_SFRMDLY(x) ((x) << 9) /* Serial Frame Delay */ -#define SSPSP_DMYSTRT(x) ((x) << 7) /* Dummy Start */ -#define SSPSP_STRTDLY(x) ((x) << 4) /* Start Delay */ -#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */ -#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */ #define SSPSP_SCMODE(x) ((x) << 0) /* Serial Bit Rate Clock Mode */ +#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */ +#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */ +#define SSPSP_STRTDLY(x) ((x) << 4) /* Start Delay */ +#define SSPSP_DMYSTRT(x) ((x) << 7) /* Dummy Start */ +#define SSPSP_SFRMDLY(x) ((x) << 9) /* Serial Frame Delay */ +#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */ +#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */ +#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ + +/* PXA3xx */ +#define SSPSP_EDMYSTRT(x) ((x) << 26) /* Extended Dummy Start */ +#define SSPSP_EDMYSTOP(x) ((x) << 28) /* Extended Dummy Stop */ +#define SSPSP_TIMING_MASK (0x7f8001f0) #define SSACD_SCDB (1 << 3) /* SSPSYSCLK Divider Bypass */ #define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */ #define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */ -#if defined(CONFIG_PXA3xx) #define SSACD_SCDX8 (1 << 7) /* SYSCLK division ratio select */ -#endif enum pxa_ssp_type { SSP_UNDEFINED = 0, -- cgit v1.2.3-59-g8ed1b From 7e4992288e55f1e15f7498ead618b3943f5cfd3f Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Fri, 19 Mar 2010 11:53:17 -0400 Subject: [ARM] mmp: support ssp in pxa168 Support ssp devices in PXA168. PXA168 could reuse the code of PXA SSP. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/include/mach/irqs.h | 10 +++++----- arch/arm/mach-mmp/include/mach/pxa168.h | 21 +++++++++++++++++++++ arch/arm/mach-mmp/include/mach/regs-apbc.h | 10 +++++----- arch/arm/mach-mmp/pxa168.c | 15 +++++++++++++++ arch/arm/plat-pxa/include/plat/ssp.h | 1 + arch/arm/plat-pxa/ssp.c | 1 + 6 files changed, 48 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index 02701196ea03..b379cdec4d38 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h @@ -5,10 +5,10 @@ * Interrupt numbers for PXA168 */ #define IRQ_PXA168_NONE (-1) -#define IRQ_PXA168_SSP3 0 -#define IRQ_PXA168_SSP2 1 -#define IRQ_PXA168_SSP1 2 -#define IRQ_PXA168_SSP0 3 +#define IRQ_PXA168_SSP4 0 +#define IRQ_PXA168_SSP3 1 +#define IRQ_PXA168_SSP2 2 +#define IRQ_PXA168_SSP1 3 #define IRQ_PXA168_PMIC_INT 4 #define IRQ_PXA168_RTC_INT 5 #define IRQ_PXA168_RTC_ALARM 6 @@ -20,7 +20,7 @@ #define IRQ_PXA168_TIMER2 14 #define IRQ_PXA168_TIMER3 15 #define IRQ_PXA168_CMU 16 -#define IRQ_PXA168_SSP4 17 +#define IRQ_PXA168_SSP5 17 #define IRQ_PXA168_MSP_WAKEUP 19 #define IRQ_PXA168_CF_WAKEUP 20 #define IRQ_PXA168_XD_WAKEUP 21 diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h index 3ad612cbdf09..3b2bd5d5eb05 100644 --- a/arch/arm/mach-mmp/include/mach/pxa168.h +++ b/arch/arm/mach-mmp/include/mach/pxa168.h @@ -14,6 +14,11 @@ extern struct pxa_device_desc pxa168_device_pwm1; extern struct pxa_device_desc pxa168_device_pwm2; extern struct pxa_device_desc pxa168_device_pwm3; extern struct pxa_device_desc pxa168_device_pwm4; +extern struct pxa_device_desc pxa168_device_ssp1; +extern struct pxa_device_desc pxa168_device_ssp2; +extern struct pxa_device_desc pxa168_device_ssp3; +extern struct pxa_device_desc pxa168_device_ssp4; +extern struct pxa_device_desc pxa168_device_ssp5; extern struct pxa_device_desc pxa168_device_nand; static inline int pxa168_add_uart(int id) @@ -67,6 +72,22 @@ static inline int pxa168_add_pwm(int id) return pxa_register_device(d, NULL, 0); } +static inline int pxa168_add_ssp(int id) +{ + struct pxa_device_desc *d = NULL; + + switch (id) { + case 1: d = &pxa168_device_ssp1; break; + case 2: d = &pxa168_device_ssp2; break; + case 3: d = &pxa168_device_ssp3; break; + case 4: d = &pxa168_device_ssp4; break; + case 5: d = &pxa168_device_ssp5; break; + default: + return -EINVAL; + } + return pxa_register_device(d, NULL, 0); +} + static inline int pxa168_add_nand(struct pxa3xx_nand_platform_data *info) { return pxa_register_device(&pxa168_device_nand, info, sizeof(*info)); diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h index 712af03fd1af..1a96585336ba 100644 --- a/arch/arm/mach-mmp/include/mach/regs-apbc.h +++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h @@ -26,8 +26,6 @@ #define APBC_PXA168_PWM2 APBC_REG(0x010) #define APBC_PXA168_PWM3 APBC_REG(0x014) #define APBC_PXA168_PWM4 APBC_REG(0x018) -#define APBC_PXA168_SSP1 APBC_REG(0x01c) -#define APBC_PXA168_SSP2 APBC_REG(0x020) #define APBC_PXA168_RTC APBC_REG(0x028) #define APBC_PXA168_TWSI0 APBC_REG(0x02c) #define APBC_PXA168_KPC APBC_REG(0x030) @@ -35,14 +33,16 @@ #define APBC_PXA168_AIB APBC_REG(0x03c) #define APBC_PXA168_SW_JTAG APBC_REG(0x040) #define APBC_PXA168_ONEWIRE APBC_REG(0x048) -#define APBC_PXA168_SSP3 APBC_REG(0x04c) #define APBC_PXA168_ASFAR APBC_REG(0x050) #define APBC_PXA168_ASSAR APBC_REG(0x054) -#define APBC_PXA168_SSP4 APBC_REG(0x058) -#define APBC_PXA168_SSP5 APBC_REG(0x05c) #define APBC_PXA168_TWSI1 APBC_REG(0x06c) #define APBC_PXA168_UART3 APBC_REG(0x070) #define APBC_PXA168_AC97 APBC_REG(0x084) +#define APBC_PXA168_SSP1 APBC_REG(0x81c) +#define APBC_PXA168_SSP2 APBC_REG(0x820) +#define APBC_PXA168_SSP3 APBC_REG(0x84c) +#define APBC_PXA168_SSP4 APBC_REG(0x858) +#define APBC_PXA168_SSP5 APBC_REG(0x85c) /* * APB Clock register offsets for PXA910 diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index 1873c821df90..652ae660634c 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c @@ -72,6 +72,11 @@ static APBC_CLK(pwm1, PXA168_PWM1, 1, 13000000); static APBC_CLK(pwm2, PXA168_PWM2, 1, 13000000); static APBC_CLK(pwm3, PXA168_PWM3, 1, 13000000); static APBC_CLK(pwm4, PXA168_PWM4, 1, 13000000); +static APBC_CLK(ssp1, PXA168_SSP1, 4, 0); +static APBC_CLK(ssp2, PXA168_SSP2, 4, 0); +static APBC_CLK(ssp3, PXA168_SSP3, 4, 0); +static APBC_CLK(ssp4, PXA168_SSP4, 4, 0); +static APBC_CLK(ssp5, PXA168_SSP5, 4, 0); static APMU_CLK(nand, NAND, 0x01db, 208000000); @@ -85,6 +90,11 @@ static struct clk_lookup pxa168_clkregs[] = { INIT_CLKREG(&clk_pwm2, "pxa168-pwm.1", NULL), INIT_CLKREG(&clk_pwm3, "pxa168-pwm.2", NULL), INIT_CLKREG(&clk_pwm4, "pxa168-pwm.3", NULL), + INIT_CLKREG(&clk_ssp1, "pxa168-ssp.0", NULL), + INIT_CLKREG(&clk_ssp2, "pxa168-ssp.1", NULL), + INIT_CLKREG(&clk_ssp3, "pxa168-ssp.2", NULL), + INIT_CLKREG(&clk_ssp4, "pxa168-ssp.3", NULL), + INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL), INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), }; @@ -132,3 +142,8 @@ PXA168_DEVICE(pwm2, "pxa168-pwm", 1, NONE, 0xd401a400, 0x10); PXA168_DEVICE(pwm3, "pxa168-pwm", 2, NONE, 0xd401a800, 0x10); PXA168_DEVICE(pwm4, "pxa168-pwm", 3, NONE, 0xd401ac00, 0x10); PXA168_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x80, 97, 99); +PXA168_DEVICE(ssp1, "pxa168-ssp", 0, SSP1, 0xd401b000, 0x40, 52, 53); +PXA168_DEVICE(ssp2, "pxa168-ssp", 1, SSP2, 0xd401c000, 0x40, 54, 55); +PXA168_DEVICE(ssp3, "pxa168-ssp", 2, SSP3, 0xd401f000, 0x40, 56, 57); +PXA168_DEVICE(ssp4, "pxa168-ssp", 3, SSP4, 0xd4020000, 0x40, 58, 59); +PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61); diff --git a/arch/arm/plat-pxa/include/plat/ssp.h b/arch/arm/plat-pxa/include/plat/ssp.h index 74f70c7cc4f0..d16d79a3a48a 100644 --- a/arch/arm/plat-pxa/include/plat/ssp.h +++ b/arch/arm/plat-pxa/include/plat/ssp.h @@ -138,6 +138,7 @@ enum pxa_ssp_type { PXA25x_SSP, /* pxa 210, 250, 255, 26x */ PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ PXA27x_SSP, + PXA168_SSP, }; struct ssp_device { diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c index 5fe230178f0a..cfebcd836f3e 100644 --- a/arch/arm/plat-pxa/ssp.c +++ b/arch/arm/plat-pxa/ssp.c @@ -192,6 +192,7 @@ static const struct platform_device_id ssp_id_table[] = { { "pxa25x-ssp", PXA25x_SSP }, { "pxa25x-nssp", PXA25x_NSSP }, { "pxa27x-ssp", PXA27x_SSP }, + { "pxa168-ssp", PXA168_SSP }, { }, }; -- cgit v1.2.3-59-g8ed1b From 07871c195a5ec7d59d34994c123472b113da09ba Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Fri, 19 Mar 2010 11:55:14 -0400 Subject: [ARM] mmp: enable ssp in aspenite Configure both ssp and wm8753 in aspenite. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/aspenite.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index a2d307ec0420..244655d323ea 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c @@ -59,6 +59,13 @@ static unsigned long common_pin_config[] __initdata = { /* UART1 */ GPIO107_UART1_RXD, GPIO108_UART1_TXD, + + /* SSP1 */ + GPIO113_I2S_MCLK, + GPIO114_I2S_FRM, + GPIO115_I2S_BCLK, + GPIO116_I2S_RXD, + GPIO117_I2S_TXD, }; static struct smc91x_platdata smc91x_info = { @@ -123,12 +130,18 @@ static struct pxa3xx_nand_platform_data aspenite_nand_info = { .nr_parts = ARRAY_SIZE(aspenite_nand_partitions), }; +static struct i2c_board_info aspenite_i2c_info[] __initdata = { + { I2C_BOARD_INFO("wm8753", 0x1b), }, +}; + static void __init common_init(void) { mfp_config(ARRAY_AND_SIZE(common_pin_config)); /* on-chip devices */ pxa168_add_uart(1); + pxa168_add_twsi(1, NULL, ARRAY_AND_SIZE(aspenite_i2c_info)); + pxa168_add_ssp(1); pxa168_add_nand(&aspenite_nand_info); /* off-chip devices */ -- cgit v1.2.3-59-g8ed1b From 077de1ad5ad8b4e08fd8853ae7e4cc628c1a369b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 22 Mar 2010 16:11:55 +0800 Subject: [ARM] pxa: avoid NULL dereferencing in error handling of ssp.c The assignments of res to the results of the two calls to platform_get_resource make it impossible to use res in the error handling code in the arguments to release_mem_region. The semantic match that finds the former problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E, E1; identifier f; statement S1,S3; iterator iter; @@ if ((E == NULL && ...) || ...) { ... when != false ((E == NULL && ...) || ...) when != true ((E != NULL && ...) || ...) when != iter(E,...) S1 when != E = E1 ( sizeof(E->f) | * E->f ) ... when any return ...; } else S3 // Signed-off-by: Julia Lawall Signed-off-by: Eric Miao --- arch/arm/plat-pxa/ssp.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c index cfebcd836f3e..3bf704d7a0d6 100644 --- a/arch/arm/plat-pxa/ssp.c +++ b/arch/arm/plat-pxa/ssp.c @@ -92,6 +92,22 @@ static int __devinit ssp_probe(struct platform_device *pdev) goto err_free; } + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no SSP RX DRCMR defined\n"); + ret = -ENODEV; + goto err_free_clk; + } + ssp->drcmr_rx = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (res == NULL) { + dev_err(&pdev->dev, "no SSP TX DRCMR defined\n"); + ret = -ENODEV; + goto err_free_clk; + } + ssp->drcmr_tx = res->start; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "no memory resource defined\n"); @@ -123,22 +139,6 @@ static int __devinit ssp_probe(struct platform_device *pdev) goto err_free_io; } - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (res == NULL) { - dev_err(&pdev->dev, "no SSP RX DRCMR defined\n"); - ret = -ENODEV; - goto err_free_io; - } - ssp->drcmr_rx = res->start; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (res == NULL) { - dev_err(&pdev->dev, "no SSP TX DRCMR defined\n"); - ret = -ENODEV; - goto err_free_io; - } - ssp->drcmr_tx = res->start; - /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id * starts from 0, do a translation here */ -- cgit v1.2.3-59-g8ed1b From c8ee5c69516fdd973b981e3ac12d49b3133930cd Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 22 Mar 2010 16:16:24 +0800 Subject: [ARM] pxa: use resource_size() in ssp.c Signed-off-by: Julia Lawall Signed-off-by: Eric Miao --- arch/arm/plat-pxa/ssp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c index 3bf704d7a0d6..52c07cc756d7 100644 --- a/arch/arm/plat-pxa/ssp.c +++ b/arch/arm/plat-pxa/ssp.c @@ -115,7 +115,7 @@ static int __devinit ssp_probe(struct platform_device *pdev) goto err_free_clk; } - res = request_mem_region(res->start, res->end - res->start + 1, + res = request_mem_region(res->start, resource_size(res), pdev->name); if (res == NULL) { dev_err(&pdev->dev, "failed to request memory resource\n"); @@ -125,7 +125,7 @@ static int __devinit ssp_probe(struct platform_device *pdev) ssp->phys_base = res->start; - ssp->mmio_base = ioremap(res->start, res->end - res->start + 1); + ssp->mmio_base = ioremap(res->start, resource_size(res)); if (ssp->mmio_base == NULL) { dev_err(&pdev->dev, "failed to ioremap() registers\n"); ret = -ENODEV; @@ -156,7 +156,7 @@ static int __devinit ssp_probe(struct platform_device *pdev) err_free_io: iounmap(ssp->mmio_base); err_free_mem: - release_mem_region(res->start, res->end - res->start + 1); + release_mem_region(res->start, resource_size(res)); err_free_clk: clk_put(ssp->clk); err_free: @@ -176,7 +176,7 @@ static int __devexit ssp_remove(struct platform_device *pdev) iounmap(ssp->mmio_base); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, res->end - res->start + 1); + release_mem_region(res->start, resource_size(res)); clk_put(ssp->clk); -- cgit v1.2.3-59-g8ed1b From 1106143d7ab43ba07678c88c85417df219354ae8 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 11 Jan 2010 21:25:15 +0800 Subject: [ARM] pxa: add MFP_LPM_KEEP_OUTPUT flag to pin config Some pins are expected to keep their last level during suspend, and introduce MFP_LPM_KEEP_OUTPUT for this. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h | 2 ++ arch/arm/mach-pxa/mfp-pxa2xx.c | 11 +++++++++++ 2 files changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h index 658b28ed129b..c54cef25895c 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h @@ -25,6 +25,8 @@ #define MFP_DIR(x) (((x) >> 23) & 0x1) #define MFP_LPM_CAN_WAKEUP (0x1 << 24) +#define MFP_LPM_KEEP_OUTPUT (0x1 << 25) + #define WAKEUP_ON_EDGE_RISE (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE) #define WAKEUP_ON_EDGE_FALL (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_FALL) #define WAKEUP_ON_EDGE_BOTH (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_BOTH) diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index cf6b720c055f..c98b5a8c3b0f 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -328,6 +328,17 @@ static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state) { int i; + /* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */ + for (i = 0; i < pxa_last_gpio; i++) { + if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && + (GPDR(i) & GPIO_bit(i))) { + if (GPLR(i) & GPIO_bit(i)) + PGSR(i) |= GPIO_bit(i); + else + PGSR(i) &= ~GPIO_bit(i); + } + } + for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { saved_gafr[0][i] = GAFR_L(i); -- cgit v1.2.3-59-g8ed1b From c09f431c338cf032c68ea68915f4dd85d92fd526 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 20 Apr 2010 14:52:50 +0800 Subject: [ARM] pxa: allow keypad GPIOs to wakeup when configured as generic Signed-off-by: Eric Miao --- arch/arm/mach-pxa/mfp-pxa2xx.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index c98b5a8c3b0f..e5b79210a90b 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -178,8 +178,17 @@ int gpio_set_wake(unsigned int gpio, unsigned int on) if (!d->valid) return -EINVAL; - if (d->keypad_gpio) - return -EINVAL; + /* Allow keypad GPIOs to wakeup system when + * configured as generic GPIOs. + */ + if (d->keypad_gpio && (MFP_AF(d->config) == 0) && + (d->config & MFP_LPM_CAN_WAKEUP)) { + if (on) + PKWR |= d->mask; + else + PKWR &= ~d->mask; + return 0; + } mux_taken = (PWER & d->mux_mask) & (~d->mask); if (on && mux_taken) @@ -239,21 +248,25 @@ static int pxa27x_pkwr_gpio[] = { int keypad_set_wake(unsigned int on) { unsigned int i, gpio, mask = 0; - - if (!on) { - PKWR = 0; - return 0; - } + struct gpio_desc *d; for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) { gpio = pxa27x_pkwr_gpio[i]; + d = &gpio_desc[gpio]; - if (gpio_desc[gpio].config & MFP_LPM_CAN_WAKEUP) + /* skip if configured as generic GPIO */ + if (MFP_AF(d->config) == 0) + continue; + + if (d->config & MFP_LPM_CAN_WAKEUP) mask |= gpio_desc[gpio].mask; } - PKWR = mask; + if (on) + PKWR |= mask; + else + PKWR &= ~mask; return 0; } -- cgit v1.2.3-59-g8ed1b From 1fe8c2bcad52d16e4d31d3680b9bb536c56df3d8 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 27 Apr 2010 11:14:24 +0800 Subject: [ARM] pxa: allow MFP_LPM_INPUT to be explicitly specified Signed-off-by: Eric Miao --- arch/arm/mach-pxa/mfp-pxa2xx.c | 1 + arch/arm/plat-pxa/mfp.c | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index e5b79210a90b..1d1419b73457 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -81,6 +81,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) PGSR(bank) &= ~mask; is_out = 1; break; + case MFP_LPM_INPUT: case MFP_LPM_DEFAULT: break; default: diff --git a/arch/arm/plat-pxa/mfp.c b/arch/arm/plat-pxa/mfp.c index be58f9fe65b0..b77e018d36c1 100644 --- a/arch/arm/plat-pxa/mfp.c +++ b/arch/arm/plat-pxa/mfp.c @@ -110,6 +110,7 @@ static const unsigned long mfpr_lpm[] = { MFPR_LPM_PULL_LOW, MFPR_LPM_PULL_HIGH, MFPR_LPM_FLOAT, + MFPR_LPM_INPUT, }; /* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */ -- cgit v1.2.3-59-g8ed1b From b6eede112673678f8a7a1680d6ad12245443829d Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 11 Jan 2010 16:17:25 +0800 Subject: [ARM] pxa/spitz: use generic GPIO API and remove pxa_gpio_mode() REVISIT: change to GPIO18 is ugly, need to make sure whether that's really necessary - GPIO18_RDY as an VLIO input signal - we don't normally need to do such kind of trick during low power mode. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/spitz.c | 4 +++- arch/arm/mach-pxa/spitz_pm.c | 28 +++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 01bdd7500df4..451029ea9eec 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -86,6 +86,7 @@ static unsigned long spitz_pin_config[] __initdata = { /* GPIOs */ GPIO9_GPIO, /* SPITZ_GPIO_nSD_DETECT */ + GPIO16_GPIO, /* SPITZ_GPIO_SYNC */ GPIO81_GPIO, /* SPITZ_GPIO_nSD_WP */ GPIO41_GPIO, /* SPITZ_GPIO_USB_CONNECT */ GPIO37_GPIO, /* SPITZ_GPIO_USB_HOST */ @@ -119,7 +120,8 @@ static unsigned long spitz_pin_config[] __initdata = { GPIO117_I2C_SCL, GPIO118_I2C_SDA, - GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, + GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, /* SPITZ_GPIO_KEY_INT */ + GPIO1_GPIO | WAKEUP_ON_EDGE_FALL, /* SPITZ_GPIO_RESET */ }; /* diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index fc5a70c40358..4209ddf6da61 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -24,9 +24,10 @@ #include #include -#include -#include +#include + #include "sharpsl.h" +#include "generic.h" #define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */ #define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */ @@ -37,10 +38,17 @@ static int spitz_last_ac_status; +static struct gpio spitz_charger_gpios[] = { + { SPITZ_GPIO_KEY_INT, GPIOF_IN, "Keyboard Interrupt" }, + { SPITZ_GPIO_SYNC, GPIOF_IN, "Sync" }, + { SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" }, + { SPITZ_GPIO_JK_B, GPIOF_OUT_INIT_LOW, "JK B" }, + { SPITZ_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" }, +}; + static void spitz_charger_init(void) { - pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN); - pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN); + gpio_request_array(ARRAY_AND_SIZE(spitz_charger_gpios)); } static void spitz_measure_temp(int on) @@ -76,6 +84,11 @@ static void spitz_discharge1(int on) gpio_set_value(SPITZ_GPIO_LED_GREEN, on); } +static unsigned long gpio18_config[] = { + GPIO18_RDY, + GPIO18_GPIO, +}; + static void spitz_presuspend(void) { spitz_last_ac_status = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN); @@ -97,7 +110,9 @@ static void spitz_presuspend(void) PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0); - pxa_gpio_mode(GPIO18_RDY|GPIO_OUT | GPIO_DFLT_HIGH); + pxa2xx_mfp_config(&gpio18_config[0], 1); + gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown"); + gpio_free(18); PRER = GPIO_bit(SPITZ_GPIO_KEY_INT); PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET); @@ -114,8 +129,7 @@ static void spitz_presuspend(void) static void spitz_postsuspend(void) { - pxa_gpio_mode(GPIO18_RDY_MD); - pxa_gpio_mode(10 | GPIO_IN); + pxa2xx_mfp_config(&gpio18_config[1], 1); } static int spitz_should_wakeup(unsigned int resume_on_alarm) -- cgit v1.2.3-59-g8ed1b From e63f591a8ce5d3b5214a14d6cebaad7b6c1c4b4c Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Fri, 8 Jan 2010 13:32:46 +0800 Subject: [ARM] pxa/corgi: use generic GPIO API and remove pxa_gpio_mode() Signed-off-by: Eric Miao --- arch/arm/mach-pxa/corgi.c | 8 ++++++-- arch/arm/mach-pxa/corgi_pm.c | 38 +++++++++++++++++++------------------- 2 files changed, 25 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index da3156d8690b..788343d0ffe1 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -130,11 +130,15 @@ static unsigned long corgi_pin_config[] __initdata = { /* GPIO */ GPIO9_GPIO, /* CORGI_GPIO_nSD_DETECT */ GPIO7_GPIO, /* CORGI_GPIO_nSD_WP */ - GPIO33_GPIO, /* CORGI_GPIO_SD_PWR */ + GPIO21_GPIO, /* CORGI_GPIO_ADC_TEMP */ GPIO22_GPIO, /* CORGI_GPIO_IR_ON */ + GPIO33_GPIO, /* CORGI_GPIO_SD_PWR */ + GPIO38_GPIO, /* CORGI_GPIO_CHRG_ON */ + GPIO43_GPIO, /* CORGI_GPIO_CHRG_UKN */ GPIO44_GPIO, /* CORGI_GPIO_HSYNC */ - GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, + GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_KEY_INT */ + GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* CORGI_GPIO_AC_IN */ }; /* diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index d4a0733e905b..bb68347d9d70 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,8 @@ #include #include #include -#include + +#include "generic.h" #include "sharpsl.h" #define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */ @@ -35,44 +37,42 @@ #define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */ #define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */ +static struct gpio charger_gpios[] = { + { CORGI_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" }, + { CORGI_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" }, + { CORGI_GPIO_CHRG_UKN, GPIOF_OUT_INIT_LOW, "Charger Unknown" }, + { CORGI_GPIO_KEY_INT, GPIOF_IN, "Key Interrupt" }, +}; + static void corgi_charger_init(void) { - pxa_gpio_mode(CORGI_GPIO_ADC_TEMP_ON | GPIO_OUT); - pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT); - pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT); - pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN); + gpio_request_array(ARRAY_AND_SIZE(charger_gpios)); } static void corgi_measure_temp(int on) { - if (on) - GPSR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON); - else - GPCR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON); + gpio_set_value(CORGI_GPIO_ADC_TEMP_ON, on); } static void corgi_charge(int on) { if (on) { if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) { - GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON); - GPSR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN); + gpio_set_value(CORGI_GPIO_CHRG_ON, 0); + gpio_set_value(CORGI_GPIO_CHRG_UKN, 1); } else { - GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON); - GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN); + gpio_set_value(CORGI_GPIO_CHRG_ON, 1); + gpio_set_value(CORGI_GPIO_CHRG_UKN, 0); } } else { - GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON); - GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN); + gpio_set_value(CORGI_GPIO_CHRG_ON, 0); + gpio_set_value(CORGI_GPIO_CHRG_UKN, 0); } } static void corgi_discharge(int on) { - if (on) - GPSR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON); - else - GPCR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON); + gpio_set_value(CORGI_GPIO_DISCHARGE_ON, on); } static void corgi_presuspend(void) -- cgit v1.2.3-59-g8ed1b From cb432b358dced89bd2af86b3f783a0a99e489421 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 11 Jan 2010 21:27:21 +0800 Subject: [ARM] pxa/corgi: cleanup GPIO configurations and low power mode settings Signed-off-by: Eric Miao --- arch/arm/mach-pxa/corgi.c | 52 +++++++++++++++++++++++++++----------------- arch/arm/mach-pxa/corgi_pm.c | 39 --------------------------------- 2 files changed, 32 insertions(+), 59 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 788343d0ffe1..f8e295900c58 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -106,18 +106,18 @@ static unsigned long corgi_pin_config[] __initdata = { GPIO8_MMC_CS0, /* GPIO Matrix Keypad */ - GPIO66_GPIO, /* column 0 */ - GPIO67_GPIO, /* column 1 */ - GPIO68_GPIO, /* column 2 */ - GPIO69_GPIO, /* column 3 */ - GPIO70_GPIO, /* column 4 */ - GPIO71_GPIO, /* column 5 */ - GPIO72_GPIO, /* column 6 */ - GPIO73_GPIO, /* column 7 */ - GPIO74_GPIO, /* column 8 */ - GPIO75_GPIO, /* column 9 */ - GPIO76_GPIO, /* column 10 */ - GPIO77_GPIO, /* column 11 */ + GPIO66_GPIO | MFP_LPM_DRIVE_HIGH, /* column 0 */ + GPIO67_GPIO | MFP_LPM_DRIVE_HIGH, /* column 1 */ + GPIO68_GPIO | MFP_LPM_DRIVE_HIGH, /* column 2 */ + GPIO69_GPIO | MFP_LPM_DRIVE_HIGH, /* column 3 */ + GPIO70_GPIO | MFP_LPM_DRIVE_HIGH, /* column 4 */ + GPIO71_GPIO | MFP_LPM_DRIVE_HIGH, /* column 5 */ + GPIO72_GPIO | MFP_LPM_DRIVE_HIGH, /* column 6 */ + GPIO73_GPIO | MFP_LPM_DRIVE_HIGH, /* column 7 */ + GPIO74_GPIO | MFP_LPM_DRIVE_HIGH, /* column 8 */ + GPIO75_GPIO | MFP_LPM_DRIVE_HIGH, /* column 9 */ + GPIO76_GPIO | MFP_LPM_DRIVE_HIGH, /* column 10 */ + GPIO77_GPIO | MFP_LPM_DRIVE_HIGH, /* column 11 */ GPIO58_GPIO, /* row 0 */ GPIO59_GPIO, /* row 1 */ GPIO60_GPIO, /* row 2 */ @@ -128,17 +128,20 @@ static unsigned long corgi_pin_config[] __initdata = { GPIO65_GPIO, /* row 7 */ /* GPIO */ - GPIO9_GPIO, /* CORGI_GPIO_nSD_DETECT */ - GPIO7_GPIO, /* CORGI_GPIO_nSD_WP */ - GPIO21_GPIO, /* CORGI_GPIO_ADC_TEMP */ - GPIO22_GPIO, /* CORGI_GPIO_IR_ON */ - GPIO33_GPIO, /* CORGI_GPIO_SD_PWR */ - GPIO38_GPIO, /* CORGI_GPIO_CHRG_ON */ - GPIO43_GPIO, /* CORGI_GPIO_CHRG_UKN */ - GPIO44_GPIO, /* CORGI_GPIO_HSYNC */ + GPIO9_GPIO, /* CORGI_GPIO_nSD_DETECT */ + GPIO7_GPIO, /* CORGI_GPIO_nSD_WP */ + GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_MAIN_BAT_{LOW,COVER} */ + GPIO13_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_LED_ORANGE */ + GPIO21_GPIO, /* CORGI_GPIO_ADC_TEMP */ + GPIO22_GPIO, /* CORGI_GPIO_IR_ON */ + GPIO33_GPIO, /* CORGI_GPIO_SD_PWR */ + GPIO38_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_CHRG_ON */ + GPIO43_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_CHRG_UKN */ + GPIO44_GPIO, /* CORGI_GPIO_HSYNC */ GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_KEY_INT */ GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* CORGI_GPIO_AC_IN */ + GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_WAKEUP */ }; /* @@ -676,6 +679,15 @@ static void __init corgi_init(void) pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config)); + /* allow wakeup from various GPIOs */ + gpio_set_wake(CORGI_GPIO_KEY_INT, 1); + gpio_set_wake(CORGI_GPIO_WAKEUP, 1); + gpio_set_wake(CORGI_GPIO_AC_IN, 1); + gpio_set_wake(CORGI_GPIO_CHRG_FULL, 1); + + if (!machine_is_corgi()) + gpio_set_wake(CORGI_GPIO_MAIN_BAT_LOW, 1); + pxa_set_ffuart_info(NULL); pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index bb68347d9d70..3f1dc74ac048 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -77,45 +77,6 @@ static void corgi_discharge(int on) static void corgi_presuspend(void) { - int i; - unsigned long wakeup_mask; - - /* charging , so CHARGE_ON bit is HIGH during OFF. */ - if (READ_GPIO_BIT(CORGI_GPIO_CHRG_ON)) - PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_ON); - else - PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_ON); - - if (READ_GPIO_BIT(CORGI_GPIO_LED_ORANGE)) - PGSR0 |= GPIO_bit(CORGI_GPIO_LED_ORANGE); - else - PGSR0 &= ~GPIO_bit(CORGI_GPIO_LED_ORANGE); - - if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN)) - PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN); - else - PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN); - - /* Resume on keyboard power key */ - PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0); - - wakeup_mask = GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) | GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_CHRG_FULL); - - if (!machine_is_corgi()) - wakeup_mask |= GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW); - - PWER = wakeup_mask | PWER_RTC; - PRER = wakeup_mask; - PFER = wakeup_mask; - - for (i = 0; i <=15; i++) { - if (PRER & PFER & GPIO_bit(i)) { - if (GPLR0 & GPIO_bit(i) ) - PRER &= ~GPIO_bit(i); - else - PFER &= ~GPIO_bit(i); - } - } } static void corgi_postsuspend(void) -- cgit v1.2.3-59-g8ed1b From cb8f3c7dea960c27fcc66830cdaab82b13f1b597 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 27 Apr 2010 14:43:03 +0800 Subject: [ARM] pxa/tosa: move CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES to mach/Kconfig Tosa is now able to use generic matrix keypad driver instead of the deprecated tosakbd.c, where CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES is still useful. Move it to mach/Kconfig. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 12 ++++++++++++ arch/arm/mach-pxa/include/mach/tosa.h | 2 +- drivers/input/keyboard/Kconfig | 10 ---------- 3 files changed, 13 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 352dc4f3820c..454cd5d5f105 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -643,6 +643,18 @@ config TOSA_BT This is a simple driver that is able to control the state of built in bluetooth chip on tosa. +config TOSA_USE_EXT_KEYCODES + bool "Tosa keyboard: use extended keycodes" + depends on MACH_TOSA + default n + help + Say Y here to enable the tosa keyboard driver to generate extended + (>= 127) keycodes. Be aware, that they can't be correctly interpreted + by either console keyboard driver or by Kdrive keybd driver. + + Say Y only if you know, what you are doing! + + config PXA_HAVE_BOARD_IRQS bool diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h index 4df2d38507dc..1bbd1f2e4beb 100644 --- a/arch/arm/mach-pxa/include/mach/tosa.h +++ b/arch/arm/mach-pxa/include/mach/tosa.h @@ -167,7 +167,7 @@ #define TOSA_KEY_SYNC KEY_102ND /* ??? */ -#ifndef CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES +#ifndef CONFIG_TOSA_USE_EXT_KEYCODES #define TOSA_KEY_RECORD KEY_YEN #define TOSA_KEY_ADDRESSBOOK KEY_KATAKANA #define TOSA_KEY_CANCEL KEY_ESC diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 64c102355f53..a74ee121f51e 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -426,16 +426,6 @@ config KEYBOARD_TOSA To compile this driver as a module, choose M here: the module will be called tosakbd. -config KEYBOARD_TOSA_USE_EXT_KEYCODES - bool "Tosa keyboard: use extended keycodes" - depends on KEYBOARD_TOSA - help - Say Y here to enable the tosa keyboard driver to generate extended - (>= 127) keycodes. Be aware, that they can't be correctly interpreted - by either console keyboard driver or by Kdrive keybd driver. - - Say Y only if you know, what you are doing! - config KEYBOARD_XTKBD tristate "XT keyboard" select SERIO -- cgit v1.2.3-59-g8ed1b From b1d9bf1d9836dcee235f49bb4eb5ba4450a3a678 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 27 Apr 2010 15:09:33 +0800 Subject: [ARM] pxa: remove pxa_gpio_mode() and files Signed-off-by: Eric Miao --- arch/arm/mach-pxa/generic.c | 31 --- arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h | 375 --------------------------- arch/arm/mach-pxa/sharpsl_pm.c | 1 - 3 files changed, 407 deletions(-) delete mode 100644 arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h (limited to 'arch') diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 3126a35aa002..baabb3ce088e 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -28,7 +28,6 @@ #include #include -#include #include "generic.h" @@ -128,33 +127,3 @@ void __init pxa_map_io(void) iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); get_clk_frequency_khz(1); } - -/* - * Configure pins for GPIO or other functions - */ -int pxa_gpio_mode(int gpio_mode) -{ - unsigned long flags; - int gpio = gpio_mode & GPIO_MD_MASK_NR; - int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; - int gafr; - - if (gpio > pxa_last_gpio) - return -EINVAL; - - local_irq_save(flags); - if (gpio_mode & GPIO_DFLT_LOW) - GPCR(gpio) = GPIO_bit(gpio); - else if (gpio_mode & GPIO_DFLT_HIGH) - GPSR(gpio) = GPIO_bit(gpio); - if (gpio_mode & GPIO_MD_MASK_DIR) - GPDR(gpio) |= GPIO_bit(gpio); - else - GPDR(gpio) &= ~GPIO_bit(gpio); - gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); - GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); - local_irq_restore(flags); - - return 0; -} -EXPORT_SYMBOL(pxa_gpio_mode); diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h b/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h deleted file mode 100644 index 1209c44aa6f1..000000000000 --- a/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h +++ /dev/null @@ -1,375 +0,0 @@ -#ifndef __ASM_ARCH_PXA2XX_GPIO_H -#define __ASM_ARCH_PXA2XX_GPIO_H - -#warning Please use mfp-pxa2[57]x.h instead of pxa2xx-gpio.h - -#include - -/* GPIO alternate function assignments */ - -#define GPIO1_RST 1 /* reset */ -#define GPIO6_MMCCLK 6 /* MMC Clock */ -#define GPIO7_48MHz 7 /* 48 MHz clock output */ -#define GPIO8_MMCCS0 8 /* MMC Chip Select 0 */ -#define GPIO9_MMCCS1 9 /* MMC Chip Select 1 */ -#define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */ -#define GPIO11_3_6MHz 11 /* 3.6 MHz oscillator out */ -#define GPIO12_32KHz 12 /* 32 kHz out */ -#define GPIO12_CIF_DD_7 12 /* Camera data pin 7 */ -#define GPIO13_MBGNT 13 /* memory controller grant */ -#define GPIO14_MBREQ 14 /* alternate bus master request */ -#define GPIO15_nCS_1 15 /* chip select 1 */ -#define GPIO16_PWM0 16 /* PWM0 output */ -#define GPIO17_PWM1 17 /* PWM1 output */ -#define GPIO17_CIF_DD_6 17 /* Camera data pin 6 */ -#define GPIO18_RDY 18 /* Ext. Bus Ready */ -#define GPIO19_DREQ1 19 /* External DMA Request */ -#define GPIO20_DREQ0 20 /* External DMA Request */ -#define GPIO23_SCLK 23 /* SSP clock */ -#define GPIO23_CIF_MCLK 23 /* Camera Master Clock */ -#define GPIO24_SFRM 24 /* SSP Frame */ -#define GPIO24_CIF_FV 24 /* Camera frame start signal */ -#define GPIO25_STXD 25 /* SSP transmit */ -#define GPIO25_CIF_LV 25 /* Camera line start signal */ -#define GPIO26_SRXD 26 /* SSP receive */ -#define GPIO26_CIF_PCLK 26 /* Camera Pixel Clock */ -#define GPIO27_SEXTCLK 27 /* SSP ext_clk */ -#define GPIO27_CIF_DD_0 27 /* Camera data pin 0 */ -#define GPIO28_BITCLK 28 /* AC97/I2S bit_clk */ -#define GPIO29_SDATA_IN 29 /* AC97 Sdata_in0 / I2S Sdata_in */ -#define GPIO30_SDATA_OUT 30 /* AC97/I2S Sdata_out */ -#define GPIO31_SYNC 31 /* AC97/I2S sync */ -#define GPIO32_SDATA_IN1 32 /* AC97 Sdata_in1 */ -#define GPIO32_SYSCLK 32 /* I2S System Clock */ -#define GPIO32_MMCCLK 32 /* MMC Clock (PXA270) */ -#define GPIO33_nCS_5 33 /* chip select 5 */ -#define GPIO34_FFRXD 34 /* FFUART receive */ -#define GPIO34_MMCCS0 34 /* MMC Chip Select 0 */ -#define GPIO35_FFCTS 35 /* FFUART Clear to send */ -#define GPIO36_FFDCD 36 /* FFUART Data carrier detect */ -#define GPIO37_FFDSR 37 /* FFUART data set ready */ -#define GPIO38_FFRI 38 /* FFUART Ring Indicator */ -#define GPIO39_MMCCS1 39 /* MMC Chip Select 1 */ -#define GPIO39_FFTXD 39 /* FFUART transmit data */ -#define GPIO40_FFDTR 40 /* FFUART data terminal Ready */ -#define GPIO41_FFRTS 41 /* FFUART request to send */ -#define GPIO42_BTRXD 42 /* BTUART receive data */ -#define GPIO42_HWRXD 42 /* HWUART receive data */ -#define GPIO42_CIF_MCLK 42 /* Camera Master Clock */ -#define GPIO43_BTTXD 43 /* BTUART transmit data */ -#define GPIO43_HWTXD 43 /* HWUART transmit data */ -#define GPIO43_CIF_FV 43 /* Camera frame start signal */ -#define GPIO44_BTCTS 44 /* BTUART clear to send */ -#define GPIO44_HWCTS 44 /* HWUART clear to send */ -#define GPIO44_CIF_LV 44 /* Camera line start signal */ -#define GPIO45_BTRTS 45 /* BTUART request to send */ -#define GPIO45_HWRTS 45 /* HWUART request to send */ -#define GPIO45_AC97_SYSCLK 45 /* AC97 System Clock */ -#define GPIO45_CIF_PCLK 45 /* Camera Pixel Clock */ -#define GPIO46_ICPRXD 46 /* ICP receive data */ -#define GPIO46_STRXD 46 /* STD_UART receive data */ -#define GPIO47_ICPTXD 47 /* ICP transmit data */ -#define GPIO47_STTXD 47 /* STD_UART transmit data */ -#define GPIO47_CIF_DD_0 47 /* Camera data pin 0 */ -#define GPIO48_nPOE 48 /* Output Enable for Card Space */ -#define GPIO48_CIF_DD_5 48 /* Camera data pin 5 */ -#define GPIO49_nPWE 49 /* Write Enable for Card Space */ -#define GPIO50_nPIOR 50 /* I/O Read for Card Space */ -#define GPIO50_CIF_DD_3 50 /* Camera data pin 3 */ -#define GPIO51_nPIOW 51 /* I/O Write for Card Space */ -#define GPIO51_CIF_DD_2 51 /* Camera data pin 2 */ -#define GPIO52_nPCE_1 52 /* Card Enable for Card Space */ -#define GPIO52_CIF_DD_4 52 /* Camera data pin 4 */ -#define GPIO53_nPCE_2 53 /* Card Enable for Card Space */ -#define GPIO53_MMCCLK 53 /* MMC Clock */ -#define GPIO53_CIF_MCLK 53 /* Camera Master Clock */ -#define GPIO54_MMCCLK 54 /* MMC Clock */ -#define GPIO54_pSKTSEL 54 /* Socket Select for Card Space */ -#define GPIO54_nPCE_2 54 /* Card Enable for Card Space (PXA27x) */ -#define GPIO54_CIF_PCLK 54 /* Camera Pixel Clock */ -#define GPIO55_nPREG 55 /* Card Address bit 26 */ -#define GPIO55_CIF_DD_1 55 /* Camera data pin 1 */ -#define GPIO56_nPWAIT 56 /* Wait signal for Card Space */ -#define GPIO57_nIOIS16 57 /* Bus Width select for I/O Card Space */ -#define GPIO58_LDD_0 58 /* LCD data pin 0 */ -#define GPIO59_LDD_1 59 /* LCD data pin 1 */ -#define GPIO60_LDD_2 60 /* LCD data pin 2 */ -#define GPIO61_LDD_3 61 /* LCD data pin 3 */ -#define GPIO62_LDD_4 62 /* LCD data pin 4 */ -#define GPIO63_LDD_5 63 /* LCD data pin 5 */ -#define GPIO64_LDD_6 64 /* LCD data pin 6 */ -#define GPIO65_LDD_7 65 /* LCD data pin 7 */ -#define GPIO66_LDD_8 66 /* LCD data pin 8 */ -#define GPIO66_MBREQ 66 /* alternate bus master req */ -#define GPIO67_LDD_9 67 /* LCD data pin 9 */ -#define GPIO67_MMCCS0 67 /* MMC Chip Select 0 */ -#define GPIO68_LDD_10 68 /* LCD data pin 10 */ -#define GPIO68_MMCCS1 68 /* MMC Chip Select 1 */ -#define GPIO69_LDD_11 69 /* LCD data pin 11 */ -#define GPIO69_MMCCLK 69 /* MMC_CLK */ -#define GPIO70_LDD_12 70 /* LCD data pin 12 */ -#define GPIO70_RTCCLK 70 /* Real Time clock (1 Hz) */ -#define GPIO71_LDD_13 71 /* LCD data pin 13 */ -#define GPIO71_3_6MHz 71 /* 3.6 MHz Oscillator clock */ -#define GPIO72_LDD_14 72 /* LCD data pin 14 */ -#define GPIO72_32kHz 72 /* 32 kHz clock */ -#define GPIO73_LDD_15 73 /* LCD data pin 15 */ -#define GPIO73_MBGNT 73 /* Memory controller grant */ -#define GPIO74_LCD_FCLK 74 /* LCD Frame clock */ -#define GPIO75_LCD_LCLK 75 /* LCD line clock */ -#define GPIO76_LCD_PCLK 76 /* LCD Pixel clock */ -#define GPIO77_LCD_ACBIAS 77 /* LCD AC Bias */ -#define GPIO78_nCS_2 78 /* chip select 2 */ -#define GPIO79_nCS_3 79 /* chip select 3 */ -#define GPIO80_nCS_4 80 /* chip select 4 */ -#define GPIO81_NSCLK 81 /* NSSP clock */ -#define GPIO81_CIF_DD_0 81 /* Camera data pin 0 */ -#define GPIO82_NSFRM 82 /* NSSP Frame */ -#define GPIO82_CIF_DD_5 82 /* Camera data pin 5 */ -#define GPIO83_NSTXD 83 /* NSSP transmit */ -#define GPIO83_CIF_DD_4 83 /* Camera data pin 4 */ -#define GPIO84_NSRXD 84 /* NSSP receive */ -#define GPIO84_CIF_FV 84 /* Camera frame start signal */ -#define GPIO85_nPCE_1 85 /* Card Enable for Card Space (PXA27x) */ -#define GPIO85_CIF_LV 85 /* Camera line start signal */ -#define GPIO90_CIF_DD_4 90 /* Camera data pin 4 */ -#define GPIO91_CIF_DD_5 91 /* Camera data pin 5 */ -#define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */ -#define GPIO93_CIF_DD_6 93 /* Camera data pin 6 */ -#define GPIO94_CIF_DD_5 94 /* Camera data pin 5 */ -#define GPIO95_CIF_DD_4 95 /* Camera data pin 4 */ -#define GPIO96_FFRXD 96 /* FFUART recieve */ -#define GPIO98_FFRTS 98 /* FFUART request to send */ -#define GPIO98_CIF_DD_0 98 /* Camera data pin 0 */ -#define GPIO99_FFTXD 99 /* FFUART transmit data */ -#define GPIO100_FFCTS 100 /* FFUART Clear to send */ -#define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */ -#define GPIO103_CIF_DD_3 103 /* Camera data pin 3 */ -#define GPIO104_CIF_DD_2 104 /* Camera data pin 2 */ -#define GPIO105_CIF_DD_1 105 /* Camera data pin 1 */ -#define GPIO106_CIF_DD_9 106 /* Camera data pin 9 */ -#define GPIO107_CIF_DD_8 107 /* Camera data pin 8 */ -#define GPIO108_CIF_DD_7 108 /* Camera data pin 7 */ -#define GPIO109_MMCDAT1 109 /* MMC DAT1 (PXA27x) */ -#define GPIO110_MMCDAT2 110 /* MMC DAT2 (PXA27x) */ -#define GPIO110_MMCCS0 110 /* MMC Chip Select 0 (PXA27x) */ -#define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ -#define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ -#define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ -#define GPIO113_I2S_SYSCLK 113 /* I2S System Clock (PXA27x) */ -#define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ -#define GPIO114_CIF_DD_1 114 /* Camera data pin 1 */ -#define GPIO115_CIF_DD_3 115 /* Camera data pin 3 */ -#define GPIO116_CIF_DD_2 116 /* Camera data pin 2 */ - -/* GPIO alternate function mode & direction */ - -#define GPIO_IN 0x000 -#define GPIO_OUT 0x080 -#define GPIO_ALT_FN_1_IN 0x100 -#define GPIO_ALT_FN_1_OUT 0x180 -#define GPIO_ALT_FN_2_IN 0x200 -#define GPIO_ALT_FN_2_OUT 0x280 -#define GPIO_ALT_FN_3_IN 0x300 -#define GPIO_ALT_FN_3_OUT 0x380 -#define GPIO_MD_MASK_NR 0x07f -#define GPIO_MD_MASK_DIR 0x080 -#define GPIO_MD_MASK_FN 0x300 -#define GPIO_DFLT_LOW 0x400 -#define GPIO_DFLT_HIGH 0x800 - -#define GPIO1_RTS_MD ( 1 | GPIO_ALT_FN_1_IN) -#define GPIO6_MMCCLK_MD ( 6 | GPIO_ALT_FN_1_OUT) -#define GPIO7_48MHz_MD ( 7 | GPIO_ALT_FN_1_OUT) -#define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT) -#define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT) -#define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT) -#define GPIO11_3_6MHz_MD (11 | GPIO_ALT_FN_1_OUT) -#define GPIO12_32KHz_MD (12 | GPIO_ALT_FN_1_OUT) -#define GPIO12_CIF_DD_7_MD (12 | GPIO_ALT_FN_2_IN) -#define GPIO13_MBGNT_MD (13 | GPIO_ALT_FN_2_OUT) -#define GPIO14_MBREQ_MD (14 | GPIO_ALT_FN_1_IN) -#define GPIO15_nCS_1_MD (15 | GPIO_ALT_FN_2_OUT) -#define GPIO16_PWM0_MD (16 | GPIO_ALT_FN_2_OUT) -#define GPIO17_PWM1_MD (17 | GPIO_ALT_FN_2_OUT) -#define GPIO17_CIF_DD_6_MD (17 | GPIO_ALT_FN_2_IN) -#define GPIO18_RDY_MD (18 | GPIO_ALT_FN_1_IN) -#define GPIO19_DREQ1_MD (19 | GPIO_ALT_FN_1_IN) -#define GPIO20_DREQ0_MD (20 | GPIO_ALT_FN_1_IN) -#define GPIO23_CIF_MCLK_MD (23 | GPIO_ALT_FN_1_OUT) -#define GPIO23_SCLK_MD (23 | GPIO_ALT_FN_2_OUT) -#define GPIO24_CIF_FV_MD (24 | GPIO_ALT_FN_1_OUT) -#define GPIO24_SFRM_MD (24 | GPIO_ALT_FN_2_OUT) -#define GPIO25_CIF_LV_MD (25 | GPIO_ALT_FN_1_OUT) -#define GPIO25_STXD_MD (25 | GPIO_ALT_FN_2_OUT) -#define GPIO26_SRXD_MD (26 | GPIO_ALT_FN_1_IN) -#define GPIO26_CIF_PCLK_MD (26 | GPIO_ALT_FN_2_IN) -#define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN) -#define GPIO27_CIF_DD_0_MD (27 | GPIO_ALT_FN_3_IN) -#define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN) -#define GPIO28_BITCLK_IN_I2S_MD (28 | GPIO_ALT_FN_2_IN) -#define GPIO28_BITCLK_OUT_I2S_MD (28 | GPIO_ALT_FN_1_OUT) -#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN) -#define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN) -#define GPIO30_SDATA_OUT_AC97_MD (30 | GPIO_ALT_FN_2_OUT) -#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT) -#define GPIO31_SYNC_I2S_MD (31 | GPIO_ALT_FN_1_OUT) -#define GPIO31_SYNC_AC97_MD (31 | GPIO_ALT_FN_2_OUT) -#define GPIO32_SDATA_IN1_AC97_MD (32 | GPIO_ALT_FN_1_IN) -#define GPIO32_SYSCLK_I2S_MD (32 | GPIO_ALT_FN_1_OUT) -#define GPIO32_MMCCLK_MD (32 | GPIO_ALT_FN_2_OUT) -#define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT) -#define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN) -#define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT) -#define GPIO35_FFCTS_MD (35 | GPIO_ALT_FN_1_IN) -#define GPIO35_KP_MKOUT6_MD (35 | GPIO_ALT_FN_2_OUT) -#define GPIO36_FFDCD_MD (36 | GPIO_ALT_FN_1_IN) -#define GPIO37_FFDSR_MD (37 | GPIO_ALT_FN_1_IN) -#define GPIO38_FFRI_MD (38 | GPIO_ALT_FN_1_IN) -#define GPIO39_MMCCS1_MD (39 | GPIO_ALT_FN_1_OUT) -#define GPIO39_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT) -#define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT) -#define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) -#define GPIO41_KP_MKOUT7_MD (41 | GPIO_ALT_FN_1_OUT) -#define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN) -#define GPIO42_HWRXD_MD (42 | GPIO_ALT_FN_3_IN) -#define GPIO42_CIF_MCLK_MD (42 | GPIO_ALT_FN_3_OUT) -#define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT) -#define GPIO43_HWTXD_MD (43 | GPIO_ALT_FN_3_OUT) -#define GPIO43_CIF_FV_MD (43 | GPIO_ALT_FN_3_OUT) -#define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN) -#define GPIO44_HWCTS_MD (44 | GPIO_ALT_FN_3_IN) -#define GPIO44_CIF_LV_MD (44 | GPIO_ALT_FN_3_OUT) -#define GPIO45_CIF_PCLK_MD (45 | GPIO_ALT_FN_3_IN) -#define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT) -#define GPIO45_HWRTS_MD (45 | GPIO_ALT_FN_3_OUT) -#define GPIO45_SYSCLK_AC97_MD (45 | GPIO_ALT_FN_1_OUT) -#define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN) -#define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN) -#define GPIO47_CIF_DD_0_MD (47 | GPIO_ALT_FN_1_IN) -#define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT) -#define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT) -#define GPIO48_CIF_DD_5_MD (48 | GPIO_ALT_FN_1_IN) -#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) -#define GPIO48_HWTXD_MD (48 | GPIO_ALT_FN_1_OUT) -#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT) -#define GPIO49_HWRXD_MD (49 | GPIO_ALT_FN_1_IN) -#define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT) -#define GPIO50_CIF_DD_3_MD (50 | GPIO_ALT_FN_1_IN) -#define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT) -#define GPIO50_HWCTS_MD (50 | GPIO_ALT_FN_1_IN) -#define GPIO50_CIF_DD_3_MD (50 | GPIO_ALT_FN_1_IN) -#define GPIO51_CIF_DD_2_MD (51 | GPIO_ALT_FN_1_IN) -#define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT) -#define GPIO51_HWRTS_MD (51 | GPIO_ALT_FN_1_OUT) -#define GPIO51_CIF_DD_2_MD (51 | GPIO_ALT_FN_1_IN) -#define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT) -#define GPIO52_CIF_DD_4_MD (52 | GPIO_ALT_FN_1_IN) -#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) -#define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT) -#define GPIO53_CIF_MCLK_MD (53 | GPIO_ALT_FN_2_OUT) -#define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT) -#define GPIO54_nPCE_2_MD (54 | GPIO_ALT_FN_2_OUT) -#define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT) -#define GPIO54_CIF_PCLK_MD (54 | GPIO_ALT_FN_3_IN) -#define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT) -#define GPIO55_CIF_DD_1_MD (55 | GPIO_ALT_FN_1_IN) -#define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN) -#define GPIO57_nIOIS16_MD (57 | GPIO_ALT_FN_1_IN) -#define GPIO58_LDD_0_MD (58 | GPIO_ALT_FN_2_OUT) -#define GPIO59_LDD_1_MD (59 | GPIO_ALT_FN_2_OUT) -#define GPIO60_LDD_2_MD (60 | GPIO_ALT_FN_2_OUT) -#define GPIO61_LDD_3_MD (61 | GPIO_ALT_FN_2_OUT) -#define GPIO62_LDD_4_MD (62 | GPIO_ALT_FN_2_OUT) -#define GPIO63_LDD_5_MD (63 | GPIO_ALT_FN_2_OUT) -#define GPIO64_LDD_6_MD (64 | GPIO_ALT_FN_2_OUT) -#define GPIO65_LDD_7_MD (65 | GPIO_ALT_FN_2_OUT) -#define GPIO66_LDD_8_MD (66 | GPIO_ALT_FN_2_OUT) -#define GPIO66_MBREQ_MD (66 | GPIO_ALT_FN_1_IN) -#define GPIO67_LDD_9_MD (67 | GPIO_ALT_FN_2_OUT) -#define GPIO67_MMCCS0_MD (67 | GPIO_ALT_FN_1_OUT) -#define GPIO68_LDD_10_MD (68 | GPIO_ALT_FN_2_OUT) -#define GPIO68_MMCCS1_MD (68 | GPIO_ALT_FN_1_OUT) -#define GPIO69_LDD_11_MD (69 | GPIO_ALT_FN_2_OUT) -#define GPIO69_MMCCLK_MD (69 | GPIO_ALT_FN_1_OUT) -#define GPIO70_LDD_12_MD (70 | GPIO_ALT_FN_2_OUT) -#define GPIO70_RTCCLK_MD (70 | GPIO_ALT_FN_1_OUT) -#define GPIO71_LDD_13_MD (71 | GPIO_ALT_FN_2_OUT) -#define GPIO71_3_6MHz_MD (71 | GPIO_ALT_FN_1_OUT) -#define GPIO72_LDD_14_MD (72 | GPIO_ALT_FN_2_OUT) -#define GPIO72_32kHz_MD (72 | GPIO_ALT_FN_1_OUT) -#define GPIO73_LDD_15_MD (73 | GPIO_ALT_FN_2_OUT) -#define GPIO73_MBGNT_MD (73 | GPIO_ALT_FN_1_OUT) -#define GPIO74_LCD_FCLK_MD (74 | GPIO_ALT_FN_2_OUT) -#define GPIO75_LCD_LCLK_MD (75 | GPIO_ALT_FN_2_OUT) -#define GPIO76_LCD_PCLK_MD (76 | GPIO_ALT_FN_2_OUT) -#define GPIO77_LCD_ACBIAS_MD (77 | GPIO_ALT_FN_2_OUT) -#define GPIO78_nCS_2_MD (78 | GPIO_ALT_FN_2_OUT) -#define GPIO78_nPCE_2_MD (78 | GPIO_ALT_FN_1_OUT) -#define GPIO79_nCS_3_MD (79 | GPIO_ALT_FN_2_OUT) -#define GPIO79_pSKTSEL_MD (79 | GPIO_ALT_FN_1_OUT) -#define GPIO80_nCS_4_MD (80 | GPIO_ALT_FN_2_OUT) -#define GPIO81_NSSP_CLK_OUT (81 | GPIO_ALT_FN_1_OUT) -#define GPIO81_NSSP_CLK_IN (81 | GPIO_ALT_FN_1_IN) -#define GPIO81_CIF_DD_0_MD (81 | GPIO_ALT_FN_2_IN) -#define GPIO82_NSSP_FRM_OUT (82 | GPIO_ALT_FN_1_OUT) -#define GPIO82_NSSP_FRM_IN (82 | GPIO_ALT_FN_1_IN) -#define GPIO82_CIF_DD_5_MD (82 | GPIO_ALT_FN_3_IN) -#define GPIO83_NSSP_TX (83 | GPIO_ALT_FN_1_OUT) -#define GPIO83_NSSP_RX (83 | GPIO_ALT_FN_2_IN) -#define GPIO83_CIF_DD_4_MD (83 | GPIO_ALT_FN_3_IN) -#define GPIO84_NSSP_TX (84 | GPIO_ALT_FN_1_OUT) -#define GPIO84_NSSP_RX (84 | GPIO_ALT_FN_2_IN) -#define GPIO84_CIF_FV_MD (84 | GPIO_ALT_FN_3_IN) -#define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) -#define GPIO85_CIF_LV_MD (85 | GPIO_ALT_FN_3_IN) -#define GPIO86_nPCE_1_MD (86 | GPIO_ALT_FN_1_OUT) -#define GPIO88_USBH1_PWR_MD (88 | GPIO_ALT_FN_1_IN) -#define GPIO89_USBH1_PEN_MD (89 | GPIO_ALT_FN_2_OUT) -#define GPIO90_CIF_DD_4_MD (90 | GPIO_ALT_FN_3_IN) -#define GPIO91_CIF_DD_5_MD (91 | GPIO_ALT_FN_3_IN) -#define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) -#define GPIO93_CIF_DD_6_MD (93 | GPIO_ALT_FN_2_IN) -#define GPIO94_CIF_DD_5_MD (94 | GPIO_ALT_FN_2_IN) -#define GPIO95_CIF_DD_4_MD (95 | GPIO_ALT_FN_2_IN) -#define GPIO95_KP_MKIN6_MD (95 | GPIO_ALT_FN_3_IN) -#define GPIO96_KP_DKIN3_MD (96 | GPIO_ALT_FN_1_IN) -#define GPIO96_FFRXD_MD (96 | GPIO_ALT_FN_3_IN) -#define GPIO97_KP_MKIN3_MD (97 | GPIO_ALT_FN_3_IN) -#define GPIO98_CIF_DD_0_MD (98 | GPIO_ALT_FN_2_IN) -#define GPIO98_FFRTS_MD (98 | GPIO_ALT_FN_3_OUT) -#define GPIO99_FFTXD_MD (99 | GPIO_ALT_FN_3_OUT) -#define GPIO100_KP_MKIN0_MD (100 | GPIO_ALT_FN_1_IN) -#define GPIO101_KP_MKIN1_MD (101 | GPIO_ALT_FN_1_IN) -#define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT) -#define GPIO102_KP_MKIN2_MD (102 | GPIO_ALT_FN_1_IN) -#define GPIO103_CIF_DD_3_MD (103 | GPIO_ALT_FN_1_IN) -#define GPIO103_KP_MKOUT0_MD (103 | GPIO_ALT_FN_2_OUT) -#define GPIO104_CIF_DD_2_MD (104 | GPIO_ALT_FN_1_IN) -#define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT) -#define GPIO104_KP_MKOUT1_MD (104 | GPIO_ALT_FN_2_OUT) -#define GPIO105_CIF_DD_1_MD (105 | GPIO_ALT_FN_1_IN) -#define GPIO105_KP_MKOUT2_MD (105 | GPIO_ALT_FN_2_OUT) -#define GPIO106_CIF_DD_9_MD (106 | GPIO_ALT_FN_1_IN) -#define GPIO106_KP_MKOUT3_MD (106 | GPIO_ALT_FN_2_OUT) -#define GPIO107_CIF_DD_8_MD (107 | GPIO_ALT_FN_1_IN) -#define GPIO107_KP_MKOUT4_MD (107 | GPIO_ALT_FN_2_OUT) -#define GPIO108_CIF_DD_7_MD (108 | GPIO_ALT_FN_1_IN) -#define GPIO108_KP_MKOUT5_MD (108 | GPIO_ALT_FN_2_OUT) -#define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCCS0_MD (110 | GPIO_ALT_FN_1_OUT) -#define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) -#define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) -#define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) -#define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT) -#define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) -#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_IN) -#define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) - -/* - * Handy routine to set GPIO alternate functions - */ -extern int pxa_gpio_mode( int gpio_mode ); - -#endif /* __ASM_ARCH_PXA2XX_GPIO_H */ diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index 463d874bb867..cb4767251f3c 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 03ba7e07f5025710470b12e18e2b9b2979d836db Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 9 Mar 2010 11:43:48 +0200 Subject: [ARM] pxa/cm-x300.c: add battery charger support Signed-off-by: Igor Grinberg Signed-off-by: Eric Miao --- arch/arm/mach-pxa/cm-x300.c | 57 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index d37cfa132a65..0e538d8895d1 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -30,6 +30,8 @@ #include #include +#include +#include #include #include @@ -584,12 +586,65 @@ static void __init cm_x300_init_rtc(void) static inline void cm_x300_init_rtc(void) {} #endif +/* Battery */ +struct power_supply_info cm_x300_psy_info = { + .name = "battery", + .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, + .voltage_max_design = 4200000, + .voltage_min_design = 3000000, + .use_for_apm = 1, +}; + +static void cm_x300_battery_low(void) +{ +#if defined(CONFIG_APM_EMULATION) + apm_queue_event(APM_LOW_BATTERY); +#endif +} + +static void cm_x300_battery_critical(void) +{ +#if defined(CONFIG_APM_EMULATION) + apm_queue_event(APM_CRITICAL_SUSPEND); +#endif +} + +struct da9030_battery_info cm_x300_battery_info = { + .battery_info = &cm_x300_psy_info, + + .charge_milliamp = 1000, + .charge_millivolt = 4200, + + .vbat_low = 3600, + .vbat_crit = 3400, + .vbat_charge_start = 4100, + .vbat_charge_stop = 4200, + .vbat_charge_restart = 4000, + + .vcharge_min = 3200, + .vcharge_max = 5500, + + .tbat_low = 197, + .tbat_high = 78, + .tbat_restart = 100, + + .batmon_interval = 0, + + .battery_low = cm_x300_battery_low, + .battery_critical = cm_x300_battery_critical, +}; + /* DA9030 */ struct da903x_subdev_info cm_x300_da9030_subdevs[] = { { .name = "da903x-backlight", .id = DA9030_ID_WLED, - } + }, + { + .name = "da903x-battery", + .id = DA9030_ID_BAT, + .platform_data = &cm_x300_battery_info, + }, }; static struct da903x_platform_data cm_x300_da9030_info = { -- cgit v1.2.3-59-g8ed1b From d768c67c0cc70c7817585676a40e0d2a9094bdbe Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 9 Mar 2010 11:43:49 +0200 Subject: [ARM] pxa/cm-x300: da903x WLED is not connected on cm-x300 Signed-off-by: Igor Grinberg Signed-off-by: Eric Miao --- arch/arm/mach-pxa/cm-x300.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 0e538d8895d1..13fdfd828d2e 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -636,10 +636,6 @@ struct da9030_battery_info cm_x300_battery_info = { /* DA9030 */ struct da903x_subdev_info cm_x300_da9030_subdevs[] = { - { - .name = "da903x-backlight", - .id = DA9030_ID_WLED, - }, { .name = "da903x-battery", .id = DA9030_ID_BAT, -- cgit v1.2.3-59-g8ed1b From e4e309708eeb87a5b2429bc1f9bd1bc469d5a8b0 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 9 Mar 2010 11:43:50 +0200 Subject: [ARM] pxa/cm-x300: fix da903x IRQ line assignment Signed-off-by: Igor Grinberg Signed-off-by: Eric Miao --- arch/arm/mach-pxa/cm-x300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 13fdfd828d2e..6fba9a08f53e 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -650,7 +650,7 @@ static struct da903x_platform_data cm_x300_da9030_info = { static struct i2c_board_info cm_x300_pmic_info = { I2C_BOARD_INFO("da9030", 0x49), - .irq = IRQ_GPIO(0), + .irq = IRQ_WAKEUP0, .platform_data = &cm_x300_da9030_info, }; -- cgit v1.2.3-59-g8ed1b From d176d64b54c72ee00f825dddd63830f8bd2b5155 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 9 Mar 2010 11:43:51 +0200 Subject: [ARM] pxa/cm-x300: add regulator on vcc_core Signed-off-by: Igor Grinberg Signed-off-by: Eric Miao --- arch/arm/mach-pxa/cm-x300.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 6fba9a08f53e..2012588fb200 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -634,6 +635,27 @@ struct da9030_battery_info cm_x300_battery_info = { .battery_critical = cm_x300_battery_critical, }; +static struct regulator_consumer_supply buck2_consumers[] = { + { + .dev = NULL, + .supply = "vcc_core", + }, +}; + +static struct regulator_init_data buck2_data = { + .constraints = { + .min_uV = 1375000, + .max_uV = 1375000, + .state_mem = { + .enabled = 0, + }, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .apply_uV = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(buck2_consumers), + .consumer_supplies = buck2_consumers, +}; + /* DA9030 */ struct da903x_subdev_info cm_x300_da9030_subdevs[] = { { @@ -641,6 +663,11 @@ struct da903x_subdev_info cm_x300_da9030_subdevs[] = { .id = DA9030_ID_BAT, .platform_data = &cm_x300_battery_info, }, + { + .name = "da903x-regulator", + .id = DA9030_ID_BUCK2, + .platform_data = &buck2_data, + }, }; static struct da903x_platform_data cm_x300_da9030_info = { -- cgit v1.2.3-59-g8ed1b From 818809752303b5b792dde4ace6321e8ccc180f65 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 9 Mar 2010 11:43:52 +0200 Subject: [ARM] pxa/cm-x300: update the memory fixup. CM-X300 bootloader passes DRAM configuration information in ATAGS, however, the first memory bank is reported at actual physical address 0x8000000. Use the configuration information supplied by the bootloader and cope with the necessity to have PHYS_ADDR=0xa0000000. Signed-off-by: Igor Grinberg Signed-off-by: Mike Rapoport Signed-off-by: Eric Miao --- arch/arm/mach-pxa/cm-x300.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 2012588fb200..be9dc7a20fbd 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -767,13 +767,13 @@ static void __init cm_x300_init(void) static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags, char **cmdline, struct meminfo *mi) { - mi->nr_banks = 2; - mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; - mi->bank[0].size = (64*1024*1024); - mi->bank[1].start = 0xc0000000; - mi->bank[1].node = 0; - mi->bank[1].size = (64*1024*1024); + /* Make sure that mi->bank[0].start = PHYS_ADDR */ + for (; tags->hdr.size; tags = tag_next(tags)) + if (tags->hdr.tag == ATAG_MEM && + tags->u.mem.start == 0x80000000) { + tags->u.mem.start = 0xa0000000; + break; + } } MACHINE_START(CM_X300, "CM-X300 module") -- cgit v1.2.3-59-g8ed1b From b637799248520d711f0fdc64666131c1c869cfbc Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 28 Feb 2010 12:41:23 +0100 Subject: [ARM] pxa: add basic support for the Aeronix Zipit Z2 handheld This patch adds support for the Zipit Z2. The parts missing from this patch are the battery support, SPI driver for the LCD and support for the Silicon Serial ID chip. Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 6 + arch/arm/mach-pxa/Makefile | 1 + arch/arm/mach-pxa/include/mach/z2.h | 41 +++ arch/arm/mach-pxa/z2.c | 609 ++++++++++++++++++++++++++++++++++++ 4 files changed, 657 insertions(+) create mode 100644 arch/arm/mach-pxa/include/mach/z2.h create mode 100644 arch/arm/mach-pxa/z2.c (limited to 'arch') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 454cd5d5f105..2e4122de6081 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -561,6 +561,12 @@ config MACH_E800 Say Y here if you intend to run this kernel on a Toshiba e800 family PDA. +config MACH_ZIPIT2 + bool "Zipit Z2 Handheld" + select PXA27x + select HAVE_PWM + select PXA_HAVE_BOARD_IRQS + endmenu config PXA25x diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index cf57fb2f73d8..e929231f6a97 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -92,6 +92,7 @@ obj-$(CONFIG_MACH_E800) += e800.o obj-$(CONFIG_MACH_RAUMFELD_RC) += raumfeld.o obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR) += raumfeld.o obj-$(CONFIG_MACH_RAUMFELD_SPEAKER) += raumfeld.o +obj-$(CONFIG_MACH_ZIPIT2) += z2.o # Support for blinky lights led-y := leds.o diff --git a/arch/arm/mach-pxa/include/mach/z2.h b/arch/arm/mach-pxa/include/mach/z2.h new file mode 100644 index 000000000000..8835c16bc82f --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/z2.h @@ -0,0 +1,41 @@ +/* + * arch/arm/mach-pxa/include/mach/z2.h + * + * Author: Ken McGuire + * Created: Feb 6, 2009 + * + * 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. + */ + +#ifndef ASM_ARCH_ZIPIT2_H +#define ASM_ARCH_ZIPIT2_H + +/* LEDs */ +#define GPIO10_ZIPITZ2_LED_WIFI 10 +#define GPIO85_ZIPITZ2_LED_CHARGED 85 +#define GPIO83_ZIPITZ2_LED_CHARGING 83 + +/* SD/MMC */ +#define GPIO96_ZIPITZ2_SD_DETECT 96 + +/* GPIO Buttons */ +#define GPIO1_ZIPITZ2_POWER_BUTTON 1 +#define GPIO98_ZIPITZ2_LID_BUTTON 98 + +/* Libertas GSPI8686 WiFi */ +#define GPIO14_ZIPITZ2_WIFI_RESET 14 +#define GPIO15_ZIPITZ2_WIFI_POWER 15 +#define GPIO24_ZIPITZ2_WIFI_CS 24 +#define GPIO36_ZIPITZ2_WIFI_IRQ 36 + +/* LCD */ +#define GPIO19_ZIPITZ2_LCD_RESET 19 +#define GPIO88_ZIPITZ2_LCD_CS 88 + +/* MISC GPIOs */ +#define GPIO0_ZIPITZ2_AC_DETECT 0 +#define GPIO37_ZIPITZ2_HEADSET_DETECT 37 + +#endif diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c new file mode 100644 index 000000000000..c837318ec1fa --- /dev/null +++ b/arch/arm/mach-pxa/z2.c @@ -0,0 +1,609 @@ +/* + * linux/arch/arm/mach-pxa/z2.c + * + * Support for the Zipit Z2 Handheld device. + * + * Author: Ken McGuire + * Created: Jan 25, 2009 + * Based on mainstone.c as modified for the Zipit Z2. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long z2_pin_config[] = { + + /* LCD - 16bpp Active TFT */ + GPIO58_LCD_LDD_0, + GPIO59_LCD_LDD_1, + GPIO60_LCD_LDD_2, + GPIO61_LCD_LDD_3, + GPIO62_LCD_LDD_4, + GPIO63_LCD_LDD_5, + GPIO64_LCD_LDD_6, + GPIO65_LCD_LDD_7, + GPIO66_LCD_LDD_8, + GPIO67_LCD_LDD_9, + GPIO68_LCD_LDD_10, + GPIO69_LCD_LDD_11, + GPIO70_LCD_LDD_12, + GPIO71_LCD_LDD_13, + GPIO72_LCD_LDD_14, + GPIO73_LCD_LDD_15, + GPIO74_LCD_FCLK, + GPIO75_LCD_LCLK, + GPIO76_LCD_PCLK, + GPIO77_LCD_BIAS, + GPIO19_GPIO, /* LCD reset */ + GPIO88_GPIO, /* LCD chipselect */ + + /* PWM */ + GPIO115_PWM1_OUT, /* Keypad Backlight */ + GPIO11_PWM2_OUT, /* LCD Backlight */ + + /* MMC */ + GPIO32_MMC_CLK, + GPIO112_MMC_CMD, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO96_GPIO, /* SD detect */ + + /* STUART */ + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, + + /* Keypad */ + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, + GPIO38_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, + GPIO16_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH, + GPIO17_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH, + GPIO103_KP_MKOUT_0, + GPIO104_KP_MKOUT_1, + GPIO105_KP_MKOUT_2, + GPIO106_KP_MKOUT_3, + GPIO107_KP_MKOUT_4, + GPIO108_KP_MKOUT_5, + GPIO35_KP_MKOUT_6, + GPIO41_KP_MKOUT_7, + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, + + /* SSP1 */ + GPIO23_SSP1_SCLK, /* SSP1_SCK */ + GPIO25_SSP1_TXD, /* SSP1_TXD */ + GPIO26_SSP1_RXD, /* SSP1_RXD */ + + /* SSP2 */ + GPIO22_SSP2_SCLK, /* SSP2_SCK */ + GPIO13_SSP2_TXD, /* SSP2_TXD */ + GPIO40_SSP2_RXD, /* SSP2_RXD */ + + /* LEDs */ + GPIO10_GPIO, /* WiFi LED */ + GPIO83_GPIO, /* Charging LED */ + GPIO85_GPIO, /* Charged LED */ + + /* I2S */ + GPIO28_I2S_BITCLK_OUT, + GPIO29_I2S_SDATA_IN, + GPIO30_I2S_SDATA_OUT, + GPIO31_I2S_SYNC, + GPIO113_I2S_SYSCLK, + + /* MISC */ + GPIO0_GPIO, /* AC power detect */ + GPIO1_GPIO, /* Power button */ + GPIO37_GPIO, /* Headphone detect */ + GPIO98_GPIO, /* Lid switch */ + GPIO14_GPIO, /* WiFi Reset */ + GPIO15_GPIO, /* WiFi Power */ + GPIO24_GPIO, /* WiFi CS */ + GPIO36_GPIO, /* WiFi IRQ */ + GPIO88_GPIO, /* LCD CS */ +}; + +/****************************************************************************** + * NOR Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct resource z2_flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct mtd_partition z2_flash_parts[] = { + { + .name = "U-Boot Bootloader", + .offset = 0x0, + .size = 0x20000, + }, + { + .name = "Linux Kernel", + .offset = 0x20000, + .size = 0x220000, + }, + { + .name = "Filesystem", + .offset = 0x240000, + .size = 0x5b0000, + }, + { + .name = "U-Boot Environment", + .offset = 0x7f0000, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data z2_flash_data = { + .width = 2, + .parts = z2_flash_parts, + .nr_parts = ARRAY_SIZE(z2_flash_parts), +}; + +static struct platform_device z2_flash = { + .name = "physmap-flash", + .id = -1, + .resource = &z2_flash_resource, + .num_resources = 1, + .dev = { + .platform_data = &z2_flash_data, + }, +}; + +static void __init z2_nor_init(void) +{ + platform_device_register(&z2_flash); +} +#else +static inline void z2_nor_init(void) {} +#endif + +/****************************************************************************** + * Backlight + ******************************************************************************/ +#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) +static struct platform_pwm_backlight_data z2_backlight_data[] = { + [0] = { + /* Keypad Backlight */ + .pwm_id = 1, + .max_brightness = 1023, + .dft_brightness = 512, + .pwm_period_ns = 1260320, + }, + [1] = { + /* LCD Backlight */ + .pwm_id = 2, + .max_brightness = 1023, + .dft_brightness = 512, + .pwm_period_ns = 1260320, + }, +}; + +static struct platform_device z2_backlight_devices[2] = { + { + .name = "pwm-backlight", + .id = 0, + .dev = { + .platform_data = &z2_backlight_data[1], + }, + }, + { + .name = "pwm-backlight", + .id = 1, + .dev = { + .platform_data = &z2_backlight_data[0], + }, + }, +}; +static void __init z2_pwm_init(void) +{ + platform_device_register(&z2_backlight_devices[0]); + platform_device_register(&z2_backlight_devices[1]); +} +#else +static inline void z2_pwm_init(void) {} +#endif + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct pxafb_mode_info z2_lcd_modes[] = { +{ + .pixclock = 192000, + .xres = 240, + .yres = 320, + .bpp = 16, + + .left_margin = 4, + .right_margin = 8, + .upper_margin = 4, + .lower_margin = 8, + + .hsync_len = 4, + .vsync_len = 4, +}, +}; + +static struct pxafb_mach_info z2_lcd_screen = { + .modes = z2_lcd_modes, + .num_modes = ARRAY_SIZE(z2_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_BIAS_ACTIVE_LOW | + LCD_ALTERNATE_MAPPING, +}; + +static void __init z2_lcd_init(void) +{ + set_pxa_fb_info(&z2_lcd_screen); +} +#else +static inline void z2_lcd_init(void) {} +#endif + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +static struct pxamci_platform_data z2_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_card_detect = GPIO96_ZIPITZ2_SD_DETECT, + .gpio_power = -1, + .gpio_card_ro = -1, + .detect_delay = 20, +}; + +static void __init z2_mmc_init(void) +{ + pxa_set_mci_info(&z2_mci_platform_data); +} +#else +static inline void z2_mmc_init(void) {} +#endif + +/****************************************************************************** + * LEDs + ******************************************************************************/ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +struct gpio_led z2_gpio_leds[] = { +{ + .name = "z2:green:wifi", + .default_trigger = "none", + .gpio = GPIO10_ZIPITZ2_LED_WIFI, + .active_low = 1, +}, { + .name = "z2:green:charged", + .default_trigger = "none", + .gpio = GPIO85_ZIPITZ2_LED_CHARGED, + .active_low = 1, +}, { + .name = "z2:amber:charging", + .default_trigger = "none", + .gpio = GPIO83_ZIPITZ2_LED_CHARGING, + .active_low = 1, +}, +}; + +static struct gpio_led_platform_data z2_gpio_led_info = { + .leds = z2_gpio_leds, + .num_leds = ARRAY_SIZE(z2_gpio_leds), +}; + +static struct platform_device z2_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &z2_gpio_led_info, + } +}; + +static void __init z2_leds_init(void) +{ + platform_device_register(&z2_leds); +} +#else +static inline void z2_leds_init(void) {} +#endif + +/****************************************************************************** + * GPIO keyboard + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) +static unsigned int z2_matrix_keys[] = { + KEY(0, 0, KEY_OPTION), + KEY(1, 0, KEY_UP), + KEY(2, 0, KEY_DOWN), + KEY(3, 0, KEY_LEFT), + KEY(4, 0, KEY_RIGHT), + KEY(5, 0, KEY_END), + KEY(6, 0, KEY_KPPLUS), + + KEY(0, 1, KEY_HOME), + KEY(1, 1, KEY_Q), + KEY(2, 1, KEY_I), + KEY(3, 1, KEY_G), + KEY(4, 1, KEY_X), + KEY(5, 1, KEY_ENTER), + KEY(6, 1, KEY_KPMINUS), + + KEY(0, 2, KEY_PAGEUP), + KEY(1, 2, KEY_W), + KEY(2, 2, KEY_O), + KEY(3, 2, KEY_H), + KEY(4, 2, KEY_C), + KEY(5, 2, KEY_LEFTALT), + + KEY(0, 3, KEY_PAGEDOWN), + KEY(1, 3, KEY_E), + KEY(2, 3, KEY_P), + KEY(3, 3, KEY_J), + KEY(4, 3, KEY_V), + KEY(5, 3, KEY_LEFTSHIFT), + + KEY(0, 4, KEY_ESC), + KEY(1, 4, KEY_R), + KEY(2, 4, KEY_A), + KEY(3, 4, KEY_K), + KEY(4, 4, KEY_B), + KEY(5, 4, KEY_LEFTCTRL), + + KEY(0, 5, KEY_TAB), + KEY(1, 5, KEY_T), + KEY(2, 5, KEY_S), + KEY(3, 5, KEY_L), + KEY(4, 5, KEY_N), + KEY(5, 5, KEY_SPACE), + + KEY(0, 6, KEY_STOPCD), + KEY(1, 6, KEY_Y), + KEY(2, 6, KEY_D), + KEY(3, 6, KEY_BACKSPACE), + KEY(4, 6, KEY_M), + KEY(5, 6, KEY_COMMA), + + KEY(0, 7, KEY_PLAYCD), + KEY(1, 7, KEY_U), + KEY(2, 7, KEY_F), + KEY(3, 7, KEY_Z), + KEY(4, 7, KEY_SEMICOLON), + KEY(5, 7, KEY_DOT), +}; + +static struct pxa27x_keypad_platform_data z2_keypad_platform_data = { + .matrix_key_rows = 7, + .matrix_key_cols = 8, + .matrix_key_map = z2_matrix_keys, + .matrix_key_map_size = ARRAY_SIZE(z2_matrix_keys), + + .debounce_interval = 30, +}; + +static void __init z2_mkp_init(void) +{ + pxa_set_keypad_info(&z2_keypad_platform_data); +} +#else +static inline void z2_mkp_init(void) {} +#endif + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button z2_pxa_buttons[] = { + {KEY_POWER, GPIO1_ZIPITZ2_POWER_BUTTON, 0, "Power Button" }, + {KEY_CLOSE, GPIO98_ZIPITZ2_LID_BUTTON, 0, "Lid Button" }, +}; + +static struct gpio_keys_platform_data z2_pxa_keys_data = { + .buttons = z2_pxa_buttons, + .nbuttons = ARRAY_SIZE(z2_pxa_buttons), +}; + +static struct platform_device z2_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &z2_pxa_keys_data, + }, +}; + +static void __init z2_keys_init(void) +{ + platform_device_register(&z2_pxa_keys); +} +#else +static inline void z2_keys_init(void) {} +#endif + +/****************************************************************************** + * SSP Devices - WiFi and LCD control + ******************************************************************************/ +#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) +/* WiFi */ +static int z2_lbs_spi_setup(struct spi_device *spi) +{ + int ret = 0; + + ret = gpio_request(GPIO15_ZIPITZ2_WIFI_POWER, "WiFi Power"); + if (ret) + goto err; + + ret = gpio_direction_output(GPIO15_ZIPITZ2_WIFI_POWER, 1); + if (ret) + goto err2; + + ret = gpio_request(GPIO14_ZIPITZ2_WIFI_RESET, "WiFi Reset"); + if (ret) + goto err2; + + ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_RESET, 0); + if (ret) + goto err3; + + /* Reset the card */ + mdelay(180); + gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 1); + mdelay(20); + + spi->bits_per_word = 16; + spi->mode = SPI_MODE_2, + + spi_setup(spi); + + return 0; + +err3: + gpio_free(GPIO14_ZIPITZ2_WIFI_RESET); +err2: + gpio_free(GPIO15_ZIPITZ2_WIFI_POWER); +err: + return ret; +}; + +static int z2_lbs_spi_teardown(struct spi_device *spi) +{ + gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 0); + gpio_set_value(GPIO15_ZIPITZ2_WIFI_POWER, 0); + gpio_free(GPIO14_ZIPITZ2_WIFI_RESET); + gpio_free(GPIO15_ZIPITZ2_WIFI_POWER); + return 0; + +}; + +static struct pxa2xx_spi_chip z2_lbs_chip_info = { + .rx_threshold = 8, + .tx_threshold = 8, + .timeout = 1000, + .gpio_cs = GPIO24_ZIPITZ2_WIFI_CS, +}; + +static struct libertas_spi_platform_data z2_lbs_pdata = { + .use_dummy_writes = 1, + .setup = z2_lbs_spi_setup, + .teardown = z2_lbs_spi_teardown, +}; + +/* LCD */ +static struct pxa2xx_spi_chip lms283_chip_info = { + .rx_threshold = 1, + .tx_threshold = 1, + .timeout = 64, + .gpio_cs = GPIO88_ZIPITZ2_LCD_CS, +}; + +static const struct lms283gf05_pdata lms283_pdata = { + .reset_gpio = GPIO19_ZIPITZ2_LCD_RESET, +}; + +static struct spi_board_info spi_board_info[] __initdata = { +{ + .modalias = "libertas_spi", + .platform_data = &z2_lbs_pdata, + .controller_data = &z2_lbs_chip_info, + .irq = gpio_to_irq(GPIO36_ZIPITZ2_WIFI_IRQ), + .max_speed_hz = 13000000, + .bus_num = 1, + .chip_select = 0, +}, +{ + .modalias = "lms283gf05", + .controller_data = &lms283_chip_info, + .platform_data = &lms283_pdata, + .max_speed_hz = 400000, + .bus_num = 2, + .chip_select = 0, +}, +}; + +static struct pxa2xx_spi_master pxa_ssp1_master_info = { + .clock_enable = CKEN_SSP, + .num_chipselect = 1, + .enable_dma = 1, +}; + +static struct pxa2xx_spi_master pxa_ssp2_master_info = { + .clock_enable = CKEN_SSP2, + .num_chipselect = 1, +}; + +static void __init z2_spi_init(void) +{ + pxa2xx_set_spi_info(1, &pxa_ssp1_master_info); + pxa2xx_set_spi_info(2, &pxa_ssp2_master_info); + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); +} +#else +static inline void z2_spi_init(void) {} +#endif + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static void __init z2_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(z2_pin_config)); + + z2_lcd_init(); + z2_mmc_init(); + z2_mkp_init(); + + pxa_set_i2c_info(NULL); + + z2_spi_init(); + z2_nor_init(); + z2_pwm_init(); + z2_leds_init(); + z2_keys_init(); +} + +MACHINE_START(ZIPIT2, "Zipit Z2") + .phys_io = 0x40000000, + .boot_params = 0xa0000100, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .map_io = pxa_map_io, + .init_irq = pxa27x_init_irq, + .timer = &pxa_timer, + .init_machine = z2_init, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 543cd84255f499a53d409014bc5ba71543474b05 Mon Sep 17 00:00:00 2001 From: Marek Date: Tue, 9 Mar 2010 04:04:12 +0100 Subject: [ARM] pxa: add basic support for Voipac PXA270 SBC This patch adds basic support for the Voipac PXA270 SBC. The device consists of the following hardware: - PXA270 @ 520 MHz - 256MB RAM (sparsemem, 2*128MB regions) - 64MB NOR flash - 640x480 LCD - Ports: 2xUHC, 1xUDC, 1xPCMCIA, VGA, FFUART, 2xPS2, Speaker, MIC Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 6 + arch/arm/mach-pxa/Makefile | 1 + arch/arm/mach-pxa/include/mach/vpac270.h | 26 +++ arch/arm/mach-pxa/vpac270.c | 305 +++++++++++++++++++++++++++++++ 4 files changed, 338 insertions(+) create mode 100644 arch/arm/mach-pxa/include/mach/vpac270.h create mode 100644 arch/arm/mach-pxa/vpac270.c (limited to 'arch') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 2e4122de6081..e4a0452e0e2d 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -249,6 +249,12 @@ config MACH_COLIBRI320 select PXA3xx select CPU_PXA320 +config MACH_VPAC270 + bool "Voipac PXA270" + select PXA27x + help + PXA270 based Single Board Computer. + comment "End-user Products (sorted by vendor name)" config MACH_H4700 diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index e929231f6a97..b8f1f4bc7ca7 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o obj-$(CONFIG_MACH_COLIBRI) += colibri-pxa270.o obj-$(CONFIG_MACH_COLIBRI300) += colibri-pxa3xx.o colibri-pxa300.o obj-$(CONFIG_MACH_COLIBRI320) += colibri-pxa3xx.o colibri-pxa320.o +obj-$(CONFIG_MACH_VPAC270) += vpac270.o # End-user Products obj-$(CONFIG_MACH_H4700) += hx4700.o diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h new file mode 100644 index 000000000000..8f8eaed101dc --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/vpac270.h @@ -0,0 +1,26 @@ +/* + * GPIOs and interrupts for Voipac PXA270 + * + * Copyright (C) 2010 + * Marek Vasut + * + * 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. + * + */ + +#ifndef _INCLUDE_VPAC270_H_ +#define _INCLUDE_VPAC270_H_ + +#define GPIO1_VPAC270_USER_BTN 1 + +#define GPIO15_VPAC270_LED_ORANGE 15 + +#define GPIO81_VPAC270_BKL_ON 81 +#define GPIO83_VPAC270_NL_ON 83 + +#define GPIO52_VPAC270_SD_READONLY 52 +#define GPIO53_VPAC270_SD_DETECT_N 53 + +#endif diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c new file mode 100644 index 000000000000..710a17c80a14 --- /dev/null +++ b/arch/arm/mach-pxa/vpac270.c @@ -0,0 +1,305 @@ +/* + * Hardware definitions for Voipac PXA270 + * + * Copyright (C) 2010 + * Marek Vasut + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long vpac270_pin_config[] __initdata = { + /* MMC */ + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, + GPIO53_GPIO, /* SD detect */ + GPIO52_GPIO, /* SD r/o switch */ + + /* GPIO KEYS */ + GPIO1_GPIO, /* USER BTN */ + + /* LEDs */ + GPIO15_GPIO, /* orange led */ + + /* FFUART */ + GPIO34_FFUART_RXD, + GPIO39_FFUART_TXD, + GPIO27_FFUART_RTS, + GPIO100_FFUART_CTS, + GPIO33_FFUART_DSR, + GPIO40_FFUART_DTR, + GPIO10_FFUART_DCD, + GPIO38_FFUART_RI, + + /* LCD */ + GPIO58_LCD_LDD_0, + GPIO59_LCD_LDD_1, + GPIO60_LCD_LDD_2, + GPIO61_LCD_LDD_3, + GPIO62_LCD_LDD_4, + GPIO63_LCD_LDD_5, + GPIO64_LCD_LDD_6, + GPIO65_LCD_LDD_7, + GPIO66_LCD_LDD_8, + GPIO67_LCD_LDD_9, + GPIO68_LCD_LDD_10, + GPIO69_LCD_LDD_11, + GPIO70_LCD_LDD_12, + GPIO71_LCD_LDD_13, + GPIO72_LCD_LDD_14, + GPIO73_LCD_LDD_15, + GPIO86_LCD_LDD_16, + GPIO87_LCD_LDD_17, + GPIO74_LCD_FCLK, + GPIO75_LCD_LCLK, + GPIO76_LCD_PCLK, + GPIO77_LCD_BIAS, +}; + +/****************************************************************************** + * NOR Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition vpac270_partitions[] = { + { + .name = "Flash", + .offset = 0x00000000, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct physmap_flash_data vpac270_flash_data[] = { + { + .width = 2, /* bankwidth in bytes */ + .parts = vpac270_partitions, + .nr_parts = ARRAY_SIZE(vpac270_partitions) + } +}; + +static struct resource vpac270_flash_resource = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_64M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device vpac270_flash = { + .name = "physmap-flash", + .id = 0, + .resource = &vpac270_flash_resource, + .num_resources = 1, + .dev = { + .platform_data = vpac270_flash_data, + }, +}; +static void __init vpac270_nor_init(void) +{ + platform_device_register(&vpac270_flash); +} +#else +static inline void vpac270_nor_init(void) {} +#endif + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +static struct pxamci_platform_data vpac270_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, + .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, + .detect_delay = 20, +}; + +static void __init vpac270_mmc_init(void) +{ + pxa_set_mci_info(&vpac270_mci_platform_data); +} +#else +static inline void vpac270_mmc_init(void) {} +#endif + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button vpac270_pxa_buttons[] = { + {KEY_POWER, GPIO1_VPAC270_USER_BTN, 0, "USER BTN"}, +}; + +static struct gpio_keys_platform_data vpac270_pxa_keys_data = { + .buttons = vpac270_pxa_buttons, + .nbuttons = ARRAY_SIZE(vpac270_pxa_buttons), +}; + +static struct platform_device vpac270_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &vpac270_pxa_keys_data, + }, +}; + +static void __init vpac270_keys_init(void) +{ + platform_device_register(&vpac270_pxa_keys); +} +#else +static inline void vpac270_keys_init(void) {} +#endif + +/****************************************************************************** + * LED + ******************************************************************************/ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +struct gpio_led vpac270_gpio_leds[] = { +{ + .name = "vpac270:orange:user", + .default_trigger = "none", + .gpio = GPIO15_VPAC270_LED_ORANGE, + .active_low = 1, +} +}; + +static struct gpio_led_platform_data vpac270_gpio_led_info = { + .leds = vpac270_gpio_leds, + .num_leds = ARRAY_SIZE(vpac270_gpio_leds), +}; + +static struct platform_device vpac270_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &vpac270_gpio_led_info, + } +}; + +static void __init vpac270_leds_init(void) +{ + platform_device_register(&vpac270_leds); +} +#else +static inline void vpac270_leds_init(void) {} +#endif + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct pxafb_mode_info vpac270_lcd_modes[] = { +{ + .pixclock = 57692, + .xres = 640, + .yres = 480, + .bpp = 32, + .depth = 18, + + .left_margin = 144, + .right_margin = 32, + .upper_margin = 13, + .lower_margin = 30, + + .hsync_len = 32, + .vsync_len = 2, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +}, +}; + +static struct pxafb_mach_info vpac270_lcd_screen = { + .modes = vpac270_lcd_modes, + .num_modes = ARRAY_SIZE(vpac270_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_18BPP, +}; + +static void vpac270_lcd_power(int on, struct fb_var_screeninfo *info) +{ + gpio_set_value(GPIO81_VPAC270_BKL_ON, on); +} + +static void __init vpac270_lcd_init(void) +{ + int ret; + + ret = gpio_request(GPIO81_VPAC270_BKL_ON, "BKL-ON"); + if (ret) { + pr_err("Requesting BKL-ON GPIO failed!\n"); + goto err; + } + + ret = gpio_direction_output(GPIO81_VPAC270_BKL_ON, 1); + if (ret) { + pr_err("Setting BKL-ON GPIO direction failed!\n"); + goto err2; + } + + vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power; + set_pxa_fb_info(&vpac270_lcd_screen); + return; + +err2: + gpio_free(GPIO81_VPAC270_BKL_ON); +err: + return; +} +#else +static inline void vpac270_lcd_init(void) {} +#endif + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static void __init vpac270_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(vpac270_pin_config)); + + pxa_set_ffuart_info(NULL); + pxa_set_btuart_info(NULL); + pxa_set_stuart_info(NULL); + + vpac270_lcd_init(); + vpac270_mmc_init(); + vpac270_nor_init(); + vpac270_leds_init(); + vpac270_keys_init(); +} + +MACHINE_START(VPAC270, "Voipac PXA270") + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .boot_params = 0xa0000100, + .map_io = pxa_map_io, + .init_irq = pxa27x_init_irq, + .timer = &pxa_timer, + .init_machine = vpac270_init +MACHINE_END -- cgit v1.2.3-59-g8ed1b From addff0faecfc5e73e8a742687255cef847e260db Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 10 Mar 2010 04:16:28 +0100 Subject: [ARM] pxa: add support for Voipac PXA270 PCMCIA PCMCIA support for Voipac PXA270 Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/vpac270.h | 8 ++ arch/arm/mach-pxa/vpac270.c | 20 +++ drivers/pcmcia/Kconfig | 3 +- drivers/pcmcia/Makefile | 1 + drivers/pcmcia/pxa2xx_vpac270.c | 229 +++++++++++++++++++++++++++++++ 5 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 drivers/pcmcia/pxa2xx_vpac270.c (limited to 'arch') diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h index 8f8eaed101dc..a77e310bcca8 100644 --- a/arch/arm/mach-pxa/include/mach/vpac270.h +++ b/arch/arm/mach-pxa/include/mach/vpac270.h @@ -23,4 +23,12 @@ #define GPIO52_VPAC270_SD_READONLY 52 #define GPIO53_VPAC270_SD_DETECT_N 53 +#define GPIO84_VPAC270_PCMCIA_CD 84 +#define GPIO35_VPAC270_PCMCIA_RDY 35 +#define GPIO107_VPAC270_PCMCIA_PPEN 107 +#define GPIO11_VPAC270_PCMCIA_RESET 11 +#define GPIO17_VPAC270_CF_CD 17 +#define GPIO12_VPAC270_CF_RDY 12 +#define GPIO16_VPAC270_CF_RESET 16 + #endif diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 710a17c80a14..f1b073707f03 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -85,6 +85,26 @@ static unsigned long vpac270_pin_config[] __initdata = { GPIO75_LCD_LCLK, GPIO76_LCD_PCLK, GPIO77_LCD_BIAS, + + /* PCMCIA */ + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO55_nPREG, + GPIO57_nIOIS16, + GPIO56_nPWAIT, + GPIO104_PSKTSEL, + GPIO84_GPIO, /* PCMCIA CD */ + GPIO35_GPIO, /* PCMCIA RDY */ + GPIO107_GPIO, /* PCMCIA PPEN */ + GPIO11_GPIO, /* PCMCIA RESET */ + GPIO17_GPIO, /* CF CD */ + GPIO12_GPIO, /* CF RDY */ + GPIO16_GPIO, /* CF RESET */ + }; /****************************************************************************** diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index d189e4743e69..a44733d44ca1 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -234,7 +234,8 @@ config PCMCIA_PXA2XX depends on ARM && ARCH_PXA && PCMCIA depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ - || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2) + || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ + || MACH_VPAC270) select PCMCIA_SOC_COMMON help Say Y here to include support for the PXA2xx PCMCIA controller diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 381b031d9d75..4dae3613c458 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -66,6 +66,7 @@ pxa2xx-obj-$(CONFIG_MACH_PALMTC) += pxa2xx_palmtc.o pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o +pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y) diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c new file mode 100644 index 000000000000..55627eccee8e --- /dev/null +++ b/drivers/pcmcia/pxa2xx_vpac270.c @@ -0,0 +1,229 @@ +/* + * linux/drivers/pcmcia/pxa2xx_vpac270.c + * + * Driver for Voipac PXA270 PCMCIA and CF sockets + * + * Copyright (C) 2010 + * Marek Vasut + * + * 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 +#include + +#include + +#include +#include + +#include "soc_common.h" + +static struct pcmcia_irqs cd_irqs[] = { + { + .sock = 0, + .irq = IRQ_GPIO(GPIO84_VPAC270_PCMCIA_CD), + .str = "PCMCIA CD" + }, + { + .sock = 1, + .irq = IRQ_GPIO(GPIO17_VPAC270_CF_CD), + .str = "CF CD" + }, +}; + +static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +{ + int ret; + + if (skt->nr == 0) { + ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD"); + if (ret) + goto err1; + ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD); + if (ret) + goto err2; + + ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY"); + if (ret) + goto err2; + ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY); + if (ret) + goto err3; + + ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN"); + if (ret) + goto err3; + ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0); + if (ret) + goto err4; + + ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET"); + if (ret) + goto err4; + ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0); + if (ret) + goto err5; + + skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); + + return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); + +err5: + gpio_free(GPIO11_VPAC270_PCMCIA_RESET); +err4: + gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); +err3: + gpio_free(GPIO35_VPAC270_PCMCIA_RDY); +err2: + gpio_free(GPIO84_VPAC270_PCMCIA_CD); +err1: + return ret; + + } else { + ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD"); + if (ret) + goto err6; + ret = gpio_direction_input(GPIO17_VPAC270_CF_CD); + if (ret) + goto err7; + + ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY"); + if (ret) + goto err7; + ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY); + if (ret) + goto err8; + + ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET"); + if (ret) + goto err8; + ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0); + if (ret) + goto err9; + + skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); + + return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); + +err9: + gpio_free(GPIO16_VPAC270_CF_RESET); +err8: + gpio_free(GPIO12_VPAC270_CF_RDY); +err7: + gpio_free(GPIO17_VPAC270_CF_CD); +err6: + return ret; + + } +} + +static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + gpio_free(GPIO11_VPAC270_PCMCIA_RESET); + gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); + gpio_free(GPIO35_VPAC270_PCMCIA_RDY); + gpio_free(GPIO84_VPAC270_PCMCIA_CD); + gpio_free(GPIO16_VPAC270_CF_RESET); + gpio_free(GPIO12_VPAC270_CF_RDY); + gpio_free(GPIO17_VPAC270_CF_CD); +} + +static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, + struct pcmcia_state *state) +{ + if (skt->nr == 0) { + state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD); + state->ready = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY); + } else { + state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD); + state->ready = !!gpio_get_value(GPIO12_VPAC270_CF_RDY); + } + state->bvd1 = 1; + state->bvd2 = 1; + state->wrprot = 0; + state->vs_3v = 1; + state->vs_Xv = 0; +} + +static int +vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, + const socket_state_t *state) +{ + if (skt->nr == 0) { + gpio_set_value(GPIO11_VPAC270_PCMCIA_RESET, + (state->flags & SS_RESET)); + gpio_set_value(GPIO107_VPAC270_PCMCIA_PPEN, + !(state->Vcc == 33 || state->Vcc == 50)); + } else { + gpio_set_value(GPIO16_VPAC270_CF_RESET, + (state->flags & SS_RESET)); + } + + return 0; +} + +static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt) +{ +} + +static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) +{ +} + +static struct pcmcia_low_level vpac270_pcmcia_ops = { + .owner = THIS_MODULE, + + .first = 0, + .nr = 2, + + .hw_init = vpac270_pcmcia_hw_init, + .hw_shutdown = vpac270_pcmcia_hw_shutdown, + + .socket_state = vpac270_pcmcia_socket_state, + .configure_socket = vpac270_pcmcia_configure_socket, + + .socket_init = vpac270_pcmcia_socket_init, + .socket_suspend = vpac270_pcmcia_socket_suspend, +}; + +static struct platform_device *vpac270_pcmcia_device; + +static int __init vpac270_pcmcia_init(void) +{ + int ret; + + if (!machine_is_vpac270()) + return -ENODEV; + + vpac270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); + if (!vpac270_pcmcia_device) + return -ENOMEM; + + ret = platform_device_add_data(vpac270_pcmcia_device, + &vpac270_pcmcia_ops, sizeof(vpac270_pcmcia_ops)); + + if (!ret) + ret = platform_device_add(vpac270_pcmcia_device); + + if (ret) + platform_device_put(vpac270_pcmcia_device); + + return ret; +} + +static void __exit vpac270_pcmcia_exit(void) +{ + platform_device_unregister(vpac270_pcmcia_device); +} + +module_init(vpac270_pcmcia_init); +module_exit(vpac270_pcmcia_exit); + +MODULE_AUTHOR("Marek Vasut "); +MODULE_DESCRIPTION("PCMCIA support for Voipac PXA270"); +MODULE_ALIAS("platform:pxa2xx-pcmcia"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From 3d98f8816adafce2933599902fd9a5c0ccedd822 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 10 Mar 2010 05:24:27 +0100 Subject: [ARM] pxa/vpac270: UDC and UHC support NOTE: I wasn't able to get it running without reseting the HXOE (so it's there based on my tests with the hardware). I'll have to investigate it properly when I have more time. Signed-off-by: Marek Vasut Reviewed-by: Robert Jarzmik Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/vpac270.h | 1 + arch/arm/mach-pxa/vpac270.c | 78 ++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h index a77e310bcca8..9f7b460d99cc 100644 --- a/arch/arm/mach-pxa/include/mach/vpac270.h +++ b/arch/arm/mach-pxa/include/mach/vpac270.h @@ -31,4 +31,5 @@ #define GPIO12_VPAC270_CF_RDY 12 #define GPIO16_VPAC270_CF_RESET 16 +#define GPIO41_VPAC270_UDC_DETECT 41 #endif diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index f1b073707f03..b2bef615b390 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,9 @@ #include #include #include +#include +#include +#include #include "generic.h" #include "devices.h" @@ -105,6 +109,14 @@ static unsigned long vpac270_pin_config[] __initdata = { GPIO12_GPIO, /* CF RDY */ GPIO16_GPIO, /* CF RESET */ + /* UHC */ + GPIO88_USBH1_PWR, + GPIO89_USBH1_PEN, + GPIO119_USBH2_PWR, + GPIO120_USBH2_PEN, + + /* UDC */ + GPIO41_GPIO, }; /****************************************************************************** @@ -232,6 +244,70 @@ static void __init vpac270_leds_init(void) static inline void vpac270_leds_init(void) {} #endif +/****************************************************************************** + * USB Host + ******************************************************************************/ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static int vpac270_ohci_init(struct device *dev) +{ + UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; + return 0; +} + +static struct pxaohci_platform_data vpac270_ohci_info = { + .port_mode = PMM_PERPORT_MODE, + .flags = ENABLE_PORT1 | ENABLE_PORT2 | + POWER_CONTROL_LOW | POWER_SENSE_LOW, + .init = vpac270_ohci_init, +}; + +static void __init vpac270_uhc_init(void) +{ + pxa_set_ohci_info(&vpac270_ohci_info); +} +#else +static inline void vpac270_uhc_init(void) {} +#endif + +/****************************************************************************** + * USB Gadget + ******************************************************************************/ +#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE) +static struct gpio_vbus_mach_info vpac270_gpio_vbus_info = { + .gpio_vbus = GPIO41_VPAC270_UDC_DETECT, + .gpio_pullup = -1, +}; + +static struct platform_device vpac270_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &vpac270_gpio_vbus_info, + }, +}; + +static void vpac270_udc_command(int cmd) +{ + if (cmd == PXA2XX_UDC_CMD_CONNECT) + UP2OCR |= UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE; + else if (cmd == PXA2XX_UDC_CMD_DISCONNECT) + UP2OCR &= ~(UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE); +} + +static struct pxa2xx_udc_mach_info vpac270_udc_info __initdata = { + .udc_command = vpac270_udc_command, + .gpio_pullup = -1, +}; + +static void __init vpac270_udc_init(void) +{ + pxa_set_udc_info(&vpac270_udc_info); + platform_device_register(&vpac270_gpio_vbus); +} +#else +static inline void vpac270_udc_init(void) {} +#endif + /****************************************************************************** * Framebuffer ******************************************************************************/ @@ -312,6 +388,8 @@ static void __init vpac270_init(void) vpac270_nor_init(); vpac270_leds_init(); vpac270_keys_init(); + vpac270_uhc_init(); + vpac270_udc_init(); } MACHINE_START(VPAC270, "Voipac PXA270") -- cgit v1.2.3-59-g8ed1b From 947fb57e3a6be2920423de42a503eea08b0c0763 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 10 Mar 2010 05:38:54 +0100 Subject: [ARM] pxa/vpac270: add ethernet support Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/vpac270.h | 3 ++ arch/arm/mach-pxa/vpac270.c | 49 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h index 9f7b460d99cc..b90b380ddab9 100644 --- a/arch/arm/mach-pxa/include/mach/vpac270.h +++ b/arch/arm/mach-pxa/include/mach/vpac270.h @@ -32,4 +32,7 @@ #define GPIO16_VPAC270_CF_RESET 16 #define GPIO41_VPAC270_UDC_DETECT 41 + +#define GPIO114_VPAC270_ETH_IRQ 114 + #endif diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index b2bef615b390..56cc24575999 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -117,6 +118,9 @@ static unsigned long vpac270_pin_config[] __initdata = { /* UDC */ GPIO41_GPIO, + + /* Ethernet */ + GPIO114_GPIO, /* IRQ */ }; /****************************************************************************** @@ -308,6 +312,50 @@ static void __init vpac270_udc_init(void) static inline void vpac270_udc_init(void) {} #endif +/****************************************************************************** + * Ethernet + ******************************************************************************/ +#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) +static struct resource vpac270_dm9000_resources[] = { + [0] = { + .start = PXA_CS2_PHYS + 0x300, + .end = PXA_CS2_PHYS + 0x303, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PXA_CS2_PHYS + 0x304, + .end = PXA_CS2_PHYS + 0x343, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ), + .end = IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + }, +}; + +static struct dm9000_plat_data vpac270_dm9000_platdata = { + .flags = DM9000_PLATF_32BITONLY, +}; + +static struct platform_device vpac270_dm9000_device = { + .name = "dm9000", + .id = -1, + .num_resources = ARRAY_SIZE(vpac270_dm9000_resources), + .resource = vpac270_dm9000_resources, + .dev = { + .platform_data = &vpac270_dm9000_platdata, + } +}; + +static void __init vpac270_eth_init(void) +{ + platform_device_register(&vpac270_dm9000_device); +} +#else +static inline void vpac270_eth_init(void) {} +#endif + /****************************************************************************** * Framebuffer ******************************************************************************/ @@ -390,6 +438,7 @@ static void __init vpac270_init(void) vpac270_keys_init(); vpac270_uhc_init(); vpac270_udc_init(); + vpac270_eth_init(); } MACHINE_START(VPAC270, "Voipac PXA270") -- cgit v1.2.3-59-g8ed1b From 1a8fb70e484589105a77f44bcd11e531c5fbe789 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 26 Mar 2010 04:45:54 +0100 Subject: [ARM] pxa/vpac270: Add touchscreen support This adds support for the UCB1400 touchscreen found in the VPAC270 device. Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/vpac270.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 56cc24575999..fa428ca54902 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -22,11 +22,13 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -121,6 +123,15 @@ static unsigned long vpac270_pin_config[] __initdata = { /* Ethernet */ GPIO114_GPIO, /* IRQ */ + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO95_AC97_nRESET, + GPIO98_AC97_SYSCLK, + GPIO113_GPIO, /* TS IRQ */ }; /****************************************************************************** @@ -356,6 +367,36 @@ static void __init vpac270_eth_init(void) static inline void vpac270_eth_init(void) {} #endif +/****************************************************************************** + * Audio and Touchscreen + ******************************************************************************/ +#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \ + defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) +static pxa2xx_audio_ops_t vpac270_ac97_pdata = { + .reset_gpio = 95, +}; + +static struct ucb1400_pdata vpac270_ucb1400_pdata = { + .irq = IRQ_GPIO(113), +}; + +static struct platform_device vpac270_ucb1400_device = { + .name = "ucb1400_core", + .id = -1, + .dev = { + .platform_data = &vpac270_ucb1400_pdata, + }, +}; + +static void __init vpac270_ts_init(void) +{ + pxa_set_ac97_info(&vpac270_ac97_pdata); + platform_device_register(&vpac270_ucb1400_device); +} +#else +static inline void vpac270_ts_init(void) {} +#endif + /****************************************************************************** * Framebuffer ******************************************************************************/ @@ -439,6 +480,7 @@ static void __init vpac270_init(void) vpac270_uhc_init(); vpac270_udc_init(); vpac270_eth_init(); + vpac270_ts_init(); } MACHINE_START(VPAC270, "Voipac PXA270") -- cgit v1.2.3-59-g8ed1b From 83a4a1022654cbb9dd55fcf7c28807a634db54bc Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 26 Mar 2010 05:38:10 +0100 Subject: [ARM] pxa/vpac270: Add DS1339 RTC support Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/vpac270.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index fa428ca54902..0a9647b1916d 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -36,6 +36,8 @@ #include #include +#include + #include "generic.h" #include "devices.h" @@ -132,6 +134,10 @@ static unsigned long vpac270_pin_config[] __initdata = { GPIO95_AC97_nRESET, GPIO98_AC97_SYSCLK, GPIO113_GPIO, /* TS IRQ */ + + /* I2C */ + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, }; /****************************************************************************** @@ -397,6 +403,25 @@ static void __init vpac270_ts_init(void) static inline void vpac270_ts_init(void) {} #endif +/****************************************************************************** + * RTC + ******************************************************************************/ +#if defined(CONFIG_RTC_DRV_DS1307) || defined(CONFIG_RTC_DRV_DS1307_MODULE) +static struct i2c_board_info __initdata vpac270_i2c_devs[] = { + { + I2C_BOARD_INFO("ds1339", 0x68), + }, +}; + +static void __init vpac270_rtc_init(void) +{ + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(vpac270_i2c_devs)); +} +#else +static inline void vpac270_rtc_init(void) {} +#endif + /****************************************************************************** * Framebuffer ******************************************************************************/ @@ -481,6 +506,7 @@ static void __init vpac270_init(void) vpac270_udc_init(); vpac270_eth_init(); vpac270_ts_init(); + vpac270_rtc_init(); } MACHINE_START(VPAC270, "Voipac PXA270") -- cgit v1.2.3-59-g8ed1b From 052345aec01cbd22285771eee6e08486c07d3bcc Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 26 Apr 2010 21:46:07 +0200 Subject: [ARM] pxa/vpac270: add ide support This patch adds support for the on-board IDE channel. I tested this with a CDROM connected over 2.5-3.5 IDE reduction with external power supplied to the CDROM. This was not tested with the Voipac 270-HDD-000 (official Voipac HDD module), but I expect no problems. Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 1 + arch/arm/mach-pxa/include/mach/vpac270.h | 2 ++ arch/arm/mach-pxa/vpac270.c | 50 ++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index e4a0452e0e2d..3b51741a4810 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -252,6 +252,7 @@ config MACH_COLIBRI320 config MACH_VPAC270 bool "Voipac PXA270" select PXA27x + select HAVE_PATA_PLATFORM help PXA270 based Single Board Computer. diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h index b90b380ddab9..0d82c47056ef 100644 --- a/arch/arm/mach-pxa/include/mach/vpac270.h +++ b/arch/arm/mach-pxa/include/mach/vpac270.h @@ -35,4 +35,6 @@ #define GPIO114_VPAC270_ETH_IRQ 114 +#define GPIO36_VPAC270_IDE_IRQ 36 + #endif diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 0a9647b1916d..6575b8f352c9 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -138,6 +139,10 @@ static unsigned long vpac270_pin_config[] __initdata = { /* I2C */ GPIO117_I2C_SCL, GPIO118_I2C_SDA, + + /* IDE */ + GPIO36_GPIO, /* IDE IRQ */ + GPIO80_DREQ_1, }; /****************************************************************************** @@ -486,6 +491,50 @@ err: static inline void vpac270_lcd_init(void) {} #endif +/****************************************************************************** + * PATA IDE + ******************************************************************************/ +#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) +static struct pata_platform_info vpac270_pata_pdata = { + .ioport_shift = 1, + .irq_flags = IRQF_TRIGGER_RISING, +}; + +static struct resource vpac270_ide_resources[] = { + [0] = { /* I/O Base address */ + .start = PXA_CS3_PHYS + 0x120, + .end = PXA_CS3_PHYS + 0x13f, + .flags = IORESOURCE_MEM + }, + [1] = { /* CTL Base address */ + .start = PXA_CS3_PHYS + 0x15c, + .end = PXA_CS3_PHYS + 0x15f, + .flags = IORESOURCE_MEM + }, + [2] = { /* IDE IRQ pin */ + .start = gpio_to_irq(GPIO36_VPAC270_IDE_IRQ), + .end = gpio_to_irq(GPIO36_VPAC270_IDE_IRQ), + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device vpac270_ide_device = { + .name = "pata_platform", + .num_resources = ARRAY_SIZE(vpac270_ide_resources), + .resource = vpac270_ide_resources, + .dev = { + .platform_data = &vpac270_pata_pdata, + } +}; + +static void __init vpac270_ide_init(void) +{ + platform_device_register(&vpac270_ide_device); +} +#else +static inline void vpac270_ide_init(void) {} +#endif + /****************************************************************************** * Machine init ******************************************************************************/ @@ -507,6 +556,7 @@ static void __init vpac270_init(void) vpac270_eth_init(); vpac270_ts_init(); vpac270_rtc_init(); + vpac270_ide_init(); } MACHINE_START(VPAC270, "Voipac PXA270") -- cgit v1.2.3-59-g8ed1b From aeec1346884688b86ac7f0f36fb30aba30b459d8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 26 Apr 2010 23:23:48 +0200 Subject: [ARM] pxa/vpac270: remove TS_IRQ magic number The touchscreen GPIO IRQ was used as a magic number. Define it properly in the board header file. This is a simple cleanup patch. Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/vpac270.h | 2 ++ arch/arm/mach-pxa/vpac270.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h index 0d82c47056ef..7bfa3dd0fd5e 100644 --- a/arch/arm/mach-pxa/include/mach/vpac270.h +++ b/arch/arm/mach-pxa/include/mach/vpac270.h @@ -37,4 +37,6 @@ #define GPIO36_VPAC270_IDE_IRQ 36 +#define GPIO113_VPAC270_TS_IRQ 113 + #endif diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 6575b8f352c9..a1b39c4674da 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -388,7 +388,7 @@ static pxa2xx_audio_ops_t vpac270_ac97_pdata = { }; static struct ucb1400_pdata vpac270_ucb1400_pdata = { - .irq = IRQ_GPIO(113), + .irq = IRQ_GPIO(GPIO113_VPAC270_TS_IRQ), }; static struct platform_device vpac270_ucb1400_device = { -- cgit v1.2.3-59-g8ed1b From bcc399bb491e0971d84aba593d79d3addf5d31ee Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 1 May 2010 06:54:36 +0200 Subject: [ARM] pxa/vpac270: add OneNAND support Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/vpac270.c | 51 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index a1b39c4674da..46ad1b7bde85 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -149,7 +150,7 @@ static unsigned long vpac270_pin_config[] __initdata = { * NOR Flash ******************************************************************************/ #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) -static struct mtd_partition vpac270_partitions[] = { +static struct mtd_partition vpac270_nor_partitions[] = { { .name = "Flash", .offset = 0x00000000, @@ -160,8 +161,8 @@ static struct mtd_partition vpac270_partitions[] = { static struct physmap_flash_data vpac270_flash_data[] = { { .width = 2, /* bankwidth in bytes */ - .parts = vpac270_partitions, - .nr_parts = ARRAY_SIZE(vpac270_partitions) + .parts = vpac270_nor_partitions, + .nr_parts = ARRAY_SIZE(vpac270_nor_partitions) } }; @@ -188,6 +189,49 @@ static void __init vpac270_nor_init(void) static inline void vpac270_nor_init(void) {} #endif +/****************************************************************************** + * OneNAND Flash + ******************************************************************************/ +#if defined(CONFIG_MTD_ONENAND) || defined(CONFIG_MTD_ONENAND_MODULE) +static struct mtd_partition vpac270_onenand_partitions[] = { + { + .name = "Flash", + .offset = 0x00000000, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct onenand_platform_data vpac270_onenand_info = { + .parts = vpac270_onenand_partitions, + .nr_parts = ARRAY_SIZE(vpac270_onenand_partitions), +}; + +static struct resource vpac270_onenand_resources[] = { + [0] = { + .start = PXA_CS0_PHYS, + .end = PXA_CS0_PHYS + SZ_1M, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device vpac270_onenand = { + .name = "onenand-flash", + .id = -1, + .resource = vpac270_onenand_resources, + .num_resources = ARRAY_SIZE(vpac270_onenand_resources), + .dev = { + .platform_data = &vpac270_onenand_info, + }, +}; + +static void __init vpac270_onenand_init(void) +{ + platform_device_register(&vpac270_onenand); +} +#else +static void __init vpac270_onenand_init(void) {} +#endif + /****************************************************************************** * SD/MMC card controller ******************************************************************************/ @@ -549,6 +593,7 @@ static void __init vpac270_init(void) vpac270_lcd_init(); vpac270_mmc_init(); vpac270_nor_init(); + vpac270_onenand_init(); vpac270_leds_init(); vpac270_keys_init(); vpac270_uhc_init(); -- cgit v1.2.3-59-g8ed1b From fb25cb33096e2f86be5e45fecbc4d20eb66a9953 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 2 May 2010 06:10:25 +0200 Subject: [ARM] pxa/vpac270: fix now invalid bit of UP2OCR This patch removes write to UP2OCR[DMSTATE] (ex-UP2OCR_DPPUBE) which is invalid on PXA270C5 and later. Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/vpac270.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 46ad1b7bde85..0954c2433a98 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -359,9 +359,9 @@ static struct platform_device vpac270_gpio_vbus = { static void vpac270_udc_command(int cmd) { if (cmd == PXA2XX_UDC_CMD_CONNECT) - UP2OCR |= UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE; + UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE; else if (cmd == PXA2XX_UDC_CMD_DISCONNECT) - UP2OCR &= ~(UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE); + UP2OCR = UP2OCR_HXOE; } static struct pxa2xx_udc_mach_info vpac270_udc_info __initdata = { -- cgit v1.2.3-59-g8ed1b From f97cab28b1895ecb0aa317cc785bb209f57fc1e8 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Wed, 14 Apr 2010 07:00:42 +0800 Subject: [ARM] pxa: make it clear by converting MMC 'delay_detect' to millisecond delay_detect in HZ is confusing, convert it to be millisecond based. And thus remove those unnecessary call to msecs_to_jiffies() at runtime for this field. Other constants are converted assuming HZ == 100, which are basically true for those platforms. The assignment in csb726.c was incorrect, and is fixed in this patch as a result. Signed-off-by: Eric Miao Acked-by: Robert Jarzmik Acked-by: Marc Zyngier Acked-by: Marek Vasut Acked-by: Mike Rapoport Acked-by: Daniel Mack --- arch/arm/mach-pxa/cm-x300.c | 4 ++-- arch/arm/mach-pxa/colibri-pxa3xx.c | 2 +- arch/arm/mach-pxa/corgi.c | 2 +- arch/arm/mach-pxa/csb726.c | 11 +---------- arch/arm/mach-pxa/em-x270.c | 2 +- arch/arm/mach-pxa/include/mach/mmc.h | 2 +- arch/arm/mach-pxa/littleton.c | 2 +- arch/arm/mach-pxa/lubbock.c | 2 +- arch/arm/mach-pxa/mioa701.c | 2 +- arch/arm/mach-pxa/mxm8x10.c | 2 +- arch/arm/mach-pxa/palmld.c | 2 +- arch/arm/mach-pxa/palmt5.c | 2 +- arch/arm/mach-pxa/palmtc.c | 2 +- arch/arm/mach-pxa/palmtx.c | 2 +- arch/arm/mach-pxa/pcm990-baseboard.c | 2 +- arch/arm/mach-pxa/poodle.c | 2 +- arch/arm/mach-pxa/raumfeld.c | 2 +- arch/arm/mach-pxa/spitz.c | 2 +- arch/arm/mach-pxa/stargate2.c | 5 +---- arch/arm/mach-pxa/tosa.c | 2 +- arch/arm/mach-pxa/trizeps4.c | 2 +- arch/arm/mach-pxa/vpac270.c | 2 +- arch/arm/mach-pxa/z2.c | 2 +- arch/arm/mach-pxa/zeus.c | 2 +- arch/arm/mach-pxa/zylonite.c | 6 +++--- drivers/mmc/host/pxamci.c | 2 +- 26 files changed, 29 insertions(+), 41 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index be9dc7a20fbd..fdda6be6c391 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -433,7 +433,7 @@ static inline void cm_x300_init_nand(void) {} #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) static struct pxamci_platform_data cm_x300_mci_platform_data = { - .detect_delay = 20, + .detect_delay_ms = 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .gpio_card_detect = GPIO82_MMC_IRQ, .gpio_card_ro = GPIO85_MMC_WP, @@ -454,7 +454,7 @@ static void cm_x300_mci2_exit(struct device *dev, void *data) } static struct pxamci_platform_data cm_x300_mci2_platform_data = { - .detect_delay = 20, + .detect_delay_ms = 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .init = cm_x300_mci2_init, .exit = cm_x300_mci2_exit, diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c index e6c0a2287eb8..199afa2ae303 100644 --- a/arch/arm/mach-pxa/colibri-pxa3xx.c +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c @@ -96,7 +96,7 @@ static void colibri_pxa3xx_mci_exit(struct device *dev, void *data) } static struct pxamci_platform_data colibri_pxa3xx_mci_platform_data = { - .detect_delay = 20, + .detect_delay_ms = 200, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .init = colibri_pxa3xx_mci_init, .exit = colibri_pxa3xx_mci_exit, diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index f8e295900c58..3d1dcb9ac08f 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -444,6 +444,7 @@ static struct platform_device corgiled_device = { * to give the card a chance to fully insert/eject. */ static struct pxamci_platform_data corgi_mci_platform_data = { + .detect_delay_ms = 250, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .gpio_card_detect = -1, .gpio_card_ro = CORGI_GPIO_nSD_WP, @@ -695,7 +696,6 @@ static void __init corgi_init(void) corgi_init_spi(); pxa_set_udc_info(&udc_info); - corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250); pxa_set_mci_info(&corgi_mci_platform_data); pxa_set_ficp_info(&corgi_ficp_platform_data); pxa_set_i2c_info(NULL); diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c index 88575b87bd33..91fd4fea6a54 100644 --- a/arch/arm/mach-pxa/csb726.c +++ b/arch/arm/mach-pxa/csb726.c @@ -125,18 +125,9 @@ static unsigned long csb726_pin_config[] = { GPIO118_I2C_SDA, }; -static struct pxamci_platform_data csb726_mci_data; - -static int csb726_mci_init(struct device *dev, - irq_handler_t detect, void *data) -{ - csb726_mci_data.detect_delay = msecs_to_jiffies(500); - return 0; -} - static struct pxamci_platform_data csb726_mci = { + .detect_delay_ms = 500, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = csb726_mci_init, /* FIXME setpower */ .gpio_card_detect = CSB726_GPIO_MMC_DETECT, .gpio_card_ro = CSB726_GPIO_MMC_RO, diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index aab04f33e49b..0517c17978f3 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -626,6 +626,7 @@ static int em_x270_mci_get_ro(struct device *dev) } static struct pxamci_platform_data em_x270_mci_platform_data = { + .detect_delay_ms = 250, .ocr_mask = MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23| MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27| MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30| @@ -643,7 +644,6 @@ static void __init em_x270_init_mmc(void) if (machine_is_em_x270()) em_x270_mci_platform_data.get_ro = em_x270_mci_get_ro; - em_x270_mci_platform_data.detect_delay = msecs_to_jiffies(250); pxa_set_mci_info(&em_x270_mci_platform_data); } #else diff --git a/arch/arm/mach-pxa/include/mach/mmc.h b/arch/arm/mach-pxa/include/mach/mmc.h index 02a69dc2ee63..9eb515bb799d 100644 --- a/arch/arm/mach-pxa/include/mach/mmc.h +++ b/arch/arm/mach-pxa/include/mach/mmc.h @@ -9,7 +9,7 @@ struct mmc_host; struct pxamci_platform_data { unsigned int ocr_mask; /* available voltages */ - unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */ + unsigned long detect_delay_ms; /* delay in millisecond before detecting cards after interrupt */ int (*init)(struct device *, irq_handler_t , void *); int (*get_ro)(struct device *); void (*setpower)(struct device *, unsigned int); diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index be727aeed217..9b9046185b00 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -271,7 +271,7 @@ static inline void littleton_init_keypad(void) {} #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) static struct pxamci_platform_data littleton_mci_platform_data = { - .detect_delay = 20, + .detect_delay_ms = 200, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .gpio_card_detect = GPIO_MMC1_CARD_DETECT, .gpio_card_ro = -1, diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 63d65a2a0387..330c3282856e 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -478,7 +478,7 @@ static void lubbock_mci_exit(struct device *dev, void *data) static struct pxamci_platform_data lubbock_mci_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .detect_delay = 1, + .detect_delay_ms = 10, .init = lubbock_mci_init, .get_ro = lubbock_mci_get_ro, .exit = lubbock_mci_exit, diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index 7a50ed8fce94..d60db87dde08 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -426,6 +426,7 @@ struct gpio_vbus_mach_info gpio_vbus_data = { * to give the card a chance to fully insert/eject. */ static struct pxamci_platform_data mioa701_mci_info = { + .detect_delay_ms = 250, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .gpio_card_detect = GPIO15_SDIO_INSERT, .gpio_card_ro = GPIO78_SDIO_RO, @@ -791,7 +792,6 @@ static void __init mioa701_machine_init(void) mio_gpio_request(ARRAY_AND_SIZE(global_gpios)); bootstrap_init(); set_pxa_fb_info(&mioa701_pxafb_info); - mioa701_mci_info.detect_delay = msecs_to_jiffies(250); pxa_set_mci_info(&mioa701_mci_info); pxa_set_keypad_info(&mioa701_keypad_info); wm97xx_bat_set_pdata(&mioa701_battery_data); diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c index 8c9c6f0d56bb..462167ac05f9 100644 --- a/arch/arm/mach-pxa/mxm8x10.c +++ b/arch/arm/mach-pxa/mxm8x10.c @@ -325,7 +325,7 @@ static mfp_cfg_t mfp_cfg[] __initdata = { #if defined(CONFIG_MMC) static struct pxamci_platform_data mxm_8x10_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .detect_delay = 1, + .detect_delay_ms = 10, .gpio_card_detect = MXM_8X10_SD_nCD, .gpio_card_ro = MXM_8X10_SD_WP, .gpio_power = -1 diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index f70c75b38769..1963819dba98 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c @@ -168,7 +168,7 @@ static struct pxamci_platform_data palmld_mci_platform_data = { .gpio_card_detect = GPIO_NR_PALMLD_SD_DETECT_N, .gpio_card_ro = GPIO_NR_PALMLD_SD_READONLY, .gpio_power = GPIO_NR_PALMLD_SD_POWER, - .detect_delay = 20, + .detect_delay_ms = 200, }; /****************************************************************************** diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index d902a813aae3..5305a3993e69 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -110,7 +110,7 @@ static struct pxamci_platform_data palmt5_mci_platform_data = { .gpio_card_detect = GPIO_NR_PALMT5_SD_DETECT_N, .gpio_card_ro = GPIO_NR_PALMT5_SD_READONLY, .gpio_power = GPIO_NR_PALMT5_SD_POWER, - .detect_delay = 20, + .detect_delay_ms = 200, }; /****************************************************************************** diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 717d7a638675..033b567e50bb 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -121,7 +121,7 @@ static struct pxamci_platform_data palmtc_mci_platform_data = { .gpio_power = GPIO_NR_PALMTC_SD_POWER, .gpio_card_ro = GPIO_NR_PALMTC_SD_READONLY, .gpio_card_detect = GPIO_NR_PALMTC_SD_DETECT_N, - .detect_delay = 20, + .detect_delay_ms = 200, }; /****************************************************************************** diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 007b58c11f8d..ecc1a401598e 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -170,7 +170,7 @@ static struct pxamci_platform_data palmtx_mci_platform_data = { .gpio_card_detect = GPIO_NR_PALMTX_SD_DETECT_N, .gpio_card_ro = GPIO_NR_PALMTX_SD_READONLY, .gpio_power = GPIO_NR_PALMTX_SD_POWER, - .detect_delay = 20, + .detect_delay_ms = 200, }; /****************************************************************************** diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 9d0ecea1760c..f56ae1008759 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -326,7 +326,7 @@ static void pcm990_mci_exit(struct device *dev, void *data) #define MSECS_PER_JIFFY (1000/HZ) static struct pxamci_platform_data pcm990_mci_platform_data = { - .detect_delay = 250 / MSECS_PER_JIFFY, + .detect_delay_ms = 250, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .init = pcm990_mci_init, .setpower = pcm990_mci_setpower, diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index dcb178807046..f4abdaafdac4 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -276,6 +276,7 @@ static void poodle_mci_exit(struct device *dev, void *data) } static struct pxamci_platform_data poodle_mci_platform_data = { + .detect_delay_ms = 250, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .init = poodle_mci_init, .setpower = poodle_mci_setpower, @@ -449,7 +450,6 @@ static void __init poodle_init(void) set_pxa_fb_parent(&poodle_locomo_device.dev); set_pxa_fb_info(&poodle_fb_info); pxa_set_udc_info(&udc_info); - poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250); pxa_set_mci_info(&poodle_mci_platform_data); pxa_set_ficp_info(&poodle_ficp_platform_data); pxa_set_i2c_info(NULL); diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index d12667bd9ebe..d4b61b3f08f3 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -714,7 +714,7 @@ static void raumfeld_mci_exit(struct device *dev, void *data) static struct pxamci_platform_data raumfeld_mci_platform_data = { .init = raumfeld_mci_init, .exit = raumfeld_mci_exit, - .detect_delay = 20, + .detect_delay_ms = 200, .gpio_card_detect = -1, .gpio_card_ro = -1, .gpio_power = -1, diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 451029ea9eec..4d2413ed0ffa 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -539,6 +539,7 @@ static void spitz_mci_setpower(struct device *dev, unsigned int vdd) } static struct pxamci_platform_data spitz_mci_platform_data = { + .detect_delay_ms = 250, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .setpower = spitz_mci_setpower, .gpio_card_detect = SPITZ_GPIO_nSD_DETECT, @@ -759,7 +760,6 @@ static void __init common_init(void) spitz_init_spi(); platform_add_devices(devices, ARRAY_SIZE(devices)); - spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250); pxa_set_mci_info(&spitz_mci_platform_data); pxa_set_ohci_info(&spitz_ohci_platform_data); pxa_set_ficp_info(&spitz_ficp_platform_data); diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index 2041eb1d90ba..af40d2a12d37 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -464,8 +464,6 @@ static struct platform_device smc91x_device = { -static struct pxamci_platform_data stargate2_mci_platform_data; - /* * The card detect interrupt isn't debounced so we delay it by 250ms * to give the card a chance to fully insert / eject. @@ -489,8 +487,6 @@ static int stargate2_mci_init(struct device *dev, goto free_power_en; } gpio_direction_input(SG2_GPIO_nSD_DETECT); - /* Delay to allow for full insertion */ - stargate2_mci_platform_data.detect_delay = msecs_to_jiffies(250); err = request_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT), stargate2_detect_int, @@ -529,6 +525,7 @@ static void stargate2_mci_exit(struct device *dev, void *data) } static struct pxamci_platform_data stargate2_mci_platform_data = { + .detect_delay_ms = 250, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .init = stargate2_mci_init, .setpower = stargate2_mci_setpower, diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index ad552791c4ce..7512b822c6ca 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -275,6 +275,7 @@ static void tosa_mci_exit(struct device *dev, void *data) } static struct pxamci_platform_data tosa_mci_platform_data = { + .detect_delay_ms = 250, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .init = tosa_mci_init, .exit = tosa_mci_exit, @@ -926,7 +927,6 @@ static void __init tosa_init(void) dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12); dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16); - tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); pxa_set_mci_info(&tosa_mci_platform_data); pxa_set_udc_info(&udc_info); pxa_set_ficp_info(&tosa_ficp_platform_data); diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 797f2544d0ce..69689112eae7 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -349,7 +349,7 @@ static void trizeps4_mci_exit(struct device *dev, void *data) static struct pxamci_platform_data trizeps4_mci_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .detect_delay = 1, + .detect_delay_ms= 10, .init = trizeps4_mci_init, .exit = trizeps4_mci_exit, .get_ro = NULL, /* write-protection not supported */ diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 0954c2433a98..9884fa978f16 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -240,7 +240,7 @@ static struct pxamci_platform_data vpac270_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, - .detect_delay = 20, + .detect_delay_ms = 200, }; static void __init vpac270_mmc_init(void) diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index c837318ec1fa..f5d1ae3db3a4 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -291,7 +291,7 @@ static struct pxamci_platform_data z2_mci_platform_data = { .gpio_card_detect = GPIO96_ZIPITZ2_SD_DETECT, .gpio_power = -1, .gpio_card_ro = -1, - .detect_delay = 20, + .detect_delay_ms = 200, }; static void __init z2_mmc_init(void) diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 39896d883584..3680f6a90623 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -644,7 +644,7 @@ static struct pxafb_mach_info zeus_fb_info = { static struct pxamci_platform_data zeus_mci_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .detect_delay = HZ/4, + .detect_delay_ms = 250, .gpio_card_detect = ZEUS_MMC_CD_GPIO, .gpio_card_ro = ZEUS_MMC_WP_GPIO, .gpio_card_ro_invert = 1, diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 2b4043c04d0c..c479cbecf784 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -218,7 +218,7 @@ static inline void zylonite_init_lcd(void) {} #if defined(CONFIG_MMC) static struct pxamci_platform_data zylonite_mci_platform_data = { - .detect_delay = 20, + .detect_delay_ms= 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .gpio_card_detect = EXT_GPIO(0), .gpio_card_ro = EXT_GPIO(2), @@ -226,7 +226,7 @@ static struct pxamci_platform_data zylonite_mci_platform_data = { }; static struct pxamci_platform_data zylonite_mci2_platform_data = { - .detect_delay = 20, + .detect_delay_ms= 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .gpio_card_detect = EXT_GPIO(1), .gpio_card_ro = EXT_GPIO(3), @@ -234,7 +234,7 @@ static struct pxamci_platform_data zylonite_mci2_platform_data = { }; static struct pxamci_platform_data zylonite_mci3_platform_data = { - .detect_delay = 20, + .detect_delay_ms= 200, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .gpio_card_detect = EXT_GPIO(30), .gpio_card_ro = EXT_GPIO(31), diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 0ed48959b590..e4f00e70a749 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -544,7 +544,7 @@ static irqreturn_t pxamci_detect_irq(int irq, void *devid) { struct pxamci_host *host = mmc_priv(devid); - mmc_detect_change(devid, host->pdata->detect_delay); + mmc_detect_change(devid, msecs_to_jiffies(host->pdata->detect_delay_ms)); return IRQ_HANDLED; } -- cgit v1.2.3-59-g8ed1b From e598863690d956ad4e18904bb5b6c63fea1ad255 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 28 Apr 2010 10:48:24 -0400 Subject: [ARM] mmp: update clock register function Use clk_add_table in order to sync with clock driver. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/mmp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index 72eb9daeea99..cca39929110f 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -101,7 +101,7 @@ static int __init mmp2_init(void) if (cpu_is_mmp2()) { mfp_init_base(MFPR_VIRT_BASE); mfp_init_addr(mmp2_addr_map); - clks_register(ARRAY_AND_SIZE(mmp2_clkregs)); + clkdev_add_table(ARRAY_AND_SIZE(mmp2_clkregs)); } return 0; -- cgit v1.2.3-59-g8ed1b From 66b196475031c748a5861390a4fadb915e14ccdc Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 28 Apr 2010 10:59:45 -0400 Subject: [ARM] mmp: enable L2 in mmp2 Enable Tauros2 L2 in mmp2. Tauros2 L2 is shared in Marvell ARM cores. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/configs/mmp2_defconfig | 2 ++ arch/arm/mach-mmp/mmp2.c | 5 +++++ arch/arm/mm/Kconfig | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig index 03f76cfc941c..db8936370b6b 100644 --- a/arch/arm/configs/mmp2_defconfig +++ b/arch/arm/configs/mmp2_defconfig @@ -246,6 +246,8 @@ CONFIG_ARM_THUMB=y # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_OUTER_CACHE=y +CONFIG_CACHE_TAUROS2=y CONFIG_ARM_L1_CACHE_SHIFT=5 # CONFIG_ARM_ERRATA_411920 is not set CONFIG_COMMON_CLKDEV=y diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index cca39929110f..e236ec0c54f6 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -15,6 +15,8 @@ #include #include +#include + #include #include #include @@ -99,6 +101,9 @@ static struct clk_lookup mmp2_clkregs[] = { static int __init mmp2_init(void) { if (cpu_is_mmp2()) { +#ifdef CONFIG_CACHE_TAUROS2 + tauros2_init(); +#endif mfp_init_base(MFPR_VIRT_BASE); mfp_init_addr(mmp2_addr_map); clkdev_add_table(ARRAY_AND_SIZE(mmp2_clkregs)); diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 5bd7c89a6045..698912602387 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -769,7 +769,7 @@ config CACHE_L2X0 config CACHE_TAUROS2 bool "Enable the Tauros2 L2 cache controller" - depends on ARCH_DOVE + depends on (ARCH_DOVE || ARCH_MMP) default y select OUTER_CACHE help -- cgit v1.2.3-59-g8ed1b From d24123bfae56aef5a38a7c89fd588f1bd7584751 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 28 Apr 2010 11:32:30 -0400 Subject: [ARM] mmp: update mmp2 defconfig Enable MAX8649 & MAX8925 regulator, dynamic debug, Marvell Jasper platform. Disable DNOTIFY, MAX8660 regulator, 88pm860x PMIC. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/configs/mmp2_defconfig | 73 ++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig index db8936370b6b..4b55dcb60029 100644 --- a/arch/arm/configs/mmp2_defconfig +++ b/arch/arm/configs/mmp2_defconfig @@ -1,13 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Tue Jan 5 13:55:22 2010 +# Linux kernel version: 2.6.34-rc5 +# Wed Apr 28 11:23:19 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y @@ -18,6 +19,7 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -32,6 +34,12 @@ CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -52,7 +60,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -85,10 +92,14 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -104,6 +115,7 @@ CONFIG_HAVE_CLK=y # # GCOV-based kernel profiling # +# CONFIG_GCOV_KERNEL is not set # CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y @@ -170,6 +182,7 @@ CONFIG_MMU=y # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set # CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set @@ -179,7 +192,6 @@ CONFIG_MMU=y # CONFIG_ARCH_STMP3XXX is not set # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set # CONFIG_ARCH_IOP33X is not set @@ -196,21 +208,26 @@ CONFIG_ARCH_MMP=y # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set # CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set # CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_U8500 is not set # CONFIG_MACH_TAVOREVB is not set # @@ -218,8 +235,10 @@ CONFIG_ARCH_MMP=y # # CONFIG_MACH_ASPENITE is not set # CONFIG_MACH_ZYLONITE2 is not set +# CONFIG_MACH_AVENGERS_LITE is not set # CONFIG_MACH_TTC_DKB is not set CONFIG_MACH_FLINT=y +CONFIG_MACH_MARVELL_JASPER=y CONFIG_CPU_MMP2=y CONFIG_PLAT_PXA=y @@ -249,6 +268,7 @@ CONFIG_ARM_THUMB=y CONFIG_OUTER_CACHE=y CONFIG_CACHE_TAUROS2=y CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_CPU_HAS_PMU=y # CONFIG_ARM_ERRATA_411920 is not set CONFIG_COMMON_CLKDEV=y @@ -300,7 +320,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M user_debug=255" +CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS2,38400 mem=128M user_debug=255" # CONFIG_XIP_KERNEL is not set # CONFIG_KEXEC is not set @@ -340,7 +360,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -534,6 +553,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -642,6 +662,7 @@ CONFIG_SERIAL_PXA=y CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -669,6 +690,7 @@ CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_PXA=y # CONFIG_I2C_PXA_SLAVE is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -681,15 +703,9 @@ CONFIG_I2C_PXA=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -704,13 +720,16 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -739,10 +758,12 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # CONFIG_MFD_CORE=y +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_ASIC3 is not set # CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set @@ -751,24 +772,27 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_TC6393XB is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +CONFIG_MFD_MAX8925=y # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -CONFIG_MFD_88PM8607=y CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set # CONFIG_REGULATOR_FIXED_VOLTAGE is not set # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set # CONFIG_REGULATOR_BQ24022 is not set # CONFIG_REGULATOR_MAX1586 is not set -CONFIG_REGULATOR_MAX8660=y +CONFIG_REGULATOR_MAX8649=y +# CONFIG_REGULATOR_MAX8660 is not set +CONFIG_REGULATOR_MAX8925=y # CONFIG_REGULATOR_LP3971 is not set # CONFIG_REGULATOR_TPS65023 is not set # CONFIG_REGULATOR_TPS6507X is not set -CONFIG_REGULATOR_88PM8607=y # CONFIG_MEDIA_SUPPORT is not set # @@ -783,6 +807,7 @@ CONFIG_LCD_CLASS_DEVICE=y # CONFIG_LCD_PLATFORM is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GENERIC=y +CONFIG_BACKLIGHT_MAX8925=y # # Display device support @@ -823,6 +848,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_MAX8925=y # CONFIG_RTC_DRV_RS5C372 is not set # CONFIG_RTC_DRV_ISL1208 is not set # CONFIG_RTC_DRV_X1205 is not set @@ -874,7 +900,6 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y @@ -885,7 +910,7 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set @@ -942,6 +967,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -969,6 +995,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -992,7 +1019,7 @@ CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set @@ -1034,6 +1061,7 @@ CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set @@ -1054,6 +1082,7 @@ CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set # CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_DYNAMIC_DEBUG=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1061,9 +1090,7 @@ CONFIG_ARM_UNWIND=y CONFIG_DEBUG_USER=y CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUG_LL=y -# CONFIG_EARLY_PRINTK is not set -# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_LL is not set # CONFIG_OC_ETM is not set # -- cgit v1.2.3-59-g8ed1b From 55d3936d30affccb904f9294a3076ccb7bf09688 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 28 Apr 2010 11:43:00 -0400 Subject: [ARM] mmp: configure gpio pins from 128 to 192 In mmp2, 6 banks of GPIO registers are supported. So we can support 192 GPIO pins at most. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/include/mach/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-mmp/include/mach/gpio.h b/arch/arm/mach-mmp/include/mach/gpio.h index ab26d13295c4..ee8b02ed8011 100644 --- a/arch/arm/mach-mmp/include/mach/gpio.h +++ b/arch/arm/mach-mmp/include/mach/gpio.h @@ -10,7 +10,7 @@ #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) #define GPIO_REG(x) (*((volatile u32 *)(GPIO_REGS_VIRT + (x)))) -#define NR_BUILTIN_GPIO (128) +#define NR_BUILTIN_GPIO (192) #define gpio_to_bank(gpio) ((gpio) >> 5) #define gpio_to_irq(gpio) (IRQ_GPIO_START + (gpio)) -- cgit v1.2.3-59-g8ed1b From 8ae84427bb05c2921dcb0200b161b904028b5784 Mon Sep 17 00:00:00 2001 From: Mingliang Hu Date: Mon, 12 Apr 2010 17:55:21 +0800 Subject: [ARM] mmp: fix clock tick rate in mmp2 In MMP2, clock tick rate should be 6500000. Signed-off-by: Mingliang Hu Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/include/mach/timex.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-mmp/include/mach/timex.h b/arch/arm/mach-mmp/include/mach/timex.h index 6cebbd0ca8f4..70c9f1d88c02 100644 --- a/arch/arm/mach-mmp/include/mach/timex.h +++ b/arch/arm/mach-mmp/include/mach/timex.h @@ -6,4 +6,8 @@ * published by the Free Software Foundation. */ +#ifdef CONFIG_CPU_MMP2 +#define CLOCK_TICK_RATE 6500000 +#else #define CLOCK_TICK_RATE 3250000 +#endif -- cgit v1.2.3-59-g8ed1b From 7f39403c56b01a8c023e8eb9ebe89007cdc4f4e6 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 28 Apr 2010 15:18:59 -0400 Subject: [ARM] mmp: update mfp setting Update mfp setting for mmp2. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/include/mach/mfp-mmp2.h | 187 +++++++++++++++++++++++++++--- arch/arm/mach-mmp/mmp2.c | 43 +++++++ arch/arm/plat-pxa/include/plat/mfp.h | 7 ++ 3 files changed, 221 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h index 9f9f8143e272..761c2dacc079 100644 --- a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h +++ b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h @@ -9,6 +9,175 @@ #define MFP_DRIVE_FAST (0x8 << 13) /* GPIO */ +#define GPIO0_GPIO0 MFP_CFG(GPIO0, AF0) +#define GPIO1_GPIO1 MFP_CFG(GPIO1, AF0) +#define GPIO2_GPIO2 MFP_CFG(GPIO2, AF0) +#define GPIO3_GPIO3 MFP_CFG(GPIO3, AF0) +#define GPIO4_GPIO4 MFP_CFG(GPIO4, AF0) +#define GPIO5_GPIO5 MFP_CFG(GPIO5, AF0) +#define GPIO6_GPIO6 MFP_CFG(GPIO6, AF0) +#define GPIO7_GPIO7 MFP_CFG(GPIO7, AF0) +#define GPIO8_GPIO8 MFP_CFG(GPIO8, AF0) +#define GPIO9_GPIO9 MFP_CFG(GPIO9, AF0) +#define GPIO10_GPIO10 MFP_CFG(GPIO10, AF0) +#define GPIO11_GPIO11 MFP_CFG(GPIO11, AF0) +#define GPIO12_GPIO12 MFP_CFG(GPIO12, AF0) +#define GPIO13_GPIO13 MFP_CFG(GPIO13, AF0) +#define GPIO14_GPIO14 MFP_CFG(GPIO14, AF0) +#define GPIO15_GPIO15 MFP_CFG(GPIO15, AF0) +#define GPIO16_GPIO16 MFP_CFG(GPIO16, AF0) +#define GPIO17_GPIO17 MFP_CFG(GPIO17, AF0) +#define GPIO18_GPIO18 MFP_CFG(GPIO18, AF0) +#define GPIO19_GPIO19 MFP_CFG(GPIO19, AF0) +#define GPIO20_GPIO20 MFP_CFG(GPIO20, AF0) +#define GPIO21_GPIO21 MFP_CFG(GPIO21, AF0) +#define GPIO22_GPIO22 MFP_CFG(GPIO22, AF0) +#define GPIO23_GPIO23 MFP_CFG(GPIO23, AF0) +#define GPIO24_GPIO24 MFP_CFG(GPIO24, AF0) +#define GPIO25_GPIO25 MFP_CFG(GPIO25, AF0) +#define GPIO26_GPIO26 MFP_CFG(GPIO26, AF0) +#define GPIO27_GPIO27 MFP_CFG(GPIO27, AF0) +#define GPIO28_GPIO28 MFP_CFG(GPIO28, AF0) +#define GPIO29_GPIO29 MFP_CFG(GPIO29, AF0) +#define GPIO30_GPIO30 MFP_CFG(GPIO30, AF0) +#define GPIO31_GPIO31 MFP_CFG(GPIO31, AF0) +#define GPIO32_GPIO32 MFP_CFG(GPIO32, AF0) +#define GPIO33_GPIO33 MFP_CFG(GPIO33, AF0) +#define GPIO34_GPIO34 MFP_CFG(GPIO34, AF0) +#define GPIO35_GPIO35 MFP_CFG(GPIO35, AF0) +#define GPIO36_GPIO36 MFP_CFG(GPIO36, AF0) +#define GPIO37_GPIO37 MFP_CFG(GPIO37, AF0) +#define GPIO38_GPIO38 MFP_CFG(GPIO38, AF0) +#define GPIO39_GPIO39 MFP_CFG(GPIO39, AF0) +#define GPIO40_GPIO40 MFP_CFG(GPIO40, AF0) +#define GPIO41_GPIO41 MFP_CFG(GPIO41, AF0) +#define GPIO42_GPIO42 MFP_CFG(GPIO42, AF0) +#define GPIO43_GPIO43 MFP_CFG(GPIO43, AF0) +#define GPIO44_GPIO44 MFP_CFG(GPIO44, AF0) +#define GPIO45_GPIO45 MFP_CFG(GPIO45, AF0) +#define GPIO46_GPIO46 MFP_CFG(GPIO46, AF0) +#define GPIO47_GPIO47 MFP_CFG(GPIO47, AF0) +#define GPIO48_GPIO48 MFP_CFG(GPIO48, AF0) +#define GPIO49_GPIO49 MFP_CFG(GPIO49, AF0) +#define GPIO50_GPIO50 MFP_CFG(GPIO50, AF0) +#define GPIO51_GPIO51 MFP_CFG(GPIO51, AF0) +#define GPIO52_GPIO52 MFP_CFG(GPIO52, AF0) +#define GPIO53_GPIO53 MFP_CFG(GPIO53, AF0) +#define GPIO54_GPIO54 MFP_CFG(GPIO54, AF0) +#define GPIO55_GPIO55 MFP_CFG(GPIO55, AF0) +#define GPIO56_GPIO56 MFP_CFG(GPIO56, AF0) +#define GPIO57_GPIO57 MFP_CFG(GPIO57, AF0) +#define GPIO58_GPIO58 MFP_CFG(GPIO58, AF0) +#define GPIO59_GPIO59 MFP_CFG(GPIO59, AF0) +#define GPIO60_GPIO60 MFP_CFG(GPIO60, AF0) +#define GPIO61_GPIO61 MFP_CFG(GPIO61, AF0) +#define GPIO62_GPIO62 MFP_CFG(GPIO62, AF0) +#define GPIO63_GPIO63 MFP_CFG(GPIO63, AF0) +#define GPIO64_GPIO64 MFP_CFG(GPIO64, AF0) +#define GPIO65_GPIO65 MFP_CFG(GPIO65, AF0) +#define GPIO66_GPIO66 MFP_CFG(GPIO66, AF0) +#define GPIO67_GPIO67 MFP_CFG(GPIO67, AF0) +#define GPIO68_GPIO68 MFP_CFG(GPIO68, AF0) +#define GPIO69_GPIO69 MFP_CFG(GPIO69, AF0) +#define GPIO70_GPIO70 MFP_CFG(GPIO70, AF0) +#define GPIO71_GPIO71 MFP_CFG(GPIO71, AF0) +#define GPIO72_GPIO72 MFP_CFG(GPIO72, AF0) +#define GPIO73_GPIO73 MFP_CFG(GPIO73, AF0) +#define GPIO74_GPIO74 MFP_CFG(GPIO74, AF0) +#define GPIO75_GPIO75 MFP_CFG(GPIO75, AF0) +#define GPIO76_GPIO76 MFP_CFG(GPIO76, AF0) +#define GPIO77_GPIO77 MFP_CFG(GPIO77, AF0) +#define GPIO78_GPIO78 MFP_CFG(GPIO78, AF0) +#define GPIO79_GPIO79 MFP_CFG(GPIO79, AF0) +#define GPIO80_GPIO80 MFP_CFG(GPIO80, AF0) +#define GPIO81_GPIO81 MFP_CFG(GPIO81, AF0) +#define GPIO82_GPIO82 MFP_CFG(GPIO82, AF0) +#define GPIO83_GPIO83 MFP_CFG(GPIO83, AF0) +#define GPIO84_GPIO84 MFP_CFG(GPIO84, AF0) +#define GPIO85_GPIO85 MFP_CFG(GPIO85, AF0) +#define GPIO86_GPIO86 MFP_CFG(GPIO86, AF0) +#define GPIO87_GPIO87 MFP_CFG(GPIO87, AF0) +#define GPIO88_GPIO88 MFP_CFG(GPIO88, AF0) +#define GPIO89_GPIO89 MFP_CFG(GPIO89, AF0) +#define GPIO90_GPIO90 MFP_CFG(GPIO90, AF0) +#define GPIO91_GPIO91 MFP_CFG(GPIO91, AF0) +#define GPIO92_GPIO92 MFP_CFG(GPIO92, AF0) +#define GPIO93_GPIO93 MFP_CFG(GPIO93, AF0) +#define GPIO94_GPIO94 MFP_CFG(GPIO94, AF0) +#define GPIO95_GPIO95 MFP_CFG(GPIO95, AF0) +#define GPIO96_GPIO96 MFP_CFG(GPIO96, AF0) +#define GPIO97_GPIO97 MFP_CFG(GPIO97, AF0) +#define GPIO98_GPIO98 MFP_CFG(GPIO98, AF0) +#define GPIO99_GPIO99 MFP_CFG(GPIO99, AF0) +#define GPIO100_GPIO100 MFP_CFG(GPIO100, AF0) +#define GPIO101_GPIO101 MFP_CFG(GPIO101, AF0) +#define GPIO102_GPIO102 MFP_CFG(GPIO102, AF1) +#define GPIO103_GPIO103 MFP_CFG(GPIO103, AF1) +#define GPIO104_GPIO104 MFP_CFG(GPIO104, AF1) +#define GPIO105_GPIO105 MFP_CFG(GPIO105, AF1) +#define GPIO106_GPIO106 MFP_CFG(GPIO106, AF1) +#define GPIO107_GPIO107 MFP_CFG(GPIO107, AF1) +#define GPIO108_GPIO108 MFP_CFG(GPIO108, AF1) +#define GPIO109_GPIO109 MFP_CFG(GPIO109, AF1) +#define GPIO110_GPIO110 MFP_CFG(GPIO110, AF1) +#define GPIO111_GPIO111 MFP_CFG(GPIO111, AF1) +#define GPIO112_GPIO112 MFP_CFG(GPIO112, AF1) +#define GPIO113_GPIO113 MFP_CFG(GPIO113, AF1) +#define GPIO114_GPIO114 MFP_CFG(GPIO114, AF0) +#define GPIO115_GPIO115 MFP_CFG(GPIO115, AF0) +#define GPIO116_GPIO116 MFP_CFG(GPIO116, AF0) +#define GPIO117_GPIO117 MFP_CFG(GPIO117, AF0) +#define GPIO118_GPIO118 MFP_CFG(GPIO118, AF0) +#define GPIO119_GPIO119 MFP_CFG(GPIO119, AF0) +#define GPIO120_GPIO120 MFP_CFG(GPIO120, AF0) +#define GPIO121_GPIO121 MFP_CFG(GPIO121, AF0) +#define GPIO122_GPIO122 MFP_CFG(GPIO122, AF0) +#define GPIO123_GPIO123 MFP_CFG(GPIO123, AF0) +#define GPIO124_GPIO124 MFP_CFG(GPIO124, AF0) +#define GPIO125_GPIO125 MFP_CFG(GPIO125, AF0) +#define GPIO126_GPIO126 MFP_CFG(GPIO126, AF0) +#define GPIO127_GPIO127 MFP_CFG(GPIO127, AF0) +#define GPIO128_GPIO128 MFP_CFG(GPIO128, AF0) +#define GPIO129_GPIO129 MFP_CFG(GPIO129, AF0) +#define GPIO130_GPIO130 MFP_CFG(GPIO130, AF0) +#define GPIO131_GPIO131 MFP_CFG(GPIO131, AF0) +#define GPIO132_GPIO132 MFP_CFG(GPIO132, AF0) +#define GPIO133_GPIO133 MFP_CFG(GPIO133, AF0) +#define GPIO134_GPIO134 MFP_CFG(GPIO134, AF0) +#define GPIO135_GPIO135 MFP_CFG(GPIO135, AF0) +#define GPIO136_GPIO136 MFP_CFG(GPIO136, AF0) +#define GPIO137_GPIO137 MFP_CFG(GPIO137, AF0) +#define GPIO138_GPIO138 MFP_CFG(GPIO138, AF0) +#define GPIO139_GPIO139 MFP_CFG(GPIO139, AF0) +#define GPIO140_GPIO140 MFP_CFG(GPIO140, AF0) +#define GPIO141_GPIO141 MFP_CFG(GPIO141, AF0) +#define GPIO142_GPIO142 MFP_CFG(GPIO142, AF1) +#define GPIO143_GPIO143 MFP_CFG(GPIO143, AF1) +#define GPIO144_GPIO144 MFP_CFG(GPIO144, AF1) +#define GPIO145_GPIO145 MFP_CFG(GPIO145, AF1) +#define GPIO146_GPIO146 MFP_CFG(GPIO146, AF1) +#define GPIO147_GPIO147 MFP_CFG(GPIO147, AF1) +#define GPIO148_GPIO148 MFP_CFG(GPIO148, AF1) +#define GPIO149_GPIO149 MFP_CFG(GPIO149, AF1) +#define GPIO150_GPIO150 MFP_CFG(GPIO150, AF1) +#define GPIO151_GPIO151 MFP_CFG(GPIO151, AF1) +#define GPIO152_GPIO152 MFP_CFG(GPIO152, AF1) +#define GPIO153_GPIO153 MFP_CFG(GPIO153, AF1) +#define GPIO154_GPIO154 MFP_CFG(GPIO154, AF1) +#define GPIO155_GPIO155 MFP_CFG(GPIO155, AF1) +#define GPIO156_GPIO156 MFP_CFG(GPIO156, AF1) +#define GPIO157_GPIO157 MFP_CFG(GPIO157, AF1) +#define GPIO158_GPIO158 MFP_CFG(GPIO158, AF1) +#define GPIO159_GPIO159 MFP_CFG(GPIO159, AF1) +#define GPIO160_GPIO160 MFP_CFG(GPIO160, AF1) +#define GPIO161_GPIO161 MFP_CFG(GPIO161, AF1) +#define GPIO162_GPIO162 MFP_CFG(GPIO162, AF1) +#define GPIO163_GPIO163 MFP_CFG(GPIO163, AF1) +#define GPIO164_GPIO164 MFP_CFG(GPIO164, AF1) +#define GPIO165_GPIO165 MFP_CFG(GPIO165, AF1) +#define GPIO166_GPIO166 MFP_CFG(GPIO166, AF1) +#define GPIO167_GPIO167 MFP_CFG(GPIO167, AF1) +#define GPIO168_GPIO168 MFP_CFG(GPIO168, AF1) /* DFI */ #define GPIO108_DFI_D15 MFP_CFG(GPIO108, AF0) @@ -47,7 +216,6 @@ /* Ethernet */ #define GPIO155_SM_ADVMUX MFP_CFG(GPIO155, AF2) -#define GPIO155_GPIO155 MFP_CFG(GPIO155, AF1) /* UART1 */ #define GPIO45_UART1_RXD MFP_CFG(GPIO45, AF1) @@ -159,6 +327,8 @@ #define GPIO44_TWSI2_SDA MFP_CFG_DRV(GPIO44, AF1, SLOW) #define GPIO71_TWSI3_SCL MFP_CFG_DRV(GPIO71, AF1, SLOW) #define GPIO72_TWSI3_SDA MFP_CFG_DRV(GPIO72, AF1, SLOW) +#define TWSI4_SCL MFP_CFG_DRV(TWSI4_SCL, AF0, SLOW) +#define TWSI4_SDA MFP_CFG_DRV(TWSI4_SDA, AF0, SLOW) #define GPIO99_TWSI5_SCL MFP_CFG_DRV(GPIO99, AF4, SLOW) #define GPIO100_TWSI5_SDA MFP_CFG_DRV(GPIO100, AF4, SLOW) #define GPIO97_TWSI6_SCL MFP_CFG_DRV(GPIO97, AF2, SLOW) @@ -218,21 +388,6 @@ #define GPIO69_CAM_MCLK MFP_CFG_DRV(GPIO69, AF1, FAST) #define GPIO70_CAM_PCLK MFP_CFG_DRV(GPIO70, AF1, FAST) -/* Wifi */ -#define GPIO45_GPIO45 MFP_CFG(GPIO45, AF0) -#define GPIO46_GPIO46 MFP_CFG(GPIO46, AF0) -#define GPIO21_GPIO21 MFP_CFG(GPIO21, AF0) -#define GPIO22_GPIO22 MFP_CFG(GPIO22, AF0) -#define GPIO55_GPIO55 MFP_CFG(GPIO55, AF0) -#define GPIO56_GPIO56 MFP_CFG(GPIO56, AF0) -#define GPIO57_GPIO57 MFP_CFG(GPIO57, AF0) -#define GPIO58_GPIO58 MFP_CFG(GPIO58, AF0) - -/* Codec*/ -#define GPIO23_GPIO23 MFP_CFG(GPIO23, AF0) - -#define GPIO101_GPIO101 MFP_CFG(GPIO101, AF0) - /* PMIC */ #define PMIC_PMIC_INT MFP_CFG(PMIC_INT, AF0) diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index e236ec0c54f6..da5cd9d10807 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -34,7 +34,50 @@ #define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x9c) static struct mfp_addr_map mmp2_addr_map[] __initdata = { + + MFP_ADDR_X(GPIO0, GPIO58, 0x54), + MFP_ADDR_X(GPIO59, GPIO73, 0x280), + MFP_ADDR_X(GPIO74, GPIO101, 0x170), + + MFP_ADDR(GPIO102, 0x0), + MFP_ADDR(GPIO103, 0x4), + MFP_ADDR(GPIO104, 0x1fc), + MFP_ADDR(GPIO105, 0x1f8), + MFP_ADDR(GPIO106, 0x1f4), + MFP_ADDR(GPIO107, 0x1f0), + MFP_ADDR(GPIO108, 0x21c), + MFP_ADDR(GPIO109, 0x218), + MFP_ADDR(GPIO110, 0x214), + MFP_ADDR(GPIO111, 0x200), + MFP_ADDR(GPIO112, 0x244), + MFP_ADDR(GPIO113, 0x25c), + MFP_ADDR(GPIO114, 0x164), + MFP_ADDR_X(GPIO115, GPIO122, 0x260), + + MFP_ADDR(GPIO123, 0x148), + MFP_ADDR_X(GPIO124, GPIO141, 0xc), + + MFP_ADDR(GPIO142, 0x8), + MFP_ADDR_X(GPIO143, GPIO151, 0x220), + MFP_ADDR_X(GPIO152, GPIO153, 0x248), + MFP_ADDR_X(GPIO154, GPIO155, 0x254), + MFP_ADDR_X(GPIO156, GPIO159, 0x14c), + + MFP_ADDR(GPIO160, 0x250), + MFP_ADDR(GPIO161, 0x210), + MFP_ADDR(GPIO162, 0x20c), + MFP_ADDR(GPIO163, 0x208), + MFP_ADDR(GPIO164, 0x204), + MFP_ADDR(GPIO165, 0x1ec), + MFP_ADDR(GPIO166, 0x1e8), + MFP_ADDR(GPIO167, 0x1e4), + MFP_ADDR(GPIO168, 0x1e0), + + MFP_ADDR_X(TWSI1_SCL, TWSI1_SDA, 0x140), + MFP_ADDR_X(TWSI4_SCL, TWSI4_SDA, 0x2bc), + MFP_ADDR(PMIC_INT, 0x2c4), + MFP_ADDR(CLK_REQ, 0x160), MFP_ADDR_END, }; diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h index 857a6839071c..9e604c80618f 100644 --- a/arch/arm/plat-pxa/include/plat/mfp.h +++ b/arch/arm/plat-pxa/include/plat/mfp.h @@ -316,6 +316,13 @@ enum { MFP_PIN_PMIC_INT, MFP_PIN_RDY, + /* additional pins on MMP2 */ + MFP_PIN_TWSI1_SCL, + MFP_PIN_TWSI1_SDA, + MFP_PIN_TWSI4_SCL, + MFP_PIN_TWSI4_SDA, + MFP_PIN_CLK_REQ, + MFP_PIN_MAX, }; -- cgit v1.2.3-59-g8ed1b From f4557870834b15bcbe14a2fcd1a0338e9f9c89b5 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 28 Apr 2010 15:24:24 -0400 Subject: [ARM] mmp: add dma support to mmp2 Add DMA support in MMP2. Signed-off-by: Lei Wen Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/mmp2.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index da5cd9d10807..7f5eb059bb01 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -149,6 +150,7 @@ static int __init mmp2_init(void) #endif mfp_init_base(MFPR_VIRT_BASE); mfp_init_addr(mmp2_addr_map); + pxa_init_dma(IRQ_MMP2_DMA_RIQ, 16); clkdev_add_table(ARRAY_AND_SIZE(mmp2_clkregs)); } -- cgit v1.2.3-59-g8ed1b From d49ea9e30bab64280eb93aaf5dedad205a30d28b Mon Sep 17 00:00:00 2001 From: Mingliang Hu Date: Mon, 12 Apr 2010 18:14:18 +0800 Subject: [ARM] mmp: add smc registers definition Signed-off-by: Mingliang Hu Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/include/mach/regs-smc.h | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 arch/arm/mach-mmp/include/mach/regs-smc.h (limited to 'arch') diff --git a/arch/arm/mach-mmp/include/mach/regs-smc.h b/arch/arm/mach-mmp/include/mach/regs-smc.h new file mode 100644 index 000000000000..e484d40d71bd --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/regs-smc.h @@ -0,0 +1,37 @@ +/* + * linux/arch/arm/mach-mmp/include/mach/regs-smc.h + * + * Static Memory Controller Registers + * + * 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. + */ + +#ifndef __ASM_MACH_REGS_SMC_H +#define __ASM_MACH_REGS_SMC_H + +#include + +#define SMC_VIRT_BASE (AXI_VIRT_BASE + 0x83800) +#define SMC_REG(x) (SMC_VIRT_BASE + (x)) + +#define SMC_MSC0 SMC_REG(0x0020) +#define SMC_MSC1 SMC_REG(0x0024) +#define SMC_SXCNFG0 SMC_REG(0x0030) +#define SMC_SXCNFG1 SMC_REG(0x0034) +#define SMC_MEMCLKCFG SMC_REG(0x0068) +#define SMC_CSDFICFG0 SMC_REG(0x0090) +#define SMC_CSDFICFG1 SMC_REG(0x0094) +#define SMC_CLK_RET_DEL SMC_REG(0x00b0) +#define SMC_ADV_RET_DEL SMC_REG(0x00b4) +#define SMC_CSADRMAP0 SMC_REG(0x00c0) +#define SMC_CSADRMAP1 SMC_REG(0x00c4) +#define SMC_WE_AP0 SMC_REG(0x00e0) +#define SMC_WE_AP1 SMC_REG(0x00e4) +#define SMC_OE_AP0 SMC_REG(0x00f0) +#define SMC_OE_AP1 SMC_REG(0x00f4) +#define SMC_ADV_AP0 SMC_REG(0x0100) +#define SMC_ADV_AP1 SMC_REG(0x0104) + +#endif /* __ASM_MACH_REGS_SMC_H */ -- cgit v1.2.3-59-g8ed1b From fed240558094058a5d372448b722fed93ddabd6b Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 28 Apr 2010 15:34:04 -0400 Subject: [ARM] mmp: update twsi index Sync twsi index to register index. It's used to avoid typo error. Signed-off-by: Haojian Zhuang Signed-off-by: Eric Miao --- arch/arm/mach-mmp/include/mach/mmp2.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h index 459f3be9cfb2..fec220bd5046 100644 --- a/arch/arm/mach-mmp/include/mach/mmp2.h +++ b/arch/arm/mach-mmp/include/mach/mmp2.h @@ -39,17 +39,17 @@ static inline int mmp2_add_twsi(int id, struct i2c_pxa_platform_data *data, int ret; switch (id) { - case 0: d = &mmp2_device_twsi1; break; - case 1: d = &mmp2_device_twsi2; break; - case 2: d = &mmp2_device_twsi3; break; - case 3: d = &mmp2_device_twsi4; break; - case 4: d = &mmp2_device_twsi5; break; - case 5: d = &mmp2_device_twsi6; break; + case 1: d = &mmp2_device_twsi1; break; + case 2: d = &mmp2_device_twsi2; break; + case 3: d = &mmp2_device_twsi3; break; + case 4: d = &mmp2_device_twsi4; break; + case 5: d = &mmp2_device_twsi5; break; + case 6: d = &mmp2_device_twsi6; break; default: return -EINVAL; } - ret = i2c_register_board_info(id, info, size); + ret = i2c_register_board_info(id - 1, info, size); if (ret) return ret; -- cgit v1.2.3-59-g8ed1b From 2503991a56483dc8477a3c6ca86da253eb5f8af9 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 28 Apr 2010 15:43:21 -0400 Subject: [ARM] mmp: append device support in jasper Support regulator MAX8649, PMIC MAX8925 into the Jasper. Backlight & power supply components of MAX8925 are enabled in Jasper. Signed-off-by: Haojian Zhuang Acked-by: Mark Brown Signed-off-by: Eric Miao --- arch/arm/mach-mmp/jasper.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c index cfd4d66ef800..d77dd41d60e1 100644 --- a/arch/arm/mach-mmp/jasper.c +++ b/arch/arm/mach-mmp/jasper.c @@ -15,12 +15,16 @@ #include #include #include +#include +#include +#include #include #include #include #include #include +#include #include "common.h" @@ -58,6 +62,63 @@ static unsigned long jasper_pin_config[] __initdata = { GPIO149_ND_CLE, GPIO112_ND_RDY0, GPIO160_ND_RDY1, + + /* PMIC */ + PMIC_PMIC_INT | MFP_LPM_EDGE_FALL, +}; + +static struct regulator_consumer_supply max8649_supply[] = { + REGULATOR_SUPPLY("vcc_core", NULL), +}; + +static struct regulator_init_data max8649_init_data = { + .constraints = { + .name = "vcc_core range", + .min_uV = 1150000, + .max_uV = 1280000, + .always_on = 1, + .boot_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max8649_supply[0], +}; + +static struct max8649_platform_data jasper_max8649_info = { + .mode = 2, /* VID1 = 1, VID0 = 0 */ + .extclk = 0, + .ramp_timing = MAX8649_RAMP_32MV, + .regulator = &max8649_init_data, +}; + +static struct max8925_backlight_pdata jasper_backlight_data = { + .dual_string = 0, +}; + +static struct max8925_power_pdata jasper_power_data = { + .batt_detect = 0, /* can't detect battery by ID pin */ + .topoff_threshold = MAX8925_TOPOFF_THR_10PER, + .fast_charge = MAX8925_FCHG_1000MA, +}; + +static struct max8925_platform_data jasper_max8925_info = { + .backlight = &jasper_backlight_data, + .power = &jasper_power_data, + .irq_base = IRQ_BOARD_START, +}; + +static struct i2c_board_info jasper_twsi1_info[] = { + [0] = { + .type = "max8649", + .addr = 0x60, + .platform_data = &jasper_max8649_info, + }, + [1] = { + .type = "max8925", + .addr = 0x3c, + .irq = IRQ_MMP2_PMIC, + .platform_data = &jasper_max8925_info, + }, }; static void __init jasper_init(void) @@ -67,6 +128,9 @@ static void __init jasper_init(void) /* on-chip devices */ mmp2_add_uart(1); mmp2_add_uart(3); + mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(jasper_twsi1_info)); + + regulator_has_full_constraints(); } MACHINE_START(MARVELL_JASPER, "Jasper Development Platform") -- cgit v1.2.3-59-g8ed1b From baffe1699c68da5040de6b274054adc995795782 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 5 May 2010 10:11:15 -0400 Subject: [ARM] pxa: add namespace on ssp In order to prevent code ambiguous, add namespace on functions in ssp driver. Signed-off-by: Haojian Zhuang Acked-by: Liam Girdwood Signed-off-by: Eric Miao --- arch/arm/plat-pxa/include/plat/ssp.h | 12 ++-- arch/arm/plat-pxa/ssp.c | 22 +++--- drivers/spi/pxa2xx_spi.c | 8 +-- sound/soc/pxa/pxa-ssp.c | 132 +++++++++++++++++------------------ 4 files changed, 87 insertions(+), 87 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-pxa/include/plat/ssp.h b/arch/arm/plat-pxa/include/plat/ssp.h index d16d79a3a48a..fe43150690ed 100644 --- a/arch/arm/plat-pxa/include/plat/ssp.h +++ b/arch/arm/plat-pxa/include/plat/ssp.h @@ -159,28 +159,28 @@ struct ssp_device { }; /** - * ssp_write_reg - Write to a SSP register + * pxa_ssp_write_reg - Write to a SSP register * * @dev: SSP device to access * @reg: Register to write to * @val: Value to be written. */ -static inline void ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val) +static inline void pxa_ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val) { __raw_writel(val, dev->mmio_base + reg); } /** - * ssp_read_reg - Read from a SSP register + * pxa_ssp_read_reg - Read from a SSP register * * @dev: SSP device to access * @reg: Register to read from */ -static inline u32 ssp_read_reg(struct ssp_device *dev, u32 reg) +static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg) { return __raw_readl(dev->mmio_base + reg); } -struct ssp_device *ssp_request(int port, const char *label); -void ssp_free(struct ssp_device *); +struct ssp_device *pxa_ssp_request(int port, const char *label); +void pxa_ssp_free(struct ssp_device *); #endif /* __ASM_ARCH_SSP_H */ diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c index 52c07cc756d7..c6357e554aba 100644 --- a/arch/arm/plat-pxa/ssp.c +++ b/arch/arm/plat-pxa/ssp.c @@ -37,7 +37,7 @@ static DEFINE_MUTEX(ssp_lock); static LIST_HEAD(ssp_list); -struct ssp_device *ssp_request(int port, const char *label) +struct ssp_device *pxa_ssp_request(int port, const char *label) { struct ssp_device *ssp = NULL; @@ -58,9 +58,9 @@ struct ssp_device *ssp_request(int port, const char *label) return ssp; } -EXPORT_SYMBOL(ssp_request); +EXPORT_SYMBOL(pxa_ssp_request); -void ssp_free(struct ssp_device *ssp) +void pxa_ssp_free(struct ssp_device *ssp) { mutex_lock(&ssp_lock); if (ssp->use_count) { @@ -70,9 +70,9 @@ void ssp_free(struct ssp_device *ssp) dev_err(&ssp->pdev->dev, "device already free\n"); mutex_unlock(&ssp_lock); } -EXPORT_SYMBOL(ssp_free); +EXPORT_SYMBOL(pxa_ssp_free); -static int __devinit ssp_probe(struct platform_device *pdev) +static int __devinit pxa_ssp_probe(struct platform_device *pdev) { const struct platform_device_id *id = platform_get_device_id(pdev); struct resource *res; @@ -164,7 +164,7 @@ err_free: return ret; } -static int __devexit ssp_remove(struct platform_device *pdev) +static int __devexit pxa_ssp_remove(struct platform_device *pdev) { struct resource *res; struct ssp_device *ssp; @@ -196,9 +196,9 @@ static const struct platform_device_id ssp_id_table[] = { { }, }; -static struct platform_driver ssp_driver = { - .probe = ssp_probe, - .remove = __devexit_p(ssp_remove), +static struct platform_driver pxa_ssp_driver = { + .probe = pxa_ssp_probe, + .remove = __devexit_p(pxa_ssp_remove), .driver = { .owner = THIS_MODULE, .name = "pxa2xx-ssp", @@ -208,12 +208,12 @@ static struct platform_driver ssp_driver = { static int __init pxa_ssp_init(void) { - return platform_driver_register(&ssp_driver); + return platform_driver_register(&pxa_ssp_driver); } static void __exit pxa_ssp_exit(void) { - platform_driver_unregister(&ssp_driver); + platform_driver_unregister(&pxa_ssp_driver); } arch_initcall(pxa_ssp_init); diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 50d6b780bc67..e76b1afafe07 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -1465,7 +1465,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) platform_info = dev->platform_data; - ssp = ssp_request(pdev->id, pdev->name); + ssp = pxa_ssp_request(pdev->id, pdev->name); if (ssp == NULL) { dev_err(&pdev->dev, "failed to request SSP%d\n", pdev->id); return -ENODEV; @@ -1475,7 +1475,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) master = spi_alloc_master(dev, sizeof(struct driver_data) + 16); if (!master) { dev_err(&pdev->dev, "cannot alloc spi_master\n"); - ssp_free(ssp); + pxa_ssp_free(ssp); return -ENOMEM; } drv_data = spi_master_get_devdata(master); @@ -1604,7 +1604,7 @@ out_error_irq_alloc: out_error_master_alloc: spi_master_put(master); - ssp_free(ssp); + pxa_ssp_free(ssp); return status; } @@ -1648,7 +1648,7 @@ static int pxa2xx_spi_remove(struct platform_device *pdev) free_irq(ssp->irq, drv_data); /* Release SSP */ - ssp_free(ssp); + pxa_ssp_free(ssp); /* Disconnect from the SPI framework */ spi_unregister_master(drv_data->master); diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 6271a100f355..a1fd23e0e3d0 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -56,15 +56,15 @@ struct ssp_priv { static void dump_registers(struct ssp_device *ssp) { dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n", - ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1), - ssp_read_reg(ssp, SSTO)); + pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1), + pxa_ssp_read_reg(ssp, SSTO)); dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n", - ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR), - ssp_read_reg(ssp, SSACD)); + pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR), + pxa_ssp_read_reg(ssp, SSACD)); } -static void ssp_enable(struct ssp_device *ssp) +static void pxa_ssp_enable(struct ssp_device *ssp) { uint32_t sscr0; @@ -72,7 +72,7 @@ static void ssp_enable(struct ssp_device *ssp) __raw_writel(sscr0, ssp->mmio_base + SSCR0); } -static void ssp_disable(struct ssp_device *ssp) +static void pxa_ssp_disable(struct ssp_device *ssp) { uint32_t sscr0; @@ -86,7 +86,7 @@ struct pxa2xx_pcm_dma_data { }; static struct pxa2xx_pcm_dma_params * -ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) +pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) { struct pxa2xx_pcm_dma_data *dma; @@ -118,7 +118,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, if (!cpu_dai->active) { clk_enable(ssp->clk); - ssp_disable(ssp); + pxa_ssp_disable(ssp); } kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); @@ -136,7 +136,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, struct ssp_device *ssp = priv->ssp; if (!cpu_dai->active) { - ssp_disable(ssp); + pxa_ssp_disable(ssp); clk_disable(ssp->clk); } @@ -159,7 +159,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) priv->to = __raw_readl(ssp->mmio_base + SSTO); priv->psp = __raw_readl(ssp->mmio_base + SSPSP); - ssp_disable(ssp); + pxa_ssp_disable(ssp); clk_disable(ssp->clk); return 0; } @@ -179,7 +179,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) __raw_writel(priv->psp, ssp->mmio_base + SSPSP); if (cpu_dai->active) - ssp_enable(ssp); + pxa_ssp_enable(ssp); else clk_disable(ssp->clk); @@ -195,9 +195,9 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) * ssp_set_clkdiv - set SSP clock divider * @div: serial clock rate divider */ -static void ssp_set_scr(struct ssp_device *ssp, u32 div) +static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div) { - u32 sscr0 = ssp_read_reg(ssp, SSCR0); + u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) { sscr0 &= ~0x0000ff00; @@ -206,15 +206,15 @@ static void ssp_set_scr(struct ssp_device *ssp, u32 div) sscr0 &= ~0x000fff00; sscr0 |= (div - 1) << 8; /* 1..4096 */ } - ssp_write_reg(ssp, SSCR0, sscr0); + pxa_ssp_write_reg(ssp, SSCR0, sscr0); } /** - * ssp_get_clkdiv - get SSP clock divider + * pxa_ssp_get_clkdiv - get SSP clock divider */ -static u32 ssp_get_scr(struct ssp_device *ssp) +static u32 pxa_ssp_get_scr(struct ssp_device *ssp) { - u32 sscr0 = ssp_read_reg(ssp, SSCR0); + u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); u32 div; if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) @@ -234,7 +234,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, struct ssp_device *ssp = priv->ssp; int val; - u32 sscr0 = ssp_read_reg(ssp, SSCR0) & + u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); dev_dbg(&ssp->pdev->dev, @@ -262,7 +262,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, break; case PXA_SSP_CLK_AUDIO: priv->sysclk = 0; - ssp_set_scr(ssp, 1); + pxa_ssp_set_scr(ssp, 1); sscr0 |= SSCR0_ACS; break; default: @@ -273,8 +273,8 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, * on PXA2xx. On PXA3xx it must be enabled when doing so. */ if (!cpu_is_pxa3xx()) clk_disable(ssp->clk); - val = ssp_read_reg(ssp, SSCR0) | sscr0; - ssp_write_reg(ssp, SSCR0, val); + val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0; + pxa_ssp_write_reg(ssp, SSCR0, val); if (!cpu_is_pxa3xx()) clk_enable(ssp->clk); @@ -293,11 +293,11 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, switch (div_id) { case PXA_SSP_AUDIO_DIV_ACDS: - val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div); - ssp_write_reg(ssp, SSACD, val); + val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div); + pxa_ssp_write_reg(ssp, SSACD, val); break; case PXA_SSP_AUDIO_DIV_SCDB: - val = ssp_read_reg(ssp, SSACD); + val = pxa_ssp_read_reg(ssp, SSACD); val &= ~SSACD_SCDB; #if defined(CONFIG_PXA3xx) if (cpu_is_pxa3xx()) @@ -320,10 +320,10 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, default: return -EINVAL; } - ssp_write_reg(ssp, SSACD, val); + pxa_ssp_write_reg(ssp, SSACD, val); break; case PXA_SSP_DIV_SCR: - ssp_set_scr(ssp, div); + pxa_ssp_set_scr(ssp, div); break; default: return -ENODEV; @@ -340,11 +340,11 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, { struct ssp_priv *priv = cpu_dai->private_data; struct ssp_device *ssp = priv->ssp; - u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70; + u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70; #if defined(CONFIG_PXA3xx) if (cpu_is_pxa3xx()) - ssp_write_reg(ssp, SSACDD, 0); + pxa_ssp_write_reg(ssp, SSACDD, 0); #endif switch (freq_out) { @@ -382,7 +382,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, val = tmp; val = (val << 16) | 64; - ssp_write_reg(ssp, SSACDD, val); + pxa_ssp_write_reg(ssp, SSACDD, val); ssacd |= (0x6 << 4); @@ -396,7 +396,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, return -EINVAL; } - ssp_write_reg(ssp, SSACD, ssacd); + pxa_ssp_write_reg(ssp, SSACD, ssacd); return 0; } @@ -411,7 +411,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, struct ssp_device *ssp = priv->ssp; u32 sscr0; - sscr0 = ssp_read_reg(ssp, SSCR0); + sscr0 = pxa_ssp_read_reg(ssp, SSCR0); sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS); /* set slot width */ @@ -428,10 +428,10 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, sscr0 |= SSCR0_SlotsPerFrm(slots); /* set active slot mask */ - ssp_write_reg(ssp, SSTSA, tx_mask); - ssp_write_reg(ssp, SSRSA, rx_mask); + pxa_ssp_write_reg(ssp, SSTSA, tx_mask); + pxa_ssp_write_reg(ssp, SSRSA, rx_mask); } - ssp_write_reg(ssp, SSCR0, sscr0); + pxa_ssp_write_reg(ssp, SSCR0, sscr0); return 0; } @@ -446,12 +446,12 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai, struct ssp_device *ssp = priv->ssp; u32 sscr1; - sscr1 = ssp_read_reg(ssp, SSCR1); + sscr1 = pxa_ssp_read_reg(ssp, SSCR1); if (tristate) sscr1 &= ~SSCR1_TTE; else sscr1 |= SSCR1_TTE; - ssp_write_reg(ssp, SSCR1, sscr1); + pxa_ssp_write_reg(ssp, SSCR1, sscr1); return 0; } @@ -475,14 +475,14 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, return 0; /* we can only change the settings if the port is not in use */ - if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { + if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { dev_err(&ssp->pdev->dev, "can't change hardware dai format: stream is in use"); return -EINVAL; } /* reset port settings */ - sscr0 = ssp_read_reg(ssp, SSCR0) & + sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7); sspsp = 0; @@ -534,9 +534,9 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, return -EINVAL; } - ssp_write_reg(ssp, SSCR0, sscr0); - ssp_write_reg(ssp, SSCR1, sscr1); - ssp_write_reg(ssp, SSPSP, sspsp); + pxa_ssp_write_reg(ssp, SSCR0, sscr0); + pxa_ssp_write_reg(ssp, SSCR1, sscr1); + pxa_ssp_write_reg(ssp, SSPSP, sspsp); dump_registers(ssp); @@ -565,7 +565,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, u32 sscr0; u32 sspsp; int width = snd_pcm_format_physical_width(params_format(params)); - int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; + int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf; struct pxa2xx_pcm_dma_params *dma_data; dma_data = snd_soc_dai_get_dma_data(dai, substream); @@ -577,22 +577,22 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, * to force 16-bit frame width on the wire (for S16_LE), even * with two channels. Use 16-bit DMA transfers for this case. */ - dma_data = ssp_get_dma_params(ssp, + dma_data = pxa_ssp_get_dma_params(ssp, ((chn == 2) && (ttsa != 1)) || (width == 32), substream->stream == SNDRV_PCM_STREAM_PLAYBACK); snd_soc_dai_set_dma_data(dai, substream, dma_data); /* we can only change the settings if the port is not in use */ - if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) + if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) return 0; /* clear selected SSP bits */ - sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS); - ssp_write_reg(ssp, SSCR0, sscr0); + sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS); + pxa_ssp_write_reg(ssp, SSCR0, sscr0); /* bit size */ - sscr0 = ssp_read_reg(ssp, SSCR0); + sscr0 = pxa_ssp_read_reg(ssp, SSCR0); switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: #ifdef CONFIG_PXA3xx @@ -608,13 +608,13 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16)); break; } - ssp_write_reg(ssp, SSCR0, sscr0); + pxa_ssp_write_reg(ssp, SSCR0, sscr0); switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: - sspsp = ssp_read_reg(ssp, SSPSP); + sspsp = pxa_ssp_read_reg(ssp, SSPSP); - if ((ssp_get_scr(ssp) == 4) && (width == 16)) { + if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) { /* This is a special case where the bitclk is 64fs * and we're not dealing with 2*32 bits of audio * samples. @@ -648,7 +648,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, sspsp |= SSPSP_DMYSTRT(1); } - ssp_write_reg(ssp, SSPSP, sspsp); + pxa_ssp_write_reg(ssp, SSPSP, sspsp); break; default: break; @@ -679,45 +679,45 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, switch (cmd) { case SNDRV_PCM_TRIGGER_RESUME: - ssp_enable(ssp); + pxa_ssp_enable(ssp); break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - val = ssp_read_reg(ssp, SSCR1); + val = pxa_ssp_read_reg(ssp, SSCR1); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) val |= SSCR1_TSRE; else val |= SSCR1_RSRE; - ssp_write_reg(ssp, SSCR1, val); - val = ssp_read_reg(ssp, SSSR); - ssp_write_reg(ssp, SSSR, val); + pxa_ssp_write_reg(ssp, SSCR1, val); + val = pxa_ssp_read_reg(ssp, SSSR); + pxa_ssp_write_reg(ssp, SSSR, val); break; case SNDRV_PCM_TRIGGER_START: - val = ssp_read_reg(ssp, SSCR1); + val = pxa_ssp_read_reg(ssp, SSCR1); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) val |= SSCR1_TSRE; else val |= SSCR1_RSRE; - ssp_write_reg(ssp, SSCR1, val); - ssp_enable(ssp); + pxa_ssp_write_reg(ssp, SSCR1, val); + pxa_ssp_enable(ssp); break; case SNDRV_PCM_TRIGGER_STOP: - val = ssp_read_reg(ssp, SSCR1); + val = pxa_ssp_read_reg(ssp, SSCR1); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) val &= ~SSCR1_TSRE; else val &= ~SSCR1_RSRE; - ssp_write_reg(ssp, SSCR1, val); + pxa_ssp_write_reg(ssp, SSCR1, val); break; case SNDRV_PCM_TRIGGER_SUSPEND: - ssp_disable(ssp); + pxa_ssp_disable(ssp); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - val = ssp_read_reg(ssp, SSCR1); + val = pxa_ssp_read_reg(ssp, SSCR1); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) val &= ~SSCR1_TSRE; else val &= ~SSCR1_RSRE; - ssp_write_reg(ssp, SSCR1, val); + pxa_ssp_write_reg(ssp, SSCR1, val); break; default: @@ -739,7 +739,7 @@ static int pxa_ssp_probe(struct platform_device *pdev, if (!priv) return -ENOMEM; - priv->ssp = ssp_request(dai->id + 1, "SoC audio"); + priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio"); if (priv->ssp == NULL) { ret = -ENODEV; goto err_priv; @@ -759,7 +759,7 @@ static void pxa_ssp_remove(struct platform_device *pdev, struct snd_soc_dai *dai) { struct ssp_priv *priv = dai->private_data; - ssp_free(priv->ssp); + pxa_ssp_free(priv->ssp); } #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ -- cgit v1.2.3-59-g8ed1b From d19f61f098ae9315b76a97962007f687683916d4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 17 Feb 2010 14:35:25 +0000 Subject: x86/PCI: Convert pci_config_lock to raw_spinlock pci_config_lock must be a real spinlock in preempt-rt. Convert it to raw_spinlock. No change for !RT kernels. Signed-off-by: Thomas Gleixner Signed-off-by: Jesse Barnes --- arch/x86/include/asm/pci_x86.h | 2 +- arch/x86/pci/common.c | 2 +- arch/x86/pci/direct.c | 16 ++++++++-------- arch/x86/pci/mmconfig_32.c | 8 ++++---- arch/x86/pci/numaq_32.c | 8 ++++---- arch/x86/pci/pcbios.c | 8 ++++---- 6 files changed, 22 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 1a0422348d6d..8d8797eae5d7 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -83,7 +83,7 @@ struct irq_routing_table { extern unsigned int pcibios_irq_mask; -extern spinlock_t pci_config_lock; +extern raw_spinlock_t pci_config_lock; extern int (*pcibios_enable_irq)(struct pci_dev *dev); extern void (*pcibios_disable_irq)(struct pci_dev *dev); diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index cf2e93869c48..215a27ae050d 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -76,7 +76,7 @@ struct pci_ops pci_root_ops = { * This interrupt-safe spinlock protects all accesses to PCI * configuration space. */ -DEFINE_SPINLOCK(pci_config_lock); +DEFINE_RAW_SPINLOCK(pci_config_lock); static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) { diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c index 347d882b3bb3..bd33620b0071 100644 --- a/arch/x86/pci/direct.c +++ b/arch/x86/pci/direct.c @@ -27,7 +27,7 @@ static int pci_conf1_read(unsigned int seg, unsigned int bus, return -EINVAL; } - spin_lock_irqsave(&pci_config_lock, flags); + raw_spin_lock_irqsave(&pci_config_lock, flags); outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8); @@ -43,7 +43,7 @@ static int pci_conf1_read(unsigned int seg, unsigned int bus, break; } - spin_unlock_irqrestore(&pci_config_lock, flags); + raw_spin_unlock_irqrestore(&pci_config_lock, flags); return 0; } @@ -56,7 +56,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus, if ((bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; - spin_lock_irqsave(&pci_config_lock, flags); + raw_spin_lock_irqsave(&pci_config_lock, flags); outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8); @@ -72,7 +72,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus, break; } - spin_unlock_irqrestore(&pci_config_lock, flags); + raw_spin_unlock_irqrestore(&pci_config_lock, flags); return 0; } @@ -108,7 +108,7 @@ static int pci_conf2_read(unsigned int seg, unsigned int bus, if (dev & 0x10) return PCIBIOS_DEVICE_NOT_FOUND; - spin_lock_irqsave(&pci_config_lock, flags); + raw_spin_lock_irqsave(&pci_config_lock, flags); outb((u8)(0xF0 | (fn << 1)), 0xCF8); outb((u8)bus, 0xCFA); @@ -127,7 +127,7 @@ static int pci_conf2_read(unsigned int seg, unsigned int bus, outb(0, 0xCF8); - spin_unlock_irqrestore(&pci_config_lock, flags); + raw_spin_unlock_irqrestore(&pci_config_lock, flags); return 0; } @@ -147,7 +147,7 @@ static int pci_conf2_write(unsigned int seg, unsigned int bus, if (dev & 0x10) return PCIBIOS_DEVICE_NOT_FOUND; - spin_lock_irqsave(&pci_config_lock, flags); + raw_spin_lock_irqsave(&pci_config_lock, flags); outb((u8)(0xF0 | (fn << 1)), 0xCF8); outb((u8)bus, 0xCFA); @@ -166,7 +166,7 @@ static int pci_conf2_write(unsigned int seg, unsigned int bus, outb(0, 0xCF8); - spin_unlock_irqrestore(&pci_config_lock, flags); + raw_spin_unlock_irqrestore(&pci_config_lock, flags); return 0; } diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index 90d5fd476ed4..a3d9c54792ae 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c @@ -64,7 +64,7 @@ err: *value = -1; if (!base) goto err; - spin_lock_irqsave(&pci_config_lock, flags); + raw_spin_lock_irqsave(&pci_config_lock, flags); pci_exp_set_dev_base(base, bus, devfn); @@ -79,7 +79,7 @@ err: *value = -1; *value = mmio_config_readl(mmcfg_virt_addr + reg); break; } - spin_unlock_irqrestore(&pci_config_lock, flags); + raw_spin_unlock_irqrestore(&pci_config_lock, flags); return 0; } @@ -97,7 +97,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, if (!base) return -EINVAL; - spin_lock_irqsave(&pci_config_lock, flags); + raw_spin_lock_irqsave(&pci_config_lock, flags); pci_exp_set_dev_base(base, bus, devfn); @@ -112,7 +112,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, mmio_config_writel(mmcfg_virt_addr + reg, value); break; } - spin_unlock_irqrestore(&pci_config_lock, flags); + raw_spin_unlock_irqrestore(&pci_config_lock, flags); return 0; } diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c index 8223738ad806..5c9e2458df4e 100644 --- a/arch/x86/pci/numaq_32.c +++ b/arch/x86/pci/numaq_32.c @@ -37,7 +37,7 @@ static int pci_conf1_mq_read(unsigned int seg, unsigned int bus, if (!value || (bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) return -EINVAL; - spin_lock_irqsave(&pci_config_lock, flags); + raw_spin_lock_irqsave(&pci_config_lock, flags); write_cf8(bus, devfn, reg); @@ -62,7 +62,7 @@ static int pci_conf1_mq_read(unsigned int seg, unsigned int bus, break; } - spin_unlock_irqrestore(&pci_config_lock, flags); + raw_spin_unlock_irqrestore(&pci_config_lock, flags); return 0; } @@ -76,7 +76,7 @@ static int pci_conf1_mq_write(unsigned int seg, unsigned int bus, if ((bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) return -EINVAL; - spin_lock_irqsave(&pci_config_lock, flags); + raw_spin_lock_irqsave(&pci_config_lock, flags); write_cf8(bus, devfn, reg); @@ -101,7 +101,7 @@ static int pci_conf1_mq_write(unsigned int seg, unsigned int bus, break; } - spin_unlock_irqrestore(&pci_config_lock, flags); + raw_spin_unlock_irqrestore(&pci_config_lock, flags); return 0; } diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index 59a225c17b84..2492d165096a 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c @@ -162,7 +162,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; - spin_lock_irqsave(&pci_config_lock, flags); + raw_spin_lock_irqsave(&pci_config_lock, flags); switch (len) { case 1: @@ -213,7 +213,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, break; } - spin_unlock_irqrestore(&pci_config_lock, flags); + raw_spin_unlock_irqrestore(&pci_config_lock, flags); return (int)((result & 0xff00) >> 8); } @@ -228,7 +228,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus, if ((bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; - spin_lock_irqsave(&pci_config_lock, flags); + raw_spin_lock_irqsave(&pci_config_lock, flags); switch (len) { case 1: @@ -269,7 +269,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus, break; } - spin_unlock_irqrestore(&pci_config_lock, flags); + raw_spin_unlock_irqrestore(&pci_config_lock, flags); return (int)((result & 0xff00) >> 8); } -- cgit v1.2.3-59-g8ed1b From 33852cb03ee4cdb05dc6e3a21ec19a4ee63511a4 Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Thu, 25 Mar 2010 16:11:37 -0700 Subject: x86/PCI: irq and pci_ids patch for additional Intel Cougar Point DeviceIDs This patch adds additional LPC Controller DeviceIDs for the Intel Cougar Point PCH. The DeviceIDs are defined and referenced as a range of values, the same way Ibex Peak was implemented. Signed-off-by: Seth Heasley Signed-off-by: Jesse Barnes --- arch/x86/pci/irq.c | 9 +++++++-- include/linux/pci_ids.h | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 5d362b5ba06f..9810a0f76c91 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -589,8 +589,6 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route case PCI_DEVICE_ID_INTEL_ICH10_1: case PCI_DEVICE_ID_INTEL_ICH10_2: case PCI_DEVICE_ID_INTEL_ICH10_3: - case PCI_DEVICE_ID_INTEL_CPT_LPC1: - case PCI_DEVICE_ID_INTEL_CPT_LPC2: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; @@ -605,6 +603,13 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route return 1; } + if ((device >= PCI_DEVICE_ID_INTEL_CPT_LPC_MIN) && + (device <= PCI_DEVICE_ID_INTEL_CPT_LPC_MAX)) { + r->name = "PIIX/ICH"; + r->get = pirq_piix_get; + r->set = pirq_piix_set; + return 1; + } return 0; } diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 9f688d243b86..ae66851870be 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2419,8 +2419,8 @@ #define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 #define PCI_DEVICE_ID_INTEL_IOAT 0x1a38 #define PCI_DEVICE_ID_INTEL_CPT_SMBUS 0x1c22 -#define PCI_DEVICE_ID_INTEL_CPT_LPC1 0x1c42 -#define PCI_DEVICE_ID_INTEL_CPT_LPC2 0x1c43 +#define PCI_DEVICE_ID_INTEL_CPT_LPC_MIN 0x1c41 +#define PCI_DEVICE_ID_INTEL_CPT_LPC_MAX 0x1c5f #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 #define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 #define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 -- cgit v1.2.3-59-g8ed1b From c394f17799523fe4bc92d173b3d9ac2d240c76a2 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 11 May 2010 09:55:07 +0300 Subject: ARM: S3C2440: Add HP iPAQ RX1950 machine support Signed-off-by: Vasily Khoruzhick Signed-off-by: Denis Grigoriev Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2440/Kconfig | 13 + arch/arm/mach-s3c2440/Makefile | 1 + arch/arm/mach-s3c2440/mach-rx1950.c | 582 ++++++++++++++++++++++++++++++++++++ 3 files changed, 596 insertions(+) create mode 100644 arch/arm/mach-s3c2440/mach-rx1950.c (limited to 'arch') diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index 7f465265cf04..a6c5df6d41ef 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig @@ -187,4 +187,17 @@ config MACH_MINI2440 Say Y here to select support for the MINI2440. Is a 10cm x 10cm board available via various sources. It can come with a 3.5" or 7" touch LCD. +config MACH_RX1950 + bool "HP iPAQ rx1950" + select CPU_S3C2442 + select S3C24XX_DCLK + select PM_H1940 if PM + select I2C + select S3C2410_PWM + select S3C_DEV_NAND + select S3C2410_IOTIMING if S3C2440_CPUFREQ + select S3C2440_XTAL_16934400 + help + Say Y here if you're using HP iPAQ rx1950 + endmenu diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile index c85ba32d8956..d5440fa34b04 100644 --- a/arch/arm/mach-s3c2440/Makefile +++ b/arch/arm/mach-s3c2440/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o +obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o # extra machine support diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c new file mode 100644 index 000000000000..8603b577a24b --- /dev/null +++ b/arch/arm/mach-s3c2440/mach-rx1950.c @@ -0,0 +1,582 @@ +/* linux/arch/arm/mach-s3c2440/mach-rx1950.c + * + * Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev, + * Copyright (c) 2007-2010 Vasily Khoruzhick + * + * based on smdk2440 written by Ben Dooks + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LCD_PWM_PERIOD 192960 +#define LCD_PWM_DUTY 127353 + +static struct map_desc rx1950_iodesc[] __initdata = { +}; + +static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = { + [0] = { + .name = "fclk", + .divisor = 0x0a, + .min_baud = 0, + .max_baud = 0, + }, +}; + +static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x03, + .ufcon = 0x51, + .clocks = rx1950_serial_clocks, + .clocks_size = ARRAY_SIZE(rx1950_serial_clocks), + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x03, + .ufcon = 0x51, + .clocks = rx1950_serial_clocks, + .clocks_size = ARRAY_SIZE(rx1950_serial_clocks), + }, + /* IR port */ + [2] = { + .hwport = 2, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x43, + .ufcon = 0xf1, + .clocks = rx1950_serial_clocks, + .clocks_size = ARRAY_SIZE(rx1950_serial_clocks), + }, +}; + +static struct s3c2410fb_display rx1950_display = { + .type = S3C2410_LCDCON1_TFT, + .width = 240, + .height = 320, + .xres = 240, + .yres = 320, + .bpp = 16, + + .pixclock = 260000, + .left_margin = 10, + .right_margin = 20, + .hsync_len = 10, + .upper_margin = 2, + .lower_margin = 2, + .vsync_len = 2, + + .lcdcon5 = S3C2410_LCDCON5_FRM565 | + S3C2410_LCDCON5_INVVCLK | + S3C2410_LCDCON5_INVVLINE | + S3C2410_LCDCON5_INVVFRAME | + S3C2410_LCDCON5_HWSWP | + (0x02 << 13) | + (0x02 << 15), + +}; + +static struct s3c2410fb_mach_info rx1950_lcd_cfg = { + .displays = &rx1950_display, + .num_displays = 1, + .default_display = 0, + + .lpcsel = 0x02, + .gpccon = 0xaa9556a9, + .gpccon_mask = 0xffc003fc, + .gpcup = 0x0000ffff, + .gpcup_mask = 0xffffffff, + + .gpdcon = 0xaa90aaa1, + .gpdcon_mask = 0xffc0fff0, + .gpdup = 0x0000fcfd, + .gpdup_mask = 0xffffffff, + +}; + +static struct pwm_device *lcd_pwm; + +void rx1950_lcd_power(int enable) +{ + int i; + static int enabled; + if (enabled == enable) + return; + if (!enable) { + + /* GPC11-GPC15->OUTPUT */ + for (i = 11; i < 16; i++) + gpio_direction_output(S3C2410_GPC(i), 1); + + /* Wait a bit here... */ + mdelay(100); + + /* GPD2-GPD7->OUTPUT */ + /* GPD11-GPD15->OUTPUT */ + /* GPD2-GPD7->1, GPD11-GPD15->1 */ + for (i = 2; i < 8; i++) + gpio_direction_output(S3C2410_GPD(i), 1); + for (i = 11; i < 16; i++) + gpio_direction_output(S3C2410_GPD(i), 1); + + /* Wait a bit here...*/ + mdelay(100); + + /* GPB0->OUTPUT, GPB0->0 */ + gpio_direction_output(S3C2410_GPB(0), 0); + + /* GPC1-GPC4->OUTPUT, GPC1-4->0 */ + for (i = 1; i < 5; i++) + gpio_direction_output(S3C2410_GPC(i), 0); + + /* GPC15-GPC11->0 */ + for (i = 11; i < 16; i++) + gpio_direction_output(S3C2410_GPC(i), 0); + + /* GPD15-GPD11->0, GPD2->GPD7->0 */ + for (i = 11; i < 16; i++) + gpio_direction_output(S3C2410_GPD(i), 0); + + for (i = 2; i < 8; i++) + gpio_direction_output(S3C2410_GPD(i), 0); + + /* GPC6->0, GPC7->0, GPC5->0 */ + gpio_direction_output(S3C2410_GPC(6), 0); + gpio_direction_output(S3C2410_GPC(7), 0); + gpio_direction_output(S3C2410_GPC(5), 0); + + /* GPB1->OUTPUT, GPB1->0 */ + gpio_direction_output(S3C2410_GPB(1), 0); + pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD); + pwm_disable(lcd_pwm); + + /* GPC0->0, GPC10->0 */ + gpio_direction_output(S3C2410_GPC(0), 0); + gpio_direction_output(S3C2410_GPC(10), 0); + } else { + pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD); + pwm_enable(lcd_pwm); + + gpio_direction_output(S3C2410_GPC(0), 1); + gpio_direction_output(S3C2410_GPC(5), 1); + + s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1); + gpio_direction_output(S3C2410_GPC(7), 1); + + for (i = 1; i < 5; i++) + s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2)); + + for (i = 11; i < 16; i++) + s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2)); + + for (i = 2; i < 8; i++) + s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2)); + + for (i = 11; i < 16; i++) + s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2)); + + gpio_direction_output(S3C2410_GPC(10), 1); + gpio_direction_output(S3C2410_GPC(6), 1); + } + enabled = enable; +} + +static void rx1950_bl_power(int enable) +{ + static int enabled; + if (enabled == enable) + return; + if (!enable) { + gpio_direction_output(S3C2410_GPB(0), 0); + } else { + /* LED driver need a "push" to power on */ + gpio_direction_output(S3C2410_GPB(0), 1); + /* Warm up backlight for one period of PWM. + * Without this trick its almost impossible to + * enable backlight with low brightness value + */ + ndelay(48000); + s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); + } + enabled = enable; +} + +static int rx1950_backlight_init(struct device *dev) +{ + WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight")); + lcd_pwm = pwm_request(1, "RX1950 LCD"); + if (IS_ERR(lcd_pwm)) { + dev_err(dev, "Unable to request PWM for LCD power!\n"); + return PTR_ERR(lcd_pwm); + } + + rx1950_lcd_power(1); + rx1950_bl_power(1); + + return 0; +} + +static void rx1950_backlight_exit(struct device *dev) +{ + rx1950_bl_power(0); + rx1950_lcd_power(0); + + pwm_free(lcd_pwm); + gpio_free(S3C2410_GPB(0)); +} + + +static int rx1950_backlight_notify(struct device *dev, int brightness) +{ + if (!brightness) { + rx1950_bl_power(0); + rx1950_lcd_power(0); + } else { + rx1950_lcd_power(1); + rx1950_bl_power(1); + } + return brightness; +} + +static struct platform_pwm_backlight_data rx1950_backlight_data = { + .pwm_id = 0, + .max_brightness = 24, + .dft_brightness = 4, + .pwm_period_ns = 48000, + .init = rx1950_backlight_init, + .notify = rx1950_backlight_notify, + .exit = rx1950_backlight_exit, +}; + +static struct platform_device rx1950_backlight = { + .name = "pwm-backlight", + .dev = { + .parent = &s3c_device_timer[0].dev, + .platform_data = &rx1950_backlight_data, + }, +}; + +static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd) +{ + switch (power_mode) { + case MMC_POWER_OFF: + gpio_direction_output(S3C2410_GPJ(1), 0); + break; + case MMC_POWER_UP: + case MMC_POWER_ON: + gpio_direction_output(S3C2410_GPJ(1), 1); + break; + default: + break; + } +} + +static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = { + .gpio_detect = S3C2410_GPF(5), + .gpio_wprotect = S3C2410_GPH(8), + .set_power = rx1950_set_mmc_power, + .ocr_avail = MMC_VDD_32_33, +}; + +static struct mtd_partition rx1950_nand_part[] = { + [0] = { + .name = "Boot0", + .offset = 0, + .size = 0x4000, + .mask_flags = MTD_WRITEABLE, + }, + [1] = { + .name = "Boot1", + .offset = MTDPART_OFS_APPEND, + .size = 0x40000, + .mask_flags = MTD_WRITEABLE, + }, + [2] = { + .name = "Kernel", + .offset = MTDPART_OFS_APPEND, + .size = 0x300000, + .mask_flags = 0, + }, + [3] = { + .name = "Filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + }, +}; + +static struct s3c2410_nand_set rx1950_nand_sets[] = { + [0] = { + .name = "Internal", + .nr_chips = 1, + .nr_partitions = ARRAY_SIZE(rx1950_nand_part), + .partitions = rx1950_nand_part, + }, +}; + +static struct s3c2410_platform_nand rx1950_nand_info = { + .tacls = 25, + .twrph0 = 50, + .twrph1 = 15, + .nr_sets = ARRAY_SIZE(rx1950_nand_sets), + .sets = rx1950_nand_sets, +}; + +static void rx1950_udc_pullup(enum s3c2410_udc_cmd_e cmd) +{ + switch (cmd) { + case S3C2410_UDC_P_ENABLE: + gpio_direction_output(S3C2410_GPJ(5), 1); + break; + case S3C2410_UDC_P_DISABLE: + gpio_direction_output(S3C2410_GPJ(5), 0); + break; + case S3C2410_UDC_P_RESET: + break; + default: + break; + } +} + +static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = { + .udc_command = rx1950_udc_pullup, + .vbus_pin = S3C2410_GPG(5), + .vbus_pin_inverted = 1, +}; + +static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = { + .delay = 10000, + .presc = 49, + .oversampling_shift = 3, +}; + +static struct gpio_keys_button rx1950_gpio_keys_table[] = { + { + .code = KEY_POWER, + .gpio = S3C2410_GPF(0), + .active_low = 1, + .desc = "Power button", + .wakeup = 1, + }, + { + .code = KEY_F5, + .gpio = S3C2410_GPF(7), + .active_low = 1, + .desc = "Record button", + }, + { + .code = KEY_F1, + .gpio = S3C2410_GPG(0), + .active_low = 1, + .desc = "Calendar button", + }, + { + .code = KEY_F2, + .gpio = S3C2410_GPG(2), + .active_low = 1, + .desc = "Contacts button", + }, + { + .code = KEY_F3, + .gpio = S3C2410_GPG(3), + .active_low = 1, + .desc = "Mail button", + }, + { + .code = KEY_F4, + .gpio = S3C2410_GPG(7), + .active_low = 1, + .desc = "WLAN button", + }, + { + .code = KEY_LEFT, + .gpio = S3C2410_GPG(10), + .active_low = 1, + .desc = "Left button", + }, + { + .code = KEY_RIGHT, + .gpio = S3C2410_GPG(11), + .active_low = 1, + .desc = "Right button", + }, + { + .code = KEY_UP, + .gpio = S3C2410_GPG(4), + .active_low = 1, + .desc = "Up button", + }, + { + .code = KEY_DOWN, + .gpio = S3C2410_GPG(6), + .active_low = 1, + .desc = "Down button", + }, + { + .code = KEY_ENTER, + .gpio = S3C2410_GPG(9), + .active_low = 1, + .desc = "Ok button" + }, +}; + +static struct gpio_keys_platform_data rx1950_gpio_keys_data = { + .buttons = rx1950_gpio_keys_table, + .nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table), +}; + +static struct platform_device rx1950_device_gpiokeys = { + .name = "gpio-keys", + .dev.platform_data = &rx1950_gpio_keys_data, +}; + +static struct s3c2410_platform_i2c rx1950_i2c_data = { + .flags = 0, + .slave_addr = 0x42, + .frequency = 400 * 1000, + .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON, +}; + +static struct platform_device *rx1950_devices[] __initdata = { + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c0, + &s3c_device_iis, + &s3c_device_usbgadget, + &s3c_device_rtc, + &s3c_device_nand, + &s3c_device_sdi, + &s3c_device_adc, + &s3c_device_ts, + &s3c_device_timer[0], + &s3c_device_timer[1], + &rx1950_backlight, + &rx1950_device_gpiokeys, +}; + +static struct clk *rx1950_clocks[] __initdata = { + &s3c24xx_clkout0, + &s3c24xx_clkout1, +}; + +static void __init rx1950_map_io(void) +{ + s3c24xx_clkout0.parent = &clk_h; + s3c24xx_clkout1.parent = &clk_f; + + s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks)); + + s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc)); + s3c24xx_init_clocks(16934000); + s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs)); + + /* setup PM */ + +#ifdef CONFIG_PM_H1940 + memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8); +#endif + + s3c_pm_init(); +} + +static void __init rx1950_init_machine(void) +{ + int i; + + s3c24xx_fb_set_platdata(&rx1950_lcd_cfg); + s3c24xx_udc_set_platdata(&rx1950_udc_cfg); + s3c24xx_ts_set_platdata(&rx1950_ts_cfg); + s3c24xx_mci_set_platdata(&rx1950_mmc_cfg); + s3c_i2c0_set_platdata(&rx1950_i2c_data); + s3c_nand_set_platdata(&rx1950_nand_info); + + /* Turn off suspend on both USB ports, and switch the + * selectable USB port to USB device mode. */ + s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | + S3C2410_MISCCR_USBSUSPND0 | + S3C2410_MISCCR_USBSUSPND1, 0x0); + + WARN_ON(gpio_request(S3C2410_GPJ(5), "UDC pullup")); + gpio_direction_output(S3C2410_GPJ(5), 0); + + /* mmc power is disabled by default */ + WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power")); + gpio_direction_output(S3C2410_GPJ(1), 0); + + for (i = 0; i < 8; i++) + WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power")); + + for (i = 10; i < 16; i++) + WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power")); + + for (i = 2; i < 8; i++) + WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power")); + + for (i = 11; i < 16; i++) + WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power")); + + WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power")); + + platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices)); +} + +MACHINE_START(RX1950, "HP iPAQ RX1950") + /* Maintainers: Vasily Khoruzhick */ + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32) S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = rx1950_map_io, + .init_irq = s3c24xx_init_irq, + .init_machine = rx1950_init_machine, + .timer = &s3c24xx_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From c4761b69f4c3bd2f6e62d9cba6d78b5fd4b24203 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 11 May 2010 09:55:09 +0300 Subject: ARM: S3C24XX: Locate kernel at 0x30108000 if PM_H1940 is enabled If PM_H1940 is enabled, kernel _must_ be located upper then 0x30008000, because this area (0x30000000-0x30100000) can be used by bootloader. If kernel is located at 0x30008000, bootloader will corrupt kernel's code during resume. Signed-off-by: Vasily Khoruzhick Signed-off-by: Ben Dooks --- arch/arm/Makefile | 2 ++ arch/arm/mach-s3c2410/Makefile.boot | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ed820e737a8a..eddcbba87c67 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -110,6 +110,8 @@ CHECKFLAGS += -D__arm__ head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o textofs-y := 0x00008000 textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 +# We don't want the htc bootloader to corrupt kernel during resume +textofs-$(CONFIG_PM_H1940) := 0x00108000 # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory ifeq ($(CONFIG_ARCH_SA1100),y) textofs-$(CONFIG_SA1111) := 0x00208000 diff --git a/arch/arm/mach-s3c2410/Makefile.boot b/arch/arm/mach-s3c2410/Makefile.boot index 7dab2a0325b5..58c1dd7f8e1d 100644 --- a/arch/arm/mach-s3c2410/Makefile.boot +++ b/arch/arm/mach-s3c2410/Makefile.boot @@ -1,3 +1,7 @@ - zreladdr-y := 0x30008000 -params_phys-y := 0x30000100 - +ifeq ($(CONFIG_PM_H1940),y) + zreladdr-y := 0x30108000 + params_phys-y := 0x30100100 +else + zreladdr-y := 0x30008000 + params_phys-y := 0x30000100 +endif -- cgit v1.2.3-59-g8ed1b From 0741b7d2699d1e7b4ceab27522c9e5518b2dbd2c Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 11 May 2010 09:55:10 +0300 Subject: ARM: RX1950: Add suspend/resume support for RX1950 Signed-off-by: Vasily Khoruzhick Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/pm.c | 4 ++-- arch/arm/mm/mmu.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c index 966119c8efee..6a61486ca755 100644 --- a/arch/arm/mach-s3c2410/pm.c +++ b/arch/arm/mach-s3c2410/pm.c @@ -60,10 +60,10 @@ static void s3c2410_pm_prepare(void) __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM)); } - /* the RX3715 uses similar code and the same H1940 and the + /* RX3715 and RX1950 use similar to H1940 code and the * same offsets for resume and checksum pointers */ - if (machine_is_rx3715()) { + if (machine_is_rx3715() || machine_is_rx1950()) { void *base = phys_to_virt(H1940_SUSPEND_CHECK); unsigned long ptr; unsigned long calc = 0; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 241c24a1c18f..45a1bc275f0a 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -869,9 +869,10 @@ void __init reserve_node_zero(pg_data_t *pgdat) if (machine_is_p720t()) res_size = 0x00014000; - /* H1940 and RX3715 need to reserve this for suspend */ + /* H1940, RX3715 and RX1950 need to reserve this for suspend */ - if (machine_is_h1940() || machine_is_rx3715()) { + if (machine_is_h1940() || machine_is_rx3715() + || machine_is_rx1950()) { reserve_bootmem_node(pgdat, 0x30003000, 0x1000, BOOTMEM_DEFAULT); reserve_bootmem_node(pgdat, 0x30081000, 0x1000, -- cgit v1.2.3-59-g8ed1b From 192ff91fc84e067a3babfddb96114a51c939548e Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 11 May 2010 09:55:11 +0300 Subject: ARM: RX1950: configure GPG13-15 as input before suspend According to datasheet GPG13-15 must be configured as input in NAND boot mode, otherwise device will not be able to wake up Signed-off-by: Vasily Khoruzhick Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/pm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c index 6a61486ca755..725636fc4dc3 100644 --- a/arch/arm/mach-s3c2410/pm.c +++ b/arch/arm/mach-s3c2410/pm.c @@ -79,6 +79,17 @@ static void s3c2410_pm_prepare(void) if ( machine_is_aml_m5900() ) s3c2410_gpio_setpin(S3C2410_GPF(2), 1); + if (machine_is_rx1950()) { + /* According to S3C2442 user's manual, page 7-17, + * when the system is operating in NAND boot mode, + * the hardware pin configuration - EINT[23:21] – + * must be set as input for starting up after + * wakeup from sleep mode + */ + s3c_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPIO_INPUT); + } } static int s3c2410_pm_resume(struct sys_device *dev) -- cgit v1.2.3-59-g8ed1b From a3c8acd04376d604370dcb6cd2143c9c14078a50 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 11 May 2010 17:47:07 -0700 Subject: x86: Add new static_cpu_has() function using alternatives For CPU-feature-specific code that touches performance-critical paths, introduce a static patching version of [boot_]cpu_has(). This is run at alternatives time and is therefore not appropriate for most initialization code, but on the other hand initialization code is generally not performance critical. On gcc 4.5+ this uses the new "asm goto" feature. Signed-off-by: H. Peter Anvin Cc: Avi Kivity Cc: Suresh Siddha LKML-Reference: <1273135546-29690-2-git-send-email-avi@redhat.com> --- arch/x86/include/asm/cpufeature.h | 57 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 0cd82d068613..9b11a5cc6662 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -175,6 +175,7 @@ #if defined(__KERNEL__) && !defined(__ASSEMBLY__) +#include #include extern const char * const x86_cap_flags[NCAPINTS*32]; @@ -283,6 +284,62 @@ extern const char * const x86_power_flags[32]; #endif /* CONFIG_X86_64 */ +/* + * Static testing of CPU features. Used the same as boot_cpu_has(). + * These are only valid after alternatives have run, but will statically + * patch the target code for additional performance. + * + */ +static __always_inline __pure bool __static_cpu_has(u8 bit) +{ +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + asm goto("1: jmp %l[t_no]\n" + "2:\n" + ".section .altinstructions,\"a\"\n" + _ASM_ALIGN "\n" + _ASM_PTR "1b\n" + _ASM_PTR "0\n" /* no replacement */ + " .byte %P0\n" /* feature bit */ + " .byte 2b - 1b\n" /* source len */ + " .byte 0\n" /* replacement len */ + " .byte 0xff + 0 - (2b-1b)\n" /* padding */ + ".previous\n" + : : "i" (bit) : : t_no); + return true; + t_no: + return false; +#else + u8 flag; + /* Open-coded due to __stringify() in ALTERNATIVE() */ + asm volatile("1: movb $0,%0\n" + "2:\n" + ".section .altinstructions,\"a\"\n" + _ASM_ALIGN "\n" + _ASM_PTR "1b\n" + _ASM_PTR "3f\n" + " .byte %P1\n" /* feature bit */ + " .byte 2b - 1b\n" /* source len */ + " .byte 4f - 3f\n" /* replacement len */ + " .byte 0xff + (4f-3f) - (2b-1b)\n" /* padding */ + ".previous\n" + ".section .altinstr_replacement,\"ax\"\n" + "3: movb $1,%0\n" + "4:\n" + ".previous\n" + : "=qm" (flag) : "i" (bit)); + return flag; +#endif +} + +#define static_cpu_has(bit) \ +( \ + __builtin_constant_p(boot_cpu_has(bit)) ? \ + boot_cpu_has(bit) : \ + (__builtin_constant_p(bit) && !((bit) & ~0xff)) ? \ + __static_cpu_has(bit) : \ + boot_cpu_has(bit) \ +) + #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */ #endif /* _ASM_X86_CPUFEATURE_H */ -- cgit v1.2.3-59-g8ed1b From c9775b4cc522e5f1b40b1366a993f0f05f600f39 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 11 May 2010 17:49:54 -0700 Subject: x86, fpu: Use static_cpu_has() to implement use_xsave() use_xsave() is now just a special case of static_cpu_has(), so use static_cpu_has(). Signed-off-by: H. Peter Anvin Cc: Avi Kivity Cc: Suresh Siddha LKML-Reference: <1273135546-29690-2-git-send-email-avi@redhat.com> --- arch/x86/include/asm/i387.h | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index 8002e9ce25fc..c991b3a7b904 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -57,16 +58,9 @@ extern int restore_i387_xstate_ia32(void __user *buf); #define X87_FSW_ES (1 << 7) /* Exception Summary */ -static inline bool use_xsave(void) +static __always_inline __pure bool use_xsave(void) { - u8 has_xsave; - - alternative_io("mov $0, %0", - "mov $1, %0", - X86_FEATURE_XSAVE, - "=qm" (has_xsave)); - - return has_xsave; + return static_cpu_has(X86_FEATURE_XSAVE); } #ifdef CONFIG_X86_64 -- cgit v1.2.3-59-g8ed1b From afdd225d0feea07f7fe6501771dbfddfda07b632 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 7 May 2010 09:24:05 +0900 Subject: ARM: SAMSUNG: Remove old email address for ben-linux@fluff.org The address ben@fluff.org is old, ben-linux@fluff.org has been in use for a long time, and we should fixup all the occasions of the older address to avoid confusion. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-h1940.c | 2 +- arch/arm/mach-s3c2412/mach-jive.c | 2 +- arch/arm/mach-s3c2412/mach-smdk2413.c | 6 +++--- arch/arm/mach-s3c2440/mach-rx3715.c | 2 +- arch/arm/mach-s3c2440/mach-smdk2440.c | 2 +- arch/arm/mach-s3c2443/mach-smdk2443.c | 2 +- arch/arm/mach-s3c64xx/mach-smdk6400.c | 2 +- arch/arm/mach-s3c64xx/mach-smdk6410.c | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index bd4ced59c9ad..b212561d2c57 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -338,7 +338,7 @@ static void __init h1940_init(void) } MACHINE_START(H1940, "IPAQ-H1940") - /* Maintainer: Ben Dooks */ + /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c index 14f4798291aa..20647f09aed6 100644 --- a/arch/arm/mach-s3c2412/mach-jive.c +++ b/arch/arm/mach-s3c2412/mach-jive.c @@ -674,7 +674,7 @@ static void __init jive_machine_init(void) } MACHINE_START(JIVE, "JIVE") - /* Maintainer: Ben Dooks */ + /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c index 0392065af1af..3d41aa74c362 100644 --- a/arch/arm/mach-s3c2412/mach-smdk2413.c +++ b/arch/arm/mach-s3c2412/mach-smdk2413.c @@ -150,7 +150,7 @@ static void __init smdk2413_machine_init(void) } MACHINE_START(S3C2413, "S3C2413") - /* Maintainer: Ben Dooks */ + /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, @@ -163,7 +163,7 @@ MACHINE_START(S3C2413, "S3C2413") MACHINE_END MACHINE_START(SMDK2412, "SMDK2412") - /* Maintainer: Ben Dooks */ + /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, @@ -176,7 +176,7 @@ MACHINE_START(SMDK2412, "SMDK2412") MACHINE_END MACHINE_START(SMDK2413, "SMDK2413") - /* Maintainer: Ben Dooks */ + /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index 1e836e506f8b..d2946de3f365 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c @@ -209,7 +209,7 @@ static void __init rx3715_init_machine(void) } MACHINE_START(RX3715, "IPAQ-RX3715") - /* Maintainer: Ben Dooks */ + /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c index 3ac3d636d615..df83276d85ae 100644 --- a/arch/arm/mach-s3c2440/mach-smdk2440.c +++ b/arch/arm/mach-s3c2440/mach-smdk2440.c @@ -174,7 +174,7 @@ static void __init smdk2440_machine_init(void) } MACHINE_START(S3C2440, "SMDK2440") - /* Maintainer: Ben Dooks */ + /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c index e2e362bda9b7..4c863d3a52f4 100644 --- a/arch/arm/mach-s3c2443/mach-smdk2443.c +++ b/arch/arm/mach-s3c2443/mach-smdk2443.c @@ -131,7 +131,7 @@ static void __init smdk2443_machine_init(void) } MACHINE_START(SMDK2443, "SMDK2443") - /* Maintainer: Ben Dooks */ + /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c index f7b18983950c..59916676d8d2 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6400.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c @@ -84,7 +84,7 @@ static void __init smdk6400_machine_init(void) } MACHINE_START(SMDK6400, "SMDK6400") - /* Maintainer: Ben Dooks */ + /* Maintainer: Ben Dooks */ .phys_io = S3C_PA_UART & 0xfff00000, .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc, .boot_params = S3C64XX_PA_SDRAM + 0x100, diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index 2d5afd221d77..9d51455feb31 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -656,7 +656,7 @@ static void __init smdk6410_machine_init(void) } MACHINE_START(SMDK6410, "SMDK6410") - /* Maintainer: Ben Dooks */ + /* Maintainer: Ben Dooks */ .phys_io = S3C_PA_UART & 0xfff00000, .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc, .boot_params = S3C64XX_PA_SDRAM + 0x100, -- cgit v1.2.3-59-g8ed1b From 0ad73cefa2ec509126af466718e0c3cb1ad8ae9b Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 11 May 2010 09:56:37 +0900 Subject: ARM: SAMSUNG: Remove static of S5P SoCs sysclass This patch removes static of s5p6440_sysclass, s5p6442_sysclass, and s5pv210_sysclass for defintion as extern. Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/cpu.c | 2 +- arch/arm/mach-s5p6442/cpu.c | 2 +- arch/arm/mach-s5pv210/cpu.c | 2 +- arch/arm/plat-samsung/include/plat/cpu.h | 3 +++ 4 files changed, 6 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c index 1794131aeacb..ca3b3206e6f8 100644 --- a/arch/arm/mach-s5p6440/cpu.c +++ b/arch/arm/mach-s5p6440/cpu.c @@ -88,7 +88,7 @@ void __init s5p6440_init_irq(void) s5p_init_irq(vic, ARRAY_SIZE(vic)); } -static struct sysdev_class s5p6440_sysclass = { +struct sysdev_class s5p6440_sysclass = { .name = "s5p6440-core", }; diff --git a/arch/arm/mach-s5p6442/cpu.c b/arch/arm/mach-s5p6442/cpu.c index bc2524df89b3..a48fb553fd01 100644 --- a/arch/arm/mach-s5p6442/cpu.c +++ b/arch/arm/mach-s5p6442/cpu.c @@ -95,7 +95,7 @@ void __init s5p6442_init_irq(void) s5p_init_irq(vic, ARRAY_SIZE(vic)); } -static struct sysdev_class s5p6442_sysclass = { +struct sysdev_class s5p6442_sysclass = { .name = "s5p6442-core", }; diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index 0e0f8fde2aa6..2b776eb5d150 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c @@ -100,7 +100,7 @@ void __init s5pv210_init_irq(void) s5p_init_irq(vic, ARRAY_SIZE(vic)); } -static struct sysdev_class s5pv210_sysclass = { +struct sysdev_class s5pv210_sysclass = { .name = "s5pv210-core", }; diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index d316b4a579f4..c54f318991b6 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -78,6 +78,9 @@ extern struct sysdev_class s3c2442_sysclass; extern struct sysdev_class s3c2443_sysclass; extern struct sysdev_class s3c6410_sysclass; extern struct sysdev_class s3c64xx_sysclass; +extern struct sysdev_class s5p6440_sysclass; +extern struct sysdev_class s5p6442_sysclass; +extern struct sysdev_class s5pv210_sysclass; extern void (*s5pc1xx_idle)(void); -- cgit v1.2.3-59-g8ed1b From 6cd82ffe0cd3836b32b29bd1436e5fd551957d54 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Tue, 4 May 2010 13:12:32 +0200 Subject: ARM: SAMSUNG: Move HWMON from plat-s3c24xx to plat-samsung Move HWMON platform definition from plat-s3c24xx to plat-samsung and adjust mach-bast to use the new s3c_hwmon_set_platdata(). This allows usage of dev-hwmon by other Samsung SoCs. Signed-off-by: Maurus Cuelenaere Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/Kconfig | 1 + arch/arm/mach-s3c2410/mach-bast.c | 2 +- arch/arm/plat-s3c24xx/devs.c | 8 ------ arch/arm/plat-samsung/Kconfig | 5 ++++ arch/arm/plat-samsung/Makefile | 1 + arch/arm/plat-samsung/dev-hwmon.c | 42 ++++++++++++++++++++++++++++++ arch/arm/plat-samsung/include/plat/hwmon.h | 10 +++++++ 7 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 arch/arm/plat-samsung/dev-hwmon.c (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 554731868b07..ca5c3c62f37b 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -110,6 +110,7 @@ config ARCH_BAST select MACH_BAST_IDE select S3C24XX_DCLK select ISA + select S3C_DEV_HWMON select S3C_DEV_USB_HOST select S3C_DEV_NAND help diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 02b1b6220cba..c8786df72b9e 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -634,7 +634,7 @@ static void __init bast_map_io(void) s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); - s3c_device_hwmon.dev.platform_data = &bast_hwmon_info; + s3c_hwmon_set_platdata(&bast_hwmon_info); s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); s3c24xx_init_clocks(0); diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 9265f09bfa58..3166f320fd65 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -338,14 +338,6 @@ struct platform_device s3c_device_adc = { .resource = s3c_adc_resource, }; -/* HWMON */ - -struct platform_device s3c_device_hwmon = { - .name = "s3c-hwmon", - .id = -1, - .dev.parent = &s3c_device_adc.dev, -}; - /* SDI */ static struct resource s3c_sdi_resource[] = { diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index d552c65fa1b0..7a36cf85e138 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -160,6 +160,11 @@ config S3C_DEV_HSMMC2 help Compile in platform device definitions for HSMMC channel 2 +config S3C_DEV_HWMON + bool + help + Compile in platform device definitions for HWMON + config S3C_DEV_I2C1 bool help diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 22c89d08f6e5..0ad820acc385 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_S3C_ADC) += adc.o obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o +obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o obj-y += dev-i2c0.o obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c new file mode 100644 index 000000000000..b3ffb9587250 --- /dev/null +++ b/arch/arm/plat-samsung/dev-hwmon.c @@ -0,0 +1,42 @@ +/* linux/arch/arm/plat-samsung/dev-hwmon.c + * + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * Adapted for HWMON by Maurus Cuelenaere + * + * Samsung series device definition for HWMON + * + * 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 +#include + +#include +#include + +struct platform_device s3c_device_hwmon = { + .name = "s3c-hwmon", + .id = -1, + .dev.parent = &s3c_device_adc.dev, +}; + +void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd) +{ + struct s3c_hwmon_pdata *npd; + + if (!pd) { + printk(KERN_ERR "%s: no platform data\n", __func__); + return; + } + + npd = kmemdup(pd, sizeof(struct s3c_hwmon_pdata), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + + s3c_device_hwmon.dev.platform_data = npd; +} diff --git a/arch/arm/plat-samsung/include/plat/hwmon.h b/arch/arm/plat-samsung/include/plat/hwmon.h index 1ba88ea0aa31..c167e4429bc7 100644 --- a/arch/arm/plat-samsung/include/plat/hwmon.h +++ b/arch/arm/plat-samsung/include/plat/hwmon.h @@ -37,5 +37,15 @@ struct s3c_hwmon_pdata { struct s3c_hwmon_chcfg *in[8]; }; +/** + * s3c_hwmon_set_platdata - Set platform data for S3C HWMON device + * @pd: Platform data to register to device. + * + * Register the given platform data for use with the S3C HWMON device. + * The call will copy the platform data, so the board definitions can + * make the structure itself __initdata. + */ +extern void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd); + #endif /* __ASM_ARCH_ADC_HWMON_H */ -- cgit v1.2.3-59-g8ed1b From 308eb7add8adaca8088c28a3f7610069b70d1ad6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 12 May 2010 12:10:39 +0200 Subject: ia64: add sparse annotation to __ia64_per_cpu_var() ia64 has its own optimized percpu accessor - __ia64_per_cpu_var(). Add percpu sparse annotations to it. Signed-off-by: Tejun Heo Reviewed-by: Christoph Lameter --- arch/ia64/include/asm/percpu.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/include/asm/percpu.h b/arch/ia64/include/asm/percpu.h index f7c00a5e0e2b..1bd408265694 100644 --- a/arch/ia64/include/asm/percpu.h +++ b/arch/ia64/include/asm/percpu.h @@ -39,7 +39,10 @@ extern void *per_cpu_init(void); * On the positive side, using __ia64_per_cpu_var() instead of __get_cpu_var() is slightly * more efficient. */ -#define __ia64_per_cpu_var(var) var +#define __ia64_per_cpu_var(var) (*({ \ + __verify_pcpu_ptr(&(var)); \ + ((typeof(var) __kernel __force *)&(var)); \ +})) #include -- cgit v1.2.3-59-g8ed1b From 614ad9814850ab618e76b4a2e272c0262ece7be0 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 24 Feb 2010 15:44:51 -0800 Subject: arm: msm: add board file for the HTC Sapphire device This adds a basic board file without Kconfig changes. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/board-sapphire.c | 118 +++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 arch/arm/mach-msm/board-sapphire.c (limited to 'arch') diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c new file mode 100644 index 000000000000..2bc1b9d5623e --- /dev/null +++ b/arch/arm/mach-msm/board-sapphire.c @@ -0,0 +1,118 @@ +/* linux/arch/arm/mach-msm/board-sapphire.c + * Copyright (C) 2007-2009 HTC Corporation. + * Author: Thomas Tsai + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "gpio_chip.h" +#include "board-sapphire.h" +#include "proc_comm.h" +#include "devices.h" + +void msm_init_irq(void); +void msm_init_gpio(void); + +static struct platform_device *devices[] __initdata = { + &msm_device_smd, + &msm_device_dmov, + &msm_device_nand, + &msm_device_uart1, + &msm_device_uart3, +}; + +extern struct sys_timer msm_timer; + +static void __init sapphire_init_irq(void) +{ + msm_init_irq(); +} + +static void __init sapphire_init(void) +{ + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static struct map_desc sapphire_io_desc[] __initdata = { + { + .virtual = SAPPHIRE_CPLD_BASE, + .pfn = __phys_to_pfn(SAPPHIRE_CPLD_START), + .length = SAPPHIRE_CPLD_SIZE, + .type = MT_DEVICE_NONSHARED + } +}; + +static void __init sapphire_fixup(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + int smi_sz = parse_tag_smi((const struct tag *)tags); + + mi->nr_banks = 1; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); + if (smi_sz == 32) { + mi->bank[0].size = (84*1024*1024); + } else if (smi_sz == 64) { + mi->bank[0].size = (101*1024*1024); + } else { + /* Give a default value when not get smi size */ + smi_sz = 64; + mi->bank[0].size = (101*1024*1024); + } +} + +static void __init sapphire_map_io(void) +{ + msm_map_common_io(); + iotable_init(sapphire_io_desc, ARRAY_SIZE(sapphire_io_desc)); + msm_clock_init(); +} + +MACHINE_START(SAPPHIRE, "sapphire") +/* Maintainer: Brian Swetland */ +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .fixup = sapphire_fixup, + .map_io = sapphire_map_io, + .init_irq = sapphire_init_irq, + .init_machine = sapphire_init, + .timer = &msm_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 2682fd3df51cf53b41a6aeba99b346cd846389c2 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 24 Feb 2010 15:47:58 -0800 Subject: arm: msm: add board file for MSM7x25/MSM7x27 SURF and FFA This adds a basic board file without Kconfig changes. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/board-msm7x27.c | 179 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 arch/arm/mach-msm/board-msm7x27.c (limited to 'arch') diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c new file mode 100644 index 000000000000..cccb9f3c9d01 --- /dev/null +++ b/arch/arm/mach-msm/board-msm7x27.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_CACHE_L2X0 +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "devices.h" +#include "socinfo.h" +#include "clock.h" + +static struct resource smc91x_resources[] = { + [0] = { + .start = 0x9C004300, + .end = 0x9C0043ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSM_GPIO_TO_INT(132), + .end = MSM_GPIO_TO_INT(132), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct platform_device *devices[] __initdata = { + &msm_device_uart3, + &msm_device_smd, + &msm_device_dmov, + &msm_device_nand, + &smc91x_device, +}; + +extern struct sys_timer msm_timer; + +static void __init msm7x2x_init_irq(void) +{ + msm_init_irq(); +} + +static void __init msm7x2x_init(void) +{ + if (socinfo_init() < 0) + BUG(); + + if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) { + smc91x_resources[0].start = 0x98000300; + smc91x_resources[0].end = 0x980003ff; + smc91x_resources[1].start = MSM_GPIO_TO_INT(85); + smc91x_resources[1].end = MSM_GPIO_TO_INT(85); + if (gpio_tlmm_config(GPIO_CFG(85, 0, + GPIO_INPUT, + GPIO_PULL_DOWN, + GPIO_2MA), + GPIO_ENABLE)) { + printk(KERN_ERR + "%s: Err: Config GPIO-85 INT\n", + __func__); + } + } + + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static void __init msm7x2x_map_io(void) +{ + msm_map_common_io(); + /* Technically dependent on the SoC but using machine_is + * macros since socinfo is not available this early and there + * are plans to restructure the code which will eliminate the + * need for socinfo. + */ + if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) + msm_clock_init(msm_clocks_7x27, msm_num_clocks_7x27); + + if (machine_is_msm7x25_surf() || machine_is_msm7x25_ffa()) + msm_clock_init(msm_clocks_7x25, msm_num_clocks_7x25); + +#ifdef CONFIG_CACHE_L2X0 + if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) { + /* 7x27 has 256KB L2 cache: + 64Kb/Way and 4-Way Associativity; + R/W latency: 3 cycles; + evmon/parity/share disabled. */ + l2x0_init(MSM_L2CC_BASE, 0x00068012, 0xfe000000); + } +#endif +} + +MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = msm7x2x_map_io, + .init_irq = msm7x2x_init_irq, + .init_machine = msm7x2x_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = msm7x2x_map_io, + .init_irq = msm7x2x_init_irq, + .init_machine = msm7x2x_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = msm7x2x_map_io, + .init_irq = msm7x2x_init_irq, + .init_machine = msm7x2x_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = msm7x2x_map_io, + .init_irq = msm7x2x_init_irq, + .init_machine = msm7x2x_init, + .timer = &msm_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 8d747cdb3d4db7fd7a0740986567a50fb232931a Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 25 Feb 2010 11:37:43 -0800 Subject: arm: msm: add board file for MSM7x30 SURF and FFA This adds a basic board file without Kconfig changes. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/board-msm7x30.c | 196 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 arch/arm/mach-msm/board-msm7x30.c (limited to 'arch') diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c new file mode 100644 index 000000000000..af132ebd86c5 --- /dev/null +++ b/arch/arm/mach-msm/board-msm7x30.c @@ -0,0 +1,196 @@ +/* Copyright (c) 2009-2010, Code Aurora Forum. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "devices.h" +#include "timer.h" +#include "socinfo.h" + +static struct resource smc91x_resources[] = { + [0] = { + .start = 0x8A000300, + .end = 0x8A0003ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSM_GPIO_TO_INT(156), + .end = MSM_GPIO_TO_INT(156), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .phy_interface = PHY_INTERFACE_MODE_MII, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, + .flags = SMSC911X_USE_32BIT, +}; + +static struct resource smsc911x_resources[] = { + [0] = { + .start = 0x8D000000, + .end = 0x8D000100, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSM_GPIO_TO_INT(88), + .end = MSM_GPIO_TO_INT(88), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, +}; + +static struct msm_gpio smsc911x_gpios[] = { + { GPIO_CFG(172, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr6" }, + { GPIO_CFG(173, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr5" }, + { GPIO_CFG(174, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr4" }, + { GPIO_CFG(175, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr3" }, + { GPIO_CFG(176, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr2" }, + { GPIO_CFG(177, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr1" }, + { GPIO_CFG(178, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr0" }, + { GPIO_CFG(88, 2, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA), "smsc911x_irq" }, +}; + +static void msm7x30_cfg_smsc911x(void) +{ + int rc; + + rc = msm_gpios_request_enable(smsc911x_gpios, + ARRAY_SIZE(smsc911x_gpios)); + if (rc) + pr_err("%s: unable to enable gpios\n", __func__); +} + +static struct platform_device *devices[] __initdata = { + &msm_device_smd, + &msm_device_dmov, + &smc91x_device, + &smsc911x_device, + &msm_device_nand, + &msm_device_uart_dm1, +}; + +static void __init msm7x30_init_irq(void) +{ + msm_init_irq(); +} + +static void __init msm_7x30_init_nand(void) +{ + int rc; + /* Enable GPIO 86 & 115 */ + rc = msm_gpios_request_enable(msm_nand_ebi2_cfg_data, + ARRAY_SIZE(msm_nand_ebi2_cfg_data)); + if (rc) + printk(KERN_ERR "%s: Failed to enable GPIO 86 & 115\n", + __func__); +} + +static void __init msm7x30_init(void) +{ + if (socinfo_init() < 0) + printk(KERN_ERR "%s: socinfo_init() failed!\n", + __func__); + msm_acpu_clock_init(&msm7x30_clock_data); + if (machine_is_msm7x30_surf() || machine_is_msm7x30_fluid()) + msm7x30_cfg_smsc911x(); + platform_add_devices(devices, ARRAY_SIZE(devices)); + msm_7x30_init_nand(); + buses_init(); +} + +static void __init msm7x30_map_io(void) +{ + msm_shared_ram_phys = 0x00000000; + msm_map_msm7x30_io(); + msm7x30_allocate_memory_regions(); + msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30); +} + +MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = msm7x30_map_io, + .init_irq = msm7x30_init_irq, + .init_machine = msm7x30_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = msm7x30_map_io, + .init_irq = msm7x30_init_irq, + .init_machine = msm7x30_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = msm7x30_map_io, + .init_irq = msm7x30_init_irq, + .init_machine = msm7x30_init, + .timer = &msm_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From a32d2feb80bb2d186d415ed8bb4997148add0bd1 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 25 Feb 2010 11:38:39 -0800 Subject: arm: msm: add board file for QSD8x50 SURF and FFA This adds a basic board file without Kconfig changes. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/board-qsd8x50.c | 176 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 arch/arm/mach-msm/board-qsd8x50.c (limited to 'arch') diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c new file mode 100644 index 000000000000..a5e862c6ef7b --- /dev/null +++ b/arch/arm/mach-msm/board-qsd8x50.c @@ -0,0 +1,176 @@ +/* Copyright (c) 2008-2009, Code Aurora Forum. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "devices.h" +#include "timer.h" +#include "socinfo.h" +#include "proc_comm.h" + +#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000) + +static struct resource smc91x_resources[] = { + [0] = { + .flags = IORESOURCE_MEM, + }, + [1] = { + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct platform_device *devices[] __initdata = { + &smc91x_device, + &msm_device_smd, + &msm_device_dmov, + &msm_device_nand, +}; + +static void __init qsd8x50_init_irq(void) +{ + msm_init_irq(); +} + +static void __init qsd8x50_init_host(void) +{ + if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa()) + return; + + vreg_usb = vreg_get(NULL, "boost"); + + if (IS_ERR(vreg_usb)) { + printk(KERN_ERR "%s: vreg get failed (%ld)\n", + __func__, PTR_ERR(vreg_usb)); + return; + } + + platform_device_register(&msm_device_hsusb_otg); +} + +static void __init qsd8x50_cfg_smc91x(void) +{ + int rc = 0; + + if (machine_is_qsd8x50_surf() || machine_is_qsd8x50a_surf()) { + smc91x_resources[0].start = 0x70000300; + smc91x_resources[0].end = 0x700003ff; + smc91x_resources[1].start = MSM_GPIO_TO_INT(156); + smc91x_resources[1].end = MSM_GPIO_TO_INT(156); + } else if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa()) { + smc91x_resources[0].start = 0x84000300; + smc91x_resources[0].end = 0x840003ff; + smc91x_resources[1].start = MSM_GPIO_TO_INT(87); + smc91x_resources[1].end = MSM_GPIO_TO_INT(87); + + rc = gpio_tlmm_config(GPIO_CFG(87, 0, GPIO_INPUT, + GPIO_PULL_DOWN, GPIO_2MA), + GPIO_ENABLE); + if (rc) { + printk(KERN_ERR "%s: gpio_tlmm_config=%d\n", + __func__, rc); + } + } else + printk(KERN_ERR "%s: invalid machine type\n", __func__); +} + +static void __init qsd8x50_init(void) +{ + if (socinfo_init() < 0) + printk(KERN_ERR "%s: socinfo_init() failed!\n", + __func__); + qsd8x50_cfg_smc91x(); + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static void __init qsd8x50_map_io(void) +{ + msm_shared_ram_phys = MSM_SHARED_RAM_PHYS; + msm_map_qsd8x50_io(); + msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50); +} + +MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = qsd8x50_map_io, + .init_irq = qsd8x50_init_irq, + .init_machine = qsd8x50_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(QSD8X50_FFA, "QCT QSD8X50 FFA") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = qsd8x50_map_io, + .init_irq = qsd8x50_init_irq, + .init_machine = qsd8x50_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(QSD8X50A_SURF, "QCT QSD8X50A SURF") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = qsd8x50_map_io, + .init_irq = qsd8x50_init_irq, + .init_machine = qsd8x50_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(QSD8X50A_FFA, "QCT QSD8X50A FFA") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .map_io = qsd8x50_map_io, + .init_irq = qsd8x50_init_irq, + .init_machine = qsd8x50_init, + .timer = &msm_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 6bd631e17eaa0d045b259ff7a6625bfe96c15283 Mon Sep 17 00:00:00 2001 From: Arve HjønnevĂ¥g Date: Wed, 29 Oct 2008 21:45:46 -0700 Subject: [ARM] msm: halibut: Add memory configuration. --- arch/arm/mach-msm/board-halibut.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index e61967dde9a1..b8da1002f47d 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -77,6 +78,15 @@ static void __init halibut_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); } +static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + mi->nr_banks=1; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); + mi->bank[0].size = (101*1024*1024); +} + static void __init halibut_map_io(void) { msm_map_common_io(); @@ -85,6 +95,7 @@ static void __init halibut_map_io(void) MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") .boot_params = 0x10000100, + .fixup = halibut_fixup, .map_io = halibut_map_io, .init_irq = halibut_init_irq, .init_machine = halibut_init, -- cgit v1.2.3-59-g8ed1b From 36cf1b55b4caa188f2d070bb18a69ebe3c70580f Mon Sep 17 00:00:00 2001 From: Arve HjønnevĂ¥g Date: Tue, 18 Nov 2008 14:58:08 -0800 Subject: [ARM] msm: Add MSM_DEBUG_UART option. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arve HjønnevĂ¥g --- arch/arm/mach-msm/board-halibut.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index b8da1002f47d..acc22886e340 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c @@ -94,6 +94,10 @@ static void __init halibut_map_io(void) } MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif .boot_params = 0x10000100, .fixup = halibut_fixup, .map_io = halibut_map_io, -- cgit v1.2.3-59-g8ed1b From d6ada2577601576099934448a0391bb37296b3db Mon Sep 17 00:00:00 2001 From: Arve HjønnevĂ¥g Date: Sat, 1 Dec 2007 18:05:26 -0800 Subject: [ARM] msm: irq: fix lockdep issues Signed-off-by: Brian Swetland --- arch/arm/mach-msm/irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c index 69ca0dd79bdf..6c8d5f8caef3 100644 --- a/arch/arm/mach-msm/irq.c +++ b/arch/arm/mach-msm/irq.c @@ -101,11 +101,11 @@ static int msm_irq_set_type(unsigned int irq, unsigned int flow_type) if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { writel(readl(treg) | b, treg); - set_irq_handler(irq, handle_edge_irq); + irq_desc[irq].handle_irq = handle_edge_irq; } if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { writel(readl(treg) & (~b), treg); - set_irq_handler(irq, handle_level_irq); + irq_desc[irq].handle_irq = handle_level_irq; } return 0; } -- cgit v1.2.3-59-g8ed1b From 5f5d585167dadce1c895a860ae0be0dc6f48ee82 Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Tue, 8 Sep 2009 20:15:37 -0700 Subject: [ARM] msm: Update list of proc_comm enums. Signed-off-by: Dima Zavin --- arch/arm/mach-msm/proc_comm.h | 102 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/proc_comm.h b/arch/arm/mach-msm/proc_comm.h index 834760f25692..235076533c03 100644 --- a/arch/arm/mach-msm/proc_comm.h +++ b/arch/arm/mach-msm/proc_comm.h @@ -62,19 +62,104 @@ enum { PCOM_RESET_CHIP_IMM, PCOM_PM_VID_EN, PCOM_VREG_PULLDOWN, + PCOM_GET_MODEM_VERSION, + PCOM_CLK_REGIME_SEC_RESET, + PCOM_CLK_REGIME_SEC_RESET_ASSERT, + PCOM_CLK_REGIME_SEC_RESET_DEASSERT, + PCOM_CLK_REGIME_SEC_PLL_REQUEST_WRP, + PCOM_CLK_REGIME_SEC_ENABLE, + PCOM_CLK_REGIME_SEC_DISABLE, + PCOM_CLK_REGIME_SEC_IS_ON, + PCOM_CLK_REGIME_SEC_SEL_CLK_INV, + PCOM_CLK_REGIME_SEC_SEL_CLK_SRC, + PCOM_CLK_REGIME_SEC_SEL_CLK_DIV, + PCOM_CLK_REGIME_SEC_ICODEC_CLK_ENABLE, + PCOM_CLK_REGIME_SEC_ICODEC_CLK_DISABLE, + PCOM_CLK_REGIME_SEC_SEL_SPEED, + PCOM_CLK_REGIME_SEC_CONFIG_GP_CLK_WRP, + PCOM_CLK_REGIME_SEC_CONFIG_MDH_CLK_WRP, + PCOM_CLK_REGIME_SEC_USB_XTAL_ON, + PCOM_CLK_REGIME_SEC_USB_XTAL_OFF, + PCOM_CLK_REGIME_SEC_SET_QDSP_DME_MODE, + PCOM_CLK_REGIME_SEC_SWITCH_ADSP_CLK, + PCOM_CLK_REGIME_SEC_GET_MAX_ADSP_CLK_KHZ, + PCOM_CLK_REGIME_SEC_GET_I2C_CLK_KHZ, + PCOM_CLK_REGIME_SEC_MSM_GET_CLK_FREQ_KHZ, + PCOM_CLK_REGIME_SEC_SEL_VFE_SRC, + PCOM_CLK_REGIME_SEC_MSM_SEL_CAMCLK, + PCOM_CLK_REGIME_SEC_MSM_SEL_LCDCLK, + PCOM_CLK_REGIME_SEC_VFE_RAIL_OFF, + PCOM_CLK_REGIME_SEC_VFE_RAIL_ON, + PCOM_CLK_REGIME_SEC_GRP_RAIL_OFF, + PCOM_CLK_REGIME_SEC_GRP_RAIL_ON, + PCOM_CLK_REGIME_SEC_VDC_RAIL_OFF, + PCOM_CLK_REGIME_SEC_VDC_RAIL_ON, + PCOM_CLK_REGIME_SEC_LCD_CTRL, + PCOM_CLK_REGIME_SEC_REGISTER_FOR_CPU_RESOURCE, + PCOM_CLK_REGIME_SEC_DEREGISTER_FOR_CPU_RESOURCE, + PCOM_CLK_REGIME_SEC_RESOURCE_REQUEST_WRP, + PCOM_CLK_REGIME_MSM_SEC_SEL_CLK_OWNER, + PCOM_CLK_REGIME_SEC_DEVMAN_REQUEST_WRP, + PCOM_GPIO_CONFIG, + PCOM_GPIO_CONFIGURE_GROUP, + PCOM_GPIO_TLMM_SET_PORT, + PCOM_GPIO_TLMM_CONFIG_EX, + PCOM_SET_FTM_BOOT_COUNT, + PCOM_RESERVED0, + PCOM_RESERVED1, + PCOM_CUSTOMER_CMD1, + PCOM_CUSTOMER_CMD2, + PCOM_CUSTOMER_CMD3, + PCOM_CLK_REGIME_ENTER_APPSBL_CHG_MODE, + PCOM_CLK_REGIME_EXIT_APPSBL_CHG_MODE, + PCOM_CLK_REGIME_SEC_RAIL_DISABLE, + PCOM_CLK_REGIME_SEC_RAIL_ENABLE, + PCOM_CLK_REGIME_SEC_RAIL_CONTROL, + PCOM_SET_SW_WATCHDOG_STATE, + PCOM_PM_MPP_CONFIG_DIGITAL_INPUT, + PCOM_PM_MPP_CONFIG_I_SINK, + PCOM_RESERVED_101, + PCOM_MSM_HSUSB_PHY_RESET, + PCOM_GET_BATT_MV_LEVEL, + PCOM_CHG_USB_IS_PC_CONNECTED, + PCOM_CHG_USB_IS_CHARGER_CONNECTED, + PCOM_CHG_USB_IS_DISCONNECTED, + PCOM_CHG_USB_IS_AVAILABLE, + PCOM_CLK_REGIME_SEC_MSM_SEL_FREQ, + PCOM_CLK_REGIME_SEC_SET_PCLK_AXI_POLICY, + PCOM_CLKCTL_RPC_RESET_ASSERT, + PCOM_CLKCTL_RPC_RESET_DEASSERT, + PCOM_CLKCTL_RPC_RAIL_ON, + PCOM_CLKCTL_RPC_RAIL_OFF, + PCOM_CLKCTL_RPC_RAIL_ENABLE, + PCOM_CLKCTL_RPC_RAIL_DISABLE, + PCOM_CLKCTL_RPC_RAIL_CONTROL, + PCOM_CLKCTL_RPC_MIN_MSMC1, PCOM_NUM_CMDS, }; enum { - PCOM_INVALID_STATUS = 0x0, - PCOM_READY, - PCOM_CMD_RUNNING, - PCOM_CMD_SUCCESS, - PCOM_CMD_FAIL, + PCOM_INVALID_STATUS = 0x0, + PCOM_READY, + PCOM_CMD_RUNNING, + PCOM_CMD_SUCCESS, + PCOM_CMD_FAIL, + PCOM_CMD_FAIL_FALSE_RETURNED, + PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_SERVER, + PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_CLIENT, + PCOM_CMD_FAIL_CMD_UNREGISTERED, + PCOM_CMD_FAIL_CMD_LOCKED, + PCOM_CMD_FAIL_SERVER_NOT_YET_READY, + PCOM_CMD_FAIL_BAD_DESTINATION, + PCOM_CMD_FAIL_SERVER_RESET, + PCOM_CMD_FAIL_SMSM_NOT_INIT, + PCOM_CMD_FAIL_PROC_COMM_BUSY, + PCOM_CMD_FAIL_PROC_COMM_NOT_INIT, + }; /* List of VREGs that support the Pull Down Resistor setting. */ -enum { +enum vreg_pdown_id { PM_VREG_PDOWN_MSMA_ID, PM_VREG_PDOWN_MSMP_ID, PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */ @@ -131,6 +216,11 @@ enum { PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID }; +enum { + PCOM_CLKRGM_APPS_RESET_USB_PHY = 34, + PCOM_CLKRGM_APPS_RESET_USBH = 37, +}; + /* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */ #define GPIO_ENABLE 0 -- cgit v1.2.3-59-g8ed1b From a6407dd7b89f0de39d315eee64ad59dd68187b38 Mon Sep 17 00:00:00 2001 From: Arve HjønnevĂ¥g Date: Fri, 17 Apr 2009 18:21:34 -0700 Subject: [ARM] msm: dma: disable_irq -> disable_irq_nosync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arve HjønnevĂ¥g --- arch/arm/mach-msm/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index f5420f9585c5..09c0c0f9729b 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c @@ -220,7 +220,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) } if (!channel_active) - disable_irq(INT_ADM_AARM); + disable_irq_nosync(INT_ADM_AARM); spin_unlock_irqrestore(&msm_dmov_lock, irq_flags); return IRQ_HANDLED; -- cgit v1.2.3-59-g8ed1b From c5541079da3cd19626410d59455d3e0f34d65943 Mon Sep 17 00:00:00 2001 From: Arve HjønnevĂ¥g Date: Thu, 25 Jun 2009 17:03:14 -0700 Subject: [ARM] msm: dma: Enable dma clock while dma is active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arve HjønnevĂ¥g --- arch/arm/mach-msm/dma.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index 09c0c0f9729b..e80cad468925 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c @@ -13,6 +13,8 @@ * */ +#include +#include #include #include #include @@ -26,6 +28,7 @@ enum { }; static DEFINE_SPINLOCK(msm_dmov_lock); +static struct clk *msm_dmov_clk; static unsigned int channel_active; static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT]; static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT]; @@ -54,6 +57,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) unsigned int status; spin_lock_irqsave(&msm_dmov_lock, irq_flags); + if (!channel_active) + clk_enable(msm_dmov_clk); status = readl(DMOV_STATUS(id)); if (list_empty(&ready_commands[id]) && (status & DMOV_STATUS_CMD_PTR_RDY)) { @@ -70,6 +75,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) channel_active |= 1U << id; writel(cmd->cmdptr, DMOV_CMD_PTR(id)); } else { + if (!channel_active) + clk_disable(msm_dmov_clk); if (list_empty(&active_commands[id])) PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status); @@ -219,8 +226,10 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); } - if (!channel_active) + if (!channel_active) { disable_irq_nosync(INT_ADM_AARM); + clk_disable(msm_dmov_clk); + } spin_unlock_irqrestore(&msm_dmov_lock, irq_flags); return IRQ_HANDLED; @@ -230,11 +239,17 @@ static int __init msm_init_datamover(void) { int i; int ret; + struct clk *clk; + for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) { INIT_LIST_HEAD(&ready_commands[i]); INIT_LIST_HEAD(&active_commands[i]); writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i)); } + clk = clk_get(NULL, "adm_clk"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + msm_dmov_clk = clk; ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL); if (ret) return ret; -- cgit v1.2.3-59-g8ed1b From 9f68fcdb8f9b0f55830f58b02cecc5c26b0ba17b Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Wed, 19 Aug 2009 18:49:45 -0700 Subject: msm: add dsb() syncronization to datamover driver Avoids problems on the scorpion core. Signed-off-by: Brian Swetland --- arch/arm/mach-msm/dma.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index e80cad468925..3d725ae518e4 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c @@ -59,6 +59,7 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) spin_lock_irqsave(&msm_dmov_lock, irq_flags); if (!channel_active) clk_enable(msm_dmov_clk); + dsb(); status = readl(DMOV_STATUS(id)); if (list_empty(&ready_commands[id]) && (status & DMOV_STATUS_CMD_PTR_RDY)) { @@ -172,6 +173,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) "for %p, result %x\n", id, cmd, ch_result); if (cmd) { list_del(&cmd->list); + dsb(); cmd->complete_func(cmd, ch_result, NULL); } } @@ -188,6 +190,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); if (cmd) { list_del(&cmd->list); + dsb(); cmd->complete_func(cmd, ch_result, &errdata); } } @@ -205,6 +208,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); if (cmd) { list_del(&cmd->list); + dsb(); cmd->complete_func(cmd, ch_result, &errdata); } /* this does not seem to work, once we get an error */ -- cgit v1.2.3-59-g8ed1b From 43b39f9f040fd49a094222f70857e3690ce653a3 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 3 Mar 2010 08:54:11 -0800 Subject: arm: msm: add cpu frequency controls This adds acpuclock-arm11.c from Google. This provides control over the cpu frequency for arm11 cpu's. This has shared authorship between Google, and Qualcomm. Most of it was written by Mike Chan at Google. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/Makefile | 1 + arch/arm/mach-msm/acpuclock-arm11.c | 523 +++++++++++++++++++++++++++++++++ arch/arm/mach-msm/acpuclock.h | 32 ++ arch/arm/mach-msm/include/mach/board.h | 11 + 4 files changed, 567 insertions(+) create mode 100644 arch/arm/mach-msm/acpuclock-arm11.c create mode 100644 arch/arm/mach-msm/acpuclock.h (limited to 'arch') diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 91e6f5c95dc1..0cb523fe3b3e 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -2,6 +2,7 @@ obj-y += io.o idle.o irq.o timer.o dma.o obj-y += devices.o obj-y += proc_comm.o obj-y += vreg.o +obj-y += acpuclock-arm11.o obj-y += clock.o clock-7x01a.o obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c new file mode 100644 index 000000000000..f9c9035bd9bb --- /dev/null +++ b/arch/arm/mach-msm/acpuclock-arm11.c @@ -0,0 +1,523 @@ +/* arch/arm/mach-msm/acpuclock.c + * + * MSM architecture clock driver + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007 QUALCOMM Incorporated + * Author: San Mehat + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "proc_comm.h" +#include "acpuclock.h" + + +#define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100) +#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) +#define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) + +/* + * ARM11 clock configuration for specific ACPU speeds + */ + +#define ACPU_PLL_TCXO -1 +#define ACPU_PLL_0 0 +#define ACPU_PLL_1 1 +#define ACPU_PLL_2 2 +#define ACPU_PLL_3 3 + +#define PERF_SWITCH_DEBUG 0 +#define PERF_SWITCH_STEP_DEBUG 0 + +struct clock_state +{ + struct clkctl_acpu_speed *current_speed; + struct mutex lock; + uint32_t acpu_switch_time_us; + uint32_t max_speed_delta_khz; + uint32_t vdd_switch_time_us; + unsigned long power_collapse_khz; + unsigned long wait_for_irq_khz; +}; + +static struct clk *ebi1_clk; +static struct clock_state drv_state = { 0 }; + +static void __init acpuclk_init(void); + +/* MSM7201A Levels 3-6 all correspond to 1.2V, level 7 corresponds to 1.325V. */ +enum { + VDD_0 = 0, + VDD_1 = 1, + VDD_2 = 2, + VDD_3 = 3, + VDD_4 = 3, + VDD_5 = 3, + VDD_6 = 3, + VDD_7 = 7, + VDD_END +}; + +struct clkctl_acpu_speed { + unsigned int a11clk_khz; + int pll; + unsigned int a11clk_src_sel; + unsigned int a11clk_src_div; + unsigned int ahbclk_khz; + unsigned int ahbclk_div; + int vdd; + unsigned int axiclk_khz; + unsigned long lpj; /* loops_per_jiffy */ +/* Index in acpu_freq_tbl[] for steppings. */ + short down; + short up; +}; + +/* + * ACPU speed table. Complete table is shown but certain speeds are commented + * out to optimized speed switching. Initalize loops_per_jiffy to 0. + * + * Table stepping up/down is optimized for 256mhz jumps while staying on the + * same PLL. + */ +#if (0) +static struct clkctl_acpu_speed acpu_freq_tbl[] = { + { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 8 }, + { 61440, ACPU_PLL_0, 4, 3, 61440, 0, VDD_0, 30720, 0, 0, 8 }, + { 81920, ACPU_PLL_0, 4, 2, 40960, 1, VDD_0, 61440, 0, 0, 8 }, + { 96000, ACPU_PLL_1, 1, 7, 48000, 1, VDD_0, 61440, 0, 0, 9 }, + { 122880, ACPU_PLL_0, 4, 1, 61440, 1, VDD_3, 61440, 0, 0, 8 }, + { 128000, ACPU_PLL_1, 1, 5, 64000, 1, VDD_3, 61440, 0, 0, 12 }, + { 176000, ACPU_PLL_2, 2, 5, 88000, 1, VDD_3, 61440, 0, 0, 11 }, + { 192000, ACPU_PLL_1, 1, 3, 64000, 2, VDD_3, 61440, 0, 0, 12 }, + { 245760, ACPU_PLL_0, 4, 0, 81920, 2, VDD_4, 61440, 0, 0, 12 }, + { 256000, ACPU_PLL_1, 1, 2, 128000, 2, VDD_5, 128000, 0, 0, 12 }, + { 264000, ACPU_PLL_2, 2, 3, 88000, 2, VDD_5, 128000, 0, 6, 13 }, + { 352000, ACPU_PLL_2, 2, 2, 88000, 3, VDD_5, 128000, 0, 6, 13 }, + { 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 5, -1 }, + { 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 11, -1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +}; +#else /* Table of freq we currently use. */ +static struct clkctl_acpu_speed acpu_freq_tbl[] = { + { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 4 }, + { 122880, ACPU_PLL_0, 4, 1, 61440, 1, VDD_3, 61440, 0, 0, 4 }, + { 128000, ACPU_PLL_1, 1, 5, 64000, 1, VDD_3, 61440, 0, 0, 6 }, + { 176000, ACPU_PLL_2, 2, 5, 88000, 1, VDD_3, 61440, 0, 0, 5 }, + { 245760, ACPU_PLL_0, 4, 0, 81920, 2, VDD_4, 61440, 0, 0, 5 }, + { 352000, ACPU_PLL_2, 2, 2, 88000, 3, VDD_5, 128000, 0, 3, 7 }, + { 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 2, -1 }, + { 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 5, -1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +}; +#endif + +static struct cpufreq_frequency_table freq_table[] = { + { 0, 122880 }, + { 1, 128000 }, + { 2, 245760 }, + { 3, 384000 }, + { 4, 528000 }, + { 5, CPUFREQ_TABLE_END }, +}; + +static int pc_pll_request(unsigned id, unsigned on) +{ + int res; + on = !!on; + +#if PERF_SWITCH_DEBUG + if (on) + printk(KERN_DEBUG "Enabling PLL %d\n", id); + else + printk(KERN_DEBUG "Disabling PLL %d\n", id); +#endif + + res = msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on); + if (res < 0) + return res; + +#if PERF_SWITCH_DEBUG + if (on) + printk(KERN_DEBUG "PLL %d enabled\n", id); + else + printk(KERN_DEBUG "PLL %d disabled\n", id); +#endif + return res; +} + + +/*---------------------------------------------------------------------------- + * ARM11 'owned' clock control + *---------------------------------------------------------------------------*/ + +unsigned long acpuclk_power_collapse(void) { + int ret = acpuclk_get_rate(); + ret *= 1000; + if (ret > drv_state.power_collapse_khz) + acpuclk_set_rate(drv_state.power_collapse_khz, 1); + return ret; +} + +unsigned long acpuclk_get_wfi_rate(void) +{ + return drv_state.wait_for_irq_khz; +} + +unsigned long acpuclk_wait_for_irq(void) { + int ret = acpuclk_get_rate(); + ret *= 1000; + if (ret > drv_state.wait_for_irq_khz) + acpuclk_set_rate(drv_state.wait_for_irq_khz, 1); + return ret; +} + +static int acpuclk_set_vdd_level(int vdd) +{ + uint32_t current_vdd; + + current_vdd = readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x07; + +#if PERF_SWITCH_DEBUG + printk(KERN_DEBUG "acpuclock: Switching VDD from %u -> %d\n", + current_vdd, vdd); +#endif + writel((1 << 7) | (vdd << 3), A11S_VDD_SVS_PLEVEL_ADDR); + udelay(drv_state.vdd_switch_time_us); + if ((readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x7) != vdd) { +#if PERF_SWITCH_DEBUG + printk(KERN_ERR "acpuclock: VDD set failed\n"); +#endif + return -EIO; + } + +#if PERF_SWITCH_DEBUG + printk(KERN_DEBUG "acpuclock: VDD switched\n"); +#endif + return 0; +} + +/* Set proper dividers for the given clock speed. */ +static void acpuclk_set_div(const struct clkctl_acpu_speed *hunt_s) { + uint32_t reg_clkctl, reg_clksel, clk_div; + + /* AHB_CLK_DIV */ + clk_div = (readl(A11S_CLK_SEL_ADDR) >> 1) & 0x03; + /* + * If the new clock divider is higher than the previous, then + * program the divider before switching the clock + */ + if (hunt_s->ahbclk_div > clk_div) { + reg_clksel = readl(A11S_CLK_SEL_ADDR); + reg_clksel &= ~(0x3 << 1); + reg_clksel |= (hunt_s->ahbclk_div << 1); + writel(reg_clksel, A11S_CLK_SEL_ADDR); + } + if ((readl(A11S_CLK_SEL_ADDR) & 0x01) == 0) { + /* SRC0 */ + + /* Program clock source */ + reg_clkctl = readl(A11S_CLK_CNTL_ADDR); + reg_clkctl &= ~(0x07 << 4); + reg_clkctl |= (hunt_s->a11clk_src_sel << 4); + writel(reg_clkctl, A11S_CLK_CNTL_ADDR); + + /* Program clock divider */ + reg_clkctl = readl(A11S_CLK_CNTL_ADDR); + reg_clkctl &= ~0xf; + reg_clkctl |= hunt_s->a11clk_src_div; + writel(reg_clkctl, A11S_CLK_CNTL_ADDR); + + /* Program clock source selection */ + reg_clksel = readl(A11S_CLK_SEL_ADDR); + reg_clksel |= 1; /* CLK_SEL_SRC1NO == SRC1 */ + writel(reg_clksel, A11S_CLK_SEL_ADDR); + } else { + /* SRC1 */ + + /* Program clock source */ + reg_clkctl = readl(A11S_CLK_CNTL_ADDR); + reg_clkctl &= ~(0x07 << 12); + reg_clkctl |= (hunt_s->a11clk_src_sel << 12); + writel(reg_clkctl, A11S_CLK_CNTL_ADDR); + + /* Program clock divider */ + reg_clkctl = readl(A11S_CLK_CNTL_ADDR); + reg_clkctl &= ~(0xf << 8); + reg_clkctl |= (hunt_s->a11clk_src_div << 8); + writel(reg_clkctl, A11S_CLK_CNTL_ADDR); + + /* Program clock source selection */ + reg_clksel = readl(A11S_CLK_SEL_ADDR); + reg_clksel &= ~1; /* CLK_SEL_SRC1NO == SRC0 */ + writel(reg_clksel, A11S_CLK_SEL_ADDR); + } + + /* + * If the new clock divider is lower than the previous, then + * program the divider after switching the clock + */ + if (hunt_s->ahbclk_div < clk_div) { + reg_clksel = readl(A11S_CLK_SEL_ADDR); + reg_clksel &= ~(0x3 << 1); + reg_clksel |= (hunt_s->ahbclk_div << 1); + writel(reg_clksel, A11S_CLK_SEL_ADDR); + } +} + +int acpuclk_set_rate(unsigned long rate, int for_power_collapse) +{ + uint32_t reg_clkctl; + struct clkctl_acpu_speed *cur_s, *tgt_s, *strt_s; + int rc = 0; + unsigned int plls_enabled = 0, pll; + + strt_s = cur_s = drv_state.current_speed; + + WARN_ONCE(cur_s == NULL, "acpuclk_set_rate: not initialized\n"); + if (cur_s == NULL) + return -ENOENT; + + if (rate == (cur_s->a11clk_khz * 1000)) + return 0; + + for (tgt_s = acpu_freq_tbl; tgt_s->a11clk_khz != 0; tgt_s++) { + if (tgt_s->a11clk_khz == (rate / 1000)) + break; + } + + if (tgt_s->a11clk_khz == 0) + return -EINVAL; + + /* Choose the highest speed speed at or below 'rate' with same PLL. */ + if (for_power_collapse && tgt_s->a11clk_khz < cur_s->a11clk_khz) { + while (tgt_s->pll != ACPU_PLL_TCXO && tgt_s->pll != cur_s->pll) + tgt_s--; + } + + if (strt_s->pll != ACPU_PLL_TCXO) + plls_enabled |= 1 << strt_s->pll; + + if (!for_power_collapse) { + mutex_lock(&drv_state.lock); + if (strt_s->pll != tgt_s->pll && tgt_s->pll != ACPU_PLL_TCXO) { + rc = pc_pll_request(tgt_s->pll, 1); + if (rc < 0) { + pr_err("PLL%d enable failed (%d)\n", + tgt_s->pll, rc); + goto out; + } + plls_enabled |= 1 << tgt_s->pll; + } + /* Increase VDD if needed. */ + if (tgt_s->vdd > cur_s->vdd) { + if ((rc = acpuclk_set_vdd_level(tgt_s->vdd)) < 0) { + printk(KERN_ERR "Unable to switch ACPU vdd\n"); + goto out; + } + } + } + + /* Set wait states for CPU inbetween frequency changes */ + reg_clkctl = readl(A11S_CLK_CNTL_ADDR); + reg_clkctl |= (100 << 16); /* set WT_ST_CNT */ + writel(reg_clkctl, A11S_CLK_CNTL_ADDR); + +#if PERF_SWITCH_DEBUG + printk(KERN_INFO "acpuclock: Switching from ACPU rate %u -> %u\n", + strt_s->a11clk_khz * 1000, tgt_s->a11clk_khz * 1000); +#endif + + while (cur_s != tgt_s) { + /* + * Always jump to target freq if within 256mhz, regulardless of + * PLL. If differnece is greater, use the predefinied + * steppings in the table. + */ + int d = abs((int)(cur_s->a11clk_khz - tgt_s->a11clk_khz)); + if (d > drv_state.max_speed_delta_khz) { + /* Step up or down depending on target vs current. */ + int clk_index = tgt_s->a11clk_khz > cur_s->a11clk_khz ? + cur_s->up : cur_s->down; + if (clk_index < 0) { /* This should not happen. */ + printk(KERN_ERR "cur:%u target: %u\n", + cur_s->a11clk_khz, tgt_s->a11clk_khz); + rc = -EINVAL; + goto out; + } + cur_s = &acpu_freq_tbl[clk_index]; + } else { + cur_s = tgt_s; + } +#if PERF_SWITCH_STEP_DEBUG + printk(KERN_DEBUG "%s: STEP khz = %u, pll = %d\n", + __FUNCTION__, cur_s->a11clk_khz, cur_s->pll); +#endif + if (!for_power_collapse&& cur_s->pll != ACPU_PLL_TCXO + && !(plls_enabled & (1 << cur_s->pll))) { + rc = pc_pll_request(cur_s->pll, 1); + if (rc < 0) { + pr_err("PLL%d enable failed (%d)\n", + cur_s->pll, rc); + goto out; + } + plls_enabled |= 1 << cur_s->pll; + } + + acpuclk_set_div(cur_s); + drv_state.current_speed = cur_s; + /* Re-adjust lpj for the new clock speed. */ + loops_per_jiffy = cur_s->lpj; + udelay(drv_state.acpu_switch_time_us); + } + + /* Nothing else to do for power collapse. */ + if (for_power_collapse) + return 0; + + /* Disable PLLs we are not using anymore. */ + plls_enabled &= ~(1 << tgt_s->pll); + for (pll = ACPU_PLL_0; pll <= ACPU_PLL_2; pll++) + if (plls_enabled & (1 << pll)) { + rc = pc_pll_request(pll, 0); + if (rc < 0) { + pr_err("PLL%d disable failed (%d)\n", pll, rc); + goto out; + } + } + + /* Change the AXI bus frequency if we can. */ + if (strt_s->axiclk_khz != tgt_s->axiclk_khz) { + rc = clk_set_rate(ebi1_clk, tgt_s->axiclk_khz * 1000); + if (rc < 0) + pr_err("Setting AXI min rate failed!\n"); + } + + /* Drop VDD level if we can. */ + if (tgt_s->vdd < strt_s->vdd) { + if (acpuclk_set_vdd_level(tgt_s->vdd) < 0) + printk(KERN_ERR "acpuclock: Unable to drop ACPU vdd\n"); + } + +#if PERF_SWITCH_DEBUG + printk(KERN_DEBUG "%s: ACPU speed change complete\n", __FUNCTION__); +#endif +out: + if (!for_power_collapse) + mutex_unlock(&drv_state.lock); + return rc; +} + +static void __init acpuclk_init(void) +{ + struct clkctl_acpu_speed *speed; + uint32_t div, sel; + int rc; + + /* + * Determine the rate of ACPU clock + */ + + if (!(readl(A11S_CLK_SEL_ADDR) & 0x01)) { /* CLK_SEL_SRC1N0 */ + /* CLK_SRC0_SEL */ + sel = (readl(A11S_CLK_CNTL_ADDR) >> 12) & 0x7; + /* CLK_SRC0_DIV */ + div = (readl(A11S_CLK_CNTL_ADDR) >> 8) & 0x0f; + } else { + /* CLK_SRC1_SEL */ + sel = (readl(A11S_CLK_CNTL_ADDR) >> 4) & 0x07; + /* CLK_SRC1_DIV */ + div = readl(A11S_CLK_CNTL_ADDR) & 0x0f; + } + + for (speed = acpu_freq_tbl; speed->a11clk_khz != 0; speed++) { + if (speed->a11clk_src_sel == sel + && (speed->a11clk_src_div == div)) + break; + } + if (speed->a11clk_khz == 0) { + printk(KERN_WARNING "Warning - ACPU clock reports invalid speed\n"); + return; + } + + drv_state.current_speed = speed; + + rc = clk_set_rate(ebi1_clk, speed->axiclk_khz * 1000); + if (rc < 0) + pr_err("Setting AXI min rate failed!\n"); + + printk(KERN_INFO "ACPU running at %d KHz\n", speed->a11clk_khz); +} + +unsigned long acpuclk_get_rate(void) +{ + WARN_ONCE(drv_state.current_speed == NULL, + "acpuclk_get_rate: not initialized\n"); + if (drv_state.current_speed) + return drv_state.current_speed->a11clk_khz; + else + return 0; +} + +uint32_t acpuclk_get_switch_time(void) +{ + return drv_state.acpu_switch_time_us; +} + +/*---------------------------------------------------------------------------- + * Clock driver initialization + *---------------------------------------------------------------------------*/ + +/* Initalize the lpj field in the acpu_freq_tbl. */ +static void __init lpj_init(void) +{ + int i; + const struct clkctl_acpu_speed *base_clk = drv_state.current_speed; + for (i = 0; acpu_freq_tbl[i].a11clk_khz; i++) { + acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy, + base_clk->a11clk_khz, + acpu_freq_tbl[i].a11clk_khz); + } +} + +void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata) +{ + pr_info("acpu_clock_init()\n"); + + ebi1_clk = clk_get(NULL, "ebi1_clk"); + + mutex_init(&drv_state.lock); + drv_state.acpu_switch_time_us = clkdata->acpu_switch_time_us; + drv_state.max_speed_delta_khz = clkdata->max_speed_delta_khz; + drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us; + drv_state.power_collapse_khz = clkdata->power_collapse_khz; + drv_state.wait_for_irq_khz = clkdata->wait_for_irq_khz; + acpuclk_init(); + lpj_init(); +#ifdef CONFIG_CPU_FREQ_TABLE + cpufreq_frequency_table_get_attr(freq_table, smp_processor_id()); +#endif +} diff --git a/arch/arm/mach-msm/acpuclock.h b/arch/arm/mach-msm/acpuclock.h new file mode 100644 index 000000000000..415de2eb9a5e --- /dev/null +++ b/arch/arm/mach-msm/acpuclock.h @@ -0,0 +1,32 @@ +/* arch/arm/mach-msm/acpuclock.h + * + * MSM architecture clock driver header + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007 QUALCOMM Incorporated + * Author: San Mehat + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef __ARCH_ARM_MACH_MSM_ACPUCLOCK_H +#define __ARCH_ARM_MACH_MSM_ACPUCLOCK_H + +int acpuclk_set_rate(unsigned long rate, int for_power_collapse); +unsigned long acpuclk_get_rate(void); +uint32_t acpuclk_get_switch_time(void); +unsigned long acpuclk_wait_for_irq(void); +unsigned long acpuclk_power_collapse(void); +unsigned long acpuclk_get_wfi_rate(void); + + +#endif + diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h index 264d62e519f3..fb12fd87bb81 100644 --- a/arch/arm/mach-msm/include/mach/board.h +++ b/arch/arm/mach-msm/include/mach/board.h @@ -27,6 +27,16 @@ struct msm_mddi_platform_data unsigned has_vsync_irq:1; }; +struct msm_acpu_clock_platform_data +{ + uint32_t acpu_switch_time_us; + uint32_t max_speed_delta_khz; + uint32_t vdd_switch_time_us; + unsigned long power_collapse_khz; + unsigned long wait_for_irq_khz; +}; + + /* common init routines for use by arch/arm/mach-msm/board-*.c */ void __init msm_add_devices(void); @@ -34,5 +44,6 @@ void __init msm_map_common_io(void); void __init msm_init_irq(void); void __init msm_init_gpio(void); void __init msm_clock_init(void); +void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *); #endif -- cgit v1.2.3-59-g8ed1b From 2012e49e8ad4ae432cf1667e945b0f335c3e6d38 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 3 Mar 2010 09:34:27 -0800 Subject: arm: msm: move board-dream.c to board-trout.c Move the naming of this board file back to the original Google naming. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/Makefile | 2 +- arch/arm/mach-msm/board-dream.c | 93 ----------------------------------------- arch/arm/mach-msm/board-dream.h | 5 --- arch/arm/mach-msm/board-trout.c | 93 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-msm/board-trout.h | 5 +++ 5 files changed, 99 insertions(+), 99 deletions(-) delete mode 100644 arch/arm/mach-msm/board-dream.c delete mode 100644 arch/arm/mach-msm/board-dream.h create mode 100644 arch/arm/mach-msm/board-trout.c create mode 100644 arch/arm/mach-msm/board-trout.h (limited to 'arch') diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 0cb523fe3b3e..86bad4f0dc7b 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -7,4 +7,4 @@ obj-y += clock.o clock-7x01a.o obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o -obj-$(CONFIG_MACH_TROUT) += board-dream.o +obj-$(CONFIG_MACH_TROUT) += board-trout.o diff --git a/arch/arm/mach-msm/board-dream.c b/arch/arm/mach-msm/board-dream.c deleted file mode 100644 index 21afa8513168..000000000000 --- a/arch/arm/mach-msm/board-dream.c +++ /dev/null @@ -1,93 +0,0 @@ -/* linux/arch/arm/mach-msm/board-dream.c - * - * Copyright (C) 2009 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "devices.h" -#include "board-dream.h" - -static struct platform_device *devices[] __initdata = { - &msm_device_uart3, - &msm_device_smd, - &msm_device_nand, - &msm_device_hsusb, - &msm_device_i2c, -}; - -extern struct sys_timer msm_timer; - -static void __init trout_init_irq(void) -{ - msm_init_irq(); -} - -static void __init trout_fixup(struct machine_desc *desc, struct tag *tags, - char **cmdline, struct meminfo *mi) -{ - mi->nr_banks = 1; - mi->bank[0].start = PHYS_OFFSET; - mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); - mi->bank[0].size = (101*1024*1024); -} - -static void __init trout_init(void) -{ - platform_add_devices(devices, ARRAY_SIZE(devices)); -} - -static struct map_desc trout_io_desc[] __initdata = { - { - .virtual = TROUT_CPLD_BASE, - .pfn = __phys_to_pfn(TROUT_CPLD_START), - .length = TROUT_CPLD_SIZE, - .type = MT_DEVICE_NONSHARED - } -}; - -static void __init trout_map_io(void) -{ - msm_map_common_io(); - iotable_init(trout_io_desc, ARRAY_SIZE(trout_io_desc)); - -#ifdef CONFIG_MSM_DEBUG_UART3 - /* route UART3 to the "H2W" extended usb connector */ - writeb(0x80, TROUT_CPLD_BASE + 0x00); -#endif - - msm_clock_init(); -} - -MACHINE_START(TROUT, "HTC Dream") - .phys_io = MSM_DEBUG_UART_PHYS, - .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, - .boot_params = 0x10000100, - .fixup = trout_fixup, - .map_io = trout_map_io, - .init_irq = trout_init_irq, - .init_machine = trout_init, - .timer = &msm_timer, -MACHINE_END diff --git a/arch/arm/mach-msm/board-dream.h b/arch/arm/mach-msm/board-dream.h deleted file mode 100644 index 4f345a5a0a61..000000000000 --- a/arch/arm/mach-msm/board-dream.h +++ /dev/null @@ -1,5 +0,0 @@ - -#define TROUT_CPLD_BASE 0xE8100000 -#define TROUT_CPLD_START 0x98000000 -#define TROUT_CPLD_SIZE SZ_4K - diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c new file mode 100644 index 000000000000..9793ff45deb4 --- /dev/null +++ b/arch/arm/mach-msm/board-trout.c @@ -0,0 +1,93 @@ +/* linux/arch/arm/mach-msm/board-trout.c + * + * Copyright (C) 2009 Google, Inc. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "devices.h" +#include "board-trout.h" + +static struct platform_device *devices[] __initdata = { + &msm_device_uart3, + &msm_device_smd, + &msm_device_nand, + &msm_device_hsusb, + &msm_device_i2c, +}; + +extern struct sys_timer msm_timer; + +static void __init trout_init_irq(void) +{ + msm_init_irq(); +} + +static void __init trout_fixup(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + mi->nr_banks = 1; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); + mi->bank[0].size = (101*1024*1024); +} + +static void __init trout_init(void) +{ + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static struct map_desc trout_io_desc[] __initdata = { + { + .virtual = TROUT_CPLD_BASE, + .pfn = __phys_to_pfn(TROUT_CPLD_START), + .length = TROUT_CPLD_SIZE, + .type = MT_DEVICE_NONSHARED + } +}; + +static void __init trout_map_io(void) +{ + msm_map_common_io(); + iotable_init(trout_io_desc, ARRAY_SIZE(trout_io_desc)); + +#ifdef CONFIG_MSM_DEBUG_UART3 + /* route UART3 to the "H2W" extended usb connector */ + writeb(0x80, TROUT_CPLD_BASE + 0x00); +#endif + + msm_clock_init(); +} + +MACHINE_START(TROUT, "HTC Dream") + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .fixup = trout_fixup, + .map_io = trout_map_io, + .init_irq = trout_init_irq, + .init_machine = trout_init, + .timer = &msm_timer, +MACHINE_END diff --git a/arch/arm/mach-msm/board-trout.h b/arch/arm/mach-msm/board-trout.h new file mode 100644 index 000000000000..4f345a5a0a61 --- /dev/null +++ b/arch/arm/mach-msm/board-trout.h @@ -0,0 +1,5 @@ + +#define TROUT_CPLD_BASE 0xE8100000 +#define TROUT_CPLD_START 0x98000000 +#define TROUT_CPLD_SIZE SZ_4K + -- cgit v1.2.3-59-g8ed1b From 0c50b444b69f49e38d16b974993a626ad74c59a7 Mon Sep 17 00:00:00 2001 From: Steve Muckle Date: Thu, 4 Mar 2010 12:38:05 -0800 Subject: arm: msm: return error pointer in vreg_get if vreg not found Signed-off-by: Steve Muckle --- arch/arm/mach-msm/vreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c index fcb0b9f25684..a839e1913c5b 100644 --- a/arch/arm/mach-msm/vreg.c +++ b/arch/arm/mach-msm/vreg.c @@ -70,7 +70,7 @@ struct vreg *vreg_get(struct device *dev, const char *id) if (!strcmp(vregs[n].name, id)) return vregs + n; } - return 0; + return ERR_PTR(-ENOENT); } void vreg_put(struct vreg *vreg) -- cgit v1.2.3-59-g8ed1b From 4783de9bba3dd607e6aa4d0a7dd598d9094c044c Mon Sep 17 00:00:00 2001 From: Steve Muckle Date: Fri, 12 Dec 2008 19:33:55 -0500 Subject: arm: msm: status for vreg Keep track of the success/failure of the last vreg proc comm command, and return that on debugfs reads. Signed-off-by: Steve Muckle --- arch/arm/mach-msm/include/mach/vreg.h | 2 +- arch/arm/mach-msm/vreg.c | 90 +++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/vreg.h b/arch/arm/mach-msm/include/mach/vreg.h index 9f9e25cb718e..6626e7864e28 100644 --- a/arch/arm/mach-msm/include/mach/vreg.h +++ b/arch/arm/mach-msm/include/mach/vreg.h @@ -23,7 +23,7 @@ struct vreg *vreg_get(struct device *dev, const char *id); void vreg_put(struct vreg *vreg); int vreg_enable(struct vreg *vreg); -void vreg_disable(struct vreg *vreg); +int vreg_disable(struct vreg *vreg); int vreg_set_level(struct vreg *vreg, unsigned mv); #endif diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c index a839e1913c5b..8b0f7b2fd8f7 100644 --- a/arch/arm/mach-msm/vreg.c +++ b/arch/arm/mach-msm/vreg.c @@ -1,6 +1,7 @@ /* arch/arm/mach-msm/vreg.c * * Copyright (C) 2008 Google, Inc. + * Copyright (c) 2009, Code Aurora Forum. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -25,42 +26,44 @@ struct vreg { const char *name; unsigned id; + int status; }; -#define VREG(_name, _id) { .name = _name, .id = _id, } +#define VREG(_name, _id, _status) \ + { .name = _name, .id = _id, .status = _status } static struct vreg vregs[] = { - VREG("msma", 0), - VREG("msmp", 1), - VREG("msme1", 2), - VREG("msmc1", 3), - VREG("msmc2", 4), - VREG("gp3", 5), - VREG("msme2", 6), - VREG("gp4", 7), - VREG("gp1", 8), - VREG("tcxo", 9), - VREG("pa", 10), - VREG("rftx", 11), - VREG("rfrx1", 12), - VREG("rfrx2", 13), - VREG("synt", 14), - VREG("wlan", 15), - VREG("usb", 16), - VREG("boost", 17), - VREG("mmc", 18), - VREG("ruim", 19), - VREG("msmc0", 20), - VREG("gp2", 21), - VREG("gp5", 22), - VREG("gp6", 23), - VREG("rf", 24), - VREG("rf_vco", 26), - VREG("mpll", 27), - VREG("s2", 28), - VREG("s3", 29), - VREG("rfubm", 30), - VREG("ncp", 31), + VREG("msma", 0, 0), + VREG("msmp", 1, 0), + VREG("msme1", 2, 0), + VREG("msmc1", 3, 0), + VREG("msmc2", 4, 0), + VREG("gp3", 5, 0), + VREG("msme2", 6, 0), + VREG("gp4", 7, 0), + VREG("gp1", 8, 0), + VREG("tcxo", 9, 0), + VREG("pa", 10, 0), + VREG("rftx", 11, 0), + VREG("rfrx1", 12, 0), + VREG("rfrx2", 13, 0), + VREG("synt", 14, 0), + VREG("wlan", 15, 0), + VREG("usb", 16, 0), + VREG("boost", 17, 0), + VREG("mmc", 18, 0), + VREG("ruim", 19, 0), + VREG("msmc0", 20, 0), + VREG("gp2", 21, 0), + VREG("gp5", 22, 0), + VREG("gp6", 23, 0), + VREG("rf", 24, 0), + VREG("rf_vco", 26, 0), + VREG("mpll", 27, 0), + VREG("s2", 28, 0), + VREG("s3", 29, 0), + VREG("rfubm", 30, 0), + VREG("ncp", 31, 0), }; struct vreg *vreg_get(struct device *dev, const char *id) @@ -81,20 +84,26 @@ int vreg_enable(struct vreg *vreg) { unsigned id = vreg->id; unsigned enable = 1; - return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); + + vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); + return vreg->status; } -void vreg_disable(struct vreg *vreg) +int vreg_disable(struct vreg *vreg) { unsigned id = vreg->id; unsigned enable = 0; - msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); + + vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); + return vreg->status; } int vreg_set_level(struct vreg *vreg, unsigned mv) { unsigned id = vreg->id; - return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv); + + vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv); + return vreg->status; } #if defined(CONFIG_DEBUG_FS) @@ -118,7 +127,14 @@ static int vreg_debug_set(void *data, u64 val) static int vreg_debug_get(void *data, u64 *val) { - return -ENOSYS; + struct vreg *vreg = data; + + if (!vreg->status) + *val = 0; + else + *val = 1; + + return 0; } DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n"); -- cgit v1.2.3-59-g8ed1b From 4eab62519f8f58aa5f72787877c459925399d617 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 4 Mar 2010 14:06:56 -0800 Subject: arm: msm: warning fix in acpuclock.c Fixes the following warning, arch/arm/mach-msm/acpuclock-arm11.c:138: warning: 'freq_table' defined but not used when CONFIG_CPU_FREQ_TABLE is not enabled. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/acpuclock-arm11.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c index f9c9035bd9bb..af5e85b91d02 100644 --- a/arch/arm/mach-msm/acpuclock-arm11.c +++ b/arch/arm/mach-msm/acpuclock-arm11.c @@ -135,6 +135,8 @@ static struct clkctl_acpu_speed acpu_freq_tbl[] = { }; #endif + +#ifdef CONFIG_CPU_FREQ_TABLE static struct cpufreq_frequency_table freq_table[] = { { 0, 122880 }, { 1, 128000 }, @@ -143,6 +145,7 @@ static struct cpufreq_frequency_table freq_table[] = { { 4, 528000 }, { 5, CPUFREQ_TABLE_END }, }; +#endif static int pc_pll_request(unsigned id, unsigned on) { -- cgit v1.2.3-59-g8ed1b From 0e44106de5adffc32e0a9294ed406f20d9a3f38d Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 29 Jun 2009 14:13:04 -0500 Subject: arm: msm: add vreg reference count Support independent enable and disable by clients for common vreg. First enable switches on and last disable switches off. This change has no check for voltage level so clients must agree on level for common vreg. Signed-off-by: Matthew Wilson --- arch/arm/mach-msm/vreg.c | 115 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c index 8b0f7b2fd8f7..63db0b3ece53 100644 --- a/arch/arm/mach-msm/vreg.c +++ b/arch/arm/mach-msm/vreg.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "proc_comm.h" @@ -27,43 +28,44 @@ struct vreg { const char *name; unsigned id; int status; + unsigned refcnt; }; -#define VREG(_name, _id, _status) \ - { .name = _name, .id = _id, .status = _status } +#define VREG(_name, _id, _status, _refcnt) \ + { .name = _name, .id = _id, .status = _status, .refcnt = _refcnt } static struct vreg vregs[] = { - VREG("msma", 0, 0), - VREG("msmp", 1, 0), - VREG("msme1", 2, 0), - VREG("msmc1", 3, 0), - VREG("msmc2", 4, 0), - VREG("gp3", 5, 0), - VREG("msme2", 6, 0), - VREG("gp4", 7, 0), - VREG("gp1", 8, 0), - VREG("tcxo", 9, 0), - VREG("pa", 10, 0), - VREG("rftx", 11, 0), - VREG("rfrx1", 12, 0), - VREG("rfrx2", 13, 0), - VREG("synt", 14, 0), - VREG("wlan", 15, 0), - VREG("usb", 16, 0), - VREG("boost", 17, 0), - VREG("mmc", 18, 0), - VREG("ruim", 19, 0), - VREG("msmc0", 20, 0), - VREG("gp2", 21, 0), - VREG("gp5", 22, 0), - VREG("gp6", 23, 0), - VREG("rf", 24, 0), - VREG("rf_vco", 26, 0), - VREG("mpll", 27, 0), - VREG("s2", 28, 0), - VREG("s3", 29, 0), - VREG("rfubm", 30, 0), - VREG("ncp", 31, 0), + VREG("msma", 0, 0, 0), + VREG("msmp", 1, 0, 0), + VREG("msme1", 2, 0, 0), + VREG("msmc1", 3, 0, 0), + VREG("msmc2", 4, 0, 0), + VREG("gp3", 5, 0, 0), + VREG("msme2", 6, 0, 0), + VREG("gp4", 7, 0, 0), + VREG("gp1", 8, 0, 0), + VREG("tcxo", 9, 0, 0), + VREG("pa", 10, 0, 0), + VREG("rftx", 11, 0, 0), + VREG("rfrx1", 12, 0, 0), + VREG("rfrx2", 13, 0, 0), + VREG("synt", 14, 0, 0), + VREG("wlan", 15, 0, 0), + VREG("usb", 16, 0, 0), + VREG("boost", 17, 0, 0), + VREG("mmc", 18, 0, 0), + VREG("ruim", 19, 0, 0), + VREG("msmc0", 20, 0, 0), + VREG("gp2", 21, 0, 0), + VREG("gp5", 22, 0, 0), + VREG("gp6", 23, 0, 0), + VREG("rf", 24, 0, 0), + VREG("rf_vco", 26, 0, 0), + VREG("mpll", 27, 0, 0), + VREG("s2", 28, 0, 0), + VREG("s3", 29, 0, 0), + VREG("rfubm", 30, 0, 0), + VREG("ncp", 31, 0, 0), }; struct vreg *vreg_get(struct device *dev, const char *id) @@ -85,7 +87,12 @@ int vreg_enable(struct vreg *vreg) unsigned id = vreg->id; unsigned enable = 1; - vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); + if (vreg->refcnt == 0) + vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); + + if ((vreg->refcnt < UINT_MAX) && (!vreg->status)) + vreg->refcnt++; + return vreg->status; } @@ -94,7 +101,15 @@ int vreg_disable(struct vreg *vreg) unsigned id = vreg->id; unsigned enable = 0; - vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); + if (!vreg->refcnt) + return 0; + + if (vreg->refcnt == 1) + vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); + + if (!vreg->status) + vreg->refcnt--; + return vreg->status; } @@ -137,21 +152,49 @@ static int vreg_debug_get(void *data, u64 *val) return 0; } +static int vreg_debug_count_set(void *data, u64 val) +{ + struct vreg *vreg = data; + if (val > UINT_MAX) + val = UINT_MAX; + vreg->refcnt = val; + return 0; +} + +static int vreg_debug_count_get(void *data, u64 *val) +{ + struct vreg *vreg = data; + + *val = vreg->refcnt; + + return 0; +} + DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n"); +DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get, + vreg_debug_count_set, "%llu\n"); static int __init vreg_debug_init(void) { struct dentry *dent; int n; + char name[32]; + const char *refcnt_name = "_refcnt"; dent = debugfs_create_dir("vreg", 0); if (IS_ERR(dent)) return 0; - for (n = 0; n < ARRAY_SIZE(vregs); n++) + for (n = 0; n < ARRAY_SIZE(vregs); n++) { (void) debugfs_create_file(vregs[n].name, 0644, dent, vregs + n, &vreg_fops); + strlcpy(name, vregs[n].name, sizeof(name)); + strlcat(name, refcnt_name, sizeof(name)); + (void) debugfs_create_file(name, 0644, + dent, vregs + n, &vreg_count_fops); + } + return 0; } -- cgit v1.2.3-59-g8ed1b From 1b70de32ac695b2faac93225aaee71a8df06c155 Mon Sep 17 00:00:00 2001 From: Willie Ruan Date: Fri, 24 Jul 2009 17:21:21 -0700 Subject: [ARM] msm: add new vreg IDs for MSM7X30 Signed-off-by: Willie Ruan --- arch/arm/mach-msm/vreg.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c index 63db0b3ece53..a9103bc6615f 100644 --- a/arch/arm/mach-msm/vreg.c +++ b/arch/arm/mach-msm/vreg.c @@ -66,6 +66,23 @@ static struct vreg vregs[] = { VREG("s3", 29, 0, 0), VREG("rfubm", 30, 0, 0), VREG("ncp", 31, 0, 0), + VREG("gp7", 32, 0, 0), + VREG("gp8", 33, 0, 0), + VREG("gp9", 34, 0, 0), + VREG("gp10", 35, 0, 0), + VREG("gp11", 36, 0, 0), + VREG("gp12", 37, 0, 0), + VREG("gp13", 38, 0, 0), + VREG("gp14", 39, 0, 0), + VREG("gp15", 40, 0, 0), + VREG("gp16", 41, 0, 0), + VREG("gp17", 42, 0, 0), + VREG("s4", 43, 0, 0), + VREG("usb2", 44, 0, 0), + VREG("wlan2", 45, 0, 0), + VREG("xo_out", 46, 0, 0), + VREG("lvsw0", 47, 0, 0), + VREG("lvsw1", 48, 0, 0), }; struct vreg *vreg_get(struct device *dev, const char *id) -- cgit v1.2.3-59-g8ed1b From 1b802ff79f03356ebe38d8fbfeb7c13fc2f4f524 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 4 Mar 2010 15:13:47 -0800 Subject: arm: msm: add board file for Nexus One (ie. mahimahi) This adds a basic board file without Kconfig changes. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/board-mahimahi.c | 87 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 arch/arm/mach-msm/board-mahimahi.c (limited to 'arch') diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c new file mode 100644 index 000000000000..bcbefdfe7b5e --- /dev/null +++ b/arch/arm/mach-msm/board-mahimahi.c @@ -0,0 +1,87 @@ +/* linux/arch/arm/mach-msm/board-mahimahi.c + * + * Copyright (C) 2009 Google, Inc. + * Copyright (C) 2009 HTC Corporation. + * Author: Dima Zavin + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "board-mahimahi.h" +#include "devices.h" +#include "proc_comm.h" + +static uint debug_uart; + +module_param_named(debug_uart, debug_uart, uint, 0); + +static struct platform_device *devices[] __initdata = { +#if !defined(CONFIG_MSM_SERIAL_DEBUGGER) + &msm_device_uart1, +#endif + &msm_device_uart_dm1, + &msm_device_nand, +}; + +static void __init mahimahi_init(void) +{ + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static void __init mahimahi_fixup(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + mi->nr_banks = 2; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); + mi->bank[0].size = (219*1024*1024); + mi->bank[1].start = MSM_HIGHMEM_BASE; + mi->bank[1].node = PHYS_TO_NID(MSM_HIGHMEM_BASE); + mi->bank[1].size = MSM_HIGHMEM_SIZE; +} + +static void __init mahimahi_map_io(void) +{ + msm_map_common_io(); + msm_clock_init(); +} + +extern struct sys_timer msm_timer; + +MACHINE_START(MAHIMAHI, "mahimahi") +#ifdef CONFIG_MSM_DEBUG_UART + .phys_io = MSM_DEBUG_UART_PHYS, + .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif + .boot_params = 0x20000100, + .fixup = mahimahi_fixup, + .map_io = mahimahi_map_io, + .init_irq = msm_init_irq, + .init_machine = mahimahi_init, + .timer = &msm_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From 5d4f77ffefdcfbe9432db371126b74478964b4a0 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Mon, 10 Nov 2008 16:30:27 -0800 Subject: [ARM] msm: common: Add SDC device runtime registration Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- arch/arm/mach-msm/devices.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/devices.c b/arch/arm/mach-msm/devices.c index 31b6b30e98bf..39bc474455c3 100644 --- a/arch/arm/mach-msm/devices.c +++ b/arch/arm/mach-msm/devices.c @@ -24,6 +24,8 @@ #include #include +#include + static struct resource resources_uart1[] = { { .start = INT_UART1, @@ -266,3 +268,23 @@ struct platform_device msm_device_sdc4 = { .coherent_dma_mask = 0xffffffff, }, }; + +static struct platform_device *msm_sdcc_devices[] __initdata = { + &msm_device_sdc1, + &msm_device_sdc2, + &msm_device_sdc3, + &msm_device_sdc4, +}; + +int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat) +{ + struct platform_device *pdev; + + if (controller < 1 || controller > 4) + return -EINVAL; + + pdev = msm_sdcc_devices[controller-1]; + pdev->dev.platform_data = plat; + return platform_device_register(pdev); +} + -- cgit v1.2.3-59-g8ed1b From 830d843b75338b94b7c769a2c3b59b04744a9323 Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Fri, 22 May 2009 20:21:50 -0700 Subject: [ARM] msm: sdcc: Make slot status irq be a resource Also, convert all SDCC IRQ resources to be named. No longer pass status_irq in the platform_data Signed-off-by: Dima Zavin Signed-off-by: Daniel Walker --- arch/arm/mach-msm/devices.c | 58 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/devices.c b/arch/arm/mach-msm/devices.c index 39bc474455c3..982f1da60160 100644 --- a/arch/arm/mach-msm/devices.c +++ b/arch/arm/mach-msm/devices.c @@ -165,8 +165,19 @@ static struct resource resources_sdc1[] = { }, { .start = INT_SDC1_0, + .end = INT_SDC1_0, + .flags = IORESOURCE_IRQ, + .name = "cmd_irq", + }, + { + .start = INT_SDC1_1, .end = INT_SDC1_1, .flags = IORESOURCE_IRQ, + .name = "pio_irq", + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, + .name = "status_irq" }, { .start = 8, @@ -183,8 +194,19 @@ static struct resource resources_sdc2[] = { }, { .start = INT_SDC2_0, + .end = INT_SDC2_0, + .flags = IORESOURCE_IRQ, + .name = "cmd_irq", + }, + { + .start = INT_SDC2_1, .end = INT_SDC2_1, .flags = IORESOURCE_IRQ, + .name = "pio_irq", + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, + .name = "status_irq" }, { .start = 8, @@ -201,8 +223,19 @@ static struct resource resources_sdc3[] = { }, { .start = INT_SDC3_0, + .end = INT_SDC3_0, + .flags = IORESOURCE_IRQ, + .name = "cmd_irq", + }, + { + .start = INT_SDC3_1, .end = INT_SDC3_1, .flags = IORESOURCE_IRQ, + .name = "pio_irq", + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, + .name = "status_irq" }, { .start = 8, @@ -219,8 +252,19 @@ static struct resource resources_sdc4[] = { }, { .start = INT_SDC4_0, + .end = INT_SDC4_0, + .flags = IORESOURCE_IRQ, + .name = "cmd_irq", + }, + { + .start = INT_SDC4_1, .end = INT_SDC4_1, .flags = IORESOURCE_IRQ, + .name = "pio_irq", + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, + .name = "status_irq" }, { .start = 8, @@ -276,15 +320,27 @@ static struct platform_device *msm_sdcc_devices[] __initdata = { &msm_device_sdc4, }; -int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat) +int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat, + unsigned int stat_irq, unsigned long stat_irq_flags) { struct platform_device *pdev; + struct resource *res; if (controller < 1 || controller > 4) return -EINVAL; pdev = msm_sdcc_devices[controller-1]; pdev->dev.platform_data = plat; + + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq"); + if (!res) + return -EINVAL; + else if (stat_irq) { + res->start = res->end = stat_irq; + res->flags &= ~IORESOURCE_DISABLED; + res->flags |= stat_irq_flags; + } + return platform_device_register(pdev); } -- cgit v1.2.3-59-g8ed1b From 2eb44eb9c8026f3f548bfbc903156b6aea54ed24 Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Mon, 29 Sep 2008 16:00:48 -0700 Subject: [ARM] msm: shared memory interface for baseband processor ipc This code provides the low level interface to the "shared memory state machine" (smsm), and the virtual serial channels (smd), used to communicate with the baseband processor. Higher level transports (rpc, ethernet, AT command channel, etc) ride on top of this. Signed-off-by: Brian Swetland --- arch/arm/mach-msm/Kconfig | 10 + arch/arm/mach-msm/Makefile | 3 +- arch/arm/mach-msm/include/mach/msm_smd.h | 107 +++ arch/arm/mach-msm/include/mach/system.h | 5 + arch/arm/mach-msm/smd.c | 1330 ++++++++++++++++++++++++++++++ arch/arm/mach-msm/smd_private.h | 171 ++++ 6 files changed, 1625 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-msm/include/mach/msm_smd.h create mode 100644 arch/arm/mach-msm/smd.c create mode 100644 arch/arm/mach-msm/smd_private.h (limited to 'arch') diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index b9fd5c528e5b..7cee7913f6f7 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -42,4 +42,14 @@ config MACH_TROUT help Support for the HTC Dream, T-Mobile G1, Android ADP1 devices. +config MSM_SMD + default y + bool "MSM Shared Memory Driver (SMD)" + help + Support for the shared memory interface between the apps + processor and the baseband processor. Provides access to + the "shared heap", as well as virtual serial channels + used to communicate with various services on the baseband + processor. + endif diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 86bad4f0dc7b..d23fd0bf9fcc 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -5,6 +5,7 @@ obj-y += vreg.o obj-y += acpuclock-arm11.o obj-y += clock.o clock-7x01a.o -obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o +obj-$(CONFIG_MSM_SMD) += smd.o obj-$(CONFIG_MACH_TROUT) += board-trout.o +obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h new file mode 100644 index 000000000000..bdf7731ab680 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_smd.h @@ -0,0 +1,107 @@ +/* linux/include/asm-arm/arch-msm/msm_smd.h + * + * Copyright (C) 2007 Google, Inc. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef __ASM_ARCH_MSM_SMD_H +#define __ASM_ARCH_MSM_SMD_H + +typedef struct smd_channel smd_channel_t; + +/* warning: notify() may be called before open returns */ +int smd_open(const char *name, smd_channel_t **ch, void *priv, + void (*notify)(void *priv, unsigned event)); + +#define SMD_EVENT_DATA 1 +#define SMD_EVENT_OPEN 2 +#define SMD_EVENT_CLOSE 3 + +int smd_close(smd_channel_t *ch); + +/* passing a null pointer for data reads and discards */ +int smd_read(smd_channel_t *ch, void *data, int len); + +/* Write to stream channels may do a partial write and return +** the length actually written. +** Write to packet channels will never do a partial write -- +** it will return the requested length written or an error. +*/ +int smd_write(smd_channel_t *ch, const void *data, int len); + +int smd_write_avail(smd_channel_t *ch); +int smd_read_avail(smd_channel_t *ch); + +/* Returns the total size of the current packet being read. +** Returns 0 if no packets available or a stream channel. +*/ +int smd_cur_packet_size(smd_channel_t *ch); + +/* used for tty unthrottling and the like -- causes the notify() +** callback to be called from the same lock context as is used +** when it is called from channel updates +*/ +void smd_kick(smd_channel_t *ch); + + +#if 0 +/* these are interruptable waits which will block you until the specified +** number of bytes are readable or writable. +*/ +int smd_wait_until_readable(smd_channel_t *ch, int bytes); +int smd_wait_until_writable(smd_channel_t *ch, int bytes); +#endif + +typedef enum +{ + SMD_PORT_DS = 0, + SMD_PORT_DIAG, + SMD_PORT_RPC_CALL, + SMD_PORT_RPC_REPLY, + SMD_PORT_BT, + SMD_PORT_CONTROL, + SMD_PORT_MEMCPY_SPARE1, + SMD_PORT_DATA1, + SMD_PORT_DATA2, + SMD_PORT_DATA3, + SMD_PORT_DATA4, + SMD_PORT_DATA5, + SMD_PORT_DATA6, + SMD_PORT_DATA7, + SMD_PORT_DATA8, + SMD_PORT_DATA9, + SMD_PORT_DATA10, + SMD_PORT_DATA11, + SMD_PORT_DATA12, + SMD_PORT_DATA13, + SMD_PORT_DATA14, + SMD_PORT_DATA15, + SMD_PORT_DATA16, + SMD_PORT_DATA17, + SMD_PORT_DATA18, + SMD_PORT_DATA19, + SMD_PORT_DATA20, + SMD_PORT_GPS_NMEA, + SMD_PORT_BRIDGE_1, + SMD_PORT_BRIDGE_2, + SMD_PORT_BRIDGE_3, + SMD_PORT_BRIDGE_4, + SMD_PORT_BRIDGE_5, + SMD_PORT_LOOPBACK, + SMD_PORT_CS_APPS_MODEM, + SMD_PORT_CS_APPS_DSP, + SMD_PORT_CS_MODEM_DSP, + SMD_NUM_PORTS, +} smd_port_id_type; + +#endif diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h index 574ccc493daf..d2e83f42ba16 100644 --- a/arch/arm/mach-msm/include/mach/system.h +++ b/arch/arm/mach-msm/include/mach/system.h @@ -21,3 +21,8 @@ static inline void arch_reset(char mode, const char *cmd) { for (;;) ; /* depends on IPC w/ other core */ } + +/* low level hardware reset hook -- for example, hitting the + * PSHOLD line on the PMIC to hard reset the system + */ +extern void (*msm_hw_reset_hook)(void); diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c new file mode 100644 index 000000000000..64d12323995e --- /dev/null +++ b/arch/arm/mach-msm/smd.c @@ -0,0 +1,1330 @@ +/* arch/arm/mach-msm/smd.c + * + * Copyright (C) 2007 Google, Inc. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "smd_private.h" +#include "proc_comm.h" + +void (*msm_hw_reset_hook)(void); + +#define MODULE_NAME "msm_smd" + +enum { + MSM_SMD_DEBUG = 1U << 0, + MSM_SMSM_DEBUG = 1U << 0, +}; + +static int msm_smd_debug_mask; + +module_param_named(debug_mask, msm_smd_debug_mask, + int, S_IRUGO | S_IWUSR | S_IWGRP); + +void *smem_find(unsigned id, unsigned size); +static void smd_diag(void); + +static unsigned last_heap_free = 0xffffffff; + +#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4) + +static inline void notify_other_smsm(void) +{ + writel(1, MSM_A2M_INT(5)); +} + +static inline void notify_other_smd(void) +{ + writel(1, MSM_A2M_INT(0)); +} + +static void smd_diag(void) +{ + char *x; + + x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); + if (x != 0) { + x[SZ_DIAG_ERR_MSG - 1] = 0; + pr_info("smem: DIAG '%s'\n", x); + } +} + +/* call when SMSM_RESET flag is set in the A9's smsm_state */ +static void handle_modem_crash(void) +{ + pr_err("ARM9 has CRASHED\n"); + smd_diag(); + + /* hard reboot if possible */ + if (msm_hw_reset_hook) + msm_hw_reset_hook(); + + /* in this case the modem or watchdog should reboot us */ + for (;;) + ; +} + +extern int (*msm_check_for_modem_crash)(void); + +static int check_for_modem_crash(void) +{ + struct smsm_shared *smsm; + + smsm = smem_find(ID_SHARED_STATE, 2 * sizeof(struct smsm_shared)); + + /* if the modem's not ready yet, we have to hope for the best */ + if (!smsm) + return 0; + + if (smsm[1].state & SMSM_RESET) { + handle_modem_crash(); + return -1; + } else { + return 0; + } +} + +#define SMD_SS_CLOSED 0x00000000 +#define SMD_SS_OPENING 0x00000001 +#define SMD_SS_OPENED 0x00000002 +#define SMD_SS_FLUSHING 0x00000003 +#define SMD_SS_CLOSING 0x00000004 +#define SMD_SS_RESET 0x00000005 +#define SMD_SS_RESET_OPENING 0x00000006 + +#define SMD_BUF_SIZE 8192 +#define SMD_CHANNELS 64 + +#define SMD_HEADER_SIZE 20 + + +/* the spinlock is used to synchronize between the +** irq handler and code that mutates the channel +** list or fiddles with channel state +*/ +static DEFINE_SPINLOCK(smd_lock); +static DEFINE_SPINLOCK(smem_lock); + +/* the mutex is used during open() and close() +** operations to avoid races while creating or +** destroying smd_channel structures +*/ +static DEFINE_MUTEX(smd_creation_mutex); + +static int smd_initialized; + +struct smd_alloc_elm { + char name[20]; + uint32_t cid; + uint32_t ctype; + uint32_t ref_count; +}; + +struct smd_half_channel { + unsigned state; + unsigned char fDSR; + unsigned char fCTS; + unsigned char fCD; + unsigned char fRI; + unsigned char fHEAD; + unsigned char fTAIL; + unsigned char fSTATE; + unsigned char fUNUSED; + unsigned tail; + unsigned head; + unsigned char data[SMD_BUF_SIZE]; +}; + +struct smd_shared { + struct smd_half_channel ch0; + struct smd_half_channel ch1; +}; + +struct smd_channel { + volatile struct smd_half_channel *send; + volatile struct smd_half_channel *recv; + struct list_head ch_list; + + unsigned current_packet; + unsigned n; + void *priv; + void (*notify)(void *priv, unsigned flags); + + int (*read)(smd_channel_t *ch, void *data, int len); + int (*write)(smd_channel_t *ch, const void *data, int len); + int (*read_avail)(smd_channel_t *ch); + int (*write_avail)(smd_channel_t *ch); + + void (*update_state)(smd_channel_t *ch); + unsigned last_state; + + char name[32]; + struct platform_device pdev; +}; + +static LIST_HEAD(smd_ch_closed_list); +static LIST_HEAD(smd_ch_list); + +static unsigned char smd_ch_allocated[64]; +static struct work_struct probe_work; + +static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); + +static void smd_channel_probe_worker(struct work_struct *work) +{ + struct smd_alloc_elm *shared; + unsigned n; + + shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); + + for (n = 0; n < 64; n++) { + if (smd_ch_allocated[n]) + continue; + if (!shared[n].ref_count) + continue; + if (!shared[n].name[0]) + continue; + smd_alloc_channel(shared[n].name, + shared[n].cid, + shared[n].ctype); + smd_ch_allocated[n] = 1; + } +} + +static char *chstate(unsigned n) +{ + switch (n) { + case SMD_SS_CLOSED: + return "CLOSED"; + case SMD_SS_OPENING: + return "OPENING"; + case SMD_SS_OPENED: + return "OPENED"; + case SMD_SS_FLUSHING: + return "FLUSHING"; + case SMD_SS_CLOSING: + return "CLOSING"; + case SMD_SS_RESET: + return "RESET"; + case SMD_SS_RESET_OPENING: + return "ROPENING"; + default: + return "UNKNOWN"; + } +} + +/* how many bytes are available for reading */ +static int smd_stream_read_avail(struct smd_channel *ch) +{ + return (ch->recv->head - ch->recv->tail) & (SMD_BUF_SIZE - 1); +} + +/* how many bytes we are free to write */ +static int smd_stream_write_avail(struct smd_channel *ch) +{ + return (SMD_BUF_SIZE - 1) - + ((ch->send->head - ch->send->tail) & (SMD_BUF_SIZE - 1)); +} + +static int smd_packet_read_avail(struct smd_channel *ch) +{ + if (ch->current_packet) { + int n = smd_stream_read_avail(ch); + if (n > ch->current_packet) + n = ch->current_packet; + return n; + } else { + return 0; + } +} + +static int smd_packet_write_avail(struct smd_channel *ch) +{ + int n = smd_stream_write_avail(ch); + return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0; +} + +static int ch_is_open(struct smd_channel *ch) +{ + return (ch->recv->state == SMD_SS_OPENED) && + (ch->send->state == SMD_SS_OPENED); +} + +/* provide a pointer and length to readable data in the fifo */ +static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr) +{ + unsigned head = ch->recv->head; + unsigned tail = ch->recv->tail; + *ptr = (void *) (ch->recv->data + tail); + + if (tail <= head) + return head - tail; + else + return SMD_BUF_SIZE - tail; +} + +/* advance the fifo read pointer after data from ch_read_buffer is consumed */ +static void ch_read_done(struct smd_channel *ch, unsigned count) +{ + BUG_ON(count > smd_stream_read_avail(ch)); + ch->recv->tail = (ch->recv->tail + count) & (SMD_BUF_SIZE - 1); + ch->recv->fTAIL = 1; +} + +/* basic read interface to ch_read_{buffer,done} used +** by smd_*_read() and update_packet_state() +** will read-and-discard if the _data pointer is null +*/ +static int ch_read(struct smd_channel *ch, void *_data, int len) +{ + void *ptr; + unsigned n; + unsigned char *data = _data; + int orig_len = len; + + while (len > 0) { + n = ch_read_buffer(ch, &ptr); + if (n == 0) + break; + + if (n > len) + n = len; + if (_data) + memcpy(data, ptr, n); + + data += n; + len -= n; + ch_read_done(ch, n); + } + + return orig_len - len; +} + +static void update_stream_state(struct smd_channel *ch) +{ + /* streams have no special state requiring updating */ +} + +static void update_packet_state(struct smd_channel *ch) +{ + unsigned hdr[5]; + int r; + + /* can't do anything if we're in the middle of a packet */ + if (ch->current_packet != 0) + return; + + /* don't bother unless we can get the full header */ + if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE) + return; + + r = ch_read(ch, hdr, SMD_HEADER_SIZE); + BUG_ON(r != SMD_HEADER_SIZE); + + ch->current_packet = hdr[0]; +} + +/* provide a pointer and length to next free space in the fifo */ +static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr) +{ + unsigned head = ch->send->head; + unsigned tail = ch->send->tail; + *ptr = (void *) (ch->send->data + head); + + if (head < tail) { + return tail - head - 1; + } else { + if (tail == 0) + return SMD_BUF_SIZE - head - 1; + else + return SMD_BUF_SIZE - head; + } +} + +/* advace the fifo write pointer after freespace + * from ch_write_buffer is filled + */ +static void ch_write_done(struct smd_channel *ch, unsigned count) +{ + BUG_ON(count > smd_stream_write_avail(ch)); + ch->send->head = (ch->send->head + count) & (SMD_BUF_SIZE - 1); + ch->send->fHEAD = 1; +} + +static void hc_set_state(volatile struct smd_half_channel *hc, unsigned n) +{ + if (n == SMD_SS_OPENED) { + hc->fDSR = 1; + hc->fCTS = 1; + hc->fCD = 1; + } else { + hc->fDSR = 0; + hc->fCTS = 0; + hc->fCD = 0; + } + hc->state = n; + hc->fSTATE = 1; + notify_other_smd(); +} + +static void do_smd_probe(void) +{ + struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; + if (shared->heap_info.free_offset != last_heap_free) { + last_heap_free = shared->heap_info.free_offset; + schedule_work(&probe_work); + } +} + +static void smd_state_change(struct smd_channel *ch, + unsigned last, unsigned next) +{ + ch->last_state = next; + + pr_info("SMD: ch %d %s -> %s\n", ch->n, + chstate(last), chstate(next)); + + switch (next) { + case SMD_SS_OPENING: + ch->recv->tail = 0; + case SMD_SS_OPENED: + if (ch->send->state != SMD_SS_OPENED) + hc_set_state(ch->send, SMD_SS_OPENED); + ch->notify(ch->priv, SMD_EVENT_OPEN); + break; + case SMD_SS_FLUSHING: + case SMD_SS_RESET: + /* we should force them to close? */ + default: + ch->notify(ch->priv, SMD_EVENT_CLOSE); + } +} + +static irqreturn_t smd_irq_handler(int irq, void *data) +{ + unsigned long flags; + struct smd_channel *ch; + int do_notify = 0; + unsigned ch_flags; + unsigned tmp; + + spin_lock_irqsave(&smd_lock, flags); + list_for_each_entry(ch, &smd_ch_list, ch_list) { + ch_flags = 0; + if (ch_is_open(ch)) { + if (ch->recv->fHEAD) { + ch->recv->fHEAD = 0; + ch_flags |= 1; + do_notify |= 1; + } + if (ch->recv->fTAIL) { + ch->recv->fTAIL = 0; + ch_flags |= 2; + do_notify |= 1; + } + if (ch->recv->fSTATE) { + ch->recv->fSTATE = 0; + ch_flags |= 4; + do_notify |= 1; + } + } + tmp = ch->recv->state; + if (tmp != ch->last_state) + smd_state_change(ch, ch->last_state, tmp); + if (ch_flags) { + ch->update_state(ch); + ch->notify(ch->priv, SMD_EVENT_DATA); + } + } + if (do_notify) + notify_other_smd(); + spin_unlock_irqrestore(&smd_lock, flags); + do_smd_probe(); + return IRQ_HANDLED; +} + +static void smd_fake_irq_handler(unsigned long arg) +{ + smd_irq_handler(0, NULL); +} + +static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0); + +void smd_sleep_exit(void) +{ + unsigned long flags; + struct smd_channel *ch; + unsigned tmp; + int need_int = 0; + + spin_lock_irqsave(&smd_lock, flags); + list_for_each_entry(ch, &smd_ch_list, ch_list) { + if (ch_is_open(ch)) { + if (ch->recv->fHEAD) { + if (msm_smd_debug_mask & MSM_SMD_DEBUG) + pr_info("smd_sleep_exit ch %d fHEAD " + "%x %x %x\n", + ch->n, ch->recv->fHEAD, + ch->recv->head, ch->recv->tail); + need_int = 1; + break; + } + if (ch->recv->fTAIL) { + if (msm_smd_debug_mask & MSM_SMD_DEBUG) + pr_info("smd_sleep_exit ch %d fTAIL " + "%x %x %x\n", + ch->n, ch->recv->fTAIL, + ch->send->head, ch->send->tail); + need_int = 1; + break; + } + if (ch->recv->fSTATE) { + if (msm_smd_debug_mask & MSM_SMD_DEBUG) + pr_info("smd_sleep_exit ch %d fSTATE %x" + "\n", ch->n, ch->recv->fSTATE); + need_int = 1; + break; + } + tmp = ch->recv->state; + if (tmp != ch->last_state) { + if (msm_smd_debug_mask & MSM_SMD_DEBUG) + pr_info("smd_sleep_exit ch %d " + "state %x != %x\n", + ch->n, tmp, ch->last_state); + need_int = 1; + break; + } + } + } + spin_unlock_irqrestore(&smd_lock, flags); + do_smd_probe(); + if (need_int) { + if (msm_smd_debug_mask & MSM_SMD_DEBUG) + pr_info("smd_sleep_exit need interrupt\n"); + tasklet_schedule(&smd_fake_irq_tasklet); + } +} + + +void smd_kick(smd_channel_t *ch) +{ + unsigned long flags; + unsigned tmp; + + spin_lock_irqsave(&smd_lock, flags); + ch->update_state(ch); + tmp = ch->recv->state; + if (tmp != ch->last_state) { + ch->last_state = tmp; + if (tmp == SMD_SS_OPENED) + ch->notify(ch->priv, SMD_EVENT_OPEN); + else + ch->notify(ch->priv, SMD_EVENT_CLOSE); + } + ch->notify(ch->priv, SMD_EVENT_DATA); + notify_other_smd(); + spin_unlock_irqrestore(&smd_lock, flags); +} + +static int smd_is_packet(int chn) +{ + if ((chn > 4) || (chn == 1)) + return 1; + else + return 0; +} + +static int smd_stream_write(smd_channel_t *ch, const void *_data, int len) +{ + void *ptr; + const unsigned char *buf = _data; + unsigned xfer; + int orig_len = len; + + if (len < 0) + return -EINVAL; + + while ((xfer = ch_write_buffer(ch, &ptr)) != 0) { + if (!ch_is_open(ch)) + break; + if (xfer > len) + xfer = len; + memcpy(ptr, buf, xfer); + ch_write_done(ch, xfer); + len -= xfer; + buf += xfer; + if (len == 0) + break; + } + + notify_other_smd(); + + return orig_len - len; +} + +static int smd_packet_write(smd_channel_t *ch, const void *_data, int len) +{ + unsigned hdr[5]; + + if (len < 0) + return -EINVAL; + + if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE)) + return -ENOMEM; + + hdr[0] = len; + hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0; + + smd_stream_write(ch, hdr, sizeof(hdr)); + smd_stream_write(ch, _data, len); + + return len; +} + +static int smd_stream_read(smd_channel_t *ch, void *data, int len) +{ + int r; + + if (len < 0) + return -EINVAL; + + r = ch_read(ch, data, len); + if (r > 0) + notify_other_smd(); + + return r; +} + +static int smd_packet_read(smd_channel_t *ch, void *data, int len) +{ + unsigned long flags; + int r; + + if (len < 0) + return -EINVAL; + + if (len > ch->current_packet) + len = ch->current_packet; + + r = ch_read(ch, data, len); + if (r > 0) + notify_other_smd(); + + spin_lock_irqsave(&smd_lock, flags); + ch->current_packet -= r; + update_packet_state(ch); + spin_unlock_irqrestore(&smd_lock, flags); + + return r; +} + +static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) +{ + struct smd_channel *ch; + struct smd_shared *shared; + + shared = smem_alloc(ID_SMD_CHANNELS + cid, sizeof(*shared)); + if (!shared) { + pr_err("smd_alloc_channel() cid %d does not exist\n", cid); + return; + } + + ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL); + if (ch == 0) { + pr_err("smd_alloc_channel() out of memory\n"); + return; + } + + ch->send = &shared->ch0; + ch->recv = &shared->ch1; + ch->n = cid; + + if (smd_is_packet(cid)) { + ch->read = smd_packet_read; + ch->write = smd_packet_write; + ch->read_avail = smd_packet_read_avail; + ch->write_avail = smd_packet_write_avail; + ch->update_state = update_packet_state; + } else { + ch->read = smd_stream_read; + ch->write = smd_stream_write; + ch->read_avail = smd_stream_read_avail; + ch->write_avail = smd_stream_write_avail; + ch->update_state = update_stream_state; + } + + memcpy(ch->name, "SMD_", 4); + memcpy(ch->name + 4, name, 20); + ch->name[23] = 0; + ch->pdev.name = ch->name; + ch->pdev.id = -1; + + pr_info("smd_alloc_channel() '%s' cid=%d, shared=%p\n", + ch->name, ch->n, shared); + + mutex_lock(&smd_creation_mutex); + list_add(&ch->ch_list, &smd_ch_closed_list); + mutex_unlock(&smd_creation_mutex); + + platform_device_register(&ch->pdev); +} + +static void do_nothing_notify(void *priv, unsigned flags) +{ +} + +struct smd_channel *smd_get_channel(const char *name) +{ + struct smd_channel *ch; + + mutex_lock(&smd_creation_mutex); + list_for_each_entry(ch, &smd_ch_closed_list, ch_list) { + if (!strcmp(name, ch->name)) { + list_del(&ch->ch_list); + mutex_unlock(&smd_creation_mutex); + return ch; + } + } + mutex_unlock(&smd_creation_mutex); + + return NULL; +} + +int smd_open(const char *name, smd_channel_t **_ch, + void *priv, void (*notify)(void *, unsigned)) +{ + struct smd_channel *ch; + unsigned long flags; + + if (smd_initialized == 0) { + pr_info("smd_open() before smd_init()\n"); + return -ENODEV; + } + + ch = smd_get_channel(name); + if (!ch) + return -ENODEV; + + if (notify == 0) + notify = do_nothing_notify; + + ch->notify = notify; + ch->current_packet = 0; + ch->last_state = SMD_SS_CLOSED; + ch->priv = priv; + + *_ch = ch; + + spin_lock_irqsave(&smd_lock, flags); + list_add(&ch->ch_list, &smd_ch_list); + + /* If the remote side is CLOSING, we need to get it to + * move to OPENING (which we'll do by moving from CLOSED to + * OPENING) and then get it to move from OPENING to + * OPENED (by doing the same state change ourselves). + * + * Otherwise, it should be OPENING and we can move directly + * to OPENED so that it will follow. + */ + if (ch->recv->state == SMD_SS_CLOSING) { + ch->send->head = 0; + hc_set_state(ch->send, SMD_SS_OPENING); + } else { + hc_set_state(ch->send, SMD_SS_OPENED); + } + spin_unlock_irqrestore(&smd_lock, flags); + smd_kick(ch); + + return 0; +} + +int smd_close(smd_channel_t *ch) +{ + unsigned long flags; + + pr_info("smd_close(%p)\n", ch); + + if (ch == 0) + return -1; + + spin_lock_irqsave(&smd_lock, flags); + ch->notify = do_nothing_notify; + list_del(&ch->ch_list); + hc_set_state(ch->send, SMD_SS_CLOSED); + spin_unlock_irqrestore(&smd_lock, flags); + + mutex_lock(&smd_creation_mutex); + list_add(&ch->ch_list, &smd_ch_closed_list); + mutex_unlock(&smd_creation_mutex); + + return 0; +} + +int smd_read(smd_channel_t *ch, void *data, int len) +{ + return ch->read(ch, data, len); +} + +int smd_write(smd_channel_t *ch, const void *data, int len) +{ + return ch->write(ch, data, len); +} + +int smd_read_avail(smd_channel_t *ch) +{ + return ch->read_avail(ch); +} + +int smd_write_avail(smd_channel_t *ch) +{ + return ch->write_avail(ch); +} + +int smd_wait_until_readable(smd_channel_t *ch, int bytes) +{ + return -1; +} + +int smd_wait_until_writable(smd_channel_t *ch, int bytes) +{ + return -1; +} + +int smd_cur_packet_size(smd_channel_t *ch) +{ + return ch->current_packet; +} + + +/* ------------------------------------------------------------------------- */ + +void *smem_alloc(unsigned id, unsigned size) +{ + return smem_find(id, size); +} + +static void *_smem_find(unsigned id, unsigned *size) +{ + struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; + struct smem_heap_entry *toc = shared->heap_toc; + + if (id >= SMEM_NUM_ITEMS) + return 0; + + if (toc[id].allocated) { + *size = toc[id].size; + return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset); + } + + return 0; +} + +void *smem_find(unsigned id, unsigned size_in) +{ + unsigned size; + void *ptr; + + ptr = _smem_find(id, &size); + if (!ptr) + return 0; + + size_in = ALIGN(size_in, 8); + if (size_in != size) { + pr_err("smem_find(%d, %d): wrong size %d\n", + id, size_in, size); + return 0; + } + + return ptr; +} + +static irqreturn_t smsm_irq_handler(int irq, void *data) +{ + unsigned long flags; + struct smsm_shared *smsm; + + spin_lock_irqsave(&smem_lock, flags); + smsm = smem_alloc(ID_SHARED_STATE, + 2 * sizeof(struct smsm_shared)); + + if (smsm == 0) { + pr_info("\n"); + } else { + unsigned apps = smsm[0].state; + unsigned modm = smsm[1].state; + + if (msm_smd_debug_mask & MSM_SMSM_DEBUG) + pr_info("\n", apps, modm); + if (modm & SMSM_RESET) { + handle_modem_crash(); + } else { + apps |= SMSM_INIT; + if (modm & SMSM_SMDINIT) + apps |= SMSM_SMDINIT; + if (modm & SMSM_RPCINIT) + apps |= SMSM_RPCINIT; + } + + if (smsm[0].state != apps) { + if (msm_smd_debug_mask & MSM_SMSM_DEBUG) + pr_info("\n", apps); + smsm[0].state = apps; + do_smd_probe(); + notify_other_smsm(); + } + } + spin_unlock_irqrestore(&smem_lock, flags); + return IRQ_HANDLED; +} + +int smsm_change_state(uint32_t clear_mask, uint32_t set_mask) +{ + unsigned long flags; + struct smsm_shared *smsm; + + spin_lock_irqsave(&smem_lock, flags); + + smsm = smem_alloc(ID_SHARED_STATE, + 2 * sizeof(struct smsm_shared)); + + if (smsm) { + if (smsm[1].state & SMSM_RESET) + handle_modem_crash(); + smsm[0].state = (smsm[0].state & ~clear_mask) | set_mask; + if (msm_smd_debug_mask & MSM_SMSM_DEBUG) + pr_info("smsm_change_state %x\n", + smsm[0].state); + notify_other_smsm(); + } + + spin_unlock_irqrestore(&smem_lock, flags); + + if (smsm == NULL) { + pr_err("smsm_change_state \n"); + return -EIO; + } + return 0; +} + +uint32_t smsm_get_state(void) +{ + unsigned long flags; + struct smsm_shared *smsm; + uint32_t rv; + + spin_lock_irqsave(&smem_lock, flags); + + smsm = smem_alloc(ID_SHARED_STATE, + 2 * sizeof(struct smsm_shared)); + + if (smsm) + rv = smsm[1].state; + else + rv = 0; + + if (rv & SMSM_RESET) + handle_modem_crash(); + + spin_unlock_irqrestore(&smem_lock, flags); + + if (smsm == NULL) + pr_err("smsm_get_state \n"); + return rv; +} + +int smsm_set_sleep_duration(uint32_t delay) +{ + uint32_t *ptr; + + ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); + if (ptr == NULL) { + pr_err("smsm_set_sleep_duration \n"); + return -EIO; + } + if (msm_smd_debug_mask & MSM_SMSM_DEBUG) + pr_info("smsm_set_sleep_duration %d -> %d\n", + *ptr, delay); + *ptr = delay; + return 0; +} + +int smsm_set_interrupt_info(struct smsm_interrupt_info *info) +{ + struct smsm_interrupt_info *ptr; + + ptr = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*ptr)); + if (ptr == NULL) { + pr_err("smsm_set_sleep_duration \n"); + return -EIO; + } + if (msm_smd_debug_mask & MSM_SMSM_DEBUG) + pr_info("smsm_set_interrupt_info %x %x -> %x %x\n", + ptr->aArm_en_mask, ptr->aArm_interrupts_pending, + info->aArm_en_mask, info->aArm_interrupts_pending); + *ptr = *info; + return 0; +} + +#define MAX_NUM_SLEEP_CLIENTS 64 +#define MAX_SLEEP_NAME_LEN 8 + +#define NUM_GPIO_INT_REGISTERS 6 +#define GPIO_SMEM_NUM_GROUPS 2 +#define GPIO_SMEM_MAX_PC_INTERRUPTS 8 + +struct tramp_gpio_save { + unsigned int enable; + unsigned int detect; + unsigned int polarity; +}; + +struct tramp_gpio_smem { + uint16_t num_fired[GPIO_SMEM_NUM_GROUPS]; + uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS]; + uint32_t enabled[NUM_GPIO_INT_REGISTERS]; + uint32_t detection[NUM_GPIO_INT_REGISTERS]; + uint32_t polarity[NUM_GPIO_INT_REGISTERS]; +}; + + +void smsm_print_sleep_info(void) +{ + unsigned long flags; + uint32_t *ptr; + struct tramp_gpio_smem *gpio; + struct smsm_interrupt_info *int_info; + + + spin_lock_irqsave(&smem_lock, flags); + + ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); + if (ptr) + pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr); + + ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr)); + if (ptr) + pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr); + + ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr)); + if (ptr) + pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr); + + int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info)); + if (int_info) + pr_info("SMEM_SMSM_INT_INFO %x %x %x\n", + int_info->aArm_en_mask, + int_info->aArm_interrupts_pending, + int_info->aArm_wakeup_reason); + + gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio)); + if (gpio) { + int i; + for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++) + pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n", + i, gpio->enabled[i], gpio->detection[i], + gpio->polarity[i]); + + for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++) + pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n", + i, gpio->num_fired[i], gpio->fired[i][0], + gpio->fired[i][1]); + } + + spin_unlock_irqrestore(&smem_lock, flags); +} + +int smd_core_init(void) +{ + int r; + pr_info("smd_core_init()\n"); + + r = request_irq(INT_A9_M2A_0, smd_irq_handler, + IRQF_TRIGGER_RISING, "smd_dev", 0); + if (r < 0) + return r; + r = enable_irq_wake(INT_A9_M2A_0); + if (r < 0) + pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n"); + + r = request_irq(INT_A9_M2A_5, smsm_irq_handler, + IRQF_TRIGGER_RISING, "smsm_dev", 0); + if (r < 0) { + free_irq(INT_A9_M2A_0, 0); + return r; + } + r = enable_irq_wake(INT_A9_M2A_5); + if (r < 0) + pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n"); + + /* we may have missed a signal while booting -- fake + * an interrupt to make sure we process any existing + * state + */ + smsm_irq_handler(0, 0); + + pr_info("smd_core_init() done\n"); + + return 0; +} + +#if defined(CONFIG_DEBUG_FS) + +static int dump_ch(char *buf, int max, int n, + struct smd_half_channel *s, + struct smd_half_channel *r) +{ + return scnprintf( + buf, max, + "ch%02d:" + " %8s(%04d/%04d) %c%c%c%c%c%c%c <->" + " %8s(%04d/%04d) %c%c%c%c%c%c%c\n", n, + chstate(s->state), s->tail, s->head, + s->fDSR ? 'D' : 'd', + s->fCTS ? 'C' : 'c', + s->fCD ? 'C' : 'c', + s->fRI ? 'I' : 'i', + s->fHEAD ? 'W' : 'w', + s->fTAIL ? 'R' : 'r', + s->fSTATE ? 'S' : 's', + chstate(r->state), r->tail, r->head, + r->fDSR ? 'D' : 'd', + r->fCTS ? 'R' : 'r', + r->fCD ? 'C' : 'c', + r->fRI ? 'I' : 'i', + r->fHEAD ? 'W' : 'w', + r->fTAIL ? 'R' : 'r', + r->fSTATE ? 'S' : 's' + ); +} + +static int debug_read_stat(char *buf, int max) +{ + struct smsm_shared *smsm; + char *msg; + int i = 0; + + smsm = smem_find(ID_SHARED_STATE, + 2 * sizeof(struct smsm_shared)); + + msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); + + if (smsm) { + if (smsm[1].state & SMSM_RESET) + i += scnprintf(buf + i, max - i, + "smsm: ARM9 HAS CRASHED\n"); + i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n", + smsm[0].state, smsm[1].state); + } else { + i += scnprintf(buf + i, max - i, "smsm: cannot find\n"); + } + if (msg) { + msg[SZ_DIAG_ERR_MSG - 1] = 0; + i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg); + } + return i; +} + +static int debug_read_mem(char *buf, int max) +{ + unsigned n; + struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; + struct smem_heap_entry *toc = shared->heap_toc; + int i = 0; + + i += scnprintf(buf + i, max - i, + "heap: init=%d free=%d remain=%d\n", + shared->heap_info.initialized, + shared->heap_info.free_offset, + shared->heap_info.heap_remaining); + + for (n = 0; n < SMEM_NUM_ITEMS; n++) { + if (toc[n].allocated == 0) + continue; + i += scnprintf(buf + i, max - i, + "%04d: offsed %08x size %08x\n", + n, toc[n].offset, toc[n].size); + } + return i; +} + +static int debug_read_ch(char *buf, int max) +{ + struct smd_shared *shared; + int n, i = 0; + + for (n = 0; n < SMD_CHANNELS; n++) { + shared = smem_find(ID_SMD_CHANNELS + n, + sizeof(struct smd_shared)); + if (shared == 0) + continue; + i += dump_ch(buf + i, max - i, n, &shared->ch0, &shared->ch1); + } + + return i; +} + +static int debug_read_version(char *buf, int max) +{ + struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; + unsigned version = shared->version[VERSION_MODEM]; + return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff); +} + +static int debug_read_build_id(char *buf, int max) +{ + unsigned size; + void *data; + + data = _smem_find(SMEM_HW_SW_BUILD_ID, &size); + if (!data) + return 0; + + if (size >= max) + size = max; + memcpy(buf, data, size); + + return size; +} + +static int debug_read_alloc_tbl(char *buf, int max) +{ + struct smd_alloc_elm *shared; + int n, i = 0; + + shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); + + for (n = 0; n < 64; n++) { + if (shared[n].ref_count == 0) + continue; + i += scnprintf(buf + i, max - i, + "%03d: %20s cid=%02d ctype=%d ref_count=%d\n", + n, shared[n].name, shared[n].cid, + shared[n].ctype, shared[n].ref_count); + } + + return i; +} + +static int debug_boom(char *buf, int max) +{ + unsigned ms = 5000; + msm_proc_comm(PCOM_RESET_MODEM, &ms, 0); + return 0; +} + +#define DEBUG_BUFMAX 4096 +static char debug_buffer[DEBUG_BUFMAX]; + +static ssize_t debug_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + int (*fill)(char *buf, int max) = file->private_data; + int bsize = fill(debug_buffer, DEBUG_BUFMAX); + return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize); +} + +static int debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static const struct file_operations debug_ops = { + .read = debug_read, + .open = debug_open, +}; + +static void debug_create(const char *name, mode_t mode, + struct dentry *dent, + int (*fill)(char *buf, int max)) +{ + debugfs_create_file(name, mode, dent, fill, &debug_ops); +} + +static void smd_debugfs_init(void) +{ + struct dentry *dent; + + dent = debugfs_create_dir("smd", 0); + if (IS_ERR(dent)) + return; + + debug_create("ch", 0444, dent, debug_read_ch); + debug_create("stat", 0444, dent, debug_read_stat); + debug_create("mem", 0444, dent, debug_read_mem); + debug_create("version", 0444, dent, debug_read_version); + debug_create("tbl", 0444, dent, debug_read_alloc_tbl); + debug_create("build", 0444, dent, debug_read_build_id); + debug_create("boom", 0444, dent, debug_boom); +} +#else +static void smd_debugfs_init(void) {} +#endif + +static int __init msm_smd_probe(struct platform_device *pdev) +{ + pr_info("smd_init()\n"); + + INIT_WORK(&probe_work, smd_channel_probe_worker); + + if (smd_core_init()) { + pr_err("smd_core_init() failed\n"); + return -1; + } + + do_smd_probe(); + + msm_check_for_modem_crash = check_for_modem_crash; + + smd_debugfs_init(); + smd_initialized = 1; + + return 0; +} + +static struct platform_driver msm_smd_driver = { + .probe = msm_smd_probe, + .driver = { + .name = MODULE_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init msm_smd_init(void) +{ + return platform_driver_register(&msm_smd_driver); +} + +module_init(msm_smd_init); + +MODULE_DESCRIPTION("MSM Shared Memory Core"); +MODULE_AUTHOR("Brian Swetland "); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h new file mode 100644 index 000000000000..c0eb3de1be54 --- /dev/null +++ b/arch/arm/mach-msm/smd_private.h @@ -0,0 +1,171 @@ +/* arch/arm/mach-msm/smd_private.h + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007 QUALCOMM Incorporated + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ +#ifndef _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_ +#define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_ + +struct smem_heap_info +{ + unsigned initialized; + unsigned free_offset; + unsigned heap_remaining; + unsigned reserved; +}; + +struct smem_heap_entry +{ + unsigned allocated; + unsigned offset; + unsigned size; + unsigned reserved; +}; + +struct smem_proc_comm +{ + unsigned command; + unsigned status; + unsigned data1; + unsigned data2; +}; + +#define PC_APPS 0 +#define PC_MODEM 1 + +#define VERSION_QDSP6 4 +#define VERSION_APPS_SBL 6 +#define VERSION_MODEM_SBL 7 +#define VERSION_APPS 8 +#define VERSION_MODEM 9 + +struct smem_shared +{ + struct smem_proc_comm proc_comm[4]; + unsigned version[32]; + struct smem_heap_info heap_info; + struct smem_heap_entry heap_toc[128]; +}; + +struct smsm_shared +{ + unsigned host; + unsigned state; +}; + +struct smsm_interrupt_info +{ + uint32_t aArm_en_mask; + uint32_t aArm_interrupts_pending; + uint32_t aArm_wakeup_reason; +}; + +#define SZ_DIAG_ERR_MSG 0xC8 +#define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE +#define ID_SMD_CHANNELS SMEM_SMD_BASE_ID +#define ID_SHARED_STATE SMEM_SMSM_SHARED_STATE +#define ID_CH_ALLOC_TBL SMEM_CHANNEL_ALLOC_TBL + +#define SMSM_INIT 0x000001 +#define SMSM_SMDINIT 0x000008 +#define SMSM_RPCINIT 0x000020 +#define SMSM_RESET 0x000040 +#define SMSM_RSA 0x0080 +#define SMSM_RUN 0x000100 +#define SMSM_PWRC 0x0200 +#define SMSM_TIMEWAIT 0x0400 +#define SMSM_TIMEINIT 0x0800 +#define SMSM_PWRC_EARLY_EXIT 0x1000 +#define SMSM_WFPI 0x2000 +#define SMSM_SLEEP 0x4000 +#define SMSM_SLEEPEXIT 0x8000 +#define SMSM_OEMSBL_RELEASE 0x10000 +#define SMSM_PWRC_SUSPEND 0x200000 + +#define SMSM_WKUP_REASON_RPC 0x00000001 +#define SMSM_WKUP_REASON_INT 0x00000002 +#define SMSM_WKUP_REASON_GPIO 0x00000004 +#define SMSM_WKUP_REASON_TIMER 0x00000008 +#define SMSM_WKUP_REASON_ALARM 0x00000010 +#define SMSM_WKUP_REASON_RESET 0x00000020 + +void *smem_alloc(unsigned id, unsigned size); +int smsm_change_state(uint32_t clear_mask, uint32_t set_mask); +uint32_t smsm_get_state(void); +int smsm_set_sleep_duration(uint32_t delay); +int smsm_set_interrupt_info(struct smsm_interrupt_info *info); +void smsm_print_sleep_info(void); + +#define SMEM_NUM_SMD_CHANNELS 64 + +typedef enum +{ + /* fixed items */ + SMEM_PROC_COMM = 0, + SMEM_HEAP_INFO, + SMEM_ALLOCATION_TABLE, + SMEM_VERSION_INFO, + SMEM_HW_RESET_DETECT, + SMEM_AARM_WARM_BOOT, + SMEM_DIAG_ERR_MESSAGE, + SMEM_SPINLOCK_ARRAY, + SMEM_MEMORY_BARRIER_LOCATION, + + /* dynamic items */ + SMEM_AARM_PARTITION_TABLE, + SMEM_AARM_BAD_BLOCK_TABLE, + SMEM_RESERVE_BAD_BLOCKS, + SMEM_WM_UUID, + SMEM_CHANNEL_ALLOC_TBL, + SMEM_SMD_BASE_ID, + SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_CHANNELS, + SMEM_SMEM_LOG_EVENTS, + SMEM_SMEM_STATIC_LOG_IDX, + SMEM_SMEM_STATIC_LOG_EVENTS, + SMEM_SMEM_SLOW_CLOCK_SYNC, + SMEM_SMEM_SLOW_CLOCK_VALUE, + SMEM_BIO_LED_BUF, + SMEM_SMSM_SHARED_STATE, + SMEM_SMSM_INT_INFO, + SMEM_SMSM_SLEEP_DELAY, + SMEM_SMSM_LIMIT_SLEEP, + SMEM_SLEEP_POWER_COLLAPSE_DISABLED, + SMEM_KEYPAD_KEYS_PRESSED, + SMEM_KEYPAD_STATE_UPDATED, + SMEM_KEYPAD_STATE_IDX, + SMEM_GPIO_INT, + SMEM_MDDI_LCD_IDX, + SMEM_MDDI_HOST_DRIVER_STATE, + SMEM_MDDI_LCD_DISP_STATE, + SMEM_LCD_CUR_PANEL, + SMEM_MARM_BOOT_SEGMENT_INFO, + SMEM_AARM_BOOT_SEGMENT_INFO, + SMEM_SLEEP_STATIC, + SMEM_SCORPION_FREQUENCY, + SMEM_SMD_PROFILES, + SMEM_TSSC_BUSY, + SMEM_HS_SUSPEND_FILTER_INFO, + SMEM_BATT_INFO, + SMEM_APPS_BOOT_MODE, + SMEM_VERSION_FIRST, + SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24, + SMEM_OSS_RRCASN1_BUF1, + SMEM_OSS_RRCASN1_BUF2, + SMEM_ID_VENDOR0, + SMEM_ID_VENDOR1, + SMEM_ID_VENDOR2, + SMEM_HW_SW_BUILD_ID, + SMEM_NUM_ITEMS, +} smem_mem_type; + +#endif -- cgit v1.2.3-59-g8ed1b From 4d4fb2660ddd2d8131ebc3314e4c648fc0f4b8dd Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Wed, 28 Jan 2009 20:25:40 -0800 Subject: [ARM] msm: smd: don't crash if the smd channel table doesn't exist Signed-off-by: Brian Swetland Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 64d12323995e..78031c0a6db3 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -204,7 +204,10 @@ static void smd_channel_probe_worker(struct work_struct *work) unsigned n; shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); - + if (!shared) { + pr_err("smd: cannot find allocation table\n"); + return; + } for (n = 0; n < 64; n++) { if (smd_ch_allocated[n]) continue; -- cgit v1.2.3-59-g8ed1b From 5b0f5a3f6084397194a8b556cdca572ad8e14f05 Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Sun, 26 Apr 2009 18:38:49 -0700 Subject: msm: smd: initial support for smd v2 - support both v2 and v1 style smd channels - support both v2 and v1 smsm shared state - update smsm state defines and smem item enum - prep work for dealing with smd to qdsp6 - simplify some smem access to minimize use of smem_alloc() at runtime Signed-off-by: Brian Swetland Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 426 ++++++++++++++++++++++++---------------- arch/arm/mach-msm/smd_private.h | 76 +++++-- 2 files changed, 313 insertions(+), 189 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 78031c0a6db3..f731ddeaa25c 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -46,10 +46,26 @@ enum { static int msm_smd_debug_mask; +struct shared_info +{ + int ready; + unsigned state_apps; + unsigned state_modem; +}; + +static unsigned dummy_state_apps; +static unsigned dummy_state_modem; + +static struct shared_info smd_info = { + .state_apps = (unsigned) &dummy_state_apps, + .state_modem = (unsigned) &dummy_state_modem, +}; + module_param_named(debug_mask, msm_smd_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); void *smem_find(unsigned id, unsigned size); +static void *smem_item(unsigned id, unsigned *size); static void smd_diag(void); static unsigned last_heap_free = 0xffffffff; @@ -61,11 +77,16 @@ static inline void notify_other_smsm(void) writel(1, MSM_A2M_INT(5)); } -static inline void notify_other_smd(void) +static inline void notify_modem_smd(void) { writel(1, MSM_A2M_INT(0)); } +static inline void notify_dsp_smd(void) +{ + writel(1, MSM_A2M_INT(8)); +} + static void smd_diag(void) { char *x; @@ -96,34 +117,25 @@ extern int (*msm_check_for_modem_crash)(void); static int check_for_modem_crash(void) { - struct smsm_shared *smsm; - - smsm = smem_find(ID_SHARED_STATE, 2 * sizeof(struct smsm_shared)); - - /* if the modem's not ready yet, we have to hope for the best */ - if (!smsm) - return 0; - - if (smsm[1].state & SMSM_RESET) { + if (readl(smd_info.state_modem) & SMSM_RESET) { handle_modem_crash(); return -1; - } else { - return 0; } + return 0; } -#define SMD_SS_CLOSED 0x00000000 -#define SMD_SS_OPENING 0x00000001 -#define SMD_SS_OPENED 0x00000002 -#define SMD_SS_FLUSHING 0x00000003 -#define SMD_SS_CLOSING 0x00000004 -#define SMD_SS_RESET 0x00000005 -#define SMD_SS_RESET_OPENING 0x00000006 +#define SMD_SS_CLOSED 0x00000000 +#define SMD_SS_OPENING 0x00000001 +#define SMD_SS_OPENED 0x00000002 +#define SMD_SS_FLUSHING 0x00000003 +#define SMD_SS_CLOSING 0x00000004 +#define SMD_SS_RESET 0x00000005 +#define SMD_SS_RESET_OPENING 0x00000006 -#define SMD_BUF_SIZE 8192 -#define SMD_CHANNELS 64 +#define SMD_BUF_SIZE 8192 +#define SMD_CHANNELS 64 -#define SMD_HEADER_SIZE 20 +#define SMD_HEADER_SIZE 20 /* the spinlock is used to synchronize between the @@ -160,21 +172,33 @@ struct smd_half_channel { unsigned char fUNUSED; unsigned tail; unsigned head; - unsigned char data[SMD_BUF_SIZE]; -}; +} __attribute__((packed)); -struct smd_shared { +struct smd_shared_v1 { struct smd_half_channel ch0; + unsigned char data0[SMD_BUF_SIZE]; struct smd_half_channel ch1; + unsigned char data1[SMD_BUF_SIZE]; }; +struct smd_shared_v2 { + struct smd_half_channel ch0; + struct smd_half_channel ch1; +}; + struct smd_channel { volatile struct smd_half_channel *send; volatile struct smd_half_channel *recv; - struct list_head ch_list; + unsigned char *send_data; + unsigned char *recv_data; + unsigned fifo_mask; + unsigned fifo_size; unsigned current_packet; unsigned n; + + struct list_head ch_list; + void *priv; void (*notify)(void *priv, unsigned flags); @@ -185,22 +209,35 @@ struct smd_channel { void (*update_state)(smd_channel_t *ch); unsigned last_state; + void (*notify_other_cpu)(void); + unsigned type; char name[32]; struct platform_device pdev; }; static LIST_HEAD(smd_ch_closed_list); -static LIST_HEAD(smd_ch_list); +static LIST_HEAD(smd_ch_list); /* todo: per-target lists */ static unsigned char smd_ch_allocated[64]; static struct work_struct probe_work; +#define SMD_TYPE_MASK 0x0FF +#define SMD_TYPE_APPS_MODEM 0x000 +#define SMD_TYPE_APPS_DSP 0x001 +#define SMD_TYPE_MODEM_DSP 0x002 + +#define SMD_KIND_MASK 0xF00 +#define SMD_KIND_UNKNOWN 0x000 +#define SMD_KIND_STREAM 0x100 +#define SMD_KIND_PACKET 0x200 + static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); static void smd_channel_probe_worker(struct work_struct *work) { struct smd_alloc_elm *shared; + unsigned type; unsigned n; shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); @@ -215,9 +252,12 @@ static void smd_channel_probe_worker(struct work_struct *work) continue; if (!shared[n].name[0]) continue; - smd_alloc_channel(shared[n].name, - shared[n].cid, - shared[n].ctype); + type = shared[n].ctype & SMD_TYPE_MASK; + if ((type == SMD_TYPE_APPS_MODEM) || + (type == SMD_TYPE_APPS_DSP)) + smd_alloc_channel(shared[n].name, + shared[n].cid, + shared[n].ctype); smd_ch_allocated[n] = 1; } } @@ -247,14 +287,14 @@ static char *chstate(unsigned n) /* how many bytes are available for reading */ static int smd_stream_read_avail(struct smd_channel *ch) { - return (ch->recv->head - ch->recv->tail) & (SMD_BUF_SIZE - 1); + return (ch->recv->head - ch->recv->tail) & ch->fifo_mask; } /* how many bytes we are free to write */ static int smd_stream_write_avail(struct smd_channel *ch) { - return (SMD_BUF_SIZE - 1) - - ((ch->send->head - ch->send->tail) & (SMD_BUF_SIZE - 1)); + return ch->fifo_mask - + ((ch->send->head - ch->send->tail) & ch->fifo_mask); } static int smd_packet_read_avail(struct smd_channel *ch) @@ -286,19 +326,19 @@ static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr) { unsigned head = ch->recv->head; unsigned tail = ch->recv->tail; - *ptr = (void *) (ch->recv->data + tail); + *ptr = (void *) (ch->recv_data + tail); if (tail <= head) return head - tail; else - return SMD_BUF_SIZE - tail; + return ch->fifo_size - tail; } /* advance the fifo read pointer after data from ch_read_buffer is consumed */ static void ch_read_done(struct smd_channel *ch, unsigned count) { BUG_ON(count > smd_stream_read_avail(ch)); - ch->recv->tail = (ch->recv->tail + count) & (SMD_BUF_SIZE - 1); + ch->recv->tail = (ch->recv->tail + count) & ch->fifo_mask; ch->recv->fTAIL = 1; } @@ -360,15 +400,15 @@ static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr) { unsigned head = ch->send->head; unsigned tail = ch->send->tail; - *ptr = (void *) (ch->send->data + head); + *ptr = (void *) (ch->send_data + head); if (head < tail) { return tail - head - 1; } else { if (tail == 0) - return SMD_BUF_SIZE - head - 1; + return ch->fifo_size - head - 1; else - return SMD_BUF_SIZE - head; + return ch->fifo_size - head; } } @@ -378,24 +418,24 @@ static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr) static void ch_write_done(struct smd_channel *ch, unsigned count) { BUG_ON(count > smd_stream_write_avail(ch)); - ch->send->head = (ch->send->head + count) & (SMD_BUF_SIZE - 1); + ch->send->head = (ch->send->head + count) & ch->fifo_mask; ch->send->fHEAD = 1; } -static void hc_set_state(volatile struct smd_half_channel *hc, unsigned n) +static void ch_set_state(struct smd_channel *ch, unsigned n) { if (n == SMD_SS_OPENED) { - hc->fDSR = 1; - hc->fCTS = 1; - hc->fCD = 1; + ch->send->fDSR = 1; + ch->send->fCTS = 1; + ch->send->fCD = 1; } else { - hc->fDSR = 0; - hc->fCTS = 0; - hc->fCD = 0; + ch->send->fDSR = 0; + ch->send->fCTS = 0; + ch->send->fCD = 0; } - hc->state = n; - hc->fSTATE = 1; - notify_other_smd(); + ch->send->state = n; + ch->send->fSTATE = 1; + ch->notify_other_cpu(); } static void do_smd_probe(void) @@ -420,7 +460,7 @@ static void smd_state_change(struct smd_channel *ch, ch->recv->tail = 0; case SMD_SS_OPENED: if (ch->send->state != SMD_SS_OPENED) - hc_set_state(ch->send, SMD_SS_OPENED); + ch_set_state(ch, SMD_SS_OPENED); ch->notify(ch->priv, SMD_EVENT_OPEN); break; case SMD_SS_FLUSHING: @@ -431,7 +471,7 @@ static void smd_state_change(struct smd_channel *ch, } } -static irqreturn_t smd_irq_handler(int irq, void *data) +static void handle_smd_irq(struct list_head *list, void (*notify)(void)) { unsigned long flags; struct smd_channel *ch; @@ -440,7 +480,7 @@ static irqreturn_t smd_irq_handler(int irq, void *data) unsigned tmp; spin_lock_irqsave(&smd_lock, flags); - list_for_each_entry(ch, &smd_ch_list, ch_list) { + list_for_each_entry(ch, list, ch_list) { ch_flags = 0; if (ch_is_open(ch)) { if (ch->recv->fHEAD) { @@ -468,9 +508,14 @@ static irqreturn_t smd_irq_handler(int irq, void *data) } } if (do_notify) - notify_other_smd(); + notify(); spin_unlock_irqrestore(&smd_lock, flags); do_smd_probe(); +} + +static irqreturn_t smd_irq_handler(int irq, void *data) +{ + handle_smd_irq(&smd_ch_list, notify_modem_smd); return IRQ_HANDLED; } @@ -553,12 +598,19 @@ void smd_kick(smd_channel_t *ch) ch->notify(ch->priv, SMD_EVENT_CLOSE); } ch->notify(ch->priv, SMD_EVENT_DATA); - notify_other_smd(); + ch->notify_other_cpu(); spin_unlock_irqrestore(&smd_lock, flags); } -static int smd_is_packet(int chn) +static int smd_is_packet(int chn, unsigned type) { + type &= SMD_KIND_MASK; + if (type == SMD_KIND_PACKET) + return 1; + if (type == SMD_KIND_STREAM) + return 0; + + /* older AMSS reports SMD_KIND_UNKNOWN always */ if ((chn > 4) || (chn == 1)) return 1; else @@ -588,7 +640,7 @@ static int smd_stream_write(smd_channel_t *ch, const void *_data, int len) break; } - notify_other_smd(); + ch->notify_other_cpu(); return orig_len - len; } @@ -621,7 +673,7 @@ static int smd_stream_read(smd_channel_t *ch, void *data, int len) r = ch_read(ch, data, len); if (r > 0) - notify_other_smd(); + ch->notify_other_cpu(); return r; } @@ -639,7 +691,7 @@ static int smd_packet_read(smd_channel_t *ch, void *data, int len) r = ch_read(ch, data, len); if (r > 0) - notify_other_smd(); + ch->notify_other_cpu(); spin_lock_irqsave(&smd_lock, flags); ch->current_packet -= r; @@ -649,28 +701,73 @@ static int smd_packet_read(smd_channel_t *ch, void *data, int len) return r; } -static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) +static int smd_alloc_v2(struct smd_channel *ch) { - struct smd_channel *ch; - struct smd_shared *shared; + struct smd_shared_v2 *shared2; + void *buffer; + unsigned buffer_sz; - shared = smem_alloc(ID_SMD_CHANNELS + cid, sizeof(*shared)); - if (!shared) { - pr_err("smd_alloc_channel() cid %d does not exist\n", cid); - return; + shared2 = smem_alloc(SMEM_SMD_BASE_ID + ch->n, sizeof(*shared2)); + buffer = smem_item(SMEM_SMD_FIFO_BASE_ID + ch->n, &buffer_sz); + + if (!buffer) + return -1; + + /* buffer must be a power-of-two size */ + if (buffer_sz & (buffer_sz - 1)) + return -1; + + buffer_sz /= 2; + ch->send = &shared2->ch0; + ch->recv = &shared2->ch1; + ch->send_data = buffer; + ch->recv_data = buffer + buffer_sz; + ch->fifo_size = buffer_sz; + return 0; +} + +static int smd_alloc_v1(struct smd_channel *ch) +{ + struct smd_shared_v1 *shared1; + shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1)); + if (!shared1) { + pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n); + return -1; } + ch->send = &shared1->ch0; + ch->recv = &shared1->ch1; + ch->send_data = shared1->data0; + ch->recv_data = shared1->data1; + ch->fifo_size = SMD_BUF_SIZE; + return 0; +} + + +static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) +{ + struct smd_channel *ch; ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL); if (ch == 0) { pr_err("smd_alloc_channel() out of memory\n"); return; } - - ch->send = &shared->ch0; - ch->recv = &shared->ch1; ch->n = cid; - if (smd_is_packet(cid)) { + if (smd_alloc_v2(ch) && smd_alloc_v1(ch)) { + kfree(ch); + return; + } + + ch->fifo_mask = ch->fifo_size - 1; + ch->type = type; + + if ((type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM) + ch->notify_other_cpu = notify_modem_smd; + else + ch->notify_other_cpu = notify_dsp_smd; + + if (smd_is_packet(cid, type)) { ch->read = smd_packet_read; ch->write = smd_packet_write; ch->read_avail = smd_packet_read_avail; @@ -684,14 +781,17 @@ static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) ch->update_state = update_stream_state; } - memcpy(ch->name, "SMD_", 4); + if ((type & 0xff) == 0) + memcpy(ch->name, "SMD_", 4); + else + memcpy(ch->name, "DSP_", 4); memcpy(ch->name + 4, name, 20); ch->name[23] = 0; ch->pdev.name = ch->name; ch->pdev.id = -1; - pr_info("smd_alloc_channel() '%s' cid=%d, shared=%p\n", - ch->name, ch->n, shared); + pr_info("smd_alloc_channel() cid=%02d size=%05d '%s'\n", + ch->n, ch->fifo_size, ch->name); mutex_lock(&smd_creation_mutex); list_add(&ch->ch_list, &smd_ch_closed_list); @@ -759,9 +859,9 @@ int smd_open(const char *name, smd_channel_t **_ch, */ if (ch->recv->state == SMD_SS_CLOSING) { ch->send->head = 0; - hc_set_state(ch->send, SMD_SS_OPENING); + ch_set_state(ch, SMD_SS_OPENING); } else { - hc_set_state(ch->send, SMD_SS_OPENED); + ch_set_state(ch, SMD_SS_OPENED); } spin_unlock_irqrestore(&smd_lock, flags); smd_kick(ch); @@ -781,7 +881,7 @@ int smd_close(smd_channel_t *ch) spin_lock_irqsave(&smd_lock, flags); ch->notify = do_nothing_notify; list_del(&ch->ch_list); - hc_set_state(ch->send, SMD_SS_CLOSED); + ch_set_state(ch, SMD_SS_CLOSED); spin_unlock_irqrestore(&smd_lock, flags); mutex_lock(&smd_creation_mutex); @@ -834,7 +934,7 @@ void *smem_alloc(unsigned id, unsigned size) return smem_find(id, size); } -static void *_smem_find(unsigned id, unsigned *size) +static void *smem_item(unsigned id, unsigned *size) { struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; struct smem_heap_entry *toc = shared->heap_toc; @@ -845,6 +945,8 @@ static void *_smem_find(unsigned id, unsigned *size) if (toc[id].allocated) { *size = toc[id].size; return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset); + } else { + *size = 0; } return 0; @@ -855,7 +957,7 @@ void *smem_find(unsigned id, unsigned size_in) unsigned size; void *ptr; - ptr = _smem_find(id, &size); + ptr = smem_item(id, &size); if (!ptr) return 0; @@ -872,38 +974,20 @@ void *smem_find(unsigned id, unsigned size_in) static irqreturn_t smsm_irq_handler(int irq, void *data) { unsigned long flags; - struct smsm_shared *smsm; + unsigned apps, modm; spin_lock_irqsave(&smem_lock, flags); - smsm = smem_alloc(ID_SHARED_STATE, - 2 * sizeof(struct smsm_shared)); - if (smsm == 0) { - pr_info("\n"); - } else { - unsigned apps = smsm[0].state; - unsigned modm = smsm[1].state; - - if (msm_smd_debug_mask & MSM_SMSM_DEBUG) - pr_info("\n", apps, modm); - if (modm & SMSM_RESET) { - handle_modem_crash(); - } else { - apps |= SMSM_INIT; - if (modm & SMSM_SMDINIT) - apps |= SMSM_SMDINIT; - if (modm & SMSM_RPCINIT) - apps |= SMSM_RPCINIT; - } + apps = readl(smd_info.state_apps); + modm = readl(smd_info.state_modem); - if (smsm[0].state != apps) { - if (msm_smd_debug_mask & MSM_SMSM_DEBUG) - pr_info("\n", apps); - smsm[0].state = apps; - do_smd_probe(); - notify_other_smsm(); - } + if (msm_smd_debug_mask & MSM_SMSM_DEBUG) + pr_info("\n", apps, modm); + if (modm & SMSM_RESET) { + handle_modem_crash(); } + do_smd_probe(); + spin_unlock_irqrestore(&smem_lock, flags); return IRQ_HANDLED; } @@ -911,55 +995,42 @@ static irqreturn_t smsm_irq_handler(int irq, void *data) int smsm_change_state(uint32_t clear_mask, uint32_t set_mask) { unsigned long flags; - struct smsm_shared *smsm; + unsigned state; + + if (!smd_info.ready) + return -EIO; spin_lock_irqsave(&smem_lock, flags); - smsm = smem_alloc(ID_SHARED_STATE, - 2 * sizeof(struct smsm_shared)); - - if (smsm) { - if (smsm[1].state & SMSM_RESET) - handle_modem_crash(); - smsm[0].state = (smsm[0].state & ~clear_mask) | set_mask; - if (msm_smd_debug_mask & MSM_SMSM_DEBUG) - pr_info("smsm_change_state %x\n", - smsm[0].state); - notify_other_smsm(); - } + if (readl(smd_info.state_modem) & SMSM_RESET) + handle_modem_crash(); + + state = (readl(smd_info.state_apps) & ~clear_mask) | set_mask; + writel(state, smd_info.state_apps); + + if (msm_smd_debug_mask & MSM_SMSM_DEBUG) + pr_info("smsm_change_state %x\n", state); + notify_other_smsm(); spin_unlock_irqrestore(&smem_lock, flags); - if (smsm == NULL) { - pr_err("smsm_change_state \n"); - return -EIO; - } return 0; } uint32_t smsm_get_state(void) { unsigned long flags; - struct smsm_shared *smsm; uint32_t rv; spin_lock_irqsave(&smem_lock, flags); - smsm = smem_alloc(ID_SHARED_STATE, - 2 * sizeof(struct smsm_shared)); - - if (smsm) - rv = smsm[1].state; - else - rv = 0; + rv = readl(smd_info.state_modem); if (rv & SMSM_RESET) handle_modem_crash(); spin_unlock_irqrestore(&smem_lock, flags); - if (smsm == NULL) - pr_err("smsm_get_state \n"); return rv; } @@ -1069,6 +1140,25 @@ int smd_core_init(void) int r; pr_info("smd_core_init()\n"); + /* wait for essential items to be initialized */ + for (;;) { + unsigned size; + void *state; + state = smem_item(SMEM_SMSM_SHARED_STATE, &size); + if (size == SMSM_V1_SIZE) { + smd_info.state_apps = state + SMSM_V1_STATE_APPS; + smd_info.state_modem = state + SMSM_V1_STATE_MODEM; + break; + } + if (size == SMSM_V2_SIZE) { + smd_info.state_apps = state + SMSM_V2_STATE_APPS; + smd_info.state_modem = state + SMSM_V2_STATE_MODEM; + break; + } + } + + smd_info.ready = 1; + r = request_irq(INT_A9_M2A_0, smd_irq_handler, IRQF_TRIGGER_RISING, "smd_dev", 0); if (r < 0) @@ -1087,11 +1177,12 @@ int smd_core_init(void) if (r < 0) pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n"); - /* we may have missed a signal while booting -- fake - * an interrupt to make sure we process any existing - * state - */ - smsm_irq_handler(0, 0); + /* check for any SMD channels that may already exist */ + do_smd_probe(); + + /* indicate that we're up and running */ + writel(SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT, smd_info.state_apps); + notify_other_smsm(); pr_info("smd_core_init() done\n"); @@ -1100,15 +1191,16 @@ int smd_core_init(void) #if defined(CONFIG_DEBUG_FS) -static int dump_ch(char *buf, int max, int n, - struct smd_half_channel *s, - struct smd_half_channel *r) +static int dump_ch(char *buf, int max, struct smd_channel *ch) { + volatile struct smd_half_channel *s = ch->send; + volatile struct smd_half_channel *r = ch->recv; + return scnprintf( buf, max, "ch%02d:" - " %8s(%04d/%04d) %c%c%c%c%c%c%c <->" - " %8s(%04d/%04d) %c%c%c%c%c%c%c\n", n, + " %8s(%05d/%05d) %c%c%c%c%c%c%c <->" + " %8s(%05d/%05d) %c%c%c%c%c%c%c\n", ch->n, chstate(s->state), s->tail, s->head, s->fDSR ? 'D' : 'd', s->fCTS ? 'C' : 'c', @@ -1130,24 +1222,19 @@ static int dump_ch(char *buf, int max, int n, static int debug_read_stat(char *buf, int max) { - struct smsm_shared *smsm; char *msg; int i = 0; - smsm = smem_find(ID_SHARED_STATE, - 2 * sizeof(struct smsm_shared)); - msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); - if (smsm) { - if (smsm[1].state & SMSM_RESET) - i += scnprintf(buf + i, max - i, - "smsm: ARM9 HAS CRASHED\n"); - i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n", - smsm[0].state, smsm[1].state); - } else { - i += scnprintf(buf + i, max - i, "smsm: cannot find\n"); - } + if (readl(smd_info.state_modem) & SMSM_RESET) + i += scnprintf(buf + i, max - i, + "smsm: ARM9 HAS CRASHED\n"); + + i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n", + readl(smd_info.state_modem), + readl(smd_info.state_apps)); + if (msg) { msg[SZ_DIAG_ERR_MSG - 1] = 0; i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg); @@ -1172,7 +1259,7 @@ static int debug_read_mem(char *buf, int max) if (toc[n].allocated == 0) continue; i += scnprintf(buf + i, max - i, - "%04d: offsed %08x size %08x\n", + "%04d: offset %08x size %08x\n", n, toc[n].offset, toc[n].size); } return i; @@ -1180,16 +1267,16 @@ static int debug_read_mem(char *buf, int max) static int debug_read_ch(char *buf, int max) { - struct smd_shared *shared; - int n, i = 0; + struct smd_channel *ch; + unsigned long flags; + int i = 0; - for (n = 0; n < SMD_CHANNELS; n++) { - shared = smem_find(ID_SMD_CHANNELS + n, - sizeof(struct smd_shared)); - if (shared == 0) - continue; - i += dump_ch(buf + i, max - i, n, &shared->ch0, &shared->ch1); - } + spin_lock_irqsave(&smd_lock, flags); + list_for_each_entry(ch, &smd_ch_list, ch_list) + i += dump_ch(buf + i, max - i, ch); + list_for_each_entry(ch, &smd_ch_closed_list, ch_list) + i += dump_ch(buf + i, max - i, ch); + spin_unlock_irqrestore(&smd_lock, flags); return i; } @@ -1206,7 +1293,7 @@ static int debug_read_build_id(char *buf, int max) unsigned size; void *data; - data = _smem_find(SMEM_HW_SW_BUILD_ID, &size); + data = smem_item(SMEM_HW_SW_BUILD_ID, &size); if (!data) return 0; @@ -1228,9 +1315,12 @@ static int debug_read_alloc_tbl(char *buf, int max) if (shared[n].ref_count == 0) continue; i += scnprintf(buf + i, max - i, - "%03d: %20s cid=%02d ctype=%d ref_count=%d\n", + "%03d: %-20s cid=%02d type=%03d " + "kind=%02d ref_count=%d\n", n, shared[n].name, shared[n].cid, - shared[n].ctype, shared[n].ref_count); + shared[n].ctype & 0xff, + (shared[n].ctype >> 8) & 0xf, + shared[n].ref_count); } return i; diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index c0eb3de1be54..732147c2f992 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -43,6 +43,7 @@ struct smem_proc_comm #define PC_APPS 0 #define PC_MODEM 1 +#define VERSION_SMD 0 #define VERSION_QDSP6 4 #define VERSION_APPS_SBL 6 #define VERSION_MODEM_SBL 7 @@ -54,14 +55,17 @@ struct smem_shared struct smem_proc_comm proc_comm[4]; unsigned version[32]; struct smem_heap_info heap_info; - struct smem_heap_entry heap_toc[128]; + struct smem_heap_entry heap_toc[512]; }; -struct smsm_shared -{ - unsigned host; - unsigned state; -}; +#define SMSM_V1_SIZE (sizeof(unsigned) * 8) +#define SMSM_V1_STATE_APPS 0x0000 +#define SMSM_V1_STATE_MODEM 0x0004 +#define SMSM_V1_STATE_DSP 0x0008 + +#define SMSM_V2_SIZE (sizeof(unsigned) * 4) +#define SMSM_V2_STATE_APPS 0x0004 +#define SMSM_V2_STATE_MODEM 0x000C struct smsm_interrupt_info { @@ -76,21 +80,31 @@ struct smsm_interrupt_info #define ID_SHARED_STATE SMEM_SMSM_SHARED_STATE #define ID_CH_ALLOC_TBL SMEM_CHANNEL_ALLOC_TBL -#define SMSM_INIT 0x000001 -#define SMSM_SMDINIT 0x000008 -#define SMSM_RPCINIT 0x000020 -#define SMSM_RESET 0x000040 -#define SMSM_RSA 0x0080 -#define SMSM_RUN 0x000100 -#define SMSM_PWRC 0x0200 -#define SMSM_TIMEWAIT 0x0400 -#define SMSM_TIMEINIT 0x0800 -#define SMSM_PWRC_EARLY_EXIT 0x1000 -#define SMSM_WFPI 0x2000 -#define SMSM_SLEEP 0x4000 -#define SMSM_SLEEPEXIT 0x8000 -#define SMSM_OEMSBL_RELEASE 0x10000 -#define SMSM_PWRC_SUSPEND 0x200000 +#define SMSM_INIT 0x00000001 +#define SMSM_SMDINIT 0x00000008 +#define SMSM_RPCINIT 0x00000020 +#define SMSM_RESET 0x00000040 +#define SMSM_RSA 0x00000080 +#define SMSM_RUN 0x00000100 +#define SMSM_PWRC 0x00000200 +#define SMSM_TIMEWAIT 0x00000400 +#define SMSM_TIMEINIT 0x00000800 +#define SMSM_PWRC_EARLY_EXIT 0x00001000 +#define SMSM_WFPI 0x00002000 +#define SMSM_SLEEP 0x00004000 +#define SMSM_SLEEPEXIT 0x00008000 +#define SMSM_APPS_REBOOT 0x00020000 +#define SMSM_SYSTEM_POWER_DOWN 0x00040000 +#define SMSM_SYSTEM_REBOOT 0x00080000 +#define SMSM_SYSTEM_DOWNLOAD 0x00100000 +#define SMSM_PWRC_SUSPEND 0x00200000 +#define SMSM_APPS_SHUTDOWN 0x00400000 +#define SMSM_SMD_LOOPBACK 0x00800000 +#define SMSM_RUN_QUIET 0x01000000 +#define SMSM_MODEM_WAIT 0x02000000 +#define SMSM_MODEM_BREAK 0x04000000 +#define SMSM_MODEM_CONTINUE 0x08000000 +#define SMSM_UNKNOWN 0x80000000 #define SMSM_WKUP_REASON_RPC 0x00000001 #define SMSM_WKUP_REASON_INT 0x00000002 @@ -165,6 +179,26 @@ typedef enum SMEM_ID_VENDOR1, SMEM_ID_VENDOR2, SMEM_HW_SW_BUILD_ID, + SMEM_SMD_BLOCK_PORT_BASE_ID, + SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID + SMEM_NUM_SMD_CHANNELS, + SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP + SMEM_NUM_SMD_CHANNELS, + SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP + SMEM_NUM_SMD_CHANNELS, + SMEM_SCLK_CONVERSION, + SMEM_SMD_SMSM_INTR_MUX, + SMEM_SMSM_CPU_INTR_MASK, + SMEM_APPS_DEM_SLAVE_DATA, + SMEM_QDSP6_DEM_SLAVE_DATA, + SMEM_CLKREGIM_BSP, + SMEM_CLKREGIM_SOURCES, + SMEM_SMD_FIFO_BASE_ID, + SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID + SMEM_NUM_SMD_CHANNELS, + SMEM_POWER_ON_STATUS_INFO, + SMEM_DAL_AREA, + SMEM_SMEM_LOG_POWER_IDX, + SMEM_SMEM_LOG_POWER_WRAP, + SMEM_SMEM_LOG_POWER_EVENTS, + SMEM_ERR_CRASH_LOG, + SMEM_ERR_F3_TRACE_LOG, SMEM_NUM_ITEMS, } smem_mem_type; -- cgit v1.2.3-59-g8ed1b From 283794100d2b1c1645b2949273aa4be29929812d Mon Sep 17 00:00:00 2001 From: Arve HjønnevĂ¥g Date: Wed, 20 May 2009 16:52:36 -0700 Subject: [ARM] msm: Add item argument to smsm_change_state and smsm_get_state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new protocol require writing to two state fields, and reading several fields. Signed-off-by: Arve HjønnevĂ¥g Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 58 ++++++++++++++++++++--------------------- arch/arm/mach-msm/smd_private.h | 30 +++++++++++++++------ 2 files changed, 50 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index f731ddeaa25c..e33fd029fa37 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -49,16 +49,13 @@ static int msm_smd_debug_mask; struct shared_info { int ready; - unsigned state_apps; - unsigned state_modem; + unsigned state; }; -static unsigned dummy_state_apps; -static unsigned dummy_state_modem; +static unsigned dummy_state[SMSM_STATE_COUNT]; static struct shared_info smd_info = { - .state_apps = (unsigned) &dummy_state_apps, - .state_modem = (unsigned) &dummy_state_modem, + .state = (unsigned) &dummy_state, }; module_param_named(debug_mask, msm_smd_debug_mask, @@ -115,9 +112,14 @@ static void handle_modem_crash(void) extern int (*msm_check_for_modem_crash)(void); +uint32_t raw_smsm_get_state(enum smsm_state_item item) +{ + return readl(smd_info.state + item * 4); +} + static int check_for_modem_crash(void) { - if (readl(smd_info.state_modem) & SMSM_RESET) { + if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) { handle_modem_crash(); return -1; } @@ -978,8 +980,8 @@ static irqreturn_t smsm_irq_handler(int irq, void *data) spin_lock_irqsave(&smem_lock, flags); - apps = readl(smd_info.state_apps); - modm = readl(smd_info.state_modem); + apps = raw_smsm_get_state(SMSM_STATE_APPS); + modm = raw_smsm_get_state(SMSM_STATE_MODEM); if (msm_smd_debug_mask & MSM_SMSM_DEBUG) pr_info("\n", apps, modm); @@ -992,24 +994,26 @@ static irqreturn_t smsm_irq_handler(int irq, void *data) return IRQ_HANDLED; } -int smsm_change_state(uint32_t clear_mask, uint32_t set_mask) +int smsm_change_state(enum smsm_state_item item, + uint32_t clear_mask, uint32_t set_mask) { unsigned long flags; unsigned state; + unsigned addr = smd_info.state + item * 4; if (!smd_info.ready) return -EIO; spin_lock_irqsave(&smem_lock, flags); - if (readl(smd_info.state_modem) & SMSM_RESET) + if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) handle_modem_crash(); - state = (readl(smd_info.state_apps) & ~clear_mask) | set_mask; - writel(state, smd_info.state_apps); + state = (readl(addr) & ~clear_mask) | set_mask; + writel(state, addr); if (msm_smd_debug_mask & MSM_SMSM_DEBUG) - pr_info("smsm_change_state %x\n", state); + pr_info("smsm_change_state %d %x\n", item, state); notify_other_smsm(); spin_unlock_irqrestore(&smem_lock, flags); @@ -1017,16 +1021,16 @@ int smsm_change_state(uint32_t clear_mask, uint32_t set_mask) return 0; } -uint32_t smsm_get_state(void) +uint32_t smsm_get_state(enum smsm_state_item item) { unsigned long flags; uint32_t rv; spin_lock_irqsave(&smem_lock, flags); - rv = readl(smd_info.state_modem); + rv = readl(smd_info.state + item * 4); - if (rv & SMSM_RESET) + if (item == SMSM_STATE_MODEM && (rv & SMSM_RESET)) handle_modem_crash(); spin_unlock_irqrestore(&smem_lock, flags); @@ -1145,14 +1149,8 @@ int smd_core_init(void) unsigned size; void *state; state = smem_item(SMEM_SMSM_SHARED_STATE, &size); - if (size == SMSM_V1_SIZE) { - smd_info.state_apps = state + SMSM_V1_STATE_APPS; - smd_info.state_modem = state + SMSM_V1_STATE_MODEM; - break; - } - if (size == SMSM_V2_SIZE) { - smd_info.state_apps = state + SMSM_V2_STATE_APPS; - smd_info.state_modem = state + SMSM_V2_STATE_MODEM; + if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) { + smd_info.state = (unsigned)state; break; } } @@ -1181,8 +1179,8 @@ int smd_core_init(void) do_smd_probe(); /* indicate that we're up and running */ - writel(SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT, smd_info.state_apps); - notify_other_smsm(); + smsm_change_state(SMSM_STATE_APPS, + ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT); pr_info("smd_core_init() done\n"); @@ -1227,13 +1225,13 @@ static int debug_read_stat(char *buf, int max) msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); - if (readl(smd_info.state_modem) & SMSM_RESET) + if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) i += scnprintf(buf + i, max - i, "smsm: ARM9 HAS CRASHED\n"); i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n", - readl(smd_info.state_modem), - readl(smd_info.state_apps)); + raw_smsm_get_state(SMSM_STATE_MODEM), + raw_smsm_get_state(SMSM_STATE_APPS)); if (msg) { msg[SZ_DIAG_ERR_MSG - 1] = 0; diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index 732147c2f992..35e08359bbdb 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -59,13 +59,7 @@ struct smem_shared }; #define SMSM_V1_SIZE (sizeof(unsigned) * 8) -#define SMSM_V1_STATE_APPS 0x0000 -#define SMSM_V1_STATE_MODEM 0x0004 -#define SMSM_V1_STATE_DSP 0x0008 - #define SMSM_V2_SIZE (sizeof(unsigned) * 4) -#define SMSM_V2_STATE_APPS 0x0004 -#define SMSM_V2_STATE_MODEM 0x000C struct smsm_interrupt_info { @@ -113,9 +107,29 @@ struct smsm_interrupt_info #define SMSM_WKUP_REASON_ALARM 0x00000010 #define SMSM_WKUP_REASON_RESET 0x00000020 +#ifndef CONFIG_ARCH_MSM_SCORPION +enum smsm_state_item { + SMSM_STATE_APPS = 1, + SMSM_STATE_MODEM = 3, + SMSM_STATE_COUNT, +}; +#else +enum smsm_state_item { + SMSM_STATE_APPS, + SMSM_STATE_MODEM, + SMSM_STATE_HEXAGON, + SMSM_STATE_APPS_DEM, + SMSM_STATE_MODEM_DEM, + SMSM_STATE_QDSP6_DEM, + SMSM_STATE_POWER_MASTER_DEM, + SMSM_STATE_TIME_MASTER_DEM, + SMSM_STATE_COUNT, +}; +#endif + void *smem_alloc(unsigned id, unsigned size); -int smsm_change_state(uint32_t clear_mask, uint32_t set_mask); -uint32_t smsm_get_state(void); +int smsm_change_state(enum smsm_state_item item, uint32_t clear_mask, uint32_t set_mask); +uint32_t smsm_get_state(enum smsm_state_item item); int smsm_set_sleep_duration(uint32_t delay); int smsm_set_interrupt_info(struct smsm_interrupt_info *info); void smsm_print_sleep_info(void); -- cgit v1.2.3-59-g8ed1b From ec9d3d14ffa9454e6d51e5dd1889d6e9e0be5198 Mon Sep 17 00:00:00 2001 From: Arve HjønnevĂ¥g Date: Tue, 16 Jun 2009 14:48:21 -0700 Subject: [ARM] msm: Add 8k power collapse support to smd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arve HjønnevĂ¥g Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 57 ++++++++++++++++++++++++++--------------- arch/arm/mach-msm/smd_private.h | 24 ++++++++++++++--- 2 files changed, 57 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index e33fd029fa37..b5f8957725de 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -1038,39 +1038,43 @@ uint32_t smsm_get_state(enum smsm_state_item item) return rv; } +#ifdef CONFIG_ARCH_MSM_SCORPION + int smsm_set_sleep_duration(uint32_t delay) { - uint32_t *ptr; - - ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); + struct msm_dem_slave_data *ptr = smem_alloc(SMEM_APPS_DEM_SLAVE_DATA, + sizeof(*ptr)); if (ptr == NULL) { - pr_err("smsm_set_sleep_duration \n"); + pr_err("smsm_set_sleep_duration \n"); return -EIO; } if (msm_smd_debug_mask & MSM_SMSM_DEBUG) pr_info("smsm_set_sleep_duration %d -> %d\n", - *ptr, delay); - *ptr = delay; + ptr->sleep_time, delay); + ptr->sleep_time = delay; return 0; } -int smsm_set_interrupt_info(struct smsm_interrupt_info *info) +#else + +int smsm_set_sleep_duration(uint32_t delay) { - struct smsm_interrupt_info *ptr; + uint32_t *ptr; - ptr = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*ptr)); + ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); if (ptr == NULL) { - pr_err("smsm_set_sleep_duration \n"); + pr_err("smsm_set_sleep_duration \n"); return -EIO; } if (msm_smd_debug_mask & MSM_SMSM_DEBUG) - pr_info("smsm_set_interrupt_info %x %x -> %x %x\n", - ptr->aArm_en_mask, ptr->aArm_interrupts_pending, - info->aArm_en_mask, info->aArm_interrupts_pending); - *ptr = *info; + pr_info("smsm_set_sleep_duration %d -> %d\n", + *ptr, delay); + *ptr = delay; return 0; } +#endif + #define MAX_NUM_SLEEP_CLIENTS 64 #define MAX_SLEEP_NAME_LEN 8 @@ -1115,12 +1119,13 @@ void smsm_print_sleep_info(void) if (ptr) pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr); +#ifndef CONFIG_ARCH_MSM_SCORPION int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info)); if (int_info) pr_info("SMEM_SMSM_INT_INFO %x %x %x\n", - int_info->aArm_en_mask, - int_info->aArm_interrupts_pending, - int_info->aArm_wakeup_reason); + int_info->interrupt_mask, + int_info->pending_interrupts, + int_info->wakeup_reason); gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio)); if (gpio) { @@ -1135,7 +1140,8 @@ void smsm_print_sleep_info(void) i, gpio->num_fired[i], gpio->fired[i][0], gpio->fired[i][1]); } - +#else +#endif spin_unlock_irqrestore(&smem_lock, flags); } @@ -1180,7 +1186,10 @@ int smd_core_init(void) /* indicate that we're up and running */ smsm_change_state(SMSM_STATE_APPS, - ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT); + ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT | SMSM_RUN); +#ifdef CONFIG_ARCH_MSM_SCORPION + smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0); +#endif pr_info("smd_core_init() done\n"); @@ -1232,7 +1241,15 @@ static int debug_read_stat(char *buf, int max) i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n", raw_smsm_get_state(SMSM_STATE_MODEM), raw_smsm_get_state(SMSM_STATE_APPS)); - +#ifdef CONFIG_ARCH_MSM_SCORPION + i += scnprintf(buf + i, max - i, "smsm dem: apps: %08x modem: %08x " + "qdsp6: %08x power: %08x time: %08x\n", + raw_smsm_get_state(SMSM_STATE_APPS_DEM), + raw_smsm_get_state(SMSM_STATE_MODEM_DEM), + raw_smsm_get_state(SMSM_STATE_QDSP6_DEM), + raw_smsm_get_state(SMSM_STATE_POWER_MASTER_DEM), + raw_smsm_get_state(SMSM_STATE_TIME_MASTER_DEM)); +#endif if (msg) { msg[SZ_DIAG_ERR_MSG - 1] = 0; i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg); diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index 35e08359bbdb..71f9612d5f50 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -61,12 +61,29 @@ struct smem_shared #define SMSM_V1_SIZE (sizeof(unsigned) * 8) #define SMSM_V2_SIZE (sizeof(unsigned) * 4) +#ifndef CONFIG_ARCH_MSM_SCORPION struct smsm_interrupt_info { - uint32_t aArm_en_mask; - uint32_t aArm_interrupts_pending; - uint32_t aArm_wakeup_reason; + uint32_t interrupt_mask; + uint32_t pending_interrupts; + uint32_t wakeup_reason; +}; +#else +#define DEM_MAX_PORT_NAME_LEN (20) +struct msm_dem_slave_data { + uint32_t sleep_time; + uint32_t interrupt_mask; + uint32_t resources_used; + uint32_t reserved1; + + uint32_t wakeup_reason; + uint32_t pending_interrupts; + uint32_t rpc_prog; + uint32_t rpc_proc; + char smd_port_name[DEM_MAX_PORT_NAME_LEN]; + uint32_t reserved2; }; +#endif #define SZ_DIAG_ERR_MSG 0xC8 #define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE @@ -131,7 +148,6 @@ void *smem_alloc(unsigned id, unsigned size); int smsm_change_state(enum smsm_state_item item, uint32_t clear_mask, uint32_t set_mask); uint32_t smsm_get_state(enum smsm_state_item item); int smsm_set_sleep_duration(uint32_t delay); -int smsm_set_interrupt_info(struct smsm_interrupt_info *info); void smsm_print_sleep_info(void); #define SMEM_NUM_SMD_CHANNELS 64 -- cgit v1.2.3-59-g8ed1b From 03e00cd350c6636b5f2a9854609fea93a5c7b677 Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Wed, 1 Jul 2009 17:58:37 -0700 Subject: [ARM] msm: cleanup smd, separate debugfs support - pull debug code into smd_debug.c - move necessary structures and defines into smd_private.h - fix some comment formatting, etc Signed-off-by: Brian Swetland Signed-off-by: Daniel Walker --- arch/arm/mach-msm/Makefile | 2 +- arch/arm/mach-msm/smd.c | 425 ++-------------------------------------- arch/arm/mach-msm/smd_debug.c | 310 +++++++++++++++++++++++++++++ arch/arm/mach-msm/smd_private.h | 101 ++++++++++ 4 files changed, 433 insertions(+), 405 deletions(-) create mode 100644 arch/arm/mach-msm/smd_debug.c (limited to 'arch') diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index d23fd0bf9fcc..9c3c4019da8a 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -5,7 +5,7 @@ obj-y += vreg.o obj-y += acpuclock-arm11.o obj-y += clock.o clock-7x01a.o -obj-$(CONFIG_MSM_SMD) += smd.o +obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o obj-$(CONFIG_MACH_TROUT) += board-trout.o obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index b5f8957725de..1aaee4d70863 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -46,8 +46,7 @@ enum { static int msm_smd_debug_mask; -struct shared_info -{ +struct shared_info { int ready; unsigned state; }; @@ -61,8 +60,7 @@ static struct shared_info smd_info = { module_param_named(debug_mask, msm_smd_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); -void *smem_find(unsigned id, unsigned size); -static void *smem_item(unsigned id, unsigned *size); +void *smem_item(unsigned id, unsigned *size); static void smd_diag(void); static unsigned last_heap_free = 0xffffffff; @@ -126,114 +124,27 @@ static int check_for_modem_crash(void) return 0; } -#define SMD_SS_CLOSED 0x00000000 -#define SMD_SS_OPENING 0x00000001 -#define SMD_SS_OPENED 0x00000002 -#define SMD_SS_FLUSHING 0x00000003 -#define SMD_SS_CLOSING 0x00000004 -#define SMD_SS_RESET 0x00000005 -#define SMD_SS_RESET_OPENING 0x00000006 - -#define SMD_BUF_SIZE 8192 -#define SMD_CHANNELS 64 - -#define SMD_HEADER_SIZE 20 - - /* the spinlock is used to synchronize between the -** irq handler and code that mutates the channel -** list or fiddles with channel state -*/ -static DEFINE_SPINLOCK(smd_lock); -static DEFINE_SPINLOCK(smem_lock); + * irq handler and code that mutates the channel + * list or fiddles with channel state + */ +DEFINE_SPINLOCK(smd_lock); +DEFINE_SPINLOCK(smem_lock); /* the mutex is used during open() and close() -** operations to avoid races while creating or -** destroying smd_channel structures -*/ + * operations to avoid races while creating or + * destroying smd_channel structures + */ static DEFINE_MUTEX(smd_creation_mutex); static int smd_initialized; -struct smd_alloc_elm { - char name[20]; - uint32_t cid; - uint32_t ctype; - uint32_t ref_count; -}; - -struct smd_half_channel { - unsigned state; - unsigned char fDSR; - unsigned char fCTS; - unsigned char fCD; - unsigned char fRI; - unsigned char fHEAD; - unsigned char fTAIL; - unsigned char fSTATE; - unsigned char fUNUSED; - unsigned tail; - unsigned head; -} __attribute__((packed)); - -struct smd_shared_v1 { - struct smd_half_channel ch0; - unsigned char data0[SMD_BUF_SIZE]; - struct smd_half_channel ch1; - unsigned char data1[SMD_BUF_SIZE]; -}; - -struct smd_shared_v2 { - struct smd_half_channel ch0; - struct smd_half_channel ch1; -}; - -struct smd_channel { - volatile struct smd_half_channel *send; - volatile struct smd_half_channel *recv; - unsigned char *send_data; - unsigned char *recv_data; - - unsigned fifo_mask; - unsigned fifo_size; - unsigned current_packet; - unsigned n; - - struct list_head ch_list; - - void *priv; - void (*notify)(void *priv, unsigned flags); - - int (*read)(smd_channel_t *ch, void *data, int len); - int (*write)(smd_channel_t *ch, const void *data, int len); - int (*read_avail)(smd_channel_t *ch); - int (*write_avail)(smd_channel_t *ch); - - void (*update_state)(smd_channel_t *ch); - unsigned last_state; - void (*notify_other_cpu)(void); - unsigned type; - - char name[32]; - struct platform_device pdev; -}; - -static LIST_HEAD(smd_ch_closed_list); -static LIST_HEAD(smd_ch_list); /* todo: per-target lists */ +LIST_HEAD(smd_ch_closed_list); +LIST_HEAD(smd_ch_list); /* todo: per-target lists */ static unsigned char smd_ch_allocated[64]; static struct work_struct probe_work; -#define SMD_TYPE_MASK 0x0FF -#define SMD_TYPE_APPS_MODEM 0x000 -#define SMD_TYPE_APPS_DSP 0x001 -#define SMD_TYPE_MODEM_DSP 0x002 - -#define SMD_KIND_MASK 0xF00 -#define SMD_KIND_UNKNOWN 0x000 -#define SMD_KIND_STREAM 0x100 -#define SMD_KIND_PACKET 0x200 - static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); static void smd_channel_probe_worker(struct work_struct *work) @@ -264,28 +175,6 @@ static void smd_channel_probe_worker(struct work_struct *work) } } -static char *chstate(unsigned n) -{ - switch (n) { - case SMD_SS_CLOSED: - return "CLOSED"; - case SMD_SS_OPENING: - return "OPENING"; - case SMD_SS_OPENED: - return "OPENED"; - case SMD_SS_FLUSHING: - return "FLUSHING"; - case SMD_SS_CLOSING: - return "CLOSING"; - case SMD_SS_RESET: - return "RESET"; - case SMD_SS_RESET_OPENING: - return "ROPENING"; - default: - return "UNKNOWN"; - } -} - /* how many bytes are available for reading */ static int smd_stream_read_avail(struct smd_channel *ch) { @@ -345,9 +234,9 @@ static void ch_read_done(struct smd_channel *ch, unsigned count) } /* basic read interface to ch_read_{buffer,done} used -** by smd_*_read() and update_packet_state() -** will read-and-discard if the _data pointer is null -*/ + * by smd_*_read() and update_packet_state() + * will read-and-discard if the _data pointer is null + */ static int ch_read(struct smd_channel *ch, void *_data, int len) { void *ptr; @@ -454,8 +343,7 @@ static void smd_state_change(struct smd_channel *ch, { ch->last_state = next; - pr_info("SMD: ch %d %s -> %s\n", ch->n, - chstate(last), chstate(next)); + pr_info("SMD: ch %d %d -> %d\n", ch->n, last, next); switch (next) { case SMD_SS_OPENING: @@ -936,7 +824,7 @@ void *smem_alloc(unsigned id, unsigned size) return smem_find(id, size); } -static void *smem_item(unsigned id, unsigned *size) +void *smem_item(unsigned id, unsigned *size) { struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; struct smem_heap_entry *toc = shared->heap_toc; @@ -1042,8 +930,9 @@ uint32_t smsm_get_state(enum smsm_state_item item) int smsm_set_sleep_duration(uint32_t delay) { - struct msm_dem_slave_data *ptr = smem_alloc(SMEM_APPS_DEM_SLAVE_DATA, - sizeof(*ptr)); + struct msm_dem_slave_data *ptr; + + ptr = smem_find(SMEM_APPS_DEM_SLAVE_DATA, sizeof(*ptr)); if (ptr == NULL) { pr_err("smsm_set_sleep_duration \n"); return -EIO; @@ -1061,7 +950,7 @@ int smsm_set_sleep_duration(uint32_t delay) { uint32_t *ptr; - ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); + ptr = smem_find(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); if (ptr == NULL) { pr_err("smsm_set_sleep_duration \n"); return -EIO; @@ -1075,76 +964,6 @@ int smsm_set_sleep_duration(uint32_t delay) #endif -#define MAX_NUM_SLEEP_CLIENTS 64 -#define MAX_SLEEP_NAME_LEN 8 - -#define NUM_GPIO_INT_REGISTERS 6 -#define GPIO_SMEM_NUM_GROUPS 2 -#define GPIO_SMEM_MAX_PC_INTERRUPTS 8 - -struct tramp_gpio_save { - unsigned int enable; - unsigned int detect; - unsigned int polarity; -}; - -struct tramp_gpio_smem { - uint16_t num_fired[GPIO_SMEM_NUM_GROUPS]; - uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS]; - uint32_t enabled[NUM_GPIO_INT_REGISTERS]; - uint32_t detection[NUM_GPIO_INT_REGISTERS]; - uint32_t polarity[NUM_GPIO_INT_REGISTERS]; -}; - - -void smsm_print_sleep_info(void) -{ - unsigned long flags; - uint32_t *ptr; - struct tramp_gpio_smem *gpio; - struct smsm_interrupt_info *int_info; - - - spin_lock_irqsave(&smem_lock, flags); - - ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); - if (ptr) - pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr); - - ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr)); - if (ptr) - pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr); - - ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr)); - if (ptr) - pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr); - -#ifndef CONFIG_ARCH_MSM_SCORPION - int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info)); - if (int_info) - pr_info("SMEM_SMSM_INT_INFO %x %x %x\n", - int_info->interrupt_mask, - int_info->pending_interrupts, - int_info->wakeup_reason); - - gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio)); - if (gpio) { - int i; - for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++) - pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n", - i, gpio->enabled[i], gpio->detection[i], - gpio->polarity[i]); - - for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++) - pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n", - i, gpio->num_fired[i], gpio->fired[i][0], - gpio->fired[i][1]); - } -#else -#endif - spin_unlock_irqrestore(&smem_lock, flags); -} - int smd_core_init(void) { int r; @@ -1196,207 +1015,6 @@ int smd_core_init(void) return 0; } -#if defined(CONFIG_DEBUG_FS) - -static int dump_ch(char *buf, int max, struct smd_channel *ch) -{ - volatile struct smd_half_channel *s = ch->send; - volatile struct smd_half_channel *r = ch->recv; - - return scnprintf( - buf, max, - "ch%02d:" - " %8s(%05d/%05d) %c%c%c%c%c%c%c <->" - " %8s(%05d/%05d) %c%c%c%c%c%c%c\n", ch->n, - chstate(s->state), s->tail, s->head, - s->fDSR ? 'D' : 'd', - s->fCTS ? 'C' : 'c', - s->fCD ? 'C' : 'c', - s->fRI ? 'I' : 'i', - s->fHEAD ? 'W' : 'w', - s->fTAIL ? 'R' : 'r', - s->fSTATE ? 'S' : 's', - chstate(r->state), r->tail, r->head, - r->fDSR ? 'D' : 'd', - r->fCTS ? 'R' : 'r', - r->fCD ? 'C' : 'c', - r->fRI ? 'I' : 'i', - r->fHEAD ? 'W' : 'w', - r->fTAIL ? 'R' : 'r', - r->fSTATE ? 'S' : 's' - ); -} - -static int debug_read_stat(char *buf, int max) -{ - char *msg; - int i = 0; - - msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); - - if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) - i += scnprintf(buf + i, max - i, - "smsm: ARM9 HAS CRASHED\n"); - - i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n", - raw_smsm_get_state(SMSM_STATE_MODEM), - raw_smsm_get_state(SMSM_STATE_APPS)); -#ifdef CONFIG_ARCH_MSM_SCORPION - i += scnprintf(buf + i, max - i, "smsm dem: apps: %08x modem: %08x " - "qdsp6: %08x power: %08x time: %08x\n", - raw_smsm_get_state(SMSM_STATE_APPS_DEM), - raw_smsm_get_state(SMSM_STATE_MODEM_DEM), - raw_smsm_get_state(SMSM_STATE_QDSP6_DEM), - raw_smsm_get_state(SMSM_STATE_POWER_MASTER_DEM), - raw_smsm_get_state(SMSM_STATE_TIME_MASTER_DEM)); -#endif - if (msg) { - msg[SZ_DIAG_ERR_MSG - 1] = 0; - i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg); - } - return i; -} - -static int debug_read_mem(char *buf, int max) -{ - unsigned n; - struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; - struct smem_heap_entry *toc = shared->heap_toc; - int i = 0; - - i += scnprintf(buf + i, max - i, - "heap: init=%d free=%d remain=%d\n", - shared->heap_info.initialized, - shared->heap_info.free_offset, - shared->heap_info.heap_remaining); - - for (n = 0; n < SMEM_NUM_ITEMS; n++) { - if (toc[n].allocated == 0) - continue; - i += scnprintf(buf + i, max - i, - "%04d: offset %08x size %08x\n", - n, toc[n].offset, toc[n].size); - } - return i; -} - -static int debug_read_ch(char *buf, int max) -{ - struct smd_channel *ch; - unsigned long flags; - int i = 0; - - spin_lock_irqsave(&smd_lock, flags); - list_for_each_entry(ch, &smd_ch_list, ch_list) - i += dump_ch(buf + i, max - i, ch); - list_for_each_entry(ch, &smd_ch_closed_list, ch_list) - i += dump_ch(buf + i, max - i, ch); - spin_unlock_irqrestore(&smd_lock, flags); - - return i; -} - -static int debug_read_version(char *buf, int max) -{ - struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; - unsigned version = shared->version[VERSION_MODEM]; - return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff); -} - -static int debug_read_build_id(char *buf, int max) -{ - unsigned size; - void *data; - - data = smem_item(SMEM_HW_SW_BUILD_ID, &size); - if (!data) - return 0; - - if (size >= max) - size = max; - memcpy(buf, data, size); - - return size; -} - -static int debug_read_alloc_tbl(char *buf, int max) -{ - struct smd_alloc_elm *shared; - int n, i = 0; - - shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); - - for (n = 0; n < 64; n++) { - if (shared[n].ref_count == 0) - continue; - i += scnprintf(buf + i, max - i, - "%03d: %-20s cid=%02d type=%03d " - "kind=%02d ref_count=%d\n", - n, shared[n].name, shared[n].cid, - shared[n].ctype & 0xff, - (shared[n].ctype >> 8) & 0xf, - shared[n].ref_count); - } - - return i; -} - -static int debug_boom(char *buf, int max) -{ - unsigned ms = 5000; - msm_proc_comm(PCOM_RESET_MODEM, &ms, 0); - return 0; -} - -#define DEBUG_BUFMAX 4096 -static char debug_buffer[DEBUG_BUFMAX]; - -static ssize_t debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - int (*fill)(char *buf, int max) = file->private_data; - int bsize = fill(debug_buffer, DEBUG_BUFMAX); - return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize); -} - -static int debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static const struct file_operations debug_ops = { - .read = debug_read, - .open = debug_open, -}; - -static void debug_create(const char *name, mode_t mode, - struct dentry *dent, - int (*fill)(char *buf, int max)) -{ - debugfs_create_file(name, mode, dent, fill, &debug_ops); -} - -static void smd_debugfs_init(void) -{ - struct dentry *dent; - - dent = debugfs_create_dir("smd", 0); - if (IS_ERR(dent)) - return; - - debug_create("ch", 0444, dent, debug_read_ch); - debug_create("stat", 0444, dent, debug_read_stat); - debug_create("mem", 0444, dent, debug_read_mem); - debug_create("version", 0444, dent, debug_read_version); - debug_create("tbl", 0444, dent, debug_read_alloc_tbl); - debug_create("build", 0444, dent, debug_read_build_id); - debug_create("boom", 0444, dent, debug_boom); -} -#else -static void smd_debugfs_init(void) {} -#endif - static int __init msm_smd_probe(struct platform_device *pdev) { pr_info("smd_init()\n"); @@ -1412,7 +1030,6 @@ static int __init msm_smd_probe(struct platform_device *pdev) msm_check_for_modem_crash = check_for_modem_crash; - smd_debugfs_init(); smd_initialized = 1; return 0; diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c new file mode 100644 index 000000000000..3bb40a7fa283 --- /dev/null +++ b/arch/arm/mach-msm/smd_debug.c @@ -0,0 +1,310 @@ +/* arch/arm/mach-msm/smd_debug.c + * + * Copyright (C) 2007 Google, Inc. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include + +#include + +#include "smd_private.h" + +#if defined(CONFIG_DEBUG_FS) + +static char *chstate(unsigned n) +{ + switch (n) { + case SMD_SS_CLOSED: + return "CLOSED"; + case SMD_SS_OPENING: + return "OPENING"; + case SMD_SS_OPENED: + return "OPENED"; + case SMD_SS_FLUSHING: + return "FLUSHING"; + case SMD_SS_CLOSING: + return "CLOSING"; + case SMD_SS_RESET: + return "RESET"; + case SMD_SS_RESET_OPENING: + return "ROPENING"; + default: + return "UNKNOWN"; + } +} + + +static int dump_ch(char *buf, int max, struct smd_channel *ch) +{ + volatile struct smd_half_channel *s = ch->send; + volatile struct smd_half_channel *r = ch->recv; + + return scnprintf( + buf, max, + "ch%02d:" + " %8s(%05d/%05d) %c%c%c%c%c%c%c <->" + " %8s(%05d/%05d) %c%c%c%c%c%c%c\n", ch->n, + chstate(s->state), s->tail, s->head, + s->fDSR ? 'D' : 'd', + s->fCTS ? 'C' : 'c', + s->fCD ? 'C' : 'c', + s->fRI ? 'I' : 'i', + s->fHEAD ? 'W' : 'w', + s->fTAIL ? 'R' : 'r', + s->fSTATE ? 'S' : 's', + chstate(r->state), r->tail, r->head, + r->fDSR ? 'D' : 'd', + r->fCTS ? 'R' : 'r', + r->fCD ? 'C' : 'c', + r->fRI ? 'I' : 'i', + r->fHEAD ? 'W' : 'w', + r->fTAIL ? 'R' : 'r', + r->fSTATE ? 'S' : 's' + ); +} + +static int debug_read_stat(char *buf, int max) +{ + char *msg; + int i = 0; + + msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); + + if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) + i += scnprintf(buf + i, max - i, + "smsm: ARM9 HAS CRASHED\n"); + + i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n", + raw_smsm_get_state(SMSM_STATE_MODEM), + raw_smsm_get_state(SMSM_STATE_APPS)); +#ifdef CONFIG_ARCH_MSM_SCORPION + i += scnprintf(buf + i, max - i, "smsm dem: apps: %08x modem: %08x " + "qdsp6: %08x power: %08x time: %08x\n", + raw_smsm_get_state(SMSM_STATE_APPS_DEM), + raw_smsm_get_state(SMSM_STATE_MODEM_DEM), + raw_smsm_get_state(SMSM_STATE_QDSP6_DEM), + raw_smsm_get_state(SMSM_STATE_POWER_MASTER_DEM), + raw_smsm_get_state(SMSM_STATE_TIME_MASTER_DEM)); +#endif + if (msg) { + msg[SZ_DIAG_ERR_MSG - 1] = 0; + i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg); + } + return i; +} + +static int debug_read_mem(char *buf, int max) +{ + unsigned n; + struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; + struct smem_heap_entry *toc = shared->heap_toc; + int i = 0; + + i += scnprintf(buf + i, max - i, + "heap: init=%d free=%d remain=%d\n", + shared->heap_info.initialized, + shared->heap_info.free_offset, + shared->heap_info.heap_remaining); + + for (n = 0; n < SMEM_NUM_ITEMS; n++) { + if (toc[n].allocated == 0) + continue; + i += scnprintf(buf + i, max - i, + "%04d: offset %08x size %08x\n", + n, toc[n].offset, toc[n].size); + } + return i; +} + +static int debug_read_ch(char *buf, int max) +{ + struct smd_channel *ch; + unsigned long flags; + int i = 0; + + spin_lock_irqsave(&smd_lock, flags); + list_for_each_entry(ch, &smd_ch_list, ch_list) + i += dump_ch(buf + i, max - i, ch); + list_for_each_entry(ch, &smd_ch_closed_list, ch_list) + i += dump_ch(buf + i, max - i, ch); + spin_unlock_irqrestore(&smd_lock, flags); + + return i; +} + +static int debug_read_version(char *buf, int max) +{ + struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; + unsigned version = shared->version[VERSION_MODEM]; + return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff); +} + +static int debug_read_build_id(char *buf, int max) +{ + unsigned size; + void *data; + + data = smem_item(SMEM_HW_SW_BUILD_ID, &size); + if (!data) + return 0; + + if (size >= max) + size = max; + memcpy(buf, data, size); + + return size; +} + +static int debug_read_alloc_tbl(char *buf, int max) +{ + struct smd_alloc_elm *shared; + int n, i = 0; + + shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); + + for (n = 0; n < 64; n++) { + if (shared[n].ref_count == 0) + continue; + i += scnprintf(buf + i, max - i, + "%03d: %-20s cid=%02d type=%03d " + "kind=%02d ref_count=%d\n", + n, shared[n].name, shared[n].cid, + shared[n].ctype & 0xff, + (shared[n].ctype >> 8) & 0xf, + shared[n].ref_count); + } + + return i; +} + +#define DEBUG_BUFMAX 4096 +static char debug_buffer[DEBUG_BUFMAX]; + +static ssize_t debug_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + int (*fill)(char *buf, int max) = file->private_data; + int bsize = fill(debug_buffer, DEBUG_BUFMAX); + return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize); +} + +static int debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static const struct file_operations debug_ops = { + .read = debug_read, + .open = debug_open, +}; + +static void debug_create(const char *name, mode_t mode, + struct dentry *dent, + int (*fill)(char *buf, int max)) +{ + debugfs_create_file(name, mode, dent, fill, &debug_ops); +} + +static void smd_debugfs_init(void) +{ + struct dentry *dent; + + dent = debugfs_create_dir("smd", 0); + if (IS_ERR(dent)) + return; + + debug_create("ch", 0444, dent, debug_read_ch); + debug_create("stat", 0444, dent, debug_read_stat); + debug_create("mem", 0444, dent, debug_read_mem); + debug_create("version", 0444, dent, debug_read_version); + debug_create("tbl", 0444, dent, debug_read_alloc_tbl); + debug_create("build", 0444, dent, debug_read_build_id); +} + +late_initcall(smd_debugfs_init); +#endif + + +#define MAX_NUM_SLEEP_CLIENTS 64 +#define MAX_SLEEP_NAME_LEN 8 + +#define NUM_GPIO_INT_REGISTERS 6 +#define GPIO_SMEM_NUM_GROUPS 2 +#define GPIO_SMEM_MAX_PC_INTERRUPTS 8 + +struct tramp_gpio_save { + unsigned int enable; + unsigned int detect; + unsigned int polarity; +}; + +struct tramp_gpio_smem { + uint16_t num_fired[GPIO_SMEM_NUM_GROUPS]; + uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS]; + uint32_t enabled[NUM_GPIO_INT_REGISTERS]; + uint32_t detection[NUM_GPIO_INT_REGISTERS]; + uint32_t polarity[NUM_GPIO_INT_REGISTERS]; +}; + + +void smsm_print_sleep_info(void) +{ + unsigned long flags; + uint32_t *ptr; + struct tramp_gpio_smem *gpio; + struct smsm_interrupt_info *int_info; + + + spin_lock_irqsave(&smem_lock, flags); + + ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); + if (ptr) + pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr); + + ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr)); + if (ptr) + pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr); + + ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr)); + if (ptr) + pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr); + +#ifndef CONFIG_ARCH_MSM_SCORPION + int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info)); + if (int_info) + pr_info("SMEM_SMSM_INT_INFO %x %x %x\n", + int_info->interrupt_mask, + int_info->pending_interrupts, + int_info->wakeup_reason); + + gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio)); + if (gpio) { + int i; + for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++) + pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n", + i, gpio->enabled[i], gpio->detection[i], + gpio->polarity[i]); + + for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++) + pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n", + i, gpio->num_fired[i], gpio->fired[i][0], + gpio->fired[i][1]); + } +#else +#endif + spin_unlock_irqrestore(&smem_lock, flags); +} + diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index 71f9612d5f50..13d7c9d31a9a 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -16,6 +16,10 @@ #ifndef _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_ #define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_ +#include +#include +#include + struct smem_heap_info { unsigned initialized; @@ -232,4 +236,101 @@ typedef enum SMEM_NUM_ITEMS, } smem_mem_type; + +#define SMD_SS_CLOSED 0x00000000 +#define SMD_SS_OPENING 0x00000001 +#define SMD_SS_OPENED 0x00000002 +#define SMD_SS_FLUSHING 0x00000003 +#define SMD_SS_CLOSING 0x00000004 +#define SMD_SS_RESET 0x00000005 +#define SMD_SS_RESET_OPENING 0x00000006 + +#define SMD_BUF_SIZE 8192 +#define SMD_CHANNELS 64 + +#define SMD_HEADER_SIZE 20 + +struct smd_alloc_elm { + char name[20]; + uint32_t cid; + uint32_t ctype; + uint32_t ref_count; +}; + +struct smd_half_channel { + unsigned state; + unsigned char fDSR; + unsigned char fCTS; + unsigned char fCD; + unsigned char fRI; + unsigned char fHEAD; + unsigned char fTAIL; + unsigned char fSTATE; + unsigned char fUNUSED; + unsigned tail; + unsigned head; +} __attribute__((packed)); + +struct smd_shared_v1 { + struct smd_half_channel ch0; + unsigned char data0[SMD_BUF_SIZE]; + struct smd_half_channel ch1; + unsigned char data1[SMD_BUF_SIZE]; +}; + +struct smd_shared_v2 { + struct smd_half_channel ch0; + struct smd_half_channel ch1; +}; + +struct smd_channel { + volatile struct smd_half_channel *send; + volatile struct smd_half_channel *recv; + unsigned char *send_data; + unsigned char *recv_data; + + unsigned fifo_mask; + unsigned fifo_size; + unsigned current_packet; + unsigned n; + + struct list_head ch_list; + + void *priv; + void (*notify)(void *priv, unsigned flags); + + int (*read)(struct smd_channel *ch, void *data, int len); + int (*write)(struct smd_channel *ch, const void *data, int len); + int (*read_avail)(struct smd_channel *ch); + int (*write_avail)(struct smd_channel *ch); + + void (*update_state)(struct smd_channel *ch); + unsigned last_state; + void (*notify_other_cpu)(void); + unsigned type; + + char name[32]; + struct platform_device pdev; +}; + +#define SMD_TYPE_MASK 0x0FF +#define SMD_TYPE_APPS_MODEM 0x000 +#define SMD_TYPE_APPS_DSP 0x001 +#define SMD_TYPE_MODEM_DSP 0x002 + +#define SMD_KIND_MASK 0xF00 +#define SMD_KIND_UNKNOWN 0x000 +#define SMD_KIND_STREAM 0x100 +#define SMD_KIND_PACKET 0x200 + +extern struct list_head smd_ch_closed_list; +extern struct list_head smd_ch_list; + +extern spinlock_t smd_lock; +extern spinlock_t smem_lock; + +void *smem_find(unsigned id, unsigned size); +void *smem_item(unsigned id, unsigned *size); +uint32_t raw_smsm_get_state(enum smsm_state_item item); + #endif -- cgit v1.2.3-59-g8ed1b From 37521a3181123dc4a9584cc4b8572c08ea0a8274 Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Wed, 1 Jul 2009 18:30:47 -0700 Subject: [ARM] msm: smd: add support for DSP SMD channels - QSD8250 has a DSP that speaks SMD, in addition to the modem - handle a separate list of modem vs dsp channels - install dsp smd irq handler as necessary Signed-off-by: Brian Swetland Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 114 ++++++++++++++++++++++++---------------- arch/arm/mach-msm/smd_debug.c | 9 ++-- arch/arm/mach-msm/smd_private.h | 3 +- 3 files changed, 76 insertions(+), 50 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 1aaee4d70863..a88a8fc05f86 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -35,6 +35,10 @@ #include "smd_private.h" #include "proc_comm.h" +#if defined(CONFIG_ARCH_QSD8X50) +#define CONFIG_QDSP6 1 +#endif + void (*msm_hw_reset_hook)(void); #define MODULE_NAME "msm_smd" @@ -70,6 +74,9 @@ static unsigned last_heap_free = 0xffffffff; static inline void notify_other_smsm(void) { writel(1, MSM_A2M_INT(5)); +#ifdef CONFIG_QDSP6 + writel(1, MSM_A2M_INT(8)); +#endif } static inline void notify_modem_smd(void) @@ -140,7 +147,8 @@ static DEFINE_MUTEX(smd_creation_mutex); static int smd_initialized; LIST_HEAD(smd_ch_closed_list); -LIST_HEAD(smd_ch_list); /* todo: per-target lists */ +LIST_HEAD(smd_ch_list_modem); +LIST_HEAD(smd_ch_list_dsp); static unsigned char smd_ch_allocated[64]; static struct work_struct probe_work; @@ -150,6 +158,7 @@ static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); static void smd_channel_probe_worker(struct work_struct *work) { struct smd_alloc_elm *shared; + unsigned ctype; unsigned type; unsigned n; @@ -165,12 +174,19 @@ static void smd_channel_probe_worker(struct work_struct *work) continue; if (!shared[n].name[0]) continue; + ctype = shared[n].ctype; + type = ctype & SMD_TYPE_MASK; + + /* DAL channels are stream but neither the modem, + * nor the DSP correctly indicate this. Fixup manually. + */ + if (!memcmp(shared[n].name, "DAL", 3)) + ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM; + type = shared[n].ctype & SMD_TYPE_MASK; if ((type == SMD_TYPE_APPS_MODEM) || (type == SMD_TYPE_APPS_DSP)) - smd_alloc_channel(shared[n].name, - shared[n].cid, - shared[n].ctype); + smd_alloc_channel(shared[n].name, shared[n].cid, ctype); smd_ch_allocated[n] = 1; } } @@ -403,67 +419,59 @@ static void handle_smd_irq(struct list_head *list, void (*notify)(void)) do_smd_probe(); } -static irqreturn_t smd_irq_handler(int irq, void *data) +static irqreturn_t smd_modem_irq_handler(int irq, void *data) +{ + handle_smd_irq(&smd_ch_list_modem, notify_modem_smd); + return IRQ_HANDLED; +} + +static irqreturn_t smd_dsp_irq_handler(int irq, void *data) { - handle_smd_irq(&smd_ch_list, notify_modem_smd); + handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd); return IRQ_HANDLED; } static void smd_fake_irq_handler(unsigned long arg) { - smd_irq_handler(0, NULL); + handle_smd_irq(&smd_ch_list_modem, notify_modem_smd); + handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd); } static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0); +static inline int smd_need_int(struct smd_channel *ch) +{ + if (ch_is_open(ch)) { + if (ch->recv->fHEAD || ch->recv->fTAIL || ch->recv->fSTATE) + return 1; + if (ch->recv->state != ch->last_state) + return 1; + } + return 0; +} + void smd_sleep_exit(void) { unsigned long flags; struct smd_channel *ch; - unsigned tmp; int need_int = 0; spin_lock_irqsave(&smd_lock, flags); - list_for_each_entry(ch, &smd_ch_list, ch_list) { - if (ch_is_open(ch)) { - if (ch->recv->fHEAD) { - if (msm_smd_debug_mask & MSM_SMD_DEBUG) - pr_info("smd_sleep_exit ch %d fHEAD " - "%x %x %x\n", - ch->n, ch->recv->fHEAD, - ch->recv->head, ch->recv->tail); - need_int = 1; - break; - } - if (ch->recv->fTAIL) { - if (msm_smd_debug_mask & MSM_SMD_DEBUG) - pr_info("smd_sleep_exit ch %d fTAIL " - "%x %x %x\n", - ch->n, ch->recv->fTAIL, - ch->send->head, ch->send->tail); - need_int = 1; - break; - } - if (ch->recv->fSTATE) { - if (msm_smd_debug_mask & MSM_SMD_DEBUG) - pr_info("smd_sleep_exit ch %d fSTATE %x" - "\n", ch->n, ch->recv->fSTATE); - need_int = 1; - break; - } - tmp = ch->recv->state; - if (tmp != ch->last_state) { - if (msm_smd_debug_mask & MSM_SMD_DEBUG) - pr_info("smd_sleep_exit ch %d " - "state %x != %x\n", - ch->n, tmp, ch->last_state); - need_int = 1; - break; - } + list_for_each_entry(ch, &smd_ch_list_modem, ch_list) { + if (smd_need_int(ch)) { + need_int = 1; + break; + } + } + list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) { + if (smd_need_int(ch)) { + need_int = 1; + break; } } spin_unlock_irqrestore(&smd_lock, flags); do_smd_probe(); + if (need_int) { if (msm_smd_debug_mask & MSM_SMD_DEBUG) pr_info("smd_sleep_exit need interrupt\n"); @@ -737,7 +745,11 @@ int smd_open(const char *name, smd_channel_t **_ch, *_ch = ch; spin_lock_irqsave(&smd_lock, flags); - list_add(&ch->ch_list, &smd_ch_list); + + if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM) + list_add(&ch->ch_list, &smd_ch_list_modem); + else + list_add(&ch->ch_list, &smd_ch_list_dsp); /* If the remote side is CLOSING, we need to get it to * move to OPENING (which we'll do by moving from CLOSED to @@ -982,7 +994,7 @@ int smd_core_init(void) smd_info.ready = 1; - r = request_irq(INT_A9_M2A_0, smd_irq_handler, + r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler, IRQF_TRIGGER_RISING, "smd_dev", 0); if (r < 0) return r; @@ -1000,6 +1012,16 @@ int smd_core_init(void) if (r < 0) pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n"); +#if defined(CONFIG_QDSP6) + r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler, + IRQF_TRIGGER_RISING, "smd_dsp", 0); + if (r < 0) { + free_irq(INT_A9_M2A_0, 0); + free_irq(INT_A9_M2A_5, 0); + return r; + } +#endif + /* check for any SMD channels that may already exist */ do_smd_probe(); diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c index 3bb40a7fa283..0cc3ef8a94d3 100644 --- a/arch/arm/mach-msm/smd_debug.c +++ b/arch/arm/mach-msm/smd_debug.c @@ -55,7 +55,7 @@ static int dump_ch(char *buf, int max, struct smd_channel *ch) buf, max, "ch%02d:" " %8s(%05d/%05d) %c%c%c%c%c%c%c <->" - " %8s(%05d/%05d) %c%c%c%c%c%c%c\n", ch->n, + " %8s(%05d/%05d) %c%c%c%c%c%c%c '%s'\n", ch->n, chstate(s->state), s->tail, s->head, s->fDSR ? 'D' : 'd', s->fCTS ? 'C' : 'c', @@ -71,7 +71,8 @@ static int dump_ch(char *buf, int max, struct smd_channel *ch) r->fRI ? 'I' : 'i', r->fHEAD ? 'W' : 'w', r->fTAIL ? 'R' : 'r', - r->fSTATE ? 'S' : 's' + r->fSTATE ? 'S' : 's', + ch->name ); } @@ -135,7 +136,9 @@ static int debug_read_ch(char *buf, int max) int i = 0; spin_lock_irqsave(&smd_lock, flags); - list_for_each_entry(ch, &smd_ch_list, ch_list) + list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) + i += dump_ch(buf + i, max - i, ch); + list_for_each_entry(ch, &smd_ch_list_modem, ch_list) i += dump_ch(buf + i, max - i, ch); list_for_each_entry(ch, &smd_ch_closed_list, ch_list) i += dump_ch(buf + i, max - i, ch); diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index 13d7c9d31a9a..5a8831cc41ee 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -324,7 +324,8 @@ struct smd_channel { #define SMD_KIND_PACKET 0x200 extern struct list_head smd_ch_closed_list; -extern struct list_head smd_ch_list; +extern struct list_head smd_ch_list_modem; +extern struct list_head smd_ch_list_dsp; extern spinlock_t smd_lock; extern spinlock_t smem_lock; -- cgit v1.2.3-59-g8ed1b From 7632fba05197999fb0d24776b567682ebd62f62a Mon Sep 17 00:00:00 2001 From: Haley Teng Date: Mon, 12 Oct 2009 10:38:10 -0700 Subject: [ARM] msm: smd: Update the correct fTAIL pointer after reading from fifo When we read data out of the sender's fifo, we need to advance the sender's tail pointer, not the receiver's. Signed-off-by: Haley Teng Acked-by: Dima Zavin Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index a88a8fc05f86..3fbba444e99c 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -246,7 +246,7 @@ static void ch_read_done(struct smd_channel *ch, unsigned count) { BUG_ON(count > smd_stream_read_avail(ch)); ch->recv->tail = (ch->recv->tail + count) & ch->fifo_mask; - ch->recv->fTAIL = 1; + ch->send->fTAIL = 1; } /* basic read interface to ch_read_{buffer,done} used -- cgit v1.2.3-59-g8ed1b From 34f719b0c25cca6e11164f926fc798c25499aa96 Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Fri, 30 Oct 2009 16:22:05 -0700 Subject: msm/qsd: smd: avoid race condition in smd channel allocation Don't mark a channel as allocated if we failed to allocate it (perhaps the modem updated one table but not the other, etc) Signed-off-by: Brian Swetland Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 3fbba444e99c..34bcc327aa88 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -153,7 +153,7 @@ LIST_HEAD(smd_ch_list_dsp); static unsigned char smd_ch_allocated[64]; static struct work_struct probe_work; -static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); +static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); static void smd_channel_probe_worker(struct work_struct *work) { @@ -186,8 +186,8 @@ static void smd_channel_probe_worker(struct work_struct *work) type = shared[n].ctype & SMD_TYPE_MASK; if ((type == SMD_TYPE_APPS_MODEM) || (type == SMD_TYPE_APPS_DSP)) - smd_alloc_channel(shared[n].name, shared[n].cid, ctype); - smd_ch_allocated[n] = 1; + if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype)) + smd_ch_allocated[n] = 1; } } @@ -641,20 +641,20 @@ static int smd_alloc_v1(struct smd_channel *ch) } -static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) +static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) { struct smd_channel *ch; ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL); if (ch == 0) { pr_err("smd_alloc_channel() out of memory\n"); - return; + return -1; } ch->n = cid; if (smd_alloc_v2(ch) && smd_alloc_v1(ch)) { kfree(ch); - return; + return -1; } ch->fifo_mask = ch->fifo_size - 1; @@ -696,6 +696,7 @@ static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) mutex_unlock(&smd_creation_mutex); platform_device_register(&ch->pdev); + return 0; } static void do_nothing_notify(void *priv, unsigned flags) -- cgit v1.2.3-59-g8ed1b From 1207babdcdfe5501d1528c86b445a9d1045ecc01 Mon Sep 17 00:00:00 2001 From: Iliyan Malchev Date: Sun, 15 Nov 2009 18:16:43 -0800 Subject: [ARM] msm: add /proc/last_radio_log when supported by the modem. Signed-off-by: Iliyan Malchev Signed-off-by: Daniel Walker --- arch/arm/mach-msm/Makefile | 1 + arch/arm/mach-msm/last_radio_log.c | 82 ++++++++++++++++++++++++++++++++++++++ arch/arm/mach-msm/smd.c | 4 ++ 3 files changed, 87 insertions(+) create mode 100644 arch/arm/mach-msm/last_radio_log.c (limited to 'arch') diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 9c3c4019da8a..147339c87277 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -6,6 +6,7 @@ obj-y += acpuclock-arm11.o obj-y += clock.o clock-7x01a.o obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o +obj-$(CONFIG_MSM_SMD) += last_radio_log.o obj-$(CONFIG_MACH_TROUT) += board-trout.o obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o diff --git a/arch/arm/mach-msm/last_radio_log.c b/arch/arm/mach-msm/last_radio_log.c new file mode 100644 index 000000000000..b64ba5a98686 --- /dev/null +++ b/arch/arm/mach-msm/last_radio_log.c @@ -0,0 +1,82 @@ +/* arch/arm/mach-msm/last_radio_log.c + * + * Extract the log from a modem crash though SMEM + * + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include "smd_private.h" + +static void *radio_log_base; +static size_t radio_log_size; + +extern void *smem_item(unsigned id, unsigned *size); + +static ssize_t last_radio_log_read(struct file *file, char __user *buf, + size_t len, loff_t *offset) +{ + loff_t pos = *offset; + ssize_t count; + + if (pos >= radio_log_size) + return 0; + + count = min(len, (size_t)(radio_log_size - pos)); + if (copy_to_user(buf, radio_log_base + pos, count)) { + pr_err("%s: copy to user failed\n", __func__); + return -EFAULT; + } + + *offset += count; + return count; +} + +static struct file_operations last_radio_log_fops = { + .read = last_radio_log_read +}; + +void msm_init_last_radio_log(struct module *owner) +{ + struct proc_dir_entry *entry; + + if (last_radio_log_fops.owner) { + pr_err("%s: already claimed\n", __func__); + return; + } + + radio_log_base = smem_item(SMEM_CLKREGIM_BSP, &radio_log_size); + if (!radio_log_base) { + pr_err("%s: could not retrieve SMEM_CLKREGIM_BSP\n", __func__); + return; + } + + entry = create_proc_entry("last_radio_log", S_IFREG | S_IRUGO, NULL); + if (!entry) { + pr_err("%s: could not create proc entry for radio log\n", + __func__); + return; + } + + pr_err("%s: last radio log is %d bytes long\n", __func__, + radio_log_size); + last_radio_log_fops.owner = owner; + entry->proc_fops = &last_radio_log_fops; + entry->size = radio_log_size; +} +EXPORT_SYMBOL(msm_init_last_radio_log); diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 34bcc327aa88..655fe42506ca 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -1038,6 +1038,8 @@ int smd_core_init(void) return 0; } +extern void msm_init_last_radio_log(struct module *); + static int __init msm_smd_probe(struct platform_device *pdev) { pr_info("smd_init()\n"); @@ -1053,6 +1055,8 @@ static int __init msm_smd_probe(struct platform_device *pdev) msm_check_for_modem_crash = check_for_modem_crash; + msm_init_last_radio_log(THIS_MODULE); + smd_initialized = 1; return 0; -- cgit v1.2.3-59-g8ed1b From 636eb9cbaef7989ce7809a0d842bf78470a0a1f4 Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Mon, 7 Dec 2009 15:28:08 -0800 Subject: msm: smd: provide atomic channel writes Some smd clients may write from multiple threads, in which case it's not safe to call smd_write without holding a lock. smd_write_atomic() provides the same functionality as smd_write() but obtains the smd lock first. Signed-off-by: Brian Swetland Signed-off-by: Daniel Walker --- arch/arm/mach-msm/include/mach/msm_smd.h | 1 + arch/arm/mach-msm/smd.c | 10 ++++++++++ 2 files changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h index bdf7731ab680..aa076e466e4c 100644 --- a/arch/arm/mach-msm/include/mach/msm_smd.h +++ b/arch/arm/mach-msm/include/mach/msm_smd.h @@ -38,6 +38,7 @@ int smd_read(smd_channel_t *ch, void *data, int len); ** it will return the requested length written or an error. */ int smd_write(smd_channel_t *ch, const void *data, int len); +int smd_write_atomic(smd_channel_t *ch, const void *data, int len); int smd_write_avail(smd_channel_t *ch); int smd_read_avail(smd_channel_t *ch); diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 655fe42506ca..086fd77dc891 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -804,6 +804,16 @@ int smd_write(smd_channel_t *ch, const void *data, int len) return ch->write(ch, data, len); } +int smd_write_atomic(smd_channel_t *ch, const void *data, int len) +{ + unsigned long flags; + int res; + spin_lock_irqsave(&smd_lock, flags); + res = ch->write(ch, data, len); + spin_unlock_irqrestore(&smd_lock, flags); + return res; +} + int smd_read_avail(smd_channel_t *ch) { return ch->read_avail(ch); -- cgit v1.2.3-59-g8ed1b From b42dc44afca902d19f86d541cbb665f31b9149a0 Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Fri, 29 Jan 2010 11:43:42 -0800 Subject: arm: msm: correctly signal the apps-to-modem irq in smd/proc_comm Signed-off-by: Dima Zavin Signed-off-by: Daniel Walker --- arch/arm/mach-msm/include/mach/msm_iomap.h | 6 ++++++ arch/arm/mach-msm/io.c | 3 +++ arch/arm/mach-msm/proc_comm.c | 11 +++++++++-- arch/arm/mach-msm/smd.c | 18 +++++++++++++----- 4 files changed, 31 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index 9dae1a98c77a..ce1effed5894 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -130,4 +130,10 @@ #define MSM_AD5_SIZE (SZ_1M*13) +#if defined(CONFIG_ARCH_MSM7X30) +#define MSM_GCC_BASE IOMEM(0xF8009000) +#define MSM_GCC_PHYS 0xC0182000 +#define MSM_GCC_SIZE SZ_4K +#endif + #endif diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 05f96b780aa6..fde5e58b51c3 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -44,6 +44,9 @@ static struct map_desc msm_io_desc[] __initdata = { MSM_DEVICE(CLK_CTL), #ifdef CONFIG_MSM_DEBUG_UART MSM_DEVICE(DEBUG_UART), +#endif +#ifdef CONFIG_ARCH_MSM7X30 + MSM_DEVICE(GCC), #endif { .virtual = (unsigned long) MSM_SHARED_RAM_BASE, diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c index 915ee704ed3c..1cbdebf57c37 100644 --- a/arch/arm/mach-msm/proc_comm.c +++ b/arch/arm/mach-msm/proc_comm.c @@ -23,11 +23,18 @@ #include "proc_comm.h" -#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4) +static inline void msm_a2m_int(uint32_t irq) +{ +#if defined(CONFIG_ARCH_MSM7X30) + writel(1 << irq, MSM_GCC_BASE + 0x8); +#else + writel(1, MSM_CSR_BASE + 0x400 + (irq * 4)); +#endif +} static inline void notify_other_proc_comm(void) { - writel(1, MSM_A2M_INT(6)); + msm_a2m_int(6); } #define APP_COMMAND 0x00 diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 086fd77dc891..b6966680a2d8 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -69,24 +69,32 @@ static void smd_diag(void); static unsigned last_heap_free = 0xffffffff; -#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4) +static inline void msm_a2m_int(uint32_t irq) +{ +#if defined(CONFIG_ARCH_MSM7X30) + writel(1 << irq, MSM_GCC_BASE + 0x8); +#else + writel(1, MSM_CSR_BASE + 0x400 + (irq * 4)); +#endif +} + static inline void notify_other_smsm(void) { - writel(1, MSM_A2M_INT(5)); + msm_a2m_int(5); #ifdef CONFIG_QDSP6 - writel(1, MSM_A2M_INT(8)); + msm_a2m_int(8); #endif } static inline void notify_modem_smd(void) { - writel(1, MSM_A2M_INT(0)); + msm_a2m_int(0); } static inline void notify_dsp_smd(void) { - writel(1, MSM_A2M_INT(8)); + msm_a2m_int(8); } static void smd_diag(void) -- cgit v1.2.3-59-g8ed1b From 93873bcbd16f7233dd5a20280af8e5394e702a8b Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Fri, 8 Jan 2010 18:30:03 -0800 Subject: [ARM] msm: smd: Force the half_channel struct aligmnent to 4 Forcing the alignment prevents gcc from generating byte reads for word member variables. Lack of this caused issues when the app processor modified struct members and the modem saw a partial word write. Signed-off-by: Dima Zavin Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd_private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index 5a8831cc41ee..2da758e65025 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -269,7 +269,7 @@ struct smd_half_channel { unsigned char fUNUSED; unsigned tail; unsigned head; -} __attribute__((packed)); +} __attribute__(( aligned(4), packed )); struct smd_shared_v1 { struct smd_half_channel ch0; -- cgit v1.2.3-59-g8ed1b From 79848a2a7333eee6424b38c05b4ea4a0ce56eb47 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Tue, 16 Mar 2010 15:20:07 -0700 Subject: arm: msm: smd: checkpatch clean up of smd/proc_comm This cleans up coding style. There are no run time changes. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/include/mach/msm_smd.h | 5 +++-- arch/arm/mach-msm/proc_comm.h | 4 ++-- arch/arm/mach-msm/smd.c | 8 ++------ arch/arm/mach-msm/smd_private.h | 24 ++++++++++-------------- 4 files changed, 17 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h index aa076e466e4c..029463ec8756 100644 --- a/arch/arm/mach-msm/include/mach/msm_smd.h +++ b/arch/arm/mach-msm/include/mach/msm_smd.h @@ -19,6 +19,8 @@ typedef struct smd_channel smd_channel_t; +extern int (*msm_check_for_modem_crash)(void); + /* warning: notify() may be called before open returns */ int smd_open(const char *name, smd_channel_t **ch, void *priv, void (*notify)(void *priv, unsigned event)); @@ -63,8 +65,7 @@ int smd_wait_until_readable(smd_channel_t *ch, int bytes); int smd_wait_until_writable(smd_channel_t *ch, int bytes); #endif -typedef enum -{ +typedef enum { SMD_PORT_DS = 0, SMD_PORT_DIAG, SMD_PORT_RPC_CALL, diff --git a/arch/arm/mach-msm/proc_comm.h b/arch/arm/mach-msm/proc_comm.h index 235076533c03..0f5cdd345eb7 100644 --- a/arch/arm/mach-msm/proc_comm.h +++ b/arch/arm/mach-msm/proc_comm.h @@ -217,8 +217,8 @@ enum vreg_pdown_id { }; enum { - PCOM_CLKRGM_APPS_RESET_USB_PHY = 34, - PCOM_CLKRGM_APPS_RESET_USBH = 37, + PCOM_CLKRGM_APPS_RESET_USB_PHY = 34, + PCOM_CLKRGM_APPS_RESET_USBH = 37, }; /* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */ diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index b6966680a2d8..b864592cbe05 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -123,8 +123,6 @@ static void handle_modem_crash(void) ; } -extern int (*msm_check_for_modem_crash)(void); - uint32_t raw_smsm_get_state(enum smsm_state_item item) { return readl(smd_info.state + item * 4); @@ -904,9 +902,9 @@ static irqreturn_t smsm_irq_handler(int irq, void *data) if (msm_smd_debug_mask & MSM_SMSM_DEBUG) pr_info("\n", apps, modm); - if (modm & SMSM_RESET) { + if (modm & SMSM_RESET) handle_modem_crash(); - } + do_smd_probe(); spin_unlock_irqrestore(&smem_lock, flags); @@ -1056,8 +1054,6 @@ int smd_core_init(void) return 0; } -extern void msm_init_last_radio_log(struct module *); - static int __init msm_smd_probe(struct platform_device *pdev) { pr_info("smd_init()\n"); diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index 2da758e65025..33a33f1b01f8 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -20,24 +20,21 @@ #include #include -struct smem_heap_info -{ +struct smem_heap_info { unsigned initialized; unsigned free_offset; unsigned heap_remaining; unsigned reserved; }; -struct smem_heap_entry -{ +struct smem_heap_entry { unsigned allocated; unsigned offset; unsigned size; unsigned reserved; }; -struct smem_proc_comm -{ +struct smem_proc_comm { unsigned command; unsigned status; unsigned data1; @@ -54,8 +51,7 @@ struct smem_proc_comm #define VERSION_APPS 8 #define VERSION_MODEM 9 -struct smem_shared -{ +struct smem_shared { struct smem_proc_comm proc_comm[4]; unsigned version[32]; struct smem_heap_info heap_info; @@ -66,8 +62,7 @@ struct smem_shared #define SMSM_V2_SIZE (sizeof(unsigned) * 4) #ifndef CONFIG_ARCH_MSM_SCORPION -struct smsm_interrupt_info -{ +struct smsm_interrupt_info { uint32_t interrupt_mask; uint32_t pending_interrupts; uint32_t wakeup_reason; @@ -156,8 +151,7 @@ void smsm_print_sleep_info(void); #define SMEM_NUM_SMD_CHANNELS 64 -typedef enum -{ +typedef enum { /* fixed items */ SMEM_PROC_COMM = 0, SMEM_HEAP_INFO, @@ -232,7 +226,7 @@ typedef enum SMEM_SMEM_LOG_POWER_WRAP, SMEM_SMEM_LOG_POWER_EVENTS, SMEM_ERR_CRASH_LOG, - SMEM_ERR_F3_TRACE_LOG, + SMEM_ERR_F3_TRACE_LOG, SMEM_NUM_ITEMS, } smem_mem_type; @@ -281,7 +275,7 @@ struct smd_shared_v1 { struct smd_shared_v2 { struct smd_half_channel ch0; struct smd_half_channel ch1; -}; +}; struct smd_channel { volatile struct smd_half_channel *send; @@ -334,4 +328,6 @@ void *smem_find(unsigned id, unsigned size); void *smem_item(unsigned id, unsigned *size); uint32_t raw_smsm_get_state(enum smsm_state_item item); +extern void msm_init_last_radio_log(struct module *); + #endif -- cgit v1.2.3-59-g8ed1b From bf83de4037780b11b27f1e32e33c1e8e7e42602e Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Tue, 16 Mar 2010 16:29:44 -0700 Subject: arm: msm: smd: use either package v3 or v4 not both This modifies SMD to use either the package v3 or package v4, but not both. The current code tries to allocate as v4 on all system which can produce a scary looking error message on boot up, smem_find(16, 40): wrong size 16424 smd_alloc_channel() cid=02 size=08192 'SMD_RPCCALL' With this error the code then falls back on the package v3 allocation method. This method is inefficient because it causes a slow down on some systems even when the allocation method can be determined at compile time. It also causes a kernel size increase that effects all system and is not needed. This change corrects the allocation to use one method or the other and not both. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/Kconfig | 24 ++++++++++++++--- arch/arm/mach-msm/smd.c | 44 +------------------------------ arch/arm/mach-msm/smd_private.h | 58 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 7cee7913f6f7..e73e9d17ca2e 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -1,5 +1,21 @@ if ARCH_MSM +choice + prompt "Qualcomm MSM SoC Type" + default ARCH_MSM7X00A + +config ARCH_MSM7X00A + bool "MSM7x00A / MSM7x01A" + select ARCH_MSM_ARM11 + select MSM_SMD_PKG3 + select CPU_V6 + +endchoice + +config ARCH_MSM_ARM11 + bool + + comment "MSM Board Type" depends on ARCH_MSM @@ -28,20 +44,22 @@ choice endchoice config MACH_HALIBUT - depends on ARCH_MSM - select CPU_V6 + depends on ARCH_MSM7X00A default y bool "Halibut Board (QCT SURF7201A)" help Support for the Qualcomm SURF7201A eval board. config MACH_TROUT - select CPU_V6 + depends on ARCH_MSM7X00A default y bool "HTC Dream (aka trout)" help Support for the HTC Dream, T-Mobile G1, Android ADP1 devices. +config MSM_SMD_PKG3 + bool + config MSM_SMD default y bool "MSM Shared Memory Driver (SMD)" diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index b864592cbe05..130b7a72bea1 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -605,48 +605,6 @@ static int smd_packet_read(smd_channel_t *ch, void *data, int len) return r; } -static int smd_alloc_v2(struct smd_channel *ch) -{ - struct smd_shared_v2 *shared2; - void *buffer; - unsigned buffer_sz; - - shared2 = smem_alloc(SMEM_SMD_BASE_ID + ch->n, sizeof(*shared2)); - buffer = smem_item(SMEM_SMD_FIFO_BASE_ID + ch->n, &buffer_sz); - - if (!buffer) - return -1; - - /* buffer must be a power-of-two size */ - if (buffer_sz & (buffer_sz - 1)) - return -1; - - buffer_sz /= 2; - ch->send = &shared2->ch0; - ch->recv = &shared2->ch1; - ch->send_data = buffer; - ch->recv_data = buffer + buffer_sz; - ch->fifo_size = buffer_sz; - return 0; -} - -static int smd_alloc_v1(struct smd_channel *ch) -{ - struct smd_shared_v1 *shared1; - shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1)); - if (!shared1) { - pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n); - return -1; - } - ch->send = &shared1->ch0; - ch->recv = &shared1->ch1; - ch->send_data = shared1->data0; - ch->recv_data = shared1->data1; - ch->fifo_size = SMD_BUF_SIZE; - return 0; -} - - static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) { struct smd_channel *ch; @@ -658,7 +616,7 @@ static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) } ch->n = cid; - if (smd_alloc_v2(ch) && smd_alloc_v1(ch)) { + if (_smd_alloc_channel(ch)) { kfree(ch); return -1; } diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index 33a33f1b01f8..3d337ce35a61 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -61,7 +61,7 @@ struct smem_shared { #define SMSM_V1_SIZE (sizeof(unsigned) * 8) #define SMSM_V2_SIZE (sizeof(unsigned) * 4) -#ifndef CONFIG_ARCH_MSM_SCORPION +#ifdef CONFIG_MSM_SMD_PKG3 struct smsm_interrupt_info { uint32_t interrupt_mask; uint32_t pending_interrupts; @@ -123,7 +123,7 @@ struct msm_dem_slave_data { #define SMSM_WKUP_REASON_ALARM 0x00000010 #define SMSM_WKUP_REASON_RESET 0x00000020 -#ifndef CONFIG_ARCH_MSM_SCORPION +#ifdef CONFIG_ARCH_MSM7X00A enum smsm_state_item { SMSM_STATE_APPS = 1, SMSM_STATE_MODEM = 3, @@ -265,6 +265,7 @@ struct smd_half_channel { unsigned head; } __attribute__(( aligned(4), packed )); +/* Only used on SMD package v3 on msm7201a */ struct smd_shared_v1 { struct smd_half_channel ch0; unsigned char data0[SMD_BUF_SIZE]; @@ -272,6 +273,7 @@ struct smd_shared_v1 { unsigned char data1[SMD_BUF_SIZE]; }; +/* Used on SMD package v4 */ struct smd_shared_v2 { struct smd_half_channel ch0; struct smd_half_channel ch1; @@ -330,4 +332,56 @@ uint32_t raw_smsm_get_state(enum smsm_state_item item); extern void msm_init_last_radio_log(struct module *); +#ifdef CONFIG_MSM_SMD_PKG3 +/* + * This allocator assumes an SMD Package v3 which only exists on + * MSM7x00 SoC's. + */ +static inline int _smd_alloc_channel(struct smd_channel *ch) +{ + struct smd_shared_v1 *shared1; + + shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1)); + if (!shared1) { + pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n); + return -1; + } + ch->send = &shared1->ch0; + ch->recv = &shared1->ch1; + ch->send_data = shared1->data0; + ch->recv_data = shared1->data1; + ch->fifo_size = SMD_BUF_SIZE; + return 0; +} +#else +/* + * This allocator assumes an SMD Package v4, the most common + * and the default. + */ +static inline int _smd_alloc_channel(struct smd_channel *ch) +{ + struct smd_shared_v2 *shared2; + void *buffer; + unsigned buffer_sz; + + shared2 = smem_alloc(SMEM_SMD_BASE_ID + ch->n, sizeof(*shared2)); + buffer = smem_item(SMEM_SMD_FIFO_BASE_ID + ch->n, &buffer_sz); + + if (!buffer) + return -1; + + /* buffer must be a power-of-two size */ + if (buffer_sz & (buffer_sz - 1)) + return -1; + + buffer_sz /= 2; + ch->send = &shared2->ch0; + ch->recv = &shared2->ch1; + ch->send_data = buffer; + ch->recv_data = buffer + buffer_sz; + ch->fifo_size = buffer_sz; + return 0; +} +#endif /* CONFIG_MSM_SMD_PKG3 */ + #endif -- cgit v1.2.3-59-g8ed1b From 1a86fbc167fdf8ac387a52d49782d7a5bc1d9ac9 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 17 Mar 2010 09:58:29 -0700 Subject: arm: msm: smd: convert unsigned addr to unsigned long "unsigned" translates to "unsigned int", but this value holds an address. We always want to use unsigned long for addresses since it will change size to fit the machine. This just convert the one address holder to unsigned long. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 130b7a72bea1..2e32d9ab3609 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -872,9 +872,9 @@ static irqreturn_t smsm_irq_handler(int irq, void *data) int smsm_change_state(enum smsm_state_item item, uint32_t clear_mask, uint32_t set_mask) { + unsigned long addr = smd_info.state + item * 4; unsigned long flags; unsigned state; - unsigned addr = smd_info.state + item * 4; if (!smd_info.ready) return -EIO; -- cgit v1.2.3-59-g8ed1b From 74df1d07ee01b7276cba64160ea6dfe195de008f Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 17 Mar 2010 10:51:10 -0700 Subject: arm: msm: smd: msm7x30 a2m clean up This moves the msm_a2m_int() function into the header, and does a small macro clean up to be more inline with Linux norms. No functional changes. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 12 ------------ arch/arm/mach-msm/smd_private.h | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 2e32d9ab3609..2a9b85ca5c07 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -26,10 +26,8 @@ #include #include #include -#include #include -#include #include #include "smd_private.h" @@ -69,16 +67,6 @@ static void smd_diag(void); static unsigned last_heap_free = 0xffffffff; -static inline void msm_a2m_int(uint32_t irq) -{ -#if defined(CONFIG_ARCH_MSM7X30) - writel(1 << irq, MSM_GCC_BASE + 0x8); -#else - writel(1, MSM_CSR_BASE + 0x400 + (irq * 4)); -#endif -} - - static inline void notify_other_smsm(void) { msm_a2m_int(5); diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index 3d337ce35a61..727bfe68aa9b 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -19,6 +19,9 @@ #include #include #include +#include + +#include struct smem_heap_info { unsigned initialized; @@ -384,4 +387,17 @@ static inline int _smd_alloc_channel(struct smd_channel *ch) } #endif /* CONFIG_MSM_SMD_PKG3 */ +#if defined(CONFIG_ARCH_MSM7X30) +static inline void msm_a2m_int(uint32_t irq) +{ + writel(1 << irq, MSM_GCC_BASE + 0x8); +} +#else +static inline void msm_a2m_int(uint32_t irq) +{ + writel(1, MSM_CSR_BASE + 0x400 + (irq * 4)); +} +#endif /* CONFIG_ARCH_MSM7X30 */ + + #endif -- cgit v1.2.3-59-g8ed1b From 3843ac3a5cd01824b5801209808e73fb9df7ee22 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 17 Mar 2010 11:10:40 -0700 Subject: arm: msm: smd: remove unneeded predefines This just removed some unneeded predefines. One needed a whole function moved down further. The others could just be deleted. No functional changes. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 77 +++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 41 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 2a9b85ca5c07..f3558f504709 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -62,9 +62,6 @@ static struct shared_info smd_info = { module_param_named(debug_mask, msm_smd_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); -void *smem_item(unsigned id, unsigned *size); -static void smd_diag(void); - static unsigned last_heap_free = 0xffffffff; static inline void notify_other_smsm(void) @@ -147,44 +144,6 @@ LIST_HEAD(smd_ch_list_dsp); static unsigned char smd_ch_allocated[64]; static struct work_struct probe_work; -static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); - -static void smd_channel_probe_worker(struct work_struct *work) -{ - struct smd_alloc_elm *shared; - unsigned ctype; - unsigned type; - unsigned n; - - shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); - if (!shared) { - pr_err("smd: cannot find allocation table\n"); - return; - } - for (n = 0; n < 64; n++) { - if (smd_ch_allocated[n]) - continue; - if (!shared[n].ref_count) - continue; - if (!shared[n].name[0]) - continue; - ctype = shared[n].ctype; - type = ctype & SMD_TYPE_MASK; - - /* DAL channels are stream but neither the modem, - * nor the DSP correctly indicate this. Fixup manually. - */ - if (!memcmp(shared[n].name, "DAL", 3)) - ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM; - - type = shared[n].ctype & SMD_TYPE_MASK; - if ((type == SMD_TYPE_APPS_MODEM) || - (type == SMD_TYPE_APPS_DSP)) - if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype)) - smd_ch_allocated[n] = 1; - } -} - /* how many bytes are available for reading */ static int smd_stream_read_avail(struct smd_channel *ch) { @@ -651,6 +610,42 @@ static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) return 0; } +static void smd_channel_probe_worker(struct work_struct *work) +{ + struct smd_alloc_elm *shared; + unsigned ctype; + unsigned type; + unsigned n; + + shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); + if (!shared) { + pr_err("smd: cannot find allocation table\n"); + return; + } + for (n = 0; n < 64; n++) { + if (smd_ch_allocated[n]) + continue; + if (!shared[n].ref_count) + continue; + if (!shared[n].name[0]) + continue; + ctype = shared[n].ctype; + type = ctype & SMD_TYPE_MASK; + + /* DAL channels are stream but neither the modem, + * nor the DSP correctly indicate this. Fixup manually. + */ + if (!memcmp(shared[n].name, "DAL", 3)) + ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM; + + type = shared[n].ctype & SMD_TYPE_MASK; + if ((type == SMD_TYPE_APPS_MODEM) || + (type == SMD_TYPE_APPS_DSP)) + if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype)) + smd_ch_allocated[n] = 1; + } +} + static void do_nothing_notify(void *priv, unsigned flags) { } -- cgit v1.2.3-59-g8ed1b From b13525c2637957a757709945fbc9bc8b1065d071 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 18 Mar 2010 10:10:30 -0700 Subject: arm: msm: smd: ifdef dsp irq handler This irq handler isn't used in all cases, so add the proper ifdef. This eliminates a compiler warning due to the function not getting used. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index f3558f504709..de9343ec5cff 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -378,11 +378,13 @@ static irqreturn_t smd_modem_irq_handler(int irq, void *data) return IRQ_HANDLED; } +#if defined(CONFIG_QDSP6) static irqreturn_t smd_dsp_irq_handler(int irq, void *data) { handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd); return IRQ_HANDLED; } +#endif static void smd_fake_irq_handler(unsigned long arg) { -- cgit v1.2.3-59-g8ed1b From 0aec66d493c1476daa88ec56b1076e51f1ceff0b Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 18 Mar 2010 12:31:08 -0700 Subject: arm: msm: smd: fix SMD modem processor sync condition When booting up we need to wait for the modem processor to partially boot. This is because the modem processor does resource allocation for us. If we don't wait the modem won't honor our requests and we end up crashing or in an unknown state. This change just formalizes the waiting process. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/proc_comm.c | 15 ++++++++++++++- arch/arm/mach-msm/proc_comm.h | 3 +++ arch/arm/mach-msm/smd.c | 7 +++++++ 3 files changed, 24 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c index 1cbdebf57c37..67e701c7f183 100644 --- a/arch/arm/mach-msm/proc_comm.c +++ b/arch/arm/mach-msm/proc_comm.c @@ -114,4 +114,17 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2) return ret; } - +/* + * We need to wait for the ARM9 to at least partially boot + * up before we can continue. Since the ARM9 does resource + * allocation, if we dont' wait we could end up crashing or in + * and unknown state. This function should be called early to + * wait on the ARM9. + */ +void __init proc_comm_boot_wait(void) +{ + void __iomem *base = MSM_SHARED_RAM_BASE; + + proc_comm_wait_for(base + MDM_STATUS, PCOM_READY); + +} diff --git a/arch/arm/mach-msm/proc_comm.h b/arch/arm/mach-msm/proc_comm.h index 0f5cdd345eb7..12da4cacd4a8 100644 --- a/arch/arm/mach-msm/proc_comm.h +++ b/arch/arm/mach-msm/proc_comm.h @@ -16,6 +16,8 @@ #ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_ #define _ARCH_ARM_MACH_MSM_PROC_COMM_H_ +#include + enum { PCOM_CMD_IDLE = 0x0, PCOM_CMD_DONE, @@ -251,5 +253,6 @@ enum { (((drvstr) & 0xF) << 17)) int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2); +void __init proc_comm_boot_wait(void); #endif diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index de9343ec5cff..cf11d414b425 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -1001,6 +1001,13 @@ static int __init msm_smd_probe(struct platform_device *pdev) { pr_info("smd_init()\n"); + /* + * If we haven't waited for the ARM9 to boot up till now, + * then we need to wait here. Otherwise this should just + * return immediately. + */ + proc_comm_boot_wait(); + INIT_WORK(&probe_work, smd_channel_probe_worker); if (smd_core_init()) { -- cgit v1.2.3-59-g8ed1b From 3a9f346a95d4faa05f4eca6470f971244073e18e Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 22 Apr 2010 14:16:46 -0700 Subject: arm: msm: smd: remove Kconfig menu option This removes the Kconfig menu option. SMD can still be selected but it's done inside the Kconfig file and not via the menu. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/Kconfig | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index e73e9d17ca2e..69cc693aa51e 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -7,6 +7,7 @@ choice config ARCH_MSM7X00A bool "MSM7x00A / MSM7x01A" select ARCH_MSM_ARM11 + select MSM_SMD select MSM_SMD_PKG3 select CPU_V6 @@ -61,13 +62,6 @@ config MSM_SMD_PKG3 bool config MSM_SMD - default y - bool "MSM Shared Memory Driver (SMD)" - help - Support for the shared memory interface between the apps - processor and the baseband processor. Provides access to - the "shared heap", as well as virtual serial channels - used to communicate with various services on the baseband - processor. + bool endif -- cgit v1.2.3-59-g8ed1b From 42df2c99162d1da63f11d073059e9633bfec11d0 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 22 Apr 2010 16:09:03 -0700 Subject: arm: msm: trout: fix build failure without UART Without a debug uart selected you get this failure, arch/arm/mach-msm/board-trout.c:85: error: 'MSM_DEBUG_UART_PHYS' undeclared here (not in a function) arch/arm/mach-msm/board-trout.c:86: error: 'MSM_DEBUG_UART_BASE' undeclared here (not in a function) This just removes these lines in that case. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/board-trout.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index 9793ff45deb4..b88aec269df5 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c @@ -82,8 +82,10 @@ static void __init trout_map_io(void) } MACHINE_START(TROUT, "HTC Dream") +#ifdef CONFIG_MSM_DEBUG_UART .phys_io = MSM_DEBUG_UART_PHYS, .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, +#endif .boot_params = 0x10000100, .fixup = trout_fixup, .map_io = trout_map_io, -- cgit v1.2.3-59-g8ed1b From 869a2a09e40529f2f3614893c98b27a87a33eaa6 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Fri, 23 Apr 2010 11:04:14 -0700 Subject: arm: msm: smd: fix initcall prototype compiler warning This fixes the following warning, arch/arm/mach-msm/smd_debug.c:240: warning: initialization from incompatible pointer type Signed-off-by: Daniel Walker --- arch/arm/mach-msm/smd_debug.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c index 0cc3ef8a94d3..3b2dd717b788 100644 --- a/arch/arm/mach-msm/smd_debug.c +++ b/arch/arm/mach-msm/smd_debug.c @@ -221,13 +221,13 @@ static void debug_create(const char *name, mode_t mode, debugfs_create_file(name, mode, dent, fill, &debug_ops); } -static void smd_debugfs_init(void) +static int smd_debugfs_init(void) { struct dentry *dent; dent = debugfs_create_dir("smd", 0); if (IS_ERR(dent)) - return; + return 1; debug_create("ch", 0444, dent, debug_read_ch); debug_create("stat", 0444, dent, debug_read_stat); @@ -235,6 +235,8 @@ static void smd_debugfs_init(void) debug_create("version", 0444, dent, debug_read_version); debug_create("tbl", 0444, dent, debug_read_alloc_tbl); debug_create("build", 0444, dent, debug_read_build_id); + + return 0; } late_initcall(smd_debugfs_init); -- cgit v1.2.3-59-g8ed1b From 29d3dedf22bc8272186a7e0d8a8243d88606b569 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Fri, 23 Apr 2010 16:02:19 -0700 Subject: arm: msm: video: add msm_fb.h Also drops the old mddi structure, which conflicts with the new file. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/include/mach/board.h | 6 -- arch/arm/mach-msm/include/mach/msm_fb.h | 147 ++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 arch/arm/mach-msm/include/mach/msm_fb.h (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h index fb12fd87bb81..7933641c4761 100644 --- a/arch/arm/mach-msm/include/mach/board.h +++ b/arch/arm/mach-msm/include/mach/board.h @@ -21,12 +21,6 @@ /* platform device data structures */ -struct msm_mddi_platform_data -{ - void (*panel_power)(int on); - unsigned has_vsync_irq:1; -}; - struct msm_acpu_clock_platform_data { uint32_t acpu_switch_time_us; diff --git a/arch/arm/mach-msm/include/mach/msm_fb.h b/arch/arm/mach-msm/include/mach/msm_fb.h new file mode 100644 index 000000000000..1f4fc81b3d8f --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_fb.h @@ -0,0 +1,147 @@ +/* arch/arm/mach-msm/include/mach/msm_fb.h + * + * Internal shared definitions for various MSM framebuffer parts. + * + * Copyright (C) 2007 Google Incorporated + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + */ + +#ifndef _MSM_FB_H_ +#define _MSM_FB_H_ + +#include + +struct mddi_info; + +struct msm_fb_data { + int xres; /* x resolution in pixels */ + int yres; /* y resolution in pixels */ + int width; /* disply width in mm */ + int height; /* display height in mm */ + unsigned output_format; +}; + +struct msmfb_callback { + void (*func)(struct msmfb_callback *); +}; + +enum { + MSM_MDDI_PMDH_INTERFACE, + MSM_MDDI_EMDH_INTERFACE, + MSM_EBI2_INTERFACE, +}; + +#define MSMFB_CAP_PARTIAL_UPDATES (1 << 0) + +struct msm_panel_data { + /* turns off the fb memory */ + int (*suspend)(struct msm_panel_data *); + /* turns on the fb memory */ + int (*resume)(struct msm_panel_data *); + /* turns off the panel */ + int (*blank)(struct msm_panel_data *); + /* turns on the panel */ + int (*unblank)(struct msm_panel_data *); + void (*wait_vsync)(struct msm_panel_data *); + void (*request_vsync)(struct msm_panel_data *, struct msmfb_callback *); + void (*clear_vsync)(struct msm_panel_data *); + /* from the enum above */ + unsigned interface_type; + /* data to be passed to the fb driver */ + struct msm_fb_data *fb_data; + + /* capabilities supported by the panel */ + uint32_t caps; +}; + +struct msm_mddi_client_data { + void (*suspend)(struct msm_mddi_client_data *); + void (*resume)(struct msm_mddi_client_data *); + void (*activate_link)(struct msm_mddi_client_data *); + void (*remote_write)(struct msm_mddi_client_data *, uint32_t val, + uint32_t reg); + uint32_t (*remote_read)(struct msm_mddi_client_data *, uint32_t reg); + void (*auto_hibernate)(struct msm_mddi_client_data *, int); + /* custom data that needs to be passed from the board file to a + * particular client */ + void *private_client_data; + struct resource *fb_resource; + /* from the list above */ + unsigned interface_type; +}; + +struct msm_mddi_platform_data { + unsigned int clk_rate; + void (*power_client)(struct msm_mddi_client_data *, int on); + + /* fixup the mfr name, product id */ + void (*fixup)(uint16_t *mfr_name, uint16_t *product_id); + + struct resource *fb_resource; /*optional*/ + /* number of clients in the list that follows */ + int num_clients; + /* array of client information of clients */ + struct { + unsigned product_id; /* mfr id in top 16 bits, product id + * in lower 16 bits + */ + char *name; /* the device name will be the platform + * device name registered for the client, + * it should match the name of the associated + * driver + */ + unsigned id; /* id for mddi client device node, will also + * be used as device id of panel devices, if + * the client device will have multiple panels + * space must be left here for them + */ + void *client_data; /* required private client data */ + unsigned int clk_rate; /* optional: if the client requires a + * different mddi clk rate + */ + } client_platform_data[]; +}; + +struct mdp_blit_req; +struct fb_info; +struct mdp_device { + struct device dev; + void (*dma)(struct mdp_device *mpd, uint32_t addr, + uint32_t stride, uint32_t w, uint32_t h, uint32_t x, + uint32_t y, struct msmfb_callback *callback, int interface); + void (*dma_wait)(struct mdp_device *mdp); + int (*blit)(struct mdp_device *mdp, struct fb_info *fb, + struct mdp_blit_req *req); + void (*set_grp_disp)(struct mdp_device *mdp, uint32_t disp_id); +}; + +struct class_interface; +int register_mdp_client(struct class_interface *class_intf); + +/**** private client data structs go below this line ***/ + +struct msm_mddi_bridge_platform_data { + /* from board file */ + int (*init)(struct msm_mddi_bridge_platform_data *, + struct msm_mddi_client_data *); + int (*uninit)(struct msm_mddi_bridge_platform_data *, + struct msm_mddi_client_data *); + /* passed to panel for use by the fb driver */ + int (*blank)(struct msm_mddi_bridge_platform_data *, + struct msm_mddi_client_data *); + int (*unblank)(struct msm_mddi_bridge_platform_data *, + struct msm_mddi_client_data *); + struct msm_fb_data fb_data; +}; + + + +#endif -- cgit v1.2.3-59-g8ed1b From d6290a3ead555c0b092d48288b4dc0566580e17f Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 26 Apr 2010 14:59:09 -0700 Subject: OMAP3: PRCM interrupt: only check and clear enabled PRCM IRQs While handling PRCM IRQs, mask out interrupts that are not enabled in PRM_IRQENABLE_MPU. If these are not masked out, non-enabled interrupts are caught, a WARN() is printed due to no 'handler' and the events are cleared. In addition to being noisy, this can also interfere with independent polling of this register by SR/VP code. This was noticed using SmartReflex transitions which cause the VPx_* interrupts to be handled since they are set in PRM_IRQSTATUS_MPU even but not enabled in PRM_IRQENABLE_MPU. Acked-by: Mike Turquette Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index ea0000bc5358..a15aa92d384e 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -267,13 +267,16 @@ static int _prcm_int_handle_wakeup(void) */ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) { - u32 irqstatus_mpu; + u32 irqenable_mpu, irqstatus_mpu; int c = 0; - do { - irqstatus_mpu = prm_read_mod_reg(OCP_MOD, - OMAP3_PRM_IRQSTATUS_MPU_OFFSET); + irqenable_mpu = prm_read_mod_reg(OCP_MOD, + OMAP3_PRM_IRQENABLE_MPU_OFFSET); + irqstatus_mpu = prm_read_mod_reg(OCP_MOD, + OMAP3_PRM_IRQSTATUS_MPU_OFFSET); + irqstatus_mpu &= irqenable_mpu; + do { if (irqstatus_mpu & (OMAP3430_WKUP_ST | OMAP3430_IO_ST)) { c = _prcm_int_handle_wakeup(); @@ -292,7 +295,11 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) prm_write_mod_reg(irqstatus_mpu, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); - } while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET)); + irqstatus_mpu = prm_read_mod_reg(OCP_MOD, + OMAP3_PRM_IRQSTATUS_MPU_OFFSET); + irqstatus_mpu &= irqenable_mpu; + + } while (irqstatus_mpu); return IRQ_HANDLED; } -- cgit v1.2.3-59-g8ed1b From 8e2efde9f1ba2fb918245f9419246e4e59b42a11 Mon Sep 17 00:00:00 2001 From: Ari Kauppi Date: Tue, 23 Mar 2010 09:04:59 +0200 Subject: OMAP3: PM: Add milliseconds interface to suspend wakeup timer Millisecond resolution is possible and there are use cases for it (automatic testing). Seconds-based interface is preserved for compatibility. Signed-off-by: Ari Kauppi Reviewed-by: Phil Carmody Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm-debug.c | 3 +++ arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm34xx.c | 17 ++++++++++------- 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 6cac9817c243..723b44e252fd 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -548,6 +548,9 @@ static int option_set(void *data, u64 val) { u32 *option = data; + if (option == &wakeup_timer_milliseconds && val >= 1000) + return -EINVAL; + *option = val; if (option == &enable_off_mode) diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index bd6466a2b039..3de6ece23fc8 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -43,6 +43,7 @@ extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); extern u32 wakeup_timer_seconds; +extern u32 wakeup_timer_milliseconds; extern struct omap_dm_timer *gptimer_wakeup; #ifdef CONFIG_PM_DEBUG diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index a15aa92d384e..e76af5b532a0 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -58,6 +58,7 @@ u32 enable_off_mode; u32 sleep_while_idle; u32 wakeup_timer_seconds; +u32 wakeup_timer_milliseconds; struct power_state { struct powerdomain *pwrdm; @@ -555,20 +556,21 @@ out: #ifdef CONFIG_SUSPEND static suspend_state_t suspend_state; -static void omap2_pm_wakeup_on_timer(u32 seconds) +static void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) { u32 tick_rate, cycles; - if (!seconds) + if (!seconds && !milliseconds) return; tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); - cycles = tick_rate * seconds; + cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; omap_dm_timer_stop(gptimer_wakeup); omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); - pr_info("PM: Resume timer in %d secs (%d ticks at %d ticks/sec.)\n", - seconds, cycles, tick_rate); + pr_info("PM: Resume timer in %u.%03u secs" + " (%d ticks at %d ticks/sec.)\n", + seconds, milliseconds, cycles, tick_rate); } static int omap3_pm_prepare(void) @@ -582,8 +584,9 @@ static int omap3_pm_suspend(void) struct power_state *pwrst; int state, ret = 0; - if (wakeup_timer_seconds) - omap2_pm_wakeup_on_timer(wakeup_timer_seconds); + if (wakeup_timer_seconds || wakeup_timer_milliseconds) + omap2_pm_wakeup_on_timer(wakeup_timer_seconds, + wakeup_timer_milliseconds); /* Read current next_pwrsts */ list_for_each_entry(pwrst, &pwrst_list, node) -- cgit v1.2.3-59-g8ed1b From f3a8cde6bc58d97723cbc965d4d03a7cd86152fb Mon Sep 17 00:00:00 2001 From: Ranjith Lohithakshan Date: Mon, 3 May 2010 17:07:51 +0530 Subject: OMAP3EVM: Update pad configuration for wakeup enabled pads OMAP3530 TRM section 7.4.4.4.2 requires OFFOUTENABLE to be set (active low) if wakeup capabilities are enabled on a pad. During OFF mode testing on OMAP3530 EVM, it was observed that the device was not residing in the OFF state. The device enters into the OFF state and immediately exits from that state as if an IO wakeup event has occured. The issue was traced down to the pad configuration of wkaeup enabled pad's. Signed-off-by: Ranjith Lohithakshan Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/board-omap3evm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 017bb2f4f7d2..3548fb859123 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -651,10 +651,10 @@ static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { #ifdef CONFIG_OMAP_MUX static struct omap_board_mux board_mux[] __initdata = { OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_INPUT_PULLUP | + OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | OMAP_PIN_OFF_WAKEUPENABLE), OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_INPUT_PULLUP | + OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | OMAP_PIN_OFF_WAKEUPENABLE), { .reg_offset = OMAP_MUX_TERMINATOR }, }; -- cgit v1.2.3-59-g8ed1b From 7a44ad2fce65ed2811ebef4adbc38bcc82cd44a7 Mon Sep 17 00:00:00 2001 From: Ranjith Lohithakshan Date: Sat, 8 May 2010 12:39:21 +0530 Subject: OMAP3: PM: Enable wakeup from ads7846 touchscreen This patch enables the wakeup capabilities of ads7846 touchscreen driver. ads7846 driver can now wakeup the system from suspend on OMAP3430 EVM and SDP boards. The earlier approach of enabling wakeup on the touchscreen GPIO pin during board level mux init is removed. Instead the wakeup flag in ads7846_platform_data is enabled. Based on the flag, the ads7846 driver will do an enable_irq_wake which will eventually call into the OMAP GPIO layer and will enable the wakeup capability on the GPIO pin. Signed-off-by: Ranjith Lohithakshan Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/board-3430sdp.c | 1 + arch/arm/mach-omap2/board-omap3evm.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 5822bcf7b15f..e7d629b3c76a 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -150,6 +150,7 @@ static int ads7846_get_pendown_state(void) static struct ads7846_platform_data tsc2046_config __initdata = { .get_pendown_state = ads7846_get_pendown_state, .keep_vref_on = 1, + .wakeup = true, }; diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 3548fb859123..cfbe695103d0 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -600,6 +600,7 @@ struct ads7846_platform_data ads7846_config = { .get_pendown_state = ads7846_get_pendown_state, .keep_vref_on = 1, .settle_delay_usecs = 150, + .wakeup = true, }; static struct omap2_mcspi_device_config ads7846_mcspi_config = { @@ -654,8 +655,7 @@ static struct omap_board_mux board_mux[] __initdata = { OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | OMAP_PIN_OFF_WAKEUPENABLE), OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | - OMAP_PIN_OFF_WAKEUPENABLE), + OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW), { .reg_offset = OMAP_MUX_TERMINATOR }, }; #else -- cgit v1.2.3-59-g8ed1b From 40742fa82ebf53c9367f5807cf1012d518516e74 Mon Sep 17 00:00:00 2001 From: Mike Chan Date: Mon, 3 May 2010 16:04:06 -0700 Subject: OMAP3: PM: Enable IO / IO-CHAIN wakeups for PER IO events can also come from GPIO modules, which reside in the PER domain. It is possible for the PER to enter RET while CORE is still in ON. If GPIO 2-6 are enabled for IO-pad wakeups, the PER domain will not wakeup in this case, unless we enable it. Signed-off-by: Mike Chan Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index e76af5b532a0..eec0916de819 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -379,9 +379,16 @@ void omap_sram_idle(void) if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON) pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state); - /* PER */ + /* Enable IO-PAD and IO-CHAIN wakeups */ per_next_state = pwrdm_read_next_pwrst(per_pwrdm); core_next_state = pwrdm_read_next_pwrst(core_pwrdm); + if (per_next_state < PWRDM_POWER_ON || + core_next_state < PWRDM_POWER_ON) { + prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); + omap3_enable_io_chain(); + } + + /* PER */ if (per_next_state < PWRDM_POWER_ON) { omap_uart_prepare_idle(2); omap2_gpio_prepare_for_retention(); @@ -406,10 +413,8 @@ void omap_sram_idle(void) omap3_core_save_context(); omap3_prcm_save_context(); } - /* Enable IO-PAD and IO-CHAIN wakeups */ - prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); - omap3_enable_io_chain(); } + omap3_intc_prepare_idle(); /* @@ -471,7 +476,8 @@ void omap_sram_idle(void) } /* Disable IO-PAD and IO-CHAIN wakeup */ - if (core_next_state < PWRDM_POWER_ON) { + if (per_next_state < PWRDM_POWER_ON || + core_next_state < PWRDM_POWER_ON) { prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); omap3_disable_io_chain(); } -- cgit v1.2.3-59-g8ed1b From 331b9e3d61cba2ad089f3f1fe2ef0122679337a1 Mon Sep 17 00:00:00 2001 From: Mike Chan Date: Mon, 3 May 2010 16:04:07 -0700 Subject: OMAP3: PM: Remove PER wakeup dependency on CORE. We can remove this wakeup dependency since now, when GPIO2-6 are enabled for IO-pad wakeup, PER domain is gauranteed to be awake or be woken up to service. The previous dependency did not handle all corner cases. Since there was no sleep dependency between CORE and PER domains, if PER enters RET and CORE is ON, PER will not be active for GPIO handling. Signed-off-by: Mike Chan Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index eec0916de819..1d7169855ac5 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -1096,14 +1096,6 @@ static int __init omap3_pm_init(void) omap3_idle_init(); clkdm_add_wkdep(neon_clkdm, mpu_clkdm); - /* - * REVISIT: This wkdep is only necessary when GPIO2-6 are enabled for - * IO-pad wakeup. Otherwise it will unnecessarily waste power - * waking up PER with every CORE wakeup - see - * http://marc.info/?l=linux-omap&m=121852150710062&w=2 - */ - clkdm_add_wkdep(per_clkdm, core_clkdm); - if (omap_type() != OMAP2_DEVICE_TYPE_GP) { omap3_secure_ram_storage = kmalloc(0x803F, GFP_KERNEL); -- cgit v1.2.3-59-g8ed1b From a118b5f3391fc60e1619a79f8ceb070bb7b39b2d Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 22 Dec 2008 14:27:12 +0200 Subject: OMAP3: GPIO fixes for off-mode Off mode is now using the omap2 retention fix code for scanning GPIOs during off-mode transitions. All the *non_wakeup_gpios variables are now used for off-mode transition tracking on OMAP3. This patch fixes cases where GPIO state changes are missed during off-mode. Signed-off-by: Tero Kristo Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 10 ++++++---- arch/arm/plat-omap/gpio.c | 19 ++++++++++++++----- 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index ea0000bc5358..5de07db636bd 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -376,14 +376,15 @@ void omap_sram_idle(void) core_next_state = pwrdm_read_next_pwrst(core_pwrdm); if (per_next_state < PWRDM_POWER_ON) { omap_uart_prepare_idle(2); - omap2_gpio_prepare_for_retention(); if (per_next_state == PWRDM_POWER_OFF) { if (core_next_state == PWRDM_POWER_ON) { per_next_state = PWRDM_POWER_RET; pwrdm_set_next_pwrst(per_pwrdm, per_next_state); per_state_modified = 1; - } else + } else { + omap2_gpio_prepare_for_retention(); omap3_per_save_context(); + } } } @@ -454,9 +455,10 @@ void omap_sram_idle(void) /* PER */ if (per_next_state < PWRDM_POWER_ON) { per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); - if (per_prev_state == PWRDM_POWER_OFF) + if (per_prev_state == PWRDM_POWER_OFF) { omap3_per_restore_context(); - omap2_gpio_resume_after_retention(); + omap2_gpio_resume_after_retention(); + } omap_uart_resume_idle(2); if (per_state_modified) pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF); diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 45a225d09125..6216f4f09e82 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -731,7 +731,9 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_CLEARWKUENA); } - } else { + } + /* This part needs to be executed always for OMAP34xx */ + if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) { if (trigger != 0) bank->enabled_non_wakeup_gpios |= gpio_bit; else @@ -1845,7 +1847,8 @@ static int __init _omap_gpio_init(void) __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); } - if (i < ARRAY_SIZE(non_wakeup_gpios)) + if (cpu_is_omap24xx() && + i < ARRAY_SIZE(non_wakeup_gpios)) bank->non_wakeup_gpios = non_wakeup_gpios[i]; gpio_count = 32; } @@ -2031,10 +2034,13 @@ static int workaround_enabled; void omap2_gpio_prepare_for_retention(void) { int i, c = 0; + int min = 0; + if (cpu_is_omap34xx()) + min = 1; /* Remove triggering for all non-wakeup GPIOs. Otherwise spurious * IRQs will be generated. See OMAP2420 Errata item 1.101. */ - for (i = 0; i < gpio_bank_count; i++) { + for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; u32 l1, l2; @@ -2088,10 +2094,13 @@ void omap2_gpio_prepare_for_retention(void) void omap2_gpio_resume_after_retention(void) { int i; + int min = 0; if (!workaround_enabled) return; - for (i = 0; i < gpio_bank_count; i++) { + if (cpu_is_omap34xx()) + min = 1; + for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; u32 l, gen, gen0, gen1; @@ -2119,7 +2128,7 @@ void omap2_gpio_resume_after_retention(void) * horribly racy, but it's the best we can do to work around * this silicon bug. */ l ^= bank->saved_datain; - l &= bank->non_wakeup_gpios; + l &= bank->enabled_non_wakeup_gpios; /* * No need to generate IRQs for the rising edge for gpio IRQs -- cgit v1.2.3-59-g8ed1b From 699117a69f53efbdf8fddbd6d991575c0a22fd74 Mon Sep 17 00:00:00 2001 From: Chunqiu Wang Date: Wed, 24 Jun 2009 17:13:39 +0000 Subject: OMAP3: GPIO: Only enable WAKEUPEN for edge detection GPIOs According to the GPIO 'Wakeup and Interrupt' section of the TRM[1], wake-up requests can only be generated on edge transitions. Also for OMAP3, only edge GPIOs may lose interrupts when PER enters RET/OFF state, this is addressed by gpio prepare|resume idle functions [1] Section 25.5.3.1 OMAP34xx_ES3.1_TRM_V_Q Signed-off-by: Chunqiu Wang Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/gpio.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 6216f4f09e82..2f185ffaca4a 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -724,7 +724,11 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, OMAP4_GPIO_IRQWAKEN0); } } else { - if (trigger != 0) + /* + * GPIO wakeup request can only be generated on edge + * transitions + */ + if (trigger & IRQ_TYPE_EDGE_BOTH) __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_SETWKUENA); else @@ -734,7 +738,13 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, } /* This part needs to be executed always for OMAP34xx */ if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) { - if (trigger != 0) + /* + * Log the edge gpio and manually trigger the IRQ + * after resume if the input level changes + * to avoid irq lost during PER RET/OFF mode + * Applies for omap2 non-wakeup gpio and all omap3 gpios + */ + if (trigger & IRQ_TYPE_EDGE_BOTH) bank->enabled_non_wakeup_gpios |= gpio_bit; else bank->enabled_non_wakeup_gpios &= ~gpio_bit; -- cgit v1.2.3-59-g8ed1b From 43ffcd9a042858a9e9f9fe014bb073e55db34c67 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 27 Jan 2009 11:09:24 -0800 Subject: OMAP2/3: GPIO: generalize prepare for idle Currently, the GPIO 'prepare' hook is only called when going to off-mode, while the function is called 'prepare_for_retention.' This patch renames the function to 'prepare_for_idle' and calls it for any powersate != PWRDM_POWER_ON passing in the powerstate. The hook itself is then responsible for doing various preparation based on the powerstate. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm24xx.c | 4 ++-- arch/arm/mach-omap2/pm34xx.c | 10 ++++------ arch/arm/plat-omap/gpio.c | 19 +++++++++++++------ arch/arm/plat-omap/include/plat/gpio.h | 4 ++-- 4 files changed, 21 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 374299ea7ade..7816c4e84a32 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -107,7 +107,7 @@ static void omap2_enter_full_retention(void) l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL; omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0); - omap2_gpio_prepare_for_retention(); + omap2_gpio_prepare_for_idle(PWRDM_POWER_RET); if (omap2_pm_debug) { omap2_pm_dump(0, 0, 0); @@ -141,7 +141,7 @@ no_sleep: tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC; omap2_pm_dump(0, 1, tmp); } - omap2_gpio_resume_after_retention(); + omap2_gpio_resume_after_idle(); clk_enable(osc_ck); diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 5de07db636bd..468e1e3321e0 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -376,15 +376,14 @@ void omap_sram_idle(void) core_next_state = pwrdm_read_next_pwrst(core_pwrdm); if (per_next_state < PWRDM_POWER_ON) { omap_uart_prepare_idle(2); + omap2_gpio_prepare_for_idle(per_next_state); if (per_next_state == PWRDM_POWER_OFF) { if (core_next_state == PWRDM_POWER_ON) { per_next_state = PWRDM_POWER_RET; pwrdm_set_next_pwrst(per_pwrdm, per_next_state); per_state_modified = 1; - } else { - omap2_gpio_prepare_for_retention(); + } else omap3_per_save_context(); - } } } @@ -455,10 +454,9 @@ void omap_sram_idle(void) /* PER */ if (per_next_state < PWRDM_POWER_ON) { per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); - if (per_prev_state == PWRDM_POWER_OFF) { + omap2_gpio_resume_after_idle(); + if (per_prev_state == PWRDM_POWER_OFF) omap3_per_restore_context(); - omap2_gpio_resume_after_retention(); - } omap_uart_resume_idle(2); if (per_state_modified) pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF); diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 2f185ffaca4a..1c81340ce65c 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -27,6 +27,7 @@ #include #include #include +#include /* * OMAP1510 GPIO registers @@ -2041,19 +2042,24 @@ static struct sys_device omap_gpio_device = { static int workaround_enabled; -void omap2_gpio_prepare_for_retention(void) +void omap2_gpio_prepare_for_idle(int power_state) { int i, c = 0; int min = 0; if (cpu_is_omap34xx()) min = 1; - /* Remove triggering for all non-wakeup GPIOs. Otherwise spurious - * IRQs will be generated. See OMAP2420 Errata item 1.101. */ + for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; u32 l1, l2; + if (power_state > PWRDM_POWER_OFF) + continue; + + /* If going to OFF, remove triggering for all + * non-wakeup GPIOs. Otherwise spurious IRQs will be + * generated. See OMAP2420 Errata item 1.101. */ if (!(bank->enabled_non_wakeup_gpios)) continue; @@ -2101,19 +2107,20 @@ void omap2_gpio_prepare_for_retention(void) workaround_enabled = 1; } -void omap2_gpio_resume_after_retention(void) +void omap2_gpio_resume_after_idle(void) { int i; int min = 0; - if (!workaround_enabled) - return; if (cpu_is_omap34xx()) min = 1; for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; u32 l, gen, gen0, gen1; + if (!workaround_enabled) + continue; + if (!(bank->enabled_non_wakeup_gpios)) continue; diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index de7c54731cbe..de1c604962eb 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -72,8 +72,8 @@ IH_GPIO_BASE + (nr)) extern int omap_gpio_init(void); /* Call from board init only */ -extern void omap2_gpio_prepare_for_retention(void); -extern void omap2_gpio_resume_after_retention(void); +extern void omap2_gpio_prepare_for_idle(int power_state); +extern void omap2_gpio_resume_after_idle(void); extern void omap_set_gpio_debounce(int gpio, int enable); extern void omap_set_gpio_debounce_time(int gpio, int enable); extern void omap_gpio_save_context(void); -- cgit v1.2.3-59-g8ed1b From 8865b9b6d5e1601453ea20c37eb981c6ccc3f4e9 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 27 Jan 2009 11:15:34 -0800 Subject: OMAP3: GPIO: disable GPIO debounce clocks on idle Ensure GPIO debounce clocks are disabled when idle. Otherwise, clocks will prevent PER powerdomain from entering retention. Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/gpio.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 1c81340ce65c..c6e1de527116 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -196,6 +196,7 @@ struct gpio_bank { struct gpio_chip chip; struct clk *dbck; u32 mod_usage; + u32 dbck_enable_mask; }; #define METHOD_MPUIO 0 @@ -647,6 +648,7 @@ void omap_set_gpio_debounce(int gpio, int enable) goto done; if (cpu_is_omap34xx() || cpu_is_omap44xx()) { + bank->dbck_enable_mask = val; if (enable) clk_enable(bank->dbck); else @@ -2054,6 +2056,9 @@ void omap2_gpio_prepare_for_idle(int power_state) struct gpio_bank *bank = &gpio_bank[i]; u32 l1, l2; + if (bank->dbck_enable_mask) + clk_disable(bank->dbck); + if (power_state > PWRDM_POWER_OFF) continue; @@ -2118,6 +2123,9 @@ void omap2_gpio_resume_after_idle(void) struct gpio_bank *bank = &gpio_bank[i]; u32 l, gen, gen0, gen1; + if (bank->dbck_enable_mask) + clk_enable(bank->dbck); + if (!workaround_enabled) continue; -- cgit v1.2.3-59-g8ed1b From c872670799d5a41fe2c1f2ccf7c531b5661dcfba Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 3 May 2010 15:53:57 -0700 Subject: OMAP3: GPIO: Removed a couple of unneeded registers from context save/restore setwkuena and setdataout are covered already by wake_en and dataout fields. Signed-off-by: Tero Kristo Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/gpio.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index c6e1de527116..b895cc9c6b78 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -305,8 +305,6 @@ struct omap3_gpio_regs { u32 risingdetect; u32 fallingdetect; u32 dataout; - u32 setwkuena; - u32 setdataout; }; static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS]; @@ -2241,10 +2239,6 @@ void omap_gpio_save_context(void) __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); gpio_context[i].dataout = __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT); - gpio_context[i].setwkuena = - __raw_readl(bank->base + OMAP24XX_GPIO_SETWKUENA); - gpio_context[i].setdataout = - __raw_readl(bank->base + OMAP24XX_GPIO_SETDATAOUT); } } @@ -2277,10 +2271,6 @@ void omap_gpio_restore_context(void) bank->base + OMAP24XX_GPIO_FALLINGDETECT); __raw_writel(gpio_context[i].dataout, bank->base + OMAP24XX_GPIO_DATAOUT); - __raw_writel(gpio_context[i].setwkuena, - bank->base + OMAP24XX_GPIO_SETWKUENA); - __raw_writel(gpio_context[i].setdataout, - bank->base + OMAP24XX_GPIO_SETDATAOUT); } } #endif -- cgit v1.2.3-59-g8ed1b From d009559a4215c71694b1a29ec0e520453087a9f6 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 14 Dec 2009 15:14:51 -0800 Subject: OMAP: GPIO: remove duplicate debugfs interface The generic gpiolib provides a debugfs interface to GPIOs which provides identical (but nicer looking) data as the OMAP specific one. This patch completely drops the OMAP specific interface (/debug/omap_gpio) in favor of using the generic one (/debug/gpio.) Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/gpio.c | 107 ---------------------------------------------- 1 file changed, 107 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index b895cc9c6b78..955597fd6d35 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -2310,110 +2310,3 @@ static int __init omap_gpio_sysinit(void) } arch_initcall(omap_gpio_sysinit); - - -#ifdef CONFIG_DEBUG_FS - -#include -#include - -static int dbg_gpio_show(struct seq_file *s, void *unused) -{ - unsigned i, j, gpio; - - for (i = 0, gpio = 0; i < gpio_bank_count; i++) { - struct gpio_bank *bank = gpio_bank + i; - unsigned bankwidth = 16; - u32 mask = 1; - - if (bank_is_mpuio(bank)) - gpio = OMAP_MPUIO(0); - else if (cpu_class_is_omap2() || cpu_is_omap7xx()) - bankwidth = 32; - - for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) { - unsigned irq, value, is_in, irqstat; - const char *label; - - label = gpiochip_is_requested(&bank->chip, j); - if (!label) - continue; - - irq = bank->virtual_irq_start + j; - value = gpio_get_value(gpio); - is_in = gpio_is_input(bank, mask); - - if (bank_is_mpuio(bank)) - seq_printf(s, "MPUIO %2d ", j); - else - seq_printf(s, "GPIO %3d ", gpio); - seq_printf(s, "(%-20.20s): %s %s", - label, - is_in ? "in " : "out", - value ? "hi" : "lo"); - -/* FIXME for at least omap2, show pullup/pulldown state */ - - irqstat = irq_desc[irq].status; -#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) - if (is_in && ((bank->suspend_wakeup & mask) - || irqstat & IRQ_TYPE_SENSE_MASK)) { - char *trigger = NULL; - - switch (irqstat & IRQ_TYPE_SENSE_MASK) { - case IRQ_TYPE_EDGE_FALLING: - trigger = "falling"; - break; - case IRQ_TYPE_EDGE_RISING: - trigger = "rising"; - break; - case IRQ_TYPE_EDGE_BOTH: - trigger = "bothedge"; - break; - case IRQ_TYPE_LEVEL_LOW: - trigger = "low"; - break; - case IRQ_TYPE_LEVEL_HIGH: - trigger = "high"; - break; - case IRQ_TYPE_NONE: - trigger = "(?)"; - break; - } - seq_printf(s, ", irq-%d %-8s%s", - irq, trigger, - (bank->suspend_wakeup & mask) - ? " wakeup" : ""); - } -#endif - seq_printf(s, "\n"); - } - - if (bank_is_mpuio(bank)) { - seq_printf(s, "\n"); - gpio = 0; - } - } - return 0; -} - -static int dbg_gpio_open(struct inode *inode, struct file *file) -{ - return single_open(file, dbg_gpio_show, &inode->i_private); -} - -static const struct file_operations debug_fops = { - .open = dbg_gpio_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init omap_gpio_debuginit(void) -{ - (void) debugfs_create_file("omap_gpio", S_IRUGO, - NULL, NULL, &debug_fops); - return 0; -} -late_initcall(omap_gpio_debuginit); -#endif -- cgit v1.2.3-59-g8ed1b From fb0491146518c24b8ded5f9afa59b1df3749dea9 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Thu, 13 May 2010 09:26:49 +0900 Subject: ARM: S5P6440: Register apll/mpll/epll mout clocks. This patch modifies the following. 1. Registers the mout_apll clksrc_clk clock. 2. The mout_mpll and mout_epll were registered as 'struct clk' types and then their parents were setup using the s3c_set_clksrc function. This patch reduces the two steps into one by registering the mout_mpll and mout_epll clocks using the s3c_register_clksrc function. 3. As per point 2 above, the init_parents array is no longer required. So the mout clocks are now put together in a new array named 'sysclks'. The sysclks array will list the system level clocks and more clocks will be added to it in the subsequent patches. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/clock.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c index b2672e16e7aa..3ad63f41309e 100644 --- a/arch/arm/mach-s5p6440/clock.c +++ b/arch/arm/mach-s5p6440/clock.c @@ -574,7 +574,7 @@ static struct clksrc_clk clksrcs[] = { }; /* Clock initialisation code */ -static struct clksrc_clk *init_parents[] = { +static struct clksrc_clk *sysclks[] = { &clk_mout_apll, &clk_mout_epll, &clk_mout_mpll, @@ -652,17 +652,12 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) clk_h_low.rate = hclk_low; clk_p_low.rate = pclk_low; - for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) - s3c_set_clksrc(init_parents[ptr], true); - for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_set_clksrc(&clksrcs[ptr], true); } static struct clk *clks[] __initdata = { &clk_ext, - &clk_mout_epll.clk, - &clk_mout_mpll.clk, &clk_dout_mpll, &clk_iis_cd_v40, &clk_pcm_cd, @@ -680,6 +675,9 @@ void __init s5p6440_register_clocks(void) if (ret > 0) printk(KERN_ERR "Failed to register %u clocks\n", ret); + for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) + s3c_register_clksrc(sysclks[ptr], 1); + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); -- cgit v1.2.3-59-g8ed1b From 30d58349608c3a31dbea0cc9238f6d8edc21e299 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Thu, 13 May 2010 09:26:58 +0900 Subject: ARM: S5P6440: Change dout_mpll clock type to clksrc_clk clock type. This patch modifies the following. 1. Modifies the dout_mpll clock type as clksrc_clk clock type. This modification allows the use of common clock code in managing the dout_mpll clock (which otherwise would need custom defined functions such as s5p6440_clk_doutmpll_get_rate). 2. s5p6440_clk_doutmpll_get_rate function is removed as it is no longer needed. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/clock.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c index 3ad63f41309e..8bd6f15a2ac1 100644 --- a/arch/arm/mach-s5p6440/clock.c +++ b/arch/arm/mach-s5p6440/clock.c @@ -247,23 +247,13 @@ static struct clk_ops s5p6440_clkarm_ops = { .round_rate = s5p6440_armclk_round_rate, }; -static unsigned long s5p6440_clk_doutmpll_get_rate(struct clk *clk) -{ - unsigned long rate = clk_get_rate(clk->parent); - - if (__raw_readl(S5P_CLK_DIV0) & S5P_CLKDIV0_MPLL_MASK) - rate /= 2; - - return rate; -} - -static struct clk clk_dout_mpll = { - .name = "dout_mpll", - .id = -1, - .parent = &clk_mout_mpll.clk, - .ops = &(struct clk_ops) { - .get_rate = s5p6440_clk_doutmpll_get_rate, +static struct clksrc_clk clk_dout_mpll = { + .clk = { + .name = "dout_mpll", + .id = -1, + .parent = &clk_mout_mpll.clk, }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 1 }, }; int s5p6440_clk48m_ctrl(struct clk *clk, int enable) @@ -490,7 +480,7 @@ static struct clk clk_pcm_cd = { static struct clk *clkset_spi_mmc_list[] = { &clk_mout_epll.clk, - &clk_dout_mpll, + &clk_dout_mpll.clk, &clk_fin_epll, }; @@ -501,7 +491,7 @@ static struct clksrc_sources clkset_spi_mmc = { static struct clk *clkset_uart_list[] = { &clk_mout_epll.clk, - &clk_dout_mpll + &clk_dout_mpll.clk, }; static struct clksrc_sources clkset_uart = { @@ -578,6 +568,7 @@ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, &clk_mout_epll, &clk_mout_mpll, + &clk_dout_mpll, }; void __init_or_cpufreq s5p6440_setup_clocks(void) @@ -658,7 +649,6 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) static struct clk *clks[] __initdata = { &clk_ext, - &clk_dout_mpll, &clk_iis_cd_v40, &clk_pcm_cd, &clk_p_low, -- cgit v1.2.3-59-g8ed1b From 9c72d016e2b556e7d8f739b21404f32333fbc5e4 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Thu, 13 May 2010 09:27:04 +0900 Subject: ARM: S5P6440: Remove usage of clk_arm and add clk_armclk clock The clk_arm clock is of type 'struct clk' whereas on S5P6440, the arm clock is more suitable to be of type 'struct clksrc_clk' (since arm clock is divided version of apll clock). This patch modifies the following. 1. Removes the usage of clk_arm clock (defined in plat-s5p) and defines the new clock 'clk_armclk' of type 'struct clksrc_clk'. 2. Rearranges the assignment of clock rate for the fout_a/m/epll clocks. This will help in calculating the clock rate of fclk from clk_armclk clock and setup the clock rate for fout_m/epll for subsequent patches which depend on it. 3. Modifies the clock rate calculation of fclk to be based on the newly added clk_armclk clock. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/clock.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c index 8bd6f15a2ac1..2c6dd544ff62 100644 --- a/arch/arm/mach-s5p6440/clock.c +++ b/arch/arm/mach-s5p6440/clock.c @@ -247,6 +247,16 @@ static struct clk_ops s5p6440_clkarm_ops = { .round_rate = s5p6440_armclk_round_rate, }; +static struct clksrc_clk clk_armclk = { + .clk = { + .name = "armclk", + .id = 1, + .parent = &clk_mout_apll.clk, + .ops = &s5p6440_clkarm_ops, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 4 }, +}; + static struct clksrc_clk clk_dout_mpll = { .clk = { .name = "dout_mpll", @@ -569,6 +579,7 @@ static struct clksrc_clk *sysclks[] = { &clk_mout_epll, &clk_mout_mpll, &clk_dout_mpll, + &clk_armclk, }; void __init_or_cpufreq s5p6440_setup_clocks(void) @@ -592,8 +603,6 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) clk_fout_epll.ops = &s5p6440_epll_ops; /* Set S5P6440 functions for arm clock */ - clk_arm.parent = &clk_mout_apll.clk; - clk_arm.ops = &s5p6440_clkarm_ops; clk_48m.enable = s5p6440_clk48m_ctrl; clkdiv0 = __raw_readl(S5P_CLK_DIV0); @@ -610,11 +619,15 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502); + clk_fout_mpll.rate = mpll; + clk_fout_epll.rate = epll; + clk_fout_apll.rate = apll; + printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \ " E=%ld.%ldMHz\n", print_mhz(apll), print_mhz(mpll), print_mhz(epll)); - fclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_ARM); + fclk = clk_get_rate(&clk_armclk.clk); hclk = fclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK); pclk = hclk / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK); @@ -633,10 +646,6 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) print_mhz(hclk), print_mhz(hclk_low), print_mhz(pclk), print_mhz(pclk_low)); - clk_fout_mpll.rate = mpll; - clk_fout_epll.rate = epll; - clk_fout_apll.rate = apll; - clk_f.rate = fclk; clk_h.rate = hclk; clk_p.rate = pclk; -- cgit v1.2.3-59-g8ed1b From e4f44f82691e927a2f5eb582793454e052b920c7 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Thu, 13 May 2010 09:27:09 +0900 Subject: ARM: S5P6440: Remove usage of clk_h and add clk_hclk clock The clk_h clock is of type 'struct clk' whereas on S5P6440, the hclk is more suitable to be of type 'struct clksrc_clk' (since hclk clock is divided version of armclk) This patch modifies the following. 1. Adds the 'clk_hclk' clock which is of type 'struct clksrc_clk'. 2. Removes all references to the clk_h clock. 3. Addes clk_hclk into the list of sysclks. 4. The clock rate 'hclk' is modified to be derived from clk_hclk. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/clock.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c index 2c6dd544ff62..bc0458e6d420 100644 --- a/arch/arm/mach-s5p6440/clock.c +++ b/arch/arm/mach-s5p6440/clock.c @@ -266,6 +266,15 @@ static struct clksrc_clk clk_dout_mpll = { .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 1 }, }; +static struct clksrc_clk clk_hclk = { + .clk = { + .name = "clk_hclk", + .id = -1, + .parent = &clk_armclk.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 4 }, +}; + int s5p6440_clk48m_ctrl(struct clk *clk, int enable) { unsigned long flags; @@ -321,7 +330,7 @@ static struct clk init_clocks_disable[] = { { .name = "nand", .id = -1, - .parent = &clk_h, + .parent = &clk_hclk.clk, .enable = s5p6440_mem_ctrl, .ctrlbit = S5P_CLKCON_MEM0_HCLK_NFCON, }, { @@ -580,6 +589,7 @@ static struct clksrc_clk *sysclks[] = { &clk_mout_mpll, &clk_dout_mpll, &clk_armclk, + &clk_hclk, }; void __init_or_cpufreq s5p6440_setup_clocks(void) @@ -628,7 +638,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) print_mhz(apll), print_mhz(mpll), print_mhz(epll)); fclk = clk_get_rate(&clk_armclk.clk); - hclk = fclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK); + hclk = clk_get_rate(&clk_hclk.clk); pclk = hclk / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK); if (__raw_readl(S5P_OTHERS) & S5P_OTHERS_HCLK_LOW_SEL_MPLL) { -- cgit v1.2.3-59-g8ed1b From 47051461ab1cc8049e676902bf1972268bed4b9a Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Thu, 13 May 2010 09:27:13 +0900 Subject: ARM: S5P6440: Remove usage of clk_p and add clk_pclk clock The clk_p clock is of type 'struct clk' whereas on S5P6440, the pclk is more suitable to be of type 'struct clksrc_clk' (since pclk clock is divided version of hclk). This patch modifies the following. 1. Adds the 'clk_pclk' clock which is of type 'struct clksrc_clk'. 2. Adds clk_pclk into the list of sysclks. 3. The clock rate 'pclk' is modified to be derived from clk_pclk. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/clock.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c index bc0458e6d420..61bc85b098ff 100644 --- a/arch/arm/mach-s5p6440/clock.c +++ b/arch/arm/mach-s5p6440/clock.c @@ -275,6 +275,15 @@ static struct clksrc_clk clk_hclk = { .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 4 }, }; +static struct clksrc_clk clk_pclk = { + .clk = { + .name = "clk_pclk", + .id = -1, + .parent = &clk_hclk.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 4 }, +}; + int s5p6440_clk48m_ctrl(struct clk *clk, int enable) { unsigned long flags; @@ -590,6 +599,7 @@ static struct clksrc_clk *sysclks[] = { &clk_dout_mpll, &clk_armclk, &clk_hclk, + &clk_pclk, }; void __init_or_cpufreq s5p6440_setup_clocks(void) @@ -639,7 +649,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) fclk = clk_get_rate(&clk_armclk.clk); hclk = clk_get_rate(&clk_hclk.clk); - pclk = hclk / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK); + pclk = clk_get_rate(&clk_pclk.clk); if (__raw_readl(S5P_OTHERS) & S5P_OTHERS_HCLK_LOW_SEL_MPLL) { /* Asynchronous mode */ -- cgit v1.2.3-59-g8ed1b From 93ad94db5509ccac65a57f6fc599d61a61767efc Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Thu, 13 May 2010 09:27:17 +0900 Subject: ARM: S5P6440: Remove usage of clk_h_low and add clk_hclk_low clock The clk_h_low clock is of type 'struct clk' whereas on S5P6440, the hclk_low clock is more suitable to be of type 'struct clksrc_clk' (since hclk_low clock is derived from a choice of clock sources and then divided by a divisor). This patch modifies the following. 1. Removes the definition and usage of clk_h_clk clock. 2. Adds the clk_hclk_low clock of type 'struct clksrc_clk' clock. 3. Adds clk_hclk_low to the list of system clocks. 4. The clock rate of hclk_low is derived from the clk_hclk_low clock. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/clock.c | 54 ++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c index 61bc85b098ff..c70b3a4075e9 100644 --- a/arch/arm/mach-s5p6440/clock.c +++ b/arch/arm/mach-s5p6440/clock.c @@ -134,15 +134,6 @@ static struct clksrc_clk clk_mout_mpll = { .reg_src = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 }, }; -static struct clk clk_h_low = { - .name = "hclk_low", - .id = -1, - .rate = 0, - .parent = NULL, - .ctrlbit = 0, - .ops = &clk_ops_def_setrate, -}; - static struct clk clk_p_low = { .name = "pclk_low", .id = -1, @@ -284,6 +275,26 @@ static struct clksrc_clk clk_pclk = { .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 4 }, }; +static struct clk *clkset_hclklow_list[] = { + &clk_mout_apll.clk, + &clk_mout_mpll.clk, +}; + +static struct clksrc_sources clkset_hclklow = { + .sources = clkset_hclklow_list, + .nr_sources = ARRAY_SIZE(clkset_hclklow_list), +}; + +static struct clksrc_clk clk_hclk_low = { + .clk = { + .name = "hclk_low", + .id = -1, + }, + .sources = &clkset_hclklow, + .reg_src = { .reg = S5P_SYS_OTHERS, .shift = 6, .size = 1 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 }, +}; + int s5p6440_clk48m_ctrl(struct clk *clk, int enable) { unsigned long flags; @@ -405,37 +416,37 @@ static struct clk init_clocks_disable[] = { }, { .name = "otg", .id = -1, - .parent = &clk_h_low, + .parent = &clk_hclk_low.clk, .enable = s5p6440_hclk0_ctrl, .ctrlbit = S5P_CLKCON_HCLK0_USB }, { .name = "post", .id = -1, - .parent = &clk_h_low, + .parent = &clk_hclk_low.clk, .enable = s5p6440_hclk0_ctrl, .ctrlbit = S5P_CLKCON_HCLK0_POST0 }, { .name = "lcd", .id = -1, - .parent = &clk_h_low, + .parent = &clk_hclk_low.clk, .enable = s5p6440_hclk1_ctrl, .ctrlbit = S5P_CLKCON_HCLK1_DISPCON, }, { .name = "hsmmc", .id = 0, - .parent = &clk_h_low, + .parent = &clk_hclk_low.clk, .enable = s5p6440_hclk0_ctrl, .ctrlbit = S5P_CLKCON_HCLK0_HSMMC0, }, { .name = "hsmmc", .id = 1, - .parent = &clk_h_low, + .parent = &clk_hclk_low.clk, .enable = s5p6440_hclk0_ctrl, .ctrlbit = S5P_CLKCON_HCLK0_HSMMC1, }, { .name = "hsmmc", .id = 2, - .parent = &clk_h_low, + .parent = &clk_hclk_low.clk, .enable = s5p6440_hclk0_ctrl, .ctrlbit = S5P_CLKCON_HCLK0_HSMMC2, }, { @@ -600,6 +611,7 @@ static struct clksrc_clk *sysclks[] = { &clk_armclk, &clk_hclk, &clk_pclk, + &clk_hclk_low, }; void __init_or_cpufreq s5p6440_setup_clocks(void) @@ -650,15 +662,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) fclk = clk_get_rate(&clk_armclk.clk); hclk = clk_get_rate(&clk_hclk.clk); pclk = clk_get_rate(&clk_pclk.clk); - - if (__raw_readl(S5P_OTHERS) & S5P_OTHERS_HCLK_LOW_SEL_MPLL) { - /* Asynchronous mode */ - hclk_low = mpll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW); - } else { - /* Synchronous mode */ - hclk_low = apll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW); - } - + hclk_low = clk_get_rate(&clk_hclk_low.clk); pclk_low = hclk_low / GET_DIV(clkdiv3, S5P_CLKDIV3_PCLK_LOW); printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ @@ -669,7 +673,6 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) clk_f.rate = fclk; clk_h.rate = hclk; clk_p.rate = pclk; - clk_h_low.rate = hclk_low; clk_p_low.rate = pclk_low; for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) @@ -681,7 +684,6 @@ static struct clk *clks[] __initdata = { &clk_iis_cd_v40, &clk_pcm_cd, &clk_p_low, - &clk_h_low, }; void __init s5p6440_register_clocks(void) -- cgit v1.2.3-59-g8ed1b From 697f8a9fe7835ba24f2da855c5de4ddbe27aa554 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Thu, 13 May 2010 09:27:29 +0900 Subject: ARM: S5P6440: Remove usage of clk_p_low and add clk_pclk_low clock The pclk_low clock is of type 'struct clk' whereas on S5P6440, the pclk_low clock is more suitable to be of type 'struct clksrc_clk' (since pclk_low clock is a divided clock of hclk_low clock). This patch modifies the following. 1. Removes the definition and usage of clk_p_clk clock. 2. Adds the clk_pclk_low clock of type 'struct clksrc_clk' clock. 3. Adds clk_pclk_low to the list of system clocks. 4. The clock rate of pclk_low is derived from the clk_pclk_low clock. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/clock.c | 55 +++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c index c70b3a4075e9..80d18f54ee70 100644 --- a/arch/arm/mach-s5p6440/clock.c +++ b/arch/arm/mach-s5p6440/clock.c @@ -134,15 +134,6 @@ static struct clksrc_clk clk_mout_mpll = { .reg_src = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 }, }; -static struct clk clk_p_low = { - .name = "pclk_low", - .id = -1, - .rate = 0, - .parent = NULL, - .ctrlbit = 0, - .ops = &clk_ops_def_setrate, -}; - enum perf_level { L0 = 532*1000, L1 = 266*1000, @@ -295,6 +286,15 @@ static struct clksrc_clk clk_hclk_low = { .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 }, }; +static struct clksrc_clk clk_pclk_low = { + .clk = { + .name = "pclk_low", + .id = -1, + .parent = &clk_hclk_low.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 }, +}; + int s5p6440_clk48m_ctrl(struct clk *clk, int enable) { unsigned long flags; @@ -356,31 +356,31 @@ static struct clk init_clocks_disable[] = { }, { .name = "adc", .id = -1, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_TSADC, }, { .name = "i2c", .id = -1, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_IIC0, }, { .name = "i2s_v40", .id = 0, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_IIS2, }, { .name = "spi", .id = 0, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_SPI0, }, { .name = "spi", .id = 1, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_SPI1, }, { @@ -452,19 +452,19 @@ static struct clk init_clocks_disable[] = { }, { .name = "rtc", .id = -1, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_RTC, }, { .name = "watchdog", .id = -1, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_WDT, }, { .name = "timers", .id = -1, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_PWM, } @@ -477,31 +477,31 @@ static struct clk init_clocks[] = { { .name = "gpio", .id = -1, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_GPIO, }, { .name = "uart", .id = 0, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_UART0, }, { .name = "uart", .id = 1, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_UART1, }, { .name = "uart", .id = 2, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_UART2, }, { .name = "uart", .id = 3, - .parent = &clk_p_low, + .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_UART3, } @@ -612,6 +612,7 @@ static struct clksrc_clk *sysclks[] = { &clk_hclk, &clk_pclk, &clk_hclk_low, + &clk_pclk_low, }; void __init_or_cpufreq s5p6440_setup_clocks(void) @@ -627,19 +628,13 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) unsigned long apll; unsigned long mpll; unsigned int ptr; - u32 clkdiv0; - u32 clkdiv3; /* Set S5P6440 functions for clk_fout_epll */ clk_fout_epll.enable = s5p6440_epll_enable; clk_fout_epll.ops = &s5p6440_epll_ops; - /* Set S5P6440 functions for arm clock */ clk_48m.enable = s5p6440_clk48m_ctrl; - clkdiv0 = __raw_readl(S5P_CLK_DIV0); - clkdiv3 = __raw_readl(S5P_CLK_DIV3); - xtal_clk = clk_get(NULL, "ext_xtal"); BUG_ON(IS_ERR(xtal_clk)); @@ -663,7 +658,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) hclk = clk_get_rate(&clk_hclk.clk); pclk = clk_get_rate(&clk_pclk.clk); hclk_low = clk_get_rate(&clk_hclk_low.clk); - pclk_low = hclk_low / GET_DIV(clkdiv3, S5P_CLKDIV3_PCLK_LOW); + pclk_low = clk_get_rate(&clk_pclk_low.clk); printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n", @@ -673,7 +668,6 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) clk_f.rate = fclk; clk_h.rate = hclk; clk_p.rate = pclk; - clk_p_low.rate = pclk_low; for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_set_clksrc(&clksrcs[ptr], true); @@ -683,7 +677,6 @@ static struct clk *clks[] __initdata = { &clk_ext, &clk_iis_cd_v40, &clk_pcm_cd, - &clk_p_low, }; void __init s5p6440_register_clocks(void) -- cgit v1.2.3-59-g8ed1b From 213907dc1b974019f5eb9c94a1c62b11a515564c Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Thu, 13 May 2010 09:27:47 +0900 Subject: ARM: S5P6440: Add clocks of type 'struct clk'. Add definitions of clocks of type 'struct clk'. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/clock.c | 82 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c index 80d18f54ee70..26b02d43a252 100644 --- a/arch/arm/mach-s5p6440/clock.c +++ b/arch/arm/mach-s5p6440/clock.c @@ -467,7 +467,73 @@ static struct clk init_clocks_disable[] = { .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_PWM, - } + }, { + .name = "hclk_fimgvg", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p6440_hclk1_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "tsi", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p6440_hclk1_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "pclk_fimgvg", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = (1 << 31), + }, { + .name = "dmc0", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = (1 << 30), + }, { + .name = "etm", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = (1 << 29), + }, { + .name = "dsim", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = (1 << 28), + }, { + .name = "gps", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = (1 << 25), + }, { + .name = "pcm", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "irom", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p6440_hclk0_ctrl, + .ctrlbit = (1 << 25), + }, { + .name = "dma", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p6440_hclk0_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "2d", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p6440_hclk0_ctrl, + .ctrlbit = (1 << 8), + }, }; /* @@ -504,7 +570,19 @@ static struct clk init_clocks[] = { .parent = &clk_pclk_low.clk, .enable = s5p6440_pclk_ctrl, .ctrlbit = S5P_CLKCON_PCLK_UART3, - } + }, { + .name = "mem", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p6440_hclk0_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "intc", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p6440_hclk0_ctrl, + .ctrlbit = (1 << 1), + }, }; static struct clk clk_iis_cd_v40 = { -- cgit v1.2.3-59-g8ed1b From 39b7781b16614c65a53f275ff63440ea806230e2 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Thu, 13 May 2010 09:27:49 +0900 Subject: ARM: S5P6440: Rename clkset_mmc_spi to clkset_group1 The clock source options avaialable in the clkset_mmc_spi are applicable to clocks such as sclk_post, sclk_dispcon and sclk_fimgvg. So this set is renamed as clkset_group1 to indicate that it can be used as clock sources for other clocks and not just for sclk_spi and sclk_mmc clocks. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/clock.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c index 26b02d43a252..b47f77d9c849 100644 --- a/arch/arm/mach-s5p6440/clock.c +++ b/arch/arm/mach-s5p6440/clock.c @@ -595,15 +595,15 @@ static struct clk clk_pcm_cd = { .id = -1, }; -static struct clk *clkset_spi_mmc_list[] = { +static struct clk *clkset_group1_list[] = { &clk_mout_epll.clk, &clk_dout_mpll.clk, &clk_fin_epll, }; -static struct clksrc_sources clkset_spi_mmc = { - .sources = clkset_spi_mmc_list, - .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list), +static struct clksrc_sources clkset_group1 = { + .sources = clkset_group1_list, + .nr_sources = ARRAY_SIZE(clkset_group1_list), }; static struct clk *clkset_uart_list[] = { @@ -624,7 +624,7 @@ static struct clksrc_clk clksrcs[] = { .ctrlbit = S5P_CLKCON_SCLK0_MMC0, .enable = s5p6440_sclk_ctrl, }, - .sources = &clkset_spi_mmc, + .sources = &clkset_group1, .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 }, .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 }, }, { @@ -634,7 +634,7 @@ static struct clksrc_clk clksrcs[] = { .ctrlbit = S5P_CLKCON_SCLK0_MMC1, .enable = s5p6440_sclk_ctrl, }, - .sources = &clkset_spi_mmc, + .sources = &clkset_group1, .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 }, .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 }, }, { @@ -644,7 +644,7 @@ static struct clksrc_clk clksrcs[] = { .ctrlbit = S5P_CLKCON_SCLK0_MMC2, .enable = s5p6440_sclk_ctrl, }, - .sources = &clkset_spi_mmc, + .sources = &clkset_group1, .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 }, .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 }, }, { @@ -664,7 +664,7 @@ static struct clksrc_clk clksrcs[] = { .ctrlbit = S5P_CLKCON_SCLK0_SPI0, .enable = s5p6440_sclk_ctrl, }, - .sources = &clkset_spi_mmc, + .sources = &clkset_group1, .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 }, .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, }, { @@ -674,7 +674,7 @@ static struct clksrc_clk clksrcs[] = { .ctrlbit = S5P_CLKCON_SCLK0_SPI1, .enable = s5p6440_sclk_ctrl, }, - .sources = &clkset_spi_mmc, + .sources = &clkset_group1, .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 }, .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, } -- cgit v1.2.3-59-g8ed1b From b3b84d652da3aba06ec26c0570ca138d8c7f1b65 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Thu, 13 May 2010 09:27:54 +0900 Subject: ARM: S5P6440: Add clocks of type 'struct clksrc_clk'. This patch adds the following. 1. Add new definitions of clock of type 'struct clksrc_clk'. 2. Add gate control function for GATE_SCLK1 which is required for new clock additions. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/clock.c | 60 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c index b47f77d9c849..ca6e48dce777 100644 --- a/arch/arm/mach-s5p6440/clock.c +++ b/arch/arm/mach-s5p6440/clock.c @@ -336,6 +336,11 @@ static int s5p6440_sclk_ctrl(struct clk *clk, int enable) return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable); } +static int s5p6440_sclk1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLK_GATE_SCLK1, clk, enable); +} + static int s5p6440_mem_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable); @@ -616,6 +621,19 @@ static struct clksrc_sources clkset_uart = { .nr_sources = ARRAY_SIZE(clkset_uart_list), }; +static struct clk *clkset_audio_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll.clk, + &clk_fin_epll, + &clk_iis_cd_v40, + &clk_pcm_cd, +}; + +static struct clksrc_sources clkset_audio = { + .sources = clkset_audio_list, + .nr_sources = ARRAY_SIZE(clkset_audio_list), +}; + static struct clksrc_clk clksrcs[] = { { .clk = { @@ -677,7 +695,47 @@ static struct clksrc_clk clksrcs[] = { .sources = &clkset_group1, .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 }, .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, - } + }, { + .clk = { + .name = "sclk_post", + .id = -1, + .ctrlbit = (1 << 10), + .enable = s5p6440_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 26, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "sclk_dispcon", + .id = -1, + .ctrlbit = (1 << 1), + .enable = s5p6440_sclk1_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimgvg", + .id = -1, + .ctrlbit = (1 << 2), + .enable = s5p6440_sclk1_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_audio2", + .id = -1, + .ctrlbit = (1 << 11), + .enable = s5p6440_sclk_ctrl, + }, + .sources = &clkset_audio, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 3 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 24, .size = 4 }, + }, }; /* Clock initialisation code */ -- cgit v1.2.3-59-g8ed1b From 720019908fd5a1bb442bb0a35a6027ba21864d25 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 12 May 2010 21:42:42 +0400 Subject: x86, perf: P4 PMU -- use hash for p4_get_escr_idx() Linear search over all p4 MSRs should be fine if only we would not use it in events scheduling routine which is pretty time critical. Lets use hashes. It should speed scheduling up significantly. v2: Steven proposed to use more gentle approach than issue BUG on error, so we use WARN_ONCE now Signed-off-by: Cyrill Gorcunov Cc: Peter Zijlstra Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Lin Ming LKML-Reference: <20100512174242.GA5190@lenovo> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_p4.c | 126 ++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 55 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index a603930271f3..cb875b1e2e87 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -668,66 +668,80 @@ static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu) } } -/* ESCRs are not sequential in memory so we need a map */ -static const unsigned int p4_escr_map[ARCH_P4_TOTAL_ESCR] = { - MSR_P4_ALF_ESCR0, /* 0 */ - MSR_P4_ALF_ESCR1, /* 1 */ - MSR_P4_BPU_ESCR0, /* 2 */ - MSR_P4_BPU_ESCR1, /* 3 */ - MSR_P4_BSU_ESCR0, /* 4 */ - MSR_P4_BSU_ESCR1, /* 5 */ - MSR_P4_CRU_ESCR0, /* 6 */ - MSR_P4_CRU_ESCR1, /* 7 */ - MSR_P4_CRU_ESCR2, /* 8 */ - MSR_P4_CRU_ESCR3, /* 9 */ - MSR_P4_CRU_ESCR4, /* 10 */ - MSR_P4_CRU_ESCR5, /* 11 */ - MSR_P4_DAC_ESCR0, /* 12 */ - MSR_P4_DAC_ESCR1, /* 13 */ - MSR_P4_FIRM_ESCR0, /* 14 */ - MSR_P4_FIRM_ESCR1, /* 15 */ - MSR_P4_FLAME_ESCR0, /* 16 */ - MSR_P4_FLAME_ESCR1, /* 17 */ - MSR_P4_FSB_ESCR0, /* 18 */ - MSR_P4_FSB_ESCR1, /* 19 */ - MSR_P4_IQ_ESCR0, /* 20 */ - MSR_P4_IQ_ESCR1, /* 21 */ - MSR_P4_IS_ESCR0, /* 22 */ - MSR_P4_IS_ESCR1, /* 23 */ - MSR_P4_ITLB_ESCR0, /* 24 */ - MSR_P4_ITLB_ESCR1, /* 25 */ - MSR_P4_IX_ESCR0, /* 26 */ - MSR_P4_IX_ESCR1, /* 27 */ - MSR_P4_MOB_ESCR0, /* 28 */ - MSR_P4_MOB_ESCR1, /* 29 */ - MSR_P4_MS_ESCR0, /* 30 */ - MSR_P4_MS_ESCR1, /* 31 */ - MSR_P4_PMH_ESCR0, /* 32 */ - MSR_P4_PMH_ESCR1, /* 33 */ - MSR_P4_RAT_ESCR0, /* 34 */ - MSR_P4_RAT_ESCR1, /* 35 */ - MSR_P4_SAAT_ESCR0, /* 36 */ - MSR_P4_SAAT_ESCR1, /* 37 */ - MSR_P4_SSU_ESCR0, /* 38 */ - MSR_P4_SSU_ESCR1, /* 39 */ - MSR_P4_TBPU_ESCR0, /* 40 */ - MSR_P4_TBPU_ESCR1, /* 41 */ - MSR_P4_TC_ESCR0, /* 42 */ - MSR_P4_TC_ESCR1, /* 43 */ - MSR_P4_U2L_ESCR0, /* 44 */ - MSR_P4_U2L_ESCR1, /* 45 */ +/* + * ESCR address hashing is tricky, ESCRs are not sequential + * in memory but all starts from MSR_P4_BSU_ESCR0 (0x03e0) and + * the metric between any ESCRs is laid in range [0xa0,0xe1] + * + * so we make ~70% filled hashtable + */ + +#define P4_ESCR_MSR_BASE 0x000003a0 +#define P4_ESCR_MSR_MAX 0x000003e1 +#define P4_ESCR_MSR_TABLE_SIZE (P4_ESCR_MSR_MAX - P4_ESCR_MSR_BASE + 1) +#define P4_ESCR_MSR_IDX(msr) (msr - P4_ESCR_MSR_BASE) +#define P4_ESCR_MSR_TABLE_ENTRY(msr) [P4_ESCR_MSR_IDX(msr)] = msr + +static const unsigned int p4_escr_table[P4_ESCR_MSR_TABLE_SIZE] = { + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR2), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR3), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR4), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR5), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR1), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR0), + P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR1), }; static int p4_get_escr_idx(unsigned int addr) { - unsigned int i; + unsigned int idx = P4_ESCR_MSR_IDX(addr); - for (i = 0; i < ARRAY_SIZE(p4_escr_map); i++) { - if (addr == p4_escr_map[i]) - return i; + if (unlikely(idx >= P4_ESCR_MSR_TABLE_SIZE || + !p4_escr_table[idx])) { + WARN_ONCE(1, "P4 PMU: Wrong address passed: %x\n", addr); + return -1; } - return -1; + return idx; } static int p4_next_cntr(int thread, unsigned long *used_mask, @@ -747,7 +761,7 @@ static int p4_next_cntr(int thread, unsigned long *used_mask, static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) { unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; - unsigned long escr_mask[BITS_TO_LONGS(ARCH_P4_TOTAL_ESCR)]; + unsigned long escr_mask[BITS_TO_LONGS(P4_ESCR_MSR_TABLE_SIZE)]; int cpu = raw_smp_processor_id(); struct hw_perf_event *hwc; struct p4_event_bind *bind; @@ -755,7 +769,7 @@ static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign int cntr_idx, escr_idx; bitmap_zero(used_mask, X86_PMC_IDX_MAX); - bitmap_zero(escr_mask, ARCH_P4_TOTAL_ESCR); + bitmap_zero(escr_mask, P4_ESCR_MSR_TABLE_SIZE); for (i = 0, num = n; i < n; i++, num--) { @@ -763,6 +777,8 @@ static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign thread = p4_ht_thread(cpu); bind = p4_config_get_bind(hwc->config); escr_idx = p4_get_escr_idx(bind->escr_msr[thread]); + if (unlikely(escr_idx == -1)) + goto done; if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) { cntr_idx = hwc->idx; -- cgit v1.2.3-59-g8ed1b From e8b96918a45732551b33764b0b526beac3866d58 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 04:59:43 +0000 Subject: sh: sh7343 mstp32 index rework This patch adds sh7343 MSTP enums for mstp_clks[] index. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 102 ++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 46 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index a066c438b404..72acbe4625a3 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -145,51 +145,61 @@ struct clk div6_clks[DIV6_NR] = { #define MSTP(_str, _parent, _reg, _bit, _flags) \ SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags) -static struct clk mstp_clks[] = { - MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT), - MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT), - MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT), - MSTP("uram0", &div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT), - MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT), - MSTP("intc3", &div4_clks[DIV4_P], MSTPCR0, 23, 0), - MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 0), - MSTP("dmac0", &div4_clks[DIV4_P], MSTPCR0, 21, 0), - MSTP("sh0", &div4_clks[DIV4_P], MSTPCR0, 20, 0), - MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0), - MSTP("ubc0", &div4_clks[DIV4_P], MSTPCR0, 17, 0), - MSTP("tmu_fck", &div4_clks[DIV4_P], MSTPCR0, 15, 0), - MSTP("cmt_fck", &r_clk, MSTPCR0, 14, 0), - MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0), - MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0), - MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0), - SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 7, 0), - SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 6, 0), - SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 5, 0), - SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 4, 0), - MSTP("sio0", &div4_clks[DIV4_P], MSTPCR0, 3, 0), - MSTP("siof0", &div4_clks[DIV4_P], MSTPCR0, 2, 0), - MSTP("siof1", &div4_clks[DIV4_P], MSTPCR0, 1, 0), - - MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0), - MSTP("i2c1", &div4_clks[DIV4_P], MSTPCR1, 8, 0), - - MSTP("tpu0", &div4_clks[DIV4_P], MSTPCR2, 25, 0), - MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0), - MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0), - MSTP("mmcif0", &div4_clks[DIV4_P], MSTPCR2, 17, 0), - MSTP("sim0", &div4_clks[DIV4_P], MSTPCR2, 16, 0), - MSTP("keysc0", &r_clk, MSTPCR2, 14, 0), - MSTP("tsif0", &div4_clks[DIV4_P], MSTPCR2, 13, 0), - MSTP("s3d40", &div4_clks[DIV4_P], MSTPCR2, 12, 0), - MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0), - MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0), - MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT), - MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0), - MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0), - MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0), - MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT), - MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT), - MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0), +enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026, + MSTP023, MSTP022, MSTP021, MSTP020, MSTP019, MSTP018, MSTP017, MSTP016, + MSTP015, MSTP014, MSTP013, MSTP012, MSTP011, MSTP010, + MSTP007, MSTP006, MSTP005, MSTP004, MSTP003, MSTP002, MSTP001, + MSTP109, MSTP108, MSTP100, + MSTP225, MSTP224, MSTP218, MSTP217, MSTP216, + MSTP214, MSTP213, MSTP212, MSTP211, MSTP208, + MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, + MSTP_NR }; + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP031] = MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT), + [MSTP030] = MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT), + [MSTP029] = MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT), + [MSTP028] = MSTP("uram0", &div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT), + [MSTP026] = MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT), + [MSTP023] = MSTP("intc3", &div4_clks[DIV4_P], MSTPCR0, 23, 0), + [MSTP022] = MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 0), + [MSTP021] = MSTP("dmac0", &div4_clks[DIV4_P], MSTPCR0, 21, 0), + [MSTP020] = MSTP("sh0", &div4_clks[DIV4_P], MSTPCR0, 20, 0), + [MSTP019] = MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0), + [MSTP017] = MSTP("ubc0", &div4_clks[DIV4_P], MSTPCR0, 17, 0), + [MSTP015] = MSTP("tmu_fck", &div4_clks[DIV4_P], MSTPCR0, 15, 0), + [MSTP014] = MSTP("cmt_fck", &r_clk, MSTPCR0, 14, 0), + [MSTP013] = MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0), + [MSTP011] = MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0), + [MSTP010] = MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0), + [MSTP007] = SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 7, 0), + [MSTP006] = SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 6, 0), + [MSTP005] = SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 5, 0), + [MSTP004] = SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 4, 0), + [MSTP003] = MSTP("sio0", &div4_clks[DIV4_P], MSTPCR0, 3, 0), + [MSTP002] = MSTP("siof0", &div4_clks[DIV4_P], MSTPCR0, 2, 0), + [MSTP001] = MSTP("siof1", &div4_clks[DIV4_P], MSTPCR0, 1, 0), + + [MSTP109] = MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0), + [MSTP108] = MSTP("i2c1", &div4_clks[DIV4_P], MSTPCR1, 8, 0), + + [MSTP225] = MSTP("tpu0", &div4_clks[DIV4_P], MSTPCR2, 25, 0), + [MSTP224] = MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0), + [MSTP218] = MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0), + [MSTP217] = MSTP("mmcif0", &div4_clks[DIV4_P], MSTPCR2, 17, 0), + [MSTP216] = MSTP("sim0", &div4_clks[DIV4_P], MSTPCR2, 16, 0), + [MSTP214] = MSTP("keysc0", &r_clk, MSTPCR2, 14, 0), + [MSTP213] = MSTP("tsif0", &div4_clks[DIV4_P], MSTPCR2, 13, 0), + [MSTP212] = MSTP("s3d40", &div4_clks[DIV4_P], MSTPCR2, 12, 0), + [MSTP211] = MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0), + [MSTP208] = MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0), + [MSTP206] = MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT), + [MSTP205] = MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0), + [MSTP204] = MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0), + [MSTP203] = MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0), + [MSTP202] = MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT), + [MSTP201] = MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT), + [MSTP200] = MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0), }; #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } @@ -221,7 +231,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks)); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } -- cgit v1.2.3-59-g8ed1b From 25637f7ae0324c636bde172d9e92bc00d4f0121d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 04:59:50 +0000 Subject: sh: sh7343 mstp32 clkdev lookup Add sh7343 MSTP clocks to the clkdev lookup table. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 62 ++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index 72acbe4625a3..f661d4633573 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -207,6 +207,68 @@ static struct clk mstp_clks[MSTP_NR] = { static struct clk_lookup lookups[] = { /* DIV6 clocks */ CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), + + /* MSTP32 clocks */ + CLKDEV_CON_ID("tlb0", &mstp_clks[MSTP031]), + CLKDEV_CON_ID("ic0", &mstp_clks[MSTP030]), + CLKDEV_CON_ID("oc0", &mstp_clks[MSTP029]), + CLKDEV_CON_ID("uram0", &mstp_clks[MSTP028]), + CLKDEV_CON_ID("xymem0", &mstp_clks[MSTP026]), + CLKDEV_CON_ID("intc3", &mstp_clks[MSTP023]), + CLKDEV_CON_ID("intc0", &mstp_clks[MSTP022]), + + CLKDEV_CON_ID("dmac0", &mstp_clks[MSTP021]), + CLKDEV_CON_ID("sh0", &mstp_clks[MSTP020]), + CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]), + CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]), + CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]), + CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP014]), + CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]), + CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]), + CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]), + { + /* SCIF0 */ + .dev_id = "sh-sci.0", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP007], + }, { + /* SCIF1 */ + .dev_id = "sh-sci.1", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP006], + }, { + /* SCIF2 */ + .dev_id = "sh-sci.2", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP005], + }, { + /* SCIF3 */ + .dev_id = "sh-sci.3", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP004], + }, + CLKDEV_CON_ID("sio0", &mstp_clks[MSTP003]), + CLKDEV_CON_ID("siof0", &mstp_clks[MSTP002]), + CLKDEV_CON_ID("siof1", &mstp_clks[MSTP001]), + CLKDEV_CON_ID("i2c0", &mstp_clks[MSTP109]), + CLKDEV_CON_ID("i2c1", &mstp_clks[MSTP108]), + CLKDEV_CON_ID("tpu0", &mstp_clks[MSTP225]), + CLKDEV_CON_ID("irda0", &mstp_clks[MSTP224]), + CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP218]), + CLKDEV_CON_ID("mmcif0", &mstp_clks[MSTP217]), + CLKDEV_CON_ID("sim0", &mstp_clks[MSTP216]), + CLKDEV_CON_ID("keysc0", &mstp_clks[MSTP214]), + CLKDEV_CON_ID("tsif0", &mstp_clks[MSTP213]), + CLKDEV_CON_ID("s3d40", &mstp_clks[MSTP212]), + CLKDEV_CON_ID("usbf0", &mstp_clks[MSTP211]), + CLKDEV_CON_ID("siu0", &mstp_clks[MSTP208]), + CLKDEV_CON_ID("jpu0", &mstp_clks[MSTP206]), + CLKDEV_CON_ID("vou0", &mstp_clks[MSTP205]), + CLKDEV_CON_ID("beu0", &mstp_clks[MSTP204]), + CLKDEV_CON_ID("ceu0", &mstp_clks[MSTP203]), + CLKDEV_CON_ID("veu0", &mstp_clks[MSTP202]), + CLKDEV_CON_ID("vpu0", &mstp_clks[MSTP201]), + CLKDEV_CON_ID("lcdc0", &mstp_clks[MSTP200]), }; int __init arch_clk_init(void) -- cgit v1.2.3-59-g8ed1b From 4780683a135abbe17f7867d295cd542cde5678b6 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 04:59:58 +0000 Subject: sh: sh7366 mstp32 index rework This patch adds sh7366 MSTP enums for mstp_clks[] index. The MSTP bit for the SIU is removed as well since it is not included in the documentation. Most likely an old copy paste error from sh7722. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 92 ++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 42 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 44cc5a0965d9..8b9cd314998e 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -148,48 +148,56 @@ struct clk div6_clks[DIV6_NR] = { #define MSTP(_str, _parent, _reg, _bit, _flags) \ SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags) -static struct clk mstp_clks[] = { +enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026, + MSTP023, MSTP022, MSTP021, MSTP020, MSTP019, MSTP018, MSTP017, MSTP016, + MSTP015, MSTP014, MSTP013, MSTP012, MSTP011, MSTP010, + MSTP007, MSTP006, MSTP005, MSTP002, MSTP001, + MSTP109, MSTP100, + MSTP227, MSTP226, MSTP224, MSTP223, MSTP222, MSTP218, MSTP217, + MSTP211, MSTP207, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, + MSTP_NR }; + +static struct clk mstp_clks[MSTP_NR] = { /* See page 52 of Datasheet V0.40: Overview -> Block Diagram */ - MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT), - MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT), - MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT), - MSTP("rsmem0", &div4_clks[DIV4_SH], MSTPCR0, 28, CLK_ENABLE_ON_INIT), - MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT), - MSTP("intc3", &div4_clks[DIV4_P], MSTPCR0, 23, 0), - MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 0), - MSTP("dmac0", &div4_clks[DIV4_P], MSTPCR0, 21, 0), - MSTP("sh0", &div4_clks[DIV4_P], MSTPCR0, 20, 0), - MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0), - MSTP("ubc0", &div4_clks[DIV4_P], MSTPCR0, 17, 0), - MSTP("tmu_fck", &div4_clks[DIV4_P], MSTPCR0, 15, 0), - MSTP("cmt_fck", &r_clk, MSTPCR0, 14, 0), - MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0), - MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0), - MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0), - SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 7, 0), - SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 6, 0), - SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 5, 0), - MSTP("msiof0", &div4_clks[DIV4_P], MSTPCR0, 2, 0), - MSTP("sbr0", &div4_clks[DIV4_P], MSTPCR0, 1, 0), - - MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0), - - MSTP("icb0", &div4_clks[DIV4_P], MSTPCR2, 27, 0), - MSTP("meram0", &div4_clks[DIV4_P], MSTPCR2, 26, 0), - MSTP("dacy1", &div4_clks[DIV4_P], MSTPCR2, 24, 0), - MSTP("dacy0", &div4_clks[DIV4_P], MSTPCR2, 23, 0), - MSTP("tsif0", &div4_clks[DIV4_P], MSTPCR2, 22, 0), - MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0), - MSTP("mmcif0", &div4_clks[DIV4_P], MSTPCR2, 17, 0), - MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0), - MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 9, 0), - MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 7, CLK_ENABLE_ON_INIT), - MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0), - MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0), - MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0), - MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT), - MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT), - MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0), + [MSTP031] = MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT), + [MSTP030] = MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT), + [MSTP029] = MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT), + [MSTP028] = MSTP("rsmem0", &div4_clks[DIV4_SH], MSTPCR0, 28, CLK_ENABLE_ON_INIT), + [MSTP026] = MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT), + [MSTP023] = MSTP("intc3", &div4_clks[DIV4_P], MSTPCR0, 23, 0), + [MSTP022] = MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 0), + [MSTP021] = MSTP("dmac0", &div4_clks[DIV4_P], MSTPCR0, 21, 0), + [MSTP020] = MSTP("sh0", &div4_clks[DIV4_P], MSTPCR0, 20, 0), + [MSTP019] = MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0), + [MSTP017] = MSTP("ubc0", &div4_clks[DIV4_P], MSTPCR0, 17, 0), + [MSTP015] = MSTP("tmu_fck", &div4_clks[DIV4_P], MSTPCR0, 15, 0), + [MSTP014] = MSTP("cmt_fck", &r_clk, MSTPCR0, 14, 0), + [MSTP013] = MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0), + [MSTP011] = MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0), + [MSTP010] = MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0), + [MSTP007] = SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 7, 0), + [MSTP006] = SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 6, 0), + [MSTP005] = SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 5, 0), + [MSTP002] = MSTP("msiof0", &div4_clks[DIV4_P], MSTPCR0, 2, 0), + [MSTP001] = MSTP("sbr0", &div4_clks[DIV4_P], MSTPCR0, 1, 0), + + [MSTP109] = MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0), + + [MSTP227] = MSTP("icb0", &div4_clks[DIV4_P], MSTPCR2, 27, 0), + [MSTP226] = MSTP("meram0", &div4_clks[DIV4_P], MSTPCR2, 26, 0), + [MSTP224] = MSTP("dacy1", &div4_clks[DIV4_P], MSTPCR2, 24, 0), + [MSTP223] = MSTP("dacy0", &div4_clks[DIV4_P], MSTPCR2, 23, 0), + [MSTP222] = MSTP("tsif0", &div4_clks[DIV4_P], MSTPCR2, 22, 0), + [MSTP218] = MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0), + [MSTP217] = MSTP("mmcif0", &div4_clks[DIV4_P], MSTPCR2, 17, 0), + [MSTP211] = MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0), + [MSTP207] = MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 7, CLK_ENABLE_ON_INIT), + [MSTP205] = MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0), + [MSTP204] = MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0), + [MSTP203] = MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0), + [MSTP202] = MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT), + [MSTP201] = MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT), + [MSTP200] = MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0), }; #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } @@ -221,7 +229,7 @@ int __init arch_clk_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks)); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } -- cgit v1.2.3-59-g8ed1b From b87cecef4ce4250c9bc44af04e60d71000d44581 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 05:00:06 +0000 Subject: sh: sh7366 mstp32 clkdev lookup Add sh7366 MSTP clocks to the clkdev lookup table. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 52 ++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 8b9cd314998e..5649bfcb9f74 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -205,6 +205,58 @@ static struct clk mstp_clks[MSTP_NR] = { static struct clk_lookup lookups[] = { /* DIV6 clocks */ CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), + + /* MSTP32 clocks */ + CLKDEV_CON_ID("tlb0", &mstp_clks[MSTP031]), + CLKDEV_CON_ID("ic0", &mstp_clks[MSTP030]), + CLKDEV_CON_ID("oc0", &mstp_clks[MSTP029]), + CLKDEV_CON_ID("rsmem0", &mstp_clks[MSTP028]), + CLKDEV_CON_ID("xymem0", &mstp_clks[MSTP026]), + CLKDEV_CON_ID("intc3", &mstp_clks[MSTP023]), + CLKDEV_CON_ID("intc0", &mstp_clks[MSTP022]), + CLKDEV_CON_ID("dmac0", &mstp_clks[MSTP021]), + CLKDEV_CON_ID("sh0", &mstp_clks[MSTP020]), + CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]), + CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]), + CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]), + CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP014]), + CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]), + CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]), + CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]), + { + /* SCIF0 */ + .dev_id = "sh-sci.0", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP007], + }, { + /* SCIF1 */ + .dev_id = "sh-sci.1", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP006], + }, { + /* SCIF2 */ + .dev_id = "sh-sci.2", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP005], + }, + CLKDEV_CON_ID("msiof0", &mstp_clks[MSTP002]), + CLKDEV_CON_ID("sbr0", &mstp_clks[MSTP001]), + CLKDEV_CON_ID("i2c0", &mstp_clks[MSTP109]), + CLKDEV_CON_ID("icb0", &mstp_clks[MSTP227]), + CLKDEV_CON_ID("meram0", &mstp_clks[MSTP226]), + CLKDEV_CON_ID("dacy1", &mstp_clks[MSTP224]), + CLKDEV_CON_ID("dacy0", &mstp_clks[MSTP223]), + CLKDEV_CON_ID("tsif0", &mstp_clks[MSTP222]), + CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP218]), + CLKDEV_CON_ID("mmcif0", &mstp_clks[MSTP217]), + CLKDEV_CON_ID("usbf0", &mstp_clks[MSTP211]), + CLKDEV_CON_ID("veu1", &mstp_clks[MSTP207]), + CLKDEV_CON_ID("vou0", &mstp_clks[MSTP205]), + CLKDEV_CON_ID("beu0", &mstp_clks[MSTP204]), + CLKDEV_CON_ID("ceu0", &mstp_clks[MSTP203]), + CLKDEV_CON_ID("veu0", &mstp_clks[MSTP202]), + CLKDEV_CON_ID("vpu0", &mstp_clks[MSTP201]), + CLKDEV_CON_ID("lcdc0", &mstp_clks[MSTP200]), }; int __init arch_clk_init(void) -- cgit v1.2.3-59-g8ed1b From 5b10a27e9f0aa7282e3b8fd470e71201d6f5764c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 05:00:14 +0000 Subject: sh: sh7785 mstp32 index rework This patch adds sh7785 MSTP enums for mstp_clks[] index. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 64 +++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 28de049a59b1..cc34ec352996 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -87,31 +87,37 @@ struct clk div4_clks[DIV4_NR] = { #define MSTPCR0 0xffc80030 #define MSTPCR1 0xffc80034 -static struct clk mstp_clks[] = { +enum { MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, + MSTP021, MSTP020, MSTP017, MSTP016, + MSTP013, MSTP012, MSTP009, MSTP008, MSTP003, MSTP002, + MSTP119, MSTP117, MSTP105, MSTP104, MSTP100, + MSTP_NR }; + +static struct clk mstp_clks[MSTP_NR] = { /* MSTPCR0 */ - SH_CLK_MSTP32("sci_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), - SH_CLK_MSTP32("sci_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), - SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), - SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), - SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), - SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), - SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0), - SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0), - SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0), - SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0), - SH_CLK_MSTP32("mmcif_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 13, 0), - SH_CLK_MSTP32("flctl_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 12, 0), - SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0), - SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0), - SH_CLK_MSTP32("siof_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 3, 0), - SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0), + [MSTP029] = SH_CLK_MSTP32("sci_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), + [MSTP028] = SH_CLK_MSTP32("sci_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), + [MSTP027] = SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), + [MSTP026] = SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), + [MSTP025] = SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), + [MSTP024] = SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), + [MSTP021] = SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0), + [MSTP020] = SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0), + [MSTP017] = SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0), + [MSTP016] = SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0), + [MSTP013] = SH_CLK_MSTP32("mmcif_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 13, 0), + [MSTP012] = SH_CLK_MSTP32("flctl_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 12, 0), + [MSTP009] = SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0), + [MSTP008] = SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0), + [MSTP003] = SH_CLK_MSTP32("siof_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 3, 0), + [MSTP002] = SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0), /* MSTPCR1 */ - SH_CLK_MSTP32("hudi_fck", -1, NULL, MSTPCR1, 19, 0), - SH_CLK_MSTP32("ubc_fck", -1, NULL, MSTPCR1, 17, 0), - SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0), - SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0), - SH_CLK_MSTP32("gdta_fck", -1, NULL, MSTPCR1, 0, 0), + [MSTP119] = SH_CLK_MSTP32("hudi_fck", -1, NULL, MSTPCR1, 19, 0), + [MSTP117] = SH_CLK_MSTP32("ubc_fck", -1, NULL, MSTPCR1, 17, 0), + [MSTP105] = SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0), + [MSTP104] = SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0), + [MSTP100] = SH_CLK_MSTP32("gdta_fck", -1, NULL, MSTPCR1, 0, 0), }; static struct clk_lookup lookups[] = { @@ -119,32 +125,32 @@ static struct clk_lookup lookups[] = { /* TMU0 */ .dev_id = "sh_tmu.0", .con_id = "tmu_fck", - .clk = &mstp_clks[13], /* tmu012_fck */ + .clk = &mstp_clks[MSTP008], }, { /* TMU1 */ .dev_id = "sh_tmu.1", .con_id = "tmu_fck", - .clk = &mstp_clks[13], + .clk = &mstp_clks[MSTP008], }, { /* TMU2 */ .dev_id = "sh_tmu.2", .con_id = "tmu_fck", - .clk = &mstp_clks[13], + .clk = &mstp_clks[MSTP008], }, { /* TMU3 */ .dev_id = "sh_tmu.3", .con_id = "tmu_fck", - .clk = &mstp_clks[12], /* tmu345_fck */ + .clk = &mstp_clks[MSTP009], }, { /* TMU4 */ .dev_id = "sh_tmu.4", .con_id = "tmu_fck", - .clk = &mstp_clks[12], + .clk = &mstp_clks[MSTP009], }, { /* TMU5 */ .dev_id = "sh_tmu.5", .con_id = "tmu_fck", - .clk = &mstp_clks[12], + .clk = &mstp_clks[MSTP009], }, }; @@ -161,7 +167,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), &div4_table); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks)); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } -- cgit v1.2.3-59-g8ed1b From eb85dcaa3e386eb5f1b9b48f707088538a789d58 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 05:00:22 +0000 Subject: sh: sh7785 mstp32 clkdev lookup Add sh7785 MSTP clocks to the clkdev lookup table. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index cc34ec352996..24d7208ff705 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -120,7 +120,47 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP100] = SH_CLK_MSTP32("gdta_fck", -1, NULL, MSTPCR1, 0, 0), }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + static struct clk_lookup lookups[] = { + /* MSTP32 clocks */ + { + /* SCIF5 */ + .dev_id = "sh-sci.5", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP029], + }, { + /* SCIF4 */ + .dev_id = "sh-sci.4", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP028], + }, { + /* SCIF3 */ + .dev_id = "sh-sci.3", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP027], + }, { + /* SCIF2 */ + .dev_id = "sh-sci.2", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP026], + }, { + /* SCIF1 */ + .dev_id = "sh-sci.1", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP025], + }, { + /* SCIF0 */ + .dev_id = "sh-sci.0", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP024], + }, + CLKDEV_CON_ID("ssi1_fck", &mstp_clks[MSTP021]), + CLKDEV_CON_ID("ssi0_fck", &mstp_clks[MSTP020]), + CLKDEV_CON_ID("hac1_fck", &mstp_clks[MSTP017]), + CLKDEV_CON_ID("hac0_fck", &mstp_clks[MSTP016]), + CLKDEV_CON_ID("mmcif_fck", &mstp_clks[MSTP013]), + CLKDEV_CON_ID("flctl_fck", &mstp_clks[MSTP012]), { /* TMU0 */ .dev_id = "sh_tmu.0", @@ -152,6 +192,13 @@ static struct clk_lookup lookups[] = { .con_id = "tmu_fck", .clk = &mstp_clks[MSTP009], }, + CLKDEV_CON_ID("siof_fck", &mstp_clks[MSTP003]), + CLKDEV_CON_ID("hspi_fck", &mstp_clks[MSTP002]), + CLKDEV_CON_ID("hudi_fck", &mstp_clks[MSTP119]), + CLKDEV_CON_ID("ubc_fck", &mstp_clks[MSTP117]), + CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]), + CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]), + CLKDEV_CON_ID("gdta_fck", &mstp_clks[MSTP100]), }; int __init arch_clk_init(void) -- cgit v1.2.3-59-g8ed1b From 8bc23d95a0cd639e8766e522e5b9cfd5345bd3e2 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 05:00:30 +0000 Subject: sh: sh7786 mstp32 index rework This patch adds sh7786 MSTP enums for mstp_clks[] index. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 94 ++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index c4a84bb2f3d9..57c13ba358c4 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -87,39 +87,47 @@ struct clk div4_clks[DIV4_NR] = { #define MSTPCR0 0xffc40030 #define MSTPCR1 0xffc40034 -static struct clk mstp_clks[] = { +enum { MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, + MSTP023, MSTP022, MSTP021, MSTP020, MSTP017, MSTP016, + MSTP015, MSTP014, MSTP011, MSTP010, MSTP009, MSTP008, + MSTP005, MSTP004, MSTP002, + MSTP112, MSTP110, MSTP109, MSTP108, + MSTP105, MSTP104, MSTP103, MSTP102, + MSTP_NR }; + +static struct clk mstp_clks[MSTP_NR] = { /* MSTPCR0 */ - SH_CLK_MSTP32("sci_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), - SH_CLK_MSTP32("sci_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), - SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), - SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), - SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), - SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), - SH_CLK_MSTP32("ssi_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 23, 0), - SH_CLK_MSTP32("ssi_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 22, 0), - SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0), - SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0), - SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0), - SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0), - SH_CLK_MSTP32("i2c_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 15, 0), - SH_CLK_MSTP32("i2c_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 14, 0), - SH_CLK_MSTP32("tmu9_11_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 11, 0), - SH_CLK_MSTP32("tmu678_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 10, 0), - SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0), - SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0), - SH_CLK_MSTP32("sdif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 5, 0), - SH_CLK_MSTP32("sdif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 4, 0), - SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0), + [MSTP029] = SH_CLK_MSTP32("sci_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), + [MSTP028] = SH_CLK_MSTP32("sci_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), + [MSTP027] = SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), + [MSTP026] = SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), + [MSTP025] = SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), + [MSTP024] = SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), + [MSTP023] = SH_CLK_MSTP32("ssi_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 23, 0), + [MSTP022] = SH_CLK_MSTP32("ssi_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 22, 0), + [MSTP021] = SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0), + [MSTP020] = SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0), + [MSTP017] = SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0), + [MSTP016] = SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0), + [MSTP015] = SH_CLK_MSTP32("i2c_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 15, 0), + [MSTP014] = SH_CLK_MSTP32("i2c_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 14, 0), + [MSTP011] = SH_CLK_MSTP32("tmu9_11_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 11, 0), + [MSTP010] = SH_CLK_MSTP32("tmu678_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 10, 0), + [MSTP009] = SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0), + [MSTP008] = SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0), + [MSTP005] = SH_CLK_MSTP32("sdif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 5, 0), + [MSTP004] = SH_CLK_MSTP32("sdif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 4, 0), + [MSTP002] = SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0), /* MSTPCR1 */ - SH_CLK_MSTP32("usb_fck", -1, NULL, MSTPCR1, 12, 0), - SH_CLK_MSTP32("pcie_fck", 2, NULL, MSTPCR1, 10, 0), - SH_CLK_MSTP32("pcie_fck", 1, NULL, MSTPCR1, 9, 0), - SH_CLK_MSTP32("pcie_fck", 0, NULL, MSTPCR1, 8, 0), - SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0), - SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0), - SH_CLK_MSTP32("du_fck", -1, NULL, MSTPCR1, 3, 0), - SH_CLK_MSTP32("ether_fck", -1, NULL, MSTPCR1, 2, 0), + [MSTP112] = SH_CLK_MSTP32("usb_fck", -1, NULL, MSTPCR1, 12, 0), + [MSTP110] = SH_CLK_MSTP32("pcie_fck", 2, NULL, MSTPCR1, 10, 0), + [MSTP109] = SH_CLK_MSTP32("pcie_fck", 1, NULL, MSTPCR1, 9, 0), + [MSTP108] = SH_CLK_MSTP32("pcie_fck", 0, NULL, MSTPCR1, 8, 0), + [MSTP105] = SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0), + [MSTP104] = SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0), + [MSTP103] = SH_CLK_MSTP32("du_fck", -1, NULL, MSTPCR1, 3, 0), + [MSTP102] = SH_CLK_MSTP32("ether_fck", -1, NULL, MSTPCR1, 2, 0), }; static struct clk_lookup lookups[] = { @@ -127,62 +135,62 @@ static struct clk_lookup lookups[] = { /* TMU0 */ .dev_id = "sh_tmu.0", .con_id = "tmu_fck", - .clk = &mstp_clks[17], /* tmu012_fck */ + .clk = &mstp_clks[MSTP008], }, { /* TMU1 */ .dev_id = "sh_tmu.1", .con_id = "tmu_fck", - .clk = &mstp_clks[17], + .clk = &mstp_clks[MSTP008], }, { /* TMU2 */ .dev_id = "sh_tmu.2", .con_id = "tmu_fck", - .clk = &mstp_clks[17], + .clk = &mstp_clks[MSTP008], }, { /* TMU3 */ .dev_id = "sh_tmu.3", .con_id = "tmu_fck", - .clk = &mstp_clks[16], /* tmu345_fck */ + .clk = &mstp_clks[MSTP009], }, { /* TMU4 */ .dev_id = "sh_tmu.4", .con_id = "tmu_fck", - .clk = &mstp_clks[16], + .clk = &mstp_clks[MSTP009], }, { /* TMU5 */ .dev_id = "sh_tmu.5", .con_id = "tmu_fck", - .clk = &mstp_clks[16], + .clk = &mstp_clks[MSTP009], }, { /* TMU6 */ .dev_id = "sh_tmu.6", .con_id = "tmu_fck", - .clk = &mstp_clks[15], /* tmu678_fck */ + .clk = &mstp_clks[MSTP010], }, { /* TMU7 */ .dev_id = "sh_tmu.7", .con_id = "tmu_fck", - .clk = &mstp_clks[15], + .clk = &mstp_clks[MSTP010], }, { /* TMU8 */ .dev_id = "sh_tmu.8", .con_id = "tmu_fck", - .clk = &mstp_clks[15], + .clk = &mstp_clks[MSTP010], }, { /* TMU9 */ .dev_id = "sh_tmu.9", .con_id = "tmu_fck", - .clk = &mstp_clks[14], /* tmu9_11_fck */ + .clk = &mstp_clks[MSTP011], }, { /* TMU10 */ .dev_id = "sh_tmu.10", .con_id = "tmu_fck", - .clk = &mstp_clks[14], + .clk = &mstp_clks[MSTP011], }, { /* TMU11 */ .dev_id = "sh_tmu.11", .con_id = "tmu_fck", - .clk = &mstp_clks[14], + .clk = &mstp_clks[MSTP011], } }; @@ -199,7 +207,7 @@ int __init arch_clk_init(void) ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), &div4_table); if (!ret) - ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks)); + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); return ret; } -- cgit v1.2.3-59-g8ed1b From d8ef3ccc1c99ae51128b28aaed6e8afc43af71ff Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 05:00:38 +0000 Subject: sh: sh7786 mstp32 clkdev lookup Add sh7786 MSTP clocks to the clkdev lookup table. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 55 +++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 57c13ba358c4..d4f5f46883af 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -130,7 +130,49 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP102] = SH_CLK_MSTP32("ether_fck", -1, NULL, MSTPCR1, 2, 0), }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + static struct clk_lookup lookups[] = { + /* MSTP32 clocks */ + { + /* SCIF5 */ + .dev_id = "sh-sci.5", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP029], + }, { + /* SCIF4 */ + .dev_id = "sh-sci.4", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP028], + }, { + /* SCIF3 */ + .dev_id = "sh-sci.3", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP027], + }, { + /* SCIF2 */ + .dev_id = "sh-sci.2", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP026], + }, { + /* SCIF1 */ + .dev_id = "sh-sci.1", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP025], + }, { + /* SCIF0 */ + .dev_id = "sh-sci.0", + .con_id = "sci_fck", + .clk = &mstp_clks[MSTP024], + }, + CLKDEV_CON_ID("ssi3_fck", &mstp_clks[MSTP023]), + CLKDEV_CON_ID("ssi2_fck", &mstp_clks[MSTP022]), + CLKDEV_CON_ID("ssi1_fck", &mstp_clks[MSTP021]), + CLKDEV_CON_ID("ssi0_fck", &mstp_clks[MSTP020]), + CLKDEV_CON_ID("hac1_fck", &mstp_clks[MSTP017]), + CLKDEV_CON_ID("hac0_fck", &mstp_clks[MSTP016]), + CLKDEV_CON_ID("i2c1_fck", &mstp_clks[MSTP015]), + CLKDEV_CON_ID("i2c0_fck", &mstp_clks[MSTP014]), { /* TMU0 */ .dev_id = "sh_tmu.0", @@ -191,7 +233,18 @@ static struct clk_lookup lookups[] = { .dev_id = "sh_tmu.11", .con_id = "tmu_fck", .clk = &mstp_clks[MSTP011], - } + }, + CLKDEV_CON_ID("sdif1_fck", &mstp_clks[MSTP005]), + CLKDEV_CON_ID("sdif0_fck", &mstp_clks[MSTP004]), + CLKDEV_CON_ID("hspi_fck", &mstp_clks[MSTP002]), + CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP112]), + CLKDEV_CON_ID("pcie2_fck", &mstp_clks[MSTP110]), + CLKDEV_CON_ID("pcie1_fck", &mstp_clks[MSTP109]), + CLKDEV_CON_ID("pcie0_fck", &mstp_clks[MSTP108]), + CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]), + CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]), + CLKDEV_CON_ID("du_fck", &mstp_clks[MSTP103]), + CLKDEV_CON_ID("ether_fck", &mstp_clks[MSTP102]), }; int __init arch_clk_init(void) -- cgit v1.2.3-59-g8ed1b From c77a9c3edee079fe0411d98cfb9d872bc336ee32 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 05:00:47 +0000 Subject: sh: get rid of mstp32 clock name and id Remove the name and the id from SH_CLK_MSTP32(). Now when lookups are handled by clkdev they are not needed anymore. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 15 +++--- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 93 +++++++++++++++++----------------- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 82 +++++++++++++++--------------- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 42 +++++++-------- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 58 ++++++++++----------- 5 files changed, 143 insertions(+), 147 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 405a12c09960..c52882c1a468 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -116,15 +116,12 @@ int clk_rate_table_find(struct clk *clk, struct cpufreq_frequency_table *freq_table, unsigned long rate); -#define SH_CLK_MSTP32(_name, _id, _parent, _enable_reg, \ - _enable_bit, _flags) \ -{ \ - .name = _name, \ - .id = _id, \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_enable_reg, \ - .enable_bit = _enable_bit, \ - .flags = _flags, \ +#define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \ +{ \ + .parent = _parent, \ + .enable_reg = (void __iomem *)_enable_reg, \ + .enable_bit = _enable_bit, \ + .flags = _flags, \ } int sh_clk_mstp32_register(struct clk *clks, int nr); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index f661d4633573..0aabb5d31356 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -142,8 +142,8 @@ struct clk div6_clks[DIV6_NR] = { [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0), }; -#define MSTP(_str, _parent, _reg, _bit, _flags) \ - SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags) +#define MSTP(_parent, _reg, _bit, _flags) \ + SH_CLK_MSTP32(_parent, _reg, _bit, _flags) enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026, MSTP023, MSTP022, MSTP021, MSTP020, MSTP019, MSTP018, MSTP017, MSTP016, @@ -156,50 +156,50 @@ enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026, MSTP_NR }; static struct clk mstp_clks[MSTP_NR] = { - [MSTP031] = MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT), - [MSTP030] = MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT), - [MSTP029] = MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT), - [MSTP028] = MSTP("uram0", &div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT), - [MSTP026] = MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT), - [MSTP023] = MSTP("intc3", &div4_clks[DIV4_P], MSTPCR0, 23, 0), - [MSTP022] = MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 0), - [MSTP021] = MSTP("dmac0", &div4_clks[DIV4_P], MSTPCR0, 21, 0), - [MSTP020] = MSTP("sh0", &div4_clks[DIV4_P], MSTPCR0, 20, 0), - [MSTP019] = MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0), - [MSTP017] = MSTP("ubc0", &div4_clks[DIV4_P], MSTPCR0, 17, 0), - [MSTP015] = MSTP("tmu_fck", &div4_clks[DIV4_P], MSTPCR0, 15, 0), - [MSTP014] = MSTP("cmt_fck", &r_clk, MSTPCR0, 14, 0), - [MSTP013] = MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0), - [MSTP011] = MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0), - [MSTP010] = MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0), - [MSTP007] = SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 7, 0), - [MSTP006] = SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 6, 0), - [MSTP005] = SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 5, 0), - [MSTP004] = SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 4, 0), - [MSTP003] = MSTP("sio0", &div4_clks[DIV4_P], MSTPCR0, 3, 0), - [MSTP002] = MSTP("siof0", &div4_clks[DIV4_P], MSTPCR0, 2, 0), - [MSTP001] = MSTP("siof1", &div4_clks[DIV4_P], MSTPCR0, 1, 0), - - [MSTP109] = MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0), - [MSTP108] = MSTP("i2c1", &div4_clks[DIV4_P], MSTPCR1, 8, 0), - - [MSTP225] = MSTP("tpu0", &div4_clks[DIV4_P], MSTPCR2, 25, 0), - [MSTP224] = MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0), - [MSTP218] = MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0), - [MSTP217] = MSTP("mmcif0", &div4_clks[DIV4_P], MSTPCR2, 17, 0), - [MSTP216] = MSTP("sim0", &div4_clks[DIV4_P], MSTPCR2, 16, 0), - [MSTP214] = MSTP("keysc0", &r_clk, MSTPCR2, 14, 0), - [MSTP213] = MSTP("tsif0", &div4_clks[DIV4_P], MSTPCR2, 13, 0), - [MSTP212] = MSTP("s3d40", &div4_clks[DIV4_P], MSTPCR2, 12, 0), - [MSTP211] = MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0), - [MSTP208] = MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0), - [MSTP206] = MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT), - [MSTP205] = MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0), - [MSTP204] = MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0), - [MSTP203] = MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0), - [MSTP202] = MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT), - [MSTP201] = MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT), - [MSTP200] = MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0), + [MSTP031] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT), + [MSTP030] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT), + [MSTP029] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT), + [MSTP028] = MSTP(&div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT), + [MSTP026] = MSTP(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT), + [MSTP023] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 23, 0), + [MSTP022] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 22, 0), + [MSTP021] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 21, 0), + [MSTP020] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 20, 0), + [MSTP019] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 19, 0), + [MSTP017] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 17, 0), + [MSTP015] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 15, 0), + [MSTP014] = MSTP(&r_clk, MSTPCR0, 14, 0), + [MSTP013] = MSTP(&r_clk, MSTPCR0, 13, 0), + [MSTP011] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 11, 0), + [MSTP010] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 10, 0), + [MSTP007] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 7, 0), + [MSTP006] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 6, 0), + [MSTP005] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 5, 0), + [MSTP004] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 4, 0), + [MSTP003] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 3, 0), + [MSTP002] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 2, 0), + [MSTP001] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 1, 0), + + [MSTP109] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 9, 0), + [MSTP108] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 8, 0), + + [MSTP225] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 25, 0), + [MSTP224] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 24, 0), + [MSTP218] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 18, 0), + [MSTP217] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 17, 0), + [MSTP216] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 16, 0), + [MSTP214] = MSTP(&r_clk, MSTPCR2, 14, 0), + [MSTP213] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 13, 0), + [MSTP212] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 12, 0), + [MSTP211] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 11, 0), + [MSTP208] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 8, 0), + [MSTP206] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT), + [MSTP205] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 5, 0), + [MSTP204] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 4, 0), + [MSTP203] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 3, 0), + [MSTP202] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT), + [MSTP201] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT), + [MSTP200] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 0, 0), }; #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } @@ -216,7 +216,6 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("xymem0", &mstp_clks[MSTP026]), CLKDEV_CON_ID("intc3", &mstp_clks[MSTP023]), CLKDEV_CON_ID("intc0", &mstp_clks[MSTP022]), - CLKDEV_CON_ID("dmac0", &mstp_clks[MSTP021]), CLKDEV_CON_ID("sh0", &mstp_clks[MSTP020]), CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 5649bfcb9f74..a3ef183656fa 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -145,8 +145,8 @@ struct clk div6_clks[DIV6_NR] = { [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0), }; -#define MSTP(_str, _parent, _reg, _bit, _flags) \ - SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags) +#define MSTP(_parent, _reg, _bit, _flags) \ + SH_CLK_MSTP32(_parent, _reg, _bit, _flags) enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026, MSTP023, MSTP022, MSTP021, MSTP020, MSTP019, MSTP018, MSTP017, MSTP016, @@ -159,45 +159,45 @@ enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026, static struct clk mstp_clks[MSTP_NR] = { /* See page 52 of Datasheet V0.40: Overview -> Block Diagram */ - [MSTP031] = MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT), - [MSTP030] = MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT), - [MSTP029] = MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT), - [MSTP028] = MSTP("rsmem0", &div4_clks[DIV4_SH], MSTPCR0, 28, CLK_ENABLE_ON_INIT), - [MSTP026] = MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT), - [MSTP023] = MSTP("intc3", &div4_clks[DIV4_P], MSTPCR0, 23, 0), - [MSTP022] = MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 0), - [MSTP021] = MSTP("dmac0", &div4_clks[DIV4_P], MSTPCR0, 21, 0), - [MSTP020] = MSTP("sh0", &div4_clks[DIV4_P], MSTPCR0, 20, 0), - [MSTP019] = MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0), - [MSTP017] = MSTP("ubc0", &div4_clks[DIV4_P], MSTPCR0, 17, 0), - [MSTP015] = MSTP("tmu_fck", &div4_clks[DIV4_P], MSTPCR0, 15, 0), - [MSTP014] = MSTP("cmt_fck", &r_clk, MSTPCR0, 14, 0), - [MSTP013] = MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0), - [MSTP011] = MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0), - [MSTP010] = MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0), - [MSTP007] = SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 7, 0), - [MSTP006] = SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 6, 0), - [MSTP005] = SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 5, 0), - [MSTP002] = MSTP("msiof0", &div4_clks[DIV4_P], MSTPCR0, 2, 0), - [MSTP001] = MSTP("sbr0", &div4_clks[DIV4_P], MSTPCR0, 1, 0), - - [MSTP109] = MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0), - - [MSTP227] = MSTP("icb0", &div4_clks[DIV4_P], MSTPCR2, 27, 0), - [MSTP226] = MSTP("meram0", &div4_clks[DIV4_P], MSTPCR2, 26, 0), - [MSTP224] = MSTP("dacy1", &div4_clks[DIV4_P], MSTPCR2, 24, 0), - [MSTP223] = MSTP("dacy0", &div4_clks[DIV4_P], MSTPCR2, 23, 0), - [MSTP222] = MSTP("tsif0", &div4_clks[DIV4_P], MSTPCR2, 22, 0), - [MSTP218] = MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0), - [MSTP217] = MSTP("mmcif0", &div4_clks[DIV4_P], MSTPCR2, 17, 0), - [MSTP211] = MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0), - [MSTP207] = MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 7, CLK_ENABLE_ON_INIT), - [MSTP205] = MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0), - [MSTP204] = MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0), - [MSTP203] = MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0), - [MSTP202] = MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT), - [MSTP201] = MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT), - [MSTP200] = MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0), + [MSTP031] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT), + [MSTP030] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT), + [MSTP029] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT), + [MSTP028] = MSTP(&div4_clks[DIV4_SH], MSTPCR0, 28, CLK_ENABLE_ON_INIT), + [MSTP026] = MSTP(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT), + [MSTP023] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 23, 0), + [MSTP022] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 22, 0), + [MSTP021] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 21, 0), + [MSTP020] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 20, 0), + [MSTP019] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 19, 0), + [MSTP017] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 17, 0), + [MSTP015] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 15, 0), + [MSTP014] = MSTP(&r_clk, MSTPCR0, 14, 0), + [MSTP013] = MSTP(&r_clk, MSTPCR0, 13, 0), + [MSTP011] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 11, 0), + [MSTP010] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 10, 0), + [MSTP007] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 7, 0), + [MSTP006] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 6, 0), + [MSTP005] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 5, 0), + [MSTP002] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 2, 0), + [MSTP001] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 1, 0), + + [MSTP109] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 9, 0), + + [MSTP227] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 27, 0), + [MSTP226] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 26, 0), + [MSTP224] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 24, 0), + [MSTP223] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 23, 0), + [MSTP222] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 22, 0), + [MSTP218] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 18, 0), + [MSTP217] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 17, 0), + [MSTP211] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 11, 0), + [MSTP207] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 7, CLK_ENABLE_ON_INIT), + [MSTP205] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 5, 0), + [MSTP204] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 4, 0), + [MSTP203] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 3, 0), + [MSTP202] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT), + [MSTP201] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT), + [MSTP200] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 0, 0), }; #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 24d7208ff705..4625b72ba50c 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -95,29 +95,29 @@ enum { MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, static struct clk mstp_clks[MSTP_NR] = { /* MSTPCR0 */ - [MSTP029] = SH_CLK_MSTP32("sci_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), - [MSTP028] = SH_CLK_MSTP32("sci_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), - [MSTP027] = SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), - [MSTP026] = SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), - [MSTP025] = SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), - [MSTP024] = SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), - [MSTP021] = SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0), - [MSTP020] = SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0), - [MSTP017] = SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0), - [MSTP016] = SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0), - [MSTP013] = SH_CLK_MSTP32("mmcif_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 13, 0), - [MSTP012] = SH_CLK_MSTP32("flctl_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 12, 0), - [MSTP009] = SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0), - [MSTP008] = SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0), - [MSTP003] = SH_CLK_MSTP32("siof_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 3, 0), - [MSTP002] = SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0), + [MSTP029] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 29, 0), + [MSTP028] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 28, 0), + [MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0), + [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0), + [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0), + [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0), + [MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0), + [MSTP020] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 20, 0), + [MSTP017] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 17, 0), + [MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0), + [MSTP013] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 13, 0), + [MSTP012] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 12, 0), + [MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0), + [MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0), + [MSTP003] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 3, 0), + [MSTP002] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 2, 0), /* MSTPCR1 */ - [MSTP119] = SH_CLK_MSTP32("hudi_fck", -1, NULL, MSTPCR1, 19, 0), - [MSTP117] = SH_CLK_MSTP32("ubc_fck", -1, NULL, MSTPCR1, 17, 0), - [MSTP105] = SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0), - [MSTP104] = SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0), - [MSTP100] = SH_CLK_MSTP32("gdta_fck", -1, NULL, MSTPCR1, 0, 0), + [MSTP119] = SH_CLK_MSTP32(NULL, MSTPCR1, 19, 0), + [MSTP117] = SH_CLK_MSTP32(NULL, MSTPCR1, 17, 0), + [MSTP105] = SH_CLK_MSTP32(NULL, MSTPCR1, 5, 0), + [MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0), + [MSTP100] = SH_CLK_MSTP32(NULL, MSTPCR1, 0, 0), }; #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index d4f5f46883af..653d96615b77 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -97,37 +97,37 @@ enum { MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, static struct clk mstp_clks[MSTP_NR] = { /* MSTPCR0 */ - [MSTP029] = SH_CLK_MSTP32("sci_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), - [MSTP028] = SH_CLK_MSTP32("sci_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), - [MSTP027] = SH_CLK_MSTP32("sci_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), - [MSTP026] = SH_CLK_MSTP32("sci_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), - [MSTP025] = SH_CLK_MSTP32("sci_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), - [MSTP024] = SH_CLK_MSTP32("sci_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), - [MSTP023] = SH_CLK_MSTP32("ssi_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 23, 0), - [MSTP022] = SH_CLK_MSTP32("ssi_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 22, 0), - [MSTP021] = SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0), - [MSTP020] = SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0), - [MSTP017] = SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0), - [MSTP016] = SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0), - [MSTP015] = SH_CLK_MSTP32("i2c_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 15, 0), - [MSTP014] = SH_CLK_MSTP32("i2c_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 14, 0), - [MSTP011] = SH_CLK_MSTP32("tmu9_11_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 11, 0), - [MSTP010] = SH_CLK_MSTP32("tmu678_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 10, 0), - [MSTP009] = SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0), - [MSTP008] = SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0), - [MSTP005] = SH_CLK_MSTP32("sdif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 5, 0), - [MSTP004] = SH_CLK_MSTP32("sdif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 4, 0), - [MSTP002] = SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0), + [MSTP029] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 29, 0), + [MSTP028] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 28, 0), + [MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0), + [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0), + [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0), + [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0), + [MSTP023] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 23, 0), + [MSTP022] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 22, 0), + [MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0), + [MSTP020] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 20, 0), + [MSTP017] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 17, 0), + [MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0), + [MSTP015] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0), + [MSTP014] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 14, 0), + [MSTP011] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 11, 0), + [MSTP010] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0), + [MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0), + [MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0), + [MSTP005] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 5, 0), + [MSTP004] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 4, 0), + [MSTP002] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 2, 0), /* MSTPCR1 */ - [MSTP112] = SH_CLK_MSTP32("usb_fck", -1, NULL, MSTPCR1, 12, 0), - [MSTP110] = SH_CLK_MSTP32("pcie_fck", 2, NULL, MSTPCR1, 10, 0), - [MSTP109] = SH_CLK_MSTP32("pcie_fck", 1, NULL, MSTPCR1, 9, 0), - [MSTP108] = SH_CLK_MSTP32("pcie_fck", 0, NULL, MSTPCR1, 8, 0), - [MSTP105] = SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0), - [MSTP104] = SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0), - [MSTP103] = SH_CLK_MSTP32("du_fck", -1, NULL, MSTPCR1, 3, 0), - [MSTP102] = SH_CLK_MSTP32("ether_fck", -1, NULL, MSTPCR1, 2, 0), + [MSTP112] = SH_CLK_MSTP32(NULL, MSTPCR1, 12, 0), + [MSTP110] = SH_CLK_MSTP32(NULL, MSTPCR1, 10, 0), + [MSTP109] = SH_CLK_MSTP32(NULL, MSTPCR1, 9, 0), + [MSTP108] = SH_CLK_MSTP32(NULL, MSTPCR1, 8, 0), + [MSTP105] = SH_CLK_MSTP32(NULL, MSTPCR1, 5, 0), + [MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0), + [MSTP103] = SH_CLK_MSTP32(NULL, MSTPCR1, 3, 0), + [MSTP102] = SH_CLK_MSTP32(NULL, MSTPCR1, 2, 0), }; #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } -- cgit v1.2.3-59-g8ed1b From d40db0c4a63c3af44fd31a7c47cc4a11a44befc7 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 07:05:09 +0000 Subject: sh: div4 reparent workaround Update the div4 set_parent() callback to use the flags instead of name to determine parent index. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock-cpg.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index 17a73ad7a20d..0b165f6ae08c 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -168,7 +168,12 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) u32 value; int ret; - if (!strcmp("pll_clk", parent->name)) + /* we really need a better way to determine parent index, but for + * now assume internal parent comes with CLK_ENABLE_ON_INIT set, + * no CLK_ENABLE_ON_INIT means external clock... + */ + + if (parent->flags & CLK_ENABLE_ON_INIT) value = __raw_readl(clk->enable_reg) & ~(1 << 7); else value = __raw_readl(clk->enable_reg) | (1 << 7); -- cgit v1.2.3-59-g8ed1b From a3e9f2b72fbcb7c4266f4b7ef1814bb8806c1fac Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 07:05:17 +0000 Subject: sh: sh7722 div4 clkdev lookup Add sh7722 DIV4 clocks to the clkdev lookup list. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 2798ceaa648f..6ad3bc22933f 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -186,6 +186,17 @@ static struct clk mstp_clks[HWBLK_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* DIV4 clocks */ + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]), + CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]), + CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]), + CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), + CLKDEV_CON_ID("irda_clk", &div4_enable_clks[DIV4_IRDA]), + CLKDEV_CON_ID("siua_clk", &div4_reparent_clks[DIV4_SIUA]), + CLKDEV_CON_ID("siub_clk", &div4_reparent_clks[DIV4_SIUB]), + /* DIV6 clocks */ CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), -- cgit v1.2.3-59-g8ed1b From 3f6623497eee32161b0558c02963fa793988b6a0 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 07:05:25 +0000 Subject: sh: sh7723 div4 clkdev lookup Add sh7723 DIV4 clocks to the clkdev lookup list. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 500715f78142..05b112dedd1a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -211,6 +211,17 @@ static struct clk mstp_clks[] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* DIV4 clocks */ + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]), + CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]), + CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]), + CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), + CLKDEV_CON_ID("irda_clk", &div4_enable_clks[DIV4_IRDA]), + CLKDEV_CON_ID("siua_clk", &div4_reparent_clks[DIV4_SIUA]), + CLKDEV_CON_ID("siub_clk", &div4_reparent_clks[DIV4_SIUB]), + /* DIV6 clocks */ CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), -- cgit v1.2.3-59-g8ed1b From 1c4cde2e6d3bcd48635f2f68ca8f03290b5cf2e7 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 07:05:32 +0000 Subject: sh: sh7724 div4 clkdev lookup Add sh7724 DIV4 clocks to the clkdev lookup list. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 2bbff53fcd87..b9ed211dae79 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -234,6 +234,13 @@ static struct clk mstp_clks[HWBLK_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* DIV4 clocks */ + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]), + CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), + CLKDEV_CON_ID("vpu_clk", &div4_clks[DIV4_M1]), + /* DIV6 clocks */ CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]), -- cgit v1.2.3-59-g8ed1b From f8ef178c88cc21b16e81dab09d1def220e9eb49e Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 07:05:42 +0000 Subject: sh: sh7343 div4 clkdev lookup Add sh7343 DIV4 clocks to the clkdev lookup list. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index 0aabb5d31356..c123b55fb45b 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -205,6 +205,16 @@ static struct clk mstp_clks[MSTP_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* DIV4 clocks */ + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]), + CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]), + CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]), + CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), + CLKDEV_CON_ID("siua_clk", &div4_clks[DIV4_SIUA]), + CLKDEV_CON_ID("siub_clk", &div4_clks[DIV4_SIUB]), + /* DIV6 clocks */ CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), -- cgit v1.2.3-59-g8ed1b From 40956e7569c4d03da69748e333dded74a608af56 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 07:05:50 +0000 Subject: sh: sh7366 div4 clkdev lookup Add sh7366 DIV4 clocks to the clkdev lookup list. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index a3ef183656fa..35290b8be2a7 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -203,6 +203,16 @@ static struct clk mstp_clks[MSTP_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* DIV4 clocks */ + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]), + CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]), + CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]), + CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), + CLKDEV_CON_ID("siua_clk", &div4_clks[DIV4_SIUA]), + CLKDEV_CON_ID("siub_clk", &div4_clks[DIV4_SIUB]), + /* DIV6 clocks */ CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]), -- cgit v1.2.3-59-g8ed1b From 956f7f442afce6df3fa2b3e77a40ecdb7fc4c9fc Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 07:05:58 +0000 Subject: sh: sh7785 div4 clkdev lookup Add sh7785 DIV4 clocks to the clkdev lookup list. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 4625b72ba50c..0a44be96c038 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -123,6 +123,16 @@ static struct clk mstp_clks[MSTP_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* DIV4 clocks */ + CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), + CLKDEV_CON_ID("du_clk", &div4_clks[DIV4_DU]), + CLKDEV_CON_ID("ga_clk", &div4_clks[DIV4_GA]), + CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_DDR]), + CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]), + CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]), + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + /* MSTP32 clocks */ { /* SCIF5 */ -- cgit v1.2.3-59-g8ed1b From 1fe3d19883b1f6a243b03456a47e0fdc9629bea6 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 07:06:05 +0000 Subject: sh: sh7786 div4 clkdev lookup Add sh7786 DIV4 clocks to the clkdev lookup list. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 653d96615b77..f00b89f86a24 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -133,6 +133,14 @@ static struct clk mstp_clks[MSTP_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* DIV4 clocks */ + CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), + CLKDEV_CON_ID("du_clk", &div4_clks[DIV4_DU]), + CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_DDR]), + CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]), + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + /* MSTP32 clocks */ { /* SCIF5 */ -- cgit v1.2.3-59-g8ed1b From 914ebf0bbb24696cd7eecee8942efecca5653126 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 07:06:13 +0000 Subject: sh: get rid of div4 clock name Remove the name parameter from SH_CLK_DIV4() and adjust the processor specific code. The lookup happens using clkdev so the name is unused. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 15 +++++++-------- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 20 ++++++++++---------- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 20 ++++++++++---------- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 22 +++++++++++----------- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 22 +++++++++++----------- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 14 +++++++------- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 20 ++++++++++---------- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 16 ++++++++-------- 8 files changed, 74 insertions(+), 75 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index c52882c1a468..f6b0bfd4e191 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -126,14 +126,13 @@ int clk_rate_table_find(struct clk *clk, int sh_clk_mstp32_register(struct clk *clks, int nr); -#define SH_CLK_DIV4(_name, _parent, _reg, _shift, _div_bitmap, _flags) \ -{ \ - .name = _name, \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_reg, \ - .enable_bit = _shift, \ - .arch_flags = _div_bitmap, \ - .flags = _flags, \ +#define SH_CLK_DIV4(_parent, _reg, _shift, _div_bitmap, _flags) \ +{ \ + .parent = _parent, \ + .enable_reg = (void __iomem *)_reg, \ + .enable_bit = _shift, \ + .arch_flags = _div_bitmap, \ + .flags = _flags, \ } struct clk_div4_table { diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index c123b55fb45b..e2e8cc278044 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -122,18 +122,18 @@ static struct clk_div4_table div4_table = { enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_SIUA, DIV4_SIUB, DIV4_NR }; -#define DIV4(_str, _reg, _bit, _mask, _flags) \ - SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags) +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) struct clk div4_clks[DIV4_NR] = { - [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_SH] = DIV4("shyway_clk", FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0), - [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0), - [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0), + [DIV4_I] = DIV4(FRQCR, 20, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0), + [DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0), + [DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0), }; enum { DIV6_V, DIV6_NR }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 35290b8be2a7..4c3a5a583012 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -125,18 +125,18 @@ static struct clk_div4_table div4_table = { enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_SIUA, DIV4_SIUB, DIV4_NR }; -#define DIV4(_str, _reg, _bit, _mask, _flags) \ - SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags) +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) struct clk div4_clks[DIV4_NR] = { - [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT), - [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_SH] = DIV4("shyway_clk", FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0), - [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0), - [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0), + [DIV4_I] = DIV4(FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT), + [DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0), + [DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0), + [DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0), }; enum { DIV6_V, DIV6_NR }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 6ad3bc22933f..2d811d975ca8 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -122,31 +122,31 @@ static struct clk_div4_table div4_table = { .div_mult_table = &div4_div_mult_table, }; -#define DIV4(_str, _reg, _bit, _mask, _flags) \ - SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags) +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR }; struct clk div4_clks[DIV4_NR] = { - [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT), - [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_SH] = DIV4("shyway_clk", FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT), - [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0), + [DIV4_I] = DIV4(FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT), + [DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT), + [DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0), }; enum { DIV4_IRDA, DIV4_ENABLE_NR }; struct clk div4_enable_clks[DIV4_ENABLE_NR] = { - [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x1fff, 0), + [DIV4_IRDA] = DIV4(IRDACLKCR, 0, 0x1fff, 0), }; enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR }; struct clk div4_reparent_clks[DIV4_REPARENT_NR] = { - [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0), - [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0), + [DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0), + [DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0), }; enum { DIV6_V, DIV6_NR }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 05b112dedd1a..7685504369cc 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -125,29 +125,29 @@ static struct clk_div4_table div4_table = { enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR }; -#define DIV4(_str, _reg, _bit, _mask, _flags) \ - SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags) +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) struct clk div4_clks[DIV4_NR] = { - [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x0dbf, CLK_ENABLE_ON_INIT), - [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x0dbf, CLK_ENABLE_ON_INIT), - [DIV4_SH] = DIV4("shyway_clk", FRQCR, 12, 0x0dbf, CLK_ENABLE_ON_INIT), - [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x0dbf, CLK_ENABLE_ON_INIT), - [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x0db4, CLK_ENABLE_ON_INIT), - [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x0dbf, 0), + [DIV4_I] = DIV4(FRQCR, 20, 0x0dbf, CLK_ENABLE_ON_INIT), + [DIV4_U] = DIV4(FRQCR, 16, 0x0dbf, CLK_ENABLE_ON_INIT), + [DIV4_SH] = DIV4(FRQCR, 12, 0x0dbf, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(FRQCR, 8, 0x0dbf, CLK_ENABLE_ON_INIT), + [DIV4_B3] = DIV4(FRQCR, 4, 0x0db4, CLK_ENABLE_ON_INIT), + [DIV4_P] = DIV4(FRQCR, 0, 0x0dbf, 0), }; enum { DIV4_IRDA, DIV4_ENABLE_NR }; struct clk div4_enable_clks[DIV4_ENABLE_NR] = { - [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x0dbf, 0), + [DIV4_IRDA] = DIV4(IRDACLKCR, 0, 0x0dbf, 0), }; enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR }; struct clk div4_reparent_clks[DIV4_REPARENT_NR] = { - [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0), - [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0), + [DIV4_SIUA] = DIV4(SCLKACR, 0, 0x0dbf, 0), + [DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x0dbf, 0), }; enum { DIV6_V, DIV6_NR }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index b9ed211dae79..6095f50fca8a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -153,15 +153,15 @@ static struct clk_div4_table div4_table = { enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_P, DIV4_M1, DIV4_NR }; -#define DIV4(_str, _reg, _bit, _mask, _flags) \ - SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags) +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) struct clk div4_clks[DIV4_NR] = { - [DIV4_I] = DIV4("cpu_clk", FRQCRA, 20, 0x2f7d, CLK_ENABLE_ON_INIT), - [DIV4_SH] = DIV4("shyway_clk", FRQCRA, 12, 0x2f7c, CLK_ENABLE_ON_INIT), - [DIV4_B] = DIV4("bus_clk", FRQCRA, 8, 0x2f7c, CLK_ENABLE_ON_INIT), - [DIV4_P] = DIV4("peripheral_clk", FRQCRA, 0, 0x2f7c, 0), - [DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT), + [DIV4_I] = DIV4(FRQCRA, 20, 0x2f7d, CLK_ENABLE_ON_INIT), + [DIV4_SH] = DIV4(FRQCRA, 12, 0x2f7c, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(FRQCRA, 8, 0x2f7c, CLK_ENABLE_ON_INIT), + [DIV4_P] = DIV4(FRQCRA, 0, 0x2f7c, 0), + [DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT), }; enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 0a44be96c038..a7a8eecfbda4 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -70,18 +70,18 @@ static struct clk_div4_table div4_table = { enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_GA, DIV4_DU, DIV4_P, DIV4_NR }; -#define DIV4(_str, _bit, _mask, _flags) \ - SH_CLK_DIV4(_str, &pll_clk, FRQMR1, _bit, _mask, _flags) +#define DIV4(_bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags) struct clk div4_clks[DIV4_NR] = { - [DIV4_P] = DIV4("peripheral_clk", 0, 0x0f80, 0), - [DIV4_DU] = DIV4("du_clk", 4, 0x0ff0, 0), - [DIV4_GA] = DIV4("ga_clk", 8, 0x0030, 0), - [DIV4_DDR] = DIV4("ddr_clk", 12, 0x000c, CLK_ENABLE_ON_INIT), - [DIV4_B] = DIV4("bus_clk", 16, 0x0fe0, CLK_ENABLE_ON_INIT), - [DIV4_SH] = DIV4("shyway_clk", 20, 0x000c, CLK_ENABLE_ON_INIT), - [DIV4_U] = DIV4("umem_clk", 24, 0x000c, CLK_ENABLE_ON_INIT), - [DIV4_I] = DIV4("cpu_clk", 28, 0x000e, CLK_ENABLE_ON_INIT), + [DIV4_P] = DIV4(0, 0x0f80, 0), + [DIV4_DU] = DIV4(4, 0x0ff0, 0), + [DIV4_GA] = DIV4(8, 0x0030, 0), + [DIV4_DDR] = DIV4(12, 0x000c, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(16, 0x0fe0, CLK_ENABLE_ON_INIT), + [DIV4_SH] = DIV4(20, 0x000c, CLK_ENABLE_ON_INIT), + [DIV4_U] = DIV4(24, 0x000c, CLK_ENABLE_ON_INIT), + [DIV4_I] = DIV4(28, 0x000e, CLK_ENABLE_ON_INIT), }; #define MSTPCR0 0xffc80030 diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index f00b89f86a24..3ce3b5a69525 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -72,16 +72,16 @@ static struct clk_div4_table div4_table = { enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_DU, DIV4_P, DIV4_NR }; -#define DIV4(_str, _bit, _mask, _flags) \ - SH_CLK_DIV4(_str, &pll_clk, FRQMR1, _bit, _mask, _flags) +#define DIV4(_bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags) struct clk div4_clks[DIV4_NR] = { - [DIV4_P] = DIV4("peripheral_clk", 0, 0x0b40, 0), - [DIV4_DU] = DIV4("du_clk", 4, 0x0010, 0), - [DIV4_DDR] = DIV4("ddr_clk", 12, 0x0002, CLK_ENABLE_ON_INIT), - [DIV4_B] = DIV4("bus_clk", 16, 0x0360, CLK_ENABLE_ON_INIT), - [DIV4_SH] = DIV4("shyway_clk", 20, 0x0002, CLK_ENABLE_ON_INIT), - [DIV4_I] = DIV4("cpu_clk", 28, 0x0006, CLK_ENABLE_ON_INIT), + [DIV4_P] = DIV4(0, 0x0b40, 0), + [DIV4_DU] = DIV4(4, 0x0010, 0), + [DIV4_DDR] = DIV4(12, 0x0002, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(16, 0x0360, CLK_ENABLE_ON_INIT), + [DIV4_SH] = DIV4(20, 0x0002, CLK_ENABLE_ON_INIT), + [DIV4_I] = DIV4(28, 0x0006, CLK_ENABLE_ON_INIT), }; #define MSTPCR0 0xffc40030 -- cgit v1.2.3-59-g8ed1b From 53041f020b31dd83aa4d0bdc78015bee58b1afe8 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:35:11 +0000 Subject: sh: switch legacy clocks to clkdev This patch converts the legacy clocks to register using clkdev. Also the clock name is removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock-cpg.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index 0b165f6ae08c..69c6472cdf58 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -2,6 +2,7 @@ #include #include #include +#include #include static int sh_clk_mstp32_enable(struct clk *clk) @@ -299,25 +300,21 @@ int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, #ifdef CONFIG_SH_CLK_CPG_LEGACY static struct clk master_clk = { - .name = "master_clk", .flags = CLK_ENABLE_ON_INIT, .rate = CONFIG_SH_PCLK_FREQ, }; static struct clk peripheral_clk = { - .name = "peripheral_clk", .parent = &master_clk, .flags = CLK_ENABLE_ON_INIT, }; static struct clk bus_clk = { - .name = "bus_clk", .parent = &master_clk, .flags = CLK_ENABLE_ON_INIT, }; static struct clk cpu_clk = { - .name = "cpu_clk", .parent = &master_clk, .flags = CLK_ENABLE_ON_INIT, }; @@ -332,6 +329,16 @@ static struct clk *onchip_clocks[] = { &cpu_clk, }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("master_clk", &master_clk), + CLKDEV_CON_ID("peripheral_clk", &peripheral_clk), + CLKDEV_CON_ID("bus_clk", &bus_clk), + CLKDEV_CON_ID("cpu_clk", &cpu_clk), +}; + int __init __deprecated cpg_clk_init(void) { int i, ret = 0; @@ -343,6 +350,8 @@ int __init __deprecated cpg_clk_init(void) ret |= clk_register(clk); } + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + clk_add_alias("tmu_fck", NULL, "peripheral_clk", NULL); clk_add_alias("mtu2_fck", NULL, "peripheral_clk", NULL); clk_add_alias("cmt_fck", NULL, "peripheral_clk", NULL); -- cgit v1.2.3-59-g8ed1b From b3f9f630d35f7eeec49221690991e834d7b27e05 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:35:19 +0000 Subject: sh: switch sh7724 to clkdev This patch converts the remaining sh7724 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 6095f50fca8a..2d9700c6b53a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -41,8 +41,6 @@ /* Fixed 32 KHz root clock for RTC and Power Management purposes */ static struct clk r_clk = { - .name = "rclk", - .id = -1, .rate = 32768, }; @@ -51,8 +49,6 @@ static struct clk r_clk = { * from the platform code. */ struct clk extal_clk = { - .name = "extal", - .id = -1, .rate = 33333333, }; @@ -76,8 +72,6 @@ static struct clk_ops fll_clk_ops = { }; static struct clk fll_clk = { - .name = "fll_clk", - .id = -1, .ops = &fll_clk_ops, .parent = &r_clk, .flags = CLK_ENABLE_ON_INIT, @@ -98,8 +92,6 @@ static struct clk_ops pll_clk_ops = { }; static struct clk pll_clk = { - .name = "pll_clk", - .id = -1, .ops = &pll_clk_ops, .flags = CLK_ENABLE_ON_INIT, }; @@ -115,8 +107,6 @@ static struct clk_ops div3_clk_ops = { }; static struct clk div3_clk = { - .name = "div3_clk", - .id = -1, .ops = &div3_clk_ops, .parent = &pll_clk, }; @@ -234,6 +224,13 @@ static struct clk mstp_clks[HWBLK_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("rclk", &r_clk), + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("fll_clk", &fll_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + CLKDEV_CON_ID("div3_clk", &div3_clk), + /* DIV4 clocks */ CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]), -- cgit v1.2.3-59-g8ed1b From 00522ac3b11f52cce6358516dd8695a588082a73 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:35:27 +0000 Subject: sh: switch sh7723 to clkdev This patch converts the remaining sh7723 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 7685504369cc..d3938f0d3702 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -38,8 +38,6 @@ /* Fixed 32 KHz root clock for RTC and Power Management purposes */ static struct clk r_clk = { - .name = "rclk", - .id = -1, .rate = 32768, }; @@ -48,8 +46,6 @@ static struct clk r_clk = { * from the platform code. */ struct clk extal_clk = { - .name = "extal", - .id = -1, .rate = 33333333, }; @@ -71,8 +67,6 @@ static struct clk_ops dll_clk_ops = { }; static struct clk dll_clk = { - .name = "dll_clk", - .id = -1, .ops = &dll_clk_ops, .parent = &r_clk, .flags = CLK_ENABLE_ON_INIT, @@ -96,8 +90,6 @@ static struct clk_ops pll_clk_ops = { }; static struct clk pll_clk = { - .name = "pll_clk", - .id = -1, .ops = &pll_clk_ops, .flags = CLK_ENABLE_ON_INIT, }; @@ -211,6 +203,12 @@ static struct clk mstp_clks[] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("rclk", &r_clk), + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("dll_clk", &dll_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + /* DIV4 clocks */ CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]), -- cgit v1.2.3-59-g8ed1b From 925bb17b725ba84159bac9defebac0cb46e01e4f Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:35:38 +0000 Subject: sh: switch sh7722 to clkdev This patch converts the remaining sh7722 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 2d811d975ca8..2030f3d9fac7 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -37,8 +37,6 @@ /* Fixed 32 KHz root clock for RTC and Power Management purposes */ static struct clk r_clk = { - .name = "rclk", - .id = -1, .rate = 32768, }; @@ -47,8 +45,6 @@ static struct clk r_clk = { * from the platform code. */ struct clk extal_clk = { - .name = "extal", - .id = -1, .rate = 33333333, }; @@ -70,8 +66,6 @@ static struct clk_ops dll_clk_ops = { }; static struct clk dll_clk = { - .name = "dll_clk", - .id = -1, .ops = &dll_clk_ops, .parent = &r_clk, .flags = CLK_ENABLE_ON_INIT, @@ -95,8 +89,6 @@ static struct clk_ops pll_clk_ops = { }; static struct clk pll_clk = { - .name = "pll_clk", - .id = -1, .ops = &pll_clk_ops, .flags = CLK_ENABLE_ON_INIT, }; @@ -186,6 +178,12 @@ static struct clk mstp_clks[HWBLK_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("rclk", &r_clk), + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("dll_clk", &dll_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + /* DIV4 clocks */ CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]), -- cgit v1.2.3-59-g8ed1b From 8249a3113094b826c5010d27c8cf07a395be2abc Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:35:45 +0000 Subject: sh: switch sh7343 to clkdev This patch converts the remaining sh7343 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index e2e8cc278044..71291ae201b9 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -37,8 +37,6 @@ /* Fixed 32 KHz root clock for RTC and Power Management purposes */ static struct clk r_clk = { - .name = "rclk", - .id = -1, .rate = 32768, }; @@ -47,8 +45,6 @@ static struct clk r_clk = { * from the platform code. */ struct clk extal_clk = { - .name = "extal", - .id = -1, .rate = 33333333, }; @@ -70,8 +66,6 @@ static struct clk_ops dll_clk_ops = { }; static struct clk dll_clk = { - .name = "dll_clk", - .id = -1, .ops = &dll_clk_ops, .parent = &r_clk, .flags = CLK_ENABLE_ON_INIT, @@ -92,8 +86,6 @@ static struct clk_ops pll_clk_ops = { }; static struct clk pll_clk = { - .name = "pll_clk", - .id = -1, .ops = &pll_clk_ops, .flags = CLK_ENABLE_ON_INIT, }; @@ -205,6 +197,12 @@ static struct clk mstp_clks[MSTP_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("rclk", &r_clk), + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("dll_clk", &dll_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + /* DIV4 clocks */ CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]), -- cgit v1.2.3-59-g8ed1b From 59aa69d9c20b1ee15fa26aa6631b555aaef91323 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:35:55 +0000 Subject: sh: switch sh7366 to clkdev This patch converts the remaining sh7366 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 4c3a5a583012..7ce5bbcd4084 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -37,8 +37,6 @@ /* Fixed 32 KHz root clock for RTC and Power Management purposes */ static struct clk r_clk = { - .name = "rclk", - .id = -1, .rate = 32768, }; @@ -47,8 +45,6 @@ static struct clk r_clk = { * from the platform code. */ struct clk extal_clk = { - .name = "extal", - .id = -1, .rate = 33333333, }; @@ -70,8 +66,6 @@ static struct clk_ops dll_clk_ops = { }; static struct clk dll_clk = { - .name = "dll_clk", - .id = -1, .ops = &dll_clk_ops, .parent = &r_clk, .flags = CLK_ENABLE_ON_INIT, @@ -95,8 +89,6 @@ static struct clk_ops pll_clk_ops = { }; static struct clk pll_clk = { - .name = "pll_clk", - .id = -1, .ops = &pll_clk_ops, .flags = CLK_ENABLE_ON_INIT, }; @@ -203,6 +195,12 @@ static struct clk mstp_clks[MSTP_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("rclk", &r_clk), + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("dll_clk", &dll_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + /* DIV4 clocks */ CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]), -- cgit v1.2.3-59-g8ed1b From 4a81fe625efc8b9122eb4473dab31fa90e07a381 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:36:03 +0000 Subject: sh: switch sh7785 to clkdev This patch converts the remaining sh7785 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index a7a8eecfbda4..c3e458aaa2b7 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -24,8 +24,6 @@ * from the platform code. */ static struct clk extal_clk = { - .name = "extal", - .id = -1, .rate = 33333333, }; @@ -43,8 +41,6 @@ static struct clk_ops pll_clk_ops = { }; static struct clk pll_clk = { - .name = "pll_clk", - .id = -1, .ops = &pll_clk_ops, .parent = &extal_clk, .flags = CLK_ENABLE_ON_INIT, @@ -123,6 +119,10 @@ static struct clk mstp_clks[MSTP_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + /* DIV4 clocks */ CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), CLKDEV_CON_ID("du_clk", &div4_clks[DIV4_DU]), -- cgit v1.2.3-59-g8ed1b From 2cf79bea43491722a23b63a6f4e54d3804c10ed6 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:36:16 +0000 Subject: sh: switch sh7786 to clkdev This patch converts the remaining sh7786 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 3ce3b5a69525..105a6d41b569 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -23,8 +23,6 @@ * from the platform code. */ static struct clk extal_clk = { - .name = "extal", - .id = -1, .rate = 33333333, }; @@ -46,8 +44,6 @@ static struct clk_ops pll_clk_ops = { }; static struct clk pll_clk = { - .name = "pll_clk", - .id = -1, .ops = &pll_clk_ops, .parent = &extal_clk, .flags = CLK_ENABLE_ON_INIT, @@ -133,6 +129,10 @@ static struct clk mstp_clks[MSTP_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + /* DIV4 clocks */ CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), CLKDEV_CON_ID("du_clk", &div4_clks[DIV4_DU]), -- cgit v1.2.3-59-g8ed1b From 29497ec42c7c3a42682e5538ca7f96cd9a00fcbb Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:36:24 +0000 Subject: sh: switch sh7780 to clkdev This patch converts the remaining sh7780 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7780.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c index 150963a6001e..62d706350060 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c @@ -11,6 +11,8 @@ */ #include #include +#include +#include #include #include #include @@ -83,7 +85,6 @@ static struct clk_ops sh7780_shyway_clk_ops = { }; static struct clk sh7780_shyway_clk = { - .name = "shyway_clk", .flags = CLK_ENABLE_ON_INIT, .ops = &sh7780_shyway_clk_ops, }; @@ -96,6 +97,13 @@ static struct clk *sh7780_onchip_clocks[] = { &sh7780_shyway_clk, }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("shyway_clk", &sh7780_shyway_clk), +}; + int __init arch_clk_init(void) { struct clk *clk; @@ -113,5 +121,7 @@ int __init arch_clk_init(void) clk_put(clk); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + return ret; } -- cgit v1.2.3-59-g8ed1b From d6a94217fb4b4d193d6064c524df22f97bd49136 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:36:32 +0000 Subject: sh: switch sh7763 to clkdev This patch converts the remaining sh7763 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7763.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c index 9f401163e71e..1f1df48008cd 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c @@ -12,6 +12,8 @@ */ #include #include +#include +#include #include #include #include @@ -77,7 +79,6 @@ static struct clk_ops sh7763_shyway_clk_ops = { }; static struct clk sh7763_shyway_clk = { - .name = "shyway_clk", .flags = CLK_ENABLE_ON_INIT, .ops = &sh7763_shyway_clk_ops, }; @@ -90,6 +91,13 @@ static struct clk *sh7763_onchip_clocks[] = { &sh7763_shyway_clk, }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("shyway_clk", &sh7763_shyway_clk), +}; + int __init arch_clk_init(void) { struct clk *clk; @@ -107,5 +115,7 @@ int __init arch_clk_init(void) clk_put(clk); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + return ret; } -- cgit v1.2.3-59-g8ed1b From f0e7f90223108e32f6b28393e4ab892209922e0b Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:36:40 +0000 Subject: sh: switch sh7757 to clkdev This patch converts the remaining sh7757 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index 86aae60677dc..0a752bd324ac 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -87,7 +88,6 @@ static struct clk_ops sh7757_shyway_clk_ops = { }; static struct clk sh7757_shyway_clk = { - .name = "shyway_clk", .flags = CLK_ENABLE_ON_INIT, .ops = &sh7757_shyway_clk_ops, }; @@ -100,6 +100,13 @@ static struct clk *sh7757_onchip_clocks[] = { &sh7757_shyway_clk, }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("shyway_clk", &sh7757_shyway_clk), +}; + static int __init sh7757_clk_init(void) { struct clk *clk = clk_get(NULL, "master_clk"); @@ -123,6 +130,8 @@ static int __init sh7757_clk_init(void) clk_put(clk); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + return 0; } -- cgit v1.2.3-59-g8ed1b From 38803d7626c3903dea98d23dfe012e98975503f3 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:36:48 +0000 Subject: sh: switch shx3 to clkdev This patch converts the remaining shx3 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-shx3.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index e75c57bdfa5e..236a6282d778 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -13,9 +13,10 @@ */ #include #include +#include +#include #include #include -#include static int ifc_divisors[] = { 1, 2, 4 ,6 }; static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, 24, 32, 36, 48 }; @@ -94,7 +95,6 @@ static struct clk_ops shx3_shyway_clk_ops = { }; static struct clk shx3_shyway_clk = { - .name = "shyway_clk", .flags = CLK_ENABLE_ON_INIT, .ops = &shx3_shyway_clk_ops, }; @@ -107,6 +107,13 @@ static struct clk *shx3_onchip_clocks[] = { &shx3_shyway_clk, }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("shyway_clk", &shx3_shyway_clk), +}; + int __init arch_clk_init(void) { struct clk *clk; @@ -124,5 +131,7 @@ int __init arch_clk_init(void) clk_put(clk); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + return ret; } -- cgit v1.2.3-59-g8ed1b From 9c352bcab7f28e472b06c91d57210b93e08f0fbb Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:36:57 +0000 Subject: sh: switch sh4-202 to clkdev This patch converts the remaining sh4-202 clocks to use clkdev for lookup. The now unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index 6b80850294da..4eabc68cd753 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -12,9 +12,10 @@ #include #include #include +#include +#include #include #include -#include #define CPG2_FRQCR3 0xfe0a0018 @@ -45,7 +46,6 @@ static struct clk_ops sh4202_emi_clk_ops = { }; static struct clk sh4202_emi_clk = { - .name = "emi_clk", .flags = CLK_ENABLE_ON_INIT, .ops = &sh4202_emi_clk_ops, }; @@ -61,7 +61,6 @@ static struct clk_ops sh4202_femi_clk_ops = { }; static struct clk sh4202_femi_clk = { - .name = "femi_clk", .flags = CLK_ENABLE_ON_INIT, .ops = &sh4202_femi_clk_ops, }; @@ -139,7 +138,6 @@ static struct clk_ops sh4202_shoc_clk_ops = { }; static struct clk sh4202_shoc_clk = { - .name = "shoc_clk", .flags = CLK_ENABLE_ON_INIT, .ops = &sh4202_shoc_clk_ops, }; @@ -150,6 +148,15 @@ static struct clk *sh4202_onchip_clocks[] = { &sh4202_shoc_clk, }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("emi_clk", &sh4202_emi_clk), + CLKDEV_CON_ID("femi_clk", &sh4202_femi_clk), + CLKDEV_CON_ID("shoc_clk", &sh4202_shoc_clk), +}; + int __init arch_clk_init(void) { struct clk *clk; @@ -167,5 +174,7 @@ int __init arch_clk_init(void) clk_put(clk); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + return ret; } -- cgit v1.2.3-59-g8ed1b From 67bbabbc8680f53c7b8780d991f655c5cbb88700 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:37:05 +0000 Subject: sh: switch boards to clkdev This patch converts the remaining board clocks to use clkdev for lookup if needed. The unused name and id from struct clk are also removed. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 2 -- arch/sh/boards/mach-highlander/setup.c | 12 +++++++++++- arch/sh/boards/mach-se/7724/setup.c | 2 -- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 6c13b92742e8..1850c087a93b 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -710,8 +710,6 @@ static struct clk_ops fsimck_clk_ops = { }; static struct clk fsimckb_clk = { - .name = "fsimckb_clk", - .id = -1, .ops = &fsimck_clk_ops, .enable_reg = (void __iomem *)FCLKBCR, .rate = 0, /* unknown */ diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c index affd66747ba3..a5ecfbacaf36 100644 --- a/arch/sh/boards/mach-highlander/setup.c +++ b/arch/sh/boards/mach-highlander/setup.c @@ -14,6 +14,7 @@ * for more details. */ #include +#include #include #include #include @@ -26,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -326,7 +328,6 @@ static struct clk_ops ivdr_clk_ops = { }; static struct clk ivdr_clk = { - .name = "ivdr_clk", .ops = &ivdr_clk_ops, }; @@ -334,6 +335,13 @@ static struct clk *r7780rp_clocks[] = { &ivdr_clk, }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("ivdr_clk", &ivdr_clk), +}; + static void r7780rp_power_off(void) { if (mach_is_r7780mp() || mach_is_r7785rp()) @@ -370,6 +378,8 @@ static void __init highlander_setup(char **cmdline_p) clk_enable(clk); } + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + __raw_writew(0x0000, PA_OBLED); /* Clear LED. */ if (mach_is_r7780rp()) diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index ccaa290e9aba..20b6053f714a 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -276,8 +276,6 @@ static struct clk_ops fsimck_clk_ops = { }; static struct clk fsimcka_clk = { - .name = "fsimcka_clk", - .id = -1, .ops = &fsimck_clk_ops, .enable_reg = (void __iomem *)FCLKACR, .rate = 0, /* unknown */ -- cgit v1.2.3-59-g8ed1b From 441c2440aba2efd8d0f48a5e3357deec92283d62 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 09:37:12 +0000 Subject: sh: remove unused clock lookup Now when all clocks are registered using clkdev, get rid of the special SH-specific clock lookup. Also ditch the unused module ref counting code. This patch syncs the SH behaviour with ARM. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 1 - arch/sh/kernel/cpu/clock.c | 37 ++----------------------------------- 2 files changed, 2 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index f6b0bfd4e191..35d219616110 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -23,7 +23,6 @@ struct clk { struct list_head node; const char *name; int id; - struct module *owner; struct clk *parent; struct clk_ops *ops; diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index a725c7feb747..8cc6935d91ae 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -398,49 +398,16 @@ EXPORT_SYMBOL_GPL(clk_round_rate); * Returns a clock. Note that we first try to use device id on the bus * and clock name. If this fails, we try to use clock name only. */ -struct clk *clk_get(struct device *dev, const char *id) +struct clk *clk_get(struct device *dev, const char *con_id) { const char *dev_id = dev ? dev_name(dev) : NULL; - struct clk *p, *clk = ERR_PTR(-ENOENT); - int idno; - clk = clk_get_sys(dev_id, id); - if (clk && !IS_ERR(clk)) - return clk; - - if (dev == NULL || dev->bus != &platform_bus_type) - idno = -1; - else - idno = to_platform_device(dev)->id; - - mutex_lock(&clock_list_sem); - list_for_each_entry(p, &clock_list, node) { - if (p->name && p->id == idno && - strcmp(id, p->name) == 0 && try_module_get(p->owner)) { - clk = p; - goto found; - } - } - - list_for_each_entry(p, &clock_list, node) { - if (p->name && - strcmp(id, p->name) == 0 && try_module_get(p->owner)) { - clk = p; - break; - } - } - -found: - mutex_unlock(&clock_list_sem); - - return clk; + return clk_get_sys(dev_id, con_id); } EXPORT_SYMBOL_GPL(clk_get); void clk_put(struct clk *clk) { - if (clk && !IS_ERR(clk)) - module_put(clk->owner); } EXPORT_SYMBOL_GPL(clk_put); -- cgit v1.2.3-59-g8ed1b From d28bdf05f72238d626c8d06b61049f6df8d78e70 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 13:29:17 +0000 Subject: sh: move sh asm/clock.h contents to linux/sh_clk.h V2 This patch is V2 of the clock framework move from arch/sh/include/asm/clock.h to include/linux/sh_clk.h and updates the include paths for files that will be shared between SH and SH-Mobile ARM. The file asm/clock.h is still kept in this version, this to depend on as few files as possible at this point. We keep SH specific stuff in there. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 147 +----------------------------------------- include/linux/sh_clk.h | 151 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 146 deletions(-) create mode 100644 include/linux/sh_clk.h (limited to 'arch') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 35d219616110..f387e5caee16 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -1,158 +1,13 @@ #ifndef __ASM_SH_CLOCK_H #define __ASM_SH_CLOCK_H -#include -#include -#include -#include -#include - -struct clk; - -struct clk_ops { - void (*init)(struct clk *clk); - int (*enable)(struct clk *clk); - void (*disable)(struct clk *clk); - unsigned long (*recalc)(struct clk *clk); - int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); - int (*set_parent)(struct clk *clk, struct clk *parent); - long (*round_rate)(struct clk *clk, unsigned long rate); -}; - -struct clk { - struct list_head node; - const char *name; - int id; - - struct clk *parent; - struct clk_ops *ops; - - struct list_head children; - struct list_head sibling; /* node for children */ - - int usecount; - - unsigned long rate; - unsigned long flags; - - void __iomem *enable_reg; - unsigned int enable_bit; - - unsigned long arch_flags; - void *priv; - struct dentry *dentry; - struct cpufreq_frequency_table *freq_table; -}; - -#define CLK_ENABLE_ON_INIT (1 << 0) +#include /* Should be defined by processor-specific code */ void __deprecated arch_init_clk_ops(struct clk_ops **, int type); int __init arch_clk_init(void); -/* arch/sh/kernel/cpu/clock.c */ -int clk_init(void); -unsigned long followparent_recalc(struct clk *); -void recalculate_root_clocks(void); -void propagate_rate(struct clk *); -int clk_reparent(struct clk *child, struct clk *parent); -int clk_register(struct clk *); -void clk_unregister(struct clk *); - /* arch/sh/kernel/cpu/clock-cpg.c */ int __init __deprecated cpg_clk_init(void); -/* the exported API, in addition to clk_set_rate */ -/** - * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter - * @clk: clock source - * @rate: desired clock rate in Hz - * @algo_id: algorithm id to be passed down to ops->set_rate - * - * Returns success (0) or negative errno. - */ -int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id); - -enum clk_sh_algo_id { - NO_CHANGE = 0, - - IUS_N1_N1, - IUS_322, - IUS_522, - IUS_N11, - - SB_N1, - - SB3_N1, - SB3_32, - SB3_43, - SB3_54, - - BP_N1, - - IP_N1, -}; - -struct clk_div_mult_table { - unsigned int *divisors; - unsigned int nr_divisors; - unsigned int *multipliers; - unsigned int nr_multipliers; -}; - -struct cpufreq_frequency_table; -void clk_rate_table_build(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - int nr_freqs, - struct clk_div_mult_table *src_table, - unsigned long *bitmap); - -long clk_rate_table_round(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - unsigned long rate); - -int clk_rate_table_find(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - unsigned long rate); - -#define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \ -{ \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_enable_reg, \ - .enable_bit = _enable_bit, \ - .flags = _flags, \ -} - -int sh_clk_mstp32_register(struct clk *clks, int nr); - -#define SH_CLK_DIV4(_parent, _reg, _shift, _div_bitmap, _flags) \ -{ \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_reg, \ - .enable_bit = _shift, \ - .arch_flags = _div_bitmap, \ - .flags = _flags, \ -} - -struct clk_div4_table { - struct clk_div_mult_table *div_mult_table; - void (*kick)(struct clk *clk); -}; - -int sh_clk_div4_register(struct clk *clks, int nr, - struct clk_div4_table *table); -int sh_clk_div4_enable_register(struct clk *clks, int nr, - struct clk_div4_table *table); -int sh_clk_div4_reparent_register(struct clk *clks, int nr, - struct clk_div4_table *table); - -#define SH_CLK_DIV6(_parent, _reg, _flags) \ -{ \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_reg, \ - .flags = _flags, \ -} - -int sh_clk_div6_register(struct clk *clks, int nr); - #endif /* __ASM_SH_CLOCK_H */ diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h new file mode 100644 index 000000000000..de911451c216 --- /dev/null +++ b/include/linux/sh_clk.h @@ -0,0 +1,151 @@ +#ifndef __SH_CLOCK_H +#define __SH_CLOCK_H + +#include +#include +#include +#include +#include + +struct clk; + +struct clk_ops { + void (*init)(struct clk *clk); + int (*enable)(struct clk *clk); + void (*disable)(struct clk *clk); + unsigned long (*recalc)(struct clk *clk); + int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); + int (*set_parent)(struct clk *clk, struct clk *parent); + long (*round_rate)(struct clk *clk, unsigned long rate); +}; + +struct clk { + struct list_head node; + const char *name; + int id; + + struct clk *parent; + struct clk_ops *ops; + + struct list_head children; + struct list_head sibling; /* node for children */ + + int usecount; + + unsigned long rate; + unsigned long flags; + + void __iomem *enable_reg; + unsigned int enable_bit; + + unsigned long arch_flags; + void *priv; + struct dentry *dentry; + struct cpufreq_frequency_table *freq_table; +}; + +#define CLK_ENABLE_ON_INIT (1 << 0) + +/* arch/sh/kernel/cpu/clock.c */ +int clk_init(void); +unsigned long followparent_recalc(struct clk *); +void recalculate_root_clocks(void); +void propagate_rate(struct clk *); +int clk_reparent(struct clk *child, struct clk *parent); +int clk_register(struct clk *); +void clk_unregister(struct clk *); + +/* the exported API, in addition to clk_set_rate */ +/** + * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter + * @clk: clock source + * @rate: desired clock rate in Hz + * @algo_id: algorithm id to be passed down to ops->set_rate + * + * Returns success (0) or negative errno. + */ +int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id); + +enum clk_sh_algo_id { + NO_CHANGE = 0, + + IUS_N1_N1, + IUS_322, + IUS_522, + IUS_N11, + + SB_N1, + + SB3_N1, + SB3_32, + SB3_43, + SB3_54, + + BP_N1, + + IP_N1, +}; + +struct clk_div_mult_table { + unsigned int *divisors; + unsigned int nr_divisors; + unsigned int *multipliers; + unsigned int nr_multipliers; +}; + +struct cpufreq_frequency_table; +void clk_rate_table_build(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + int nr_freqs, + struct clk_div_mult_table *src_table, + unsigned long *bitmap); + +long clk_rate_table_round(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + unsigned long rate); + +int clk_rate_table_find(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + unsigned long rate); + +#define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \ +{ \ + .parent = _parent, \ + .enable_reg = (void __iomem *)_enable_reg, \ + .enable_bit = _enable_bit, \ + .flags = _flags, \ +} + +int sh_clk_mstp32_register(struct clk *clks, int nr); + +#define SH_CLK_DIV4(_parent, _reg, _shift, _div_bitmap, _flags) \ +{ \ + .parent = _parent, \ + .enable_reg = (void __iomem *)_reg, \ + .enable_bit = _shift, \ + .arch_flags = _div_bitmap, \ + .flags = _flags, \ +} + +struct clk_div4_table { + struct clk_div_mult_table *div_mult_table; + void (*kick)(struct clk *clk); +}; + +int sh_clk_div4_register(struct clk *clks, int nr, + struct clk_div4_table *table); +int sh_clk_div4_enable_register(struct clk *clks, int nr, + struct clk_div4_table *table); +int sh_clk_div4_reparent_register(struct clk *clks, int nr, + struct clk_div4_table *table); + +#define SH_CLK_DIV6(_parent, _reg, _flags) \ +{ \ + .parent = _parent, \ + .enable_reg = (void __iomem *)_reg, \ + .flags = _flags, \ +} + +int sh_clk_div6_register(struct clk *clks, int nr); + +#endif /* __SH_CLOCK_H */ -- cgit v1.2.3-59-g8ed1b From 8b5ee113e1b97097e992a0301d0cac2530b31fc2 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 13:29:25 +0000 Subject: sh: move sh clock.c contents to drivers/sh/clk. This patch is V2 of the SH clock framework move from arch/sh/kernel/cpu/clock.c to drivers/sh/clk.c. All code except the following functions are moved: clk_init(), clk_get() and clk_put(). The init function is still kept in clock.c since it depends on the SH-specific machvec implementation. The symbols clk_get() and clk_put() already exist in the common ARM clkdev code, those symbols are left in the SH tree to avoid duplicating them for SH-Mobile ARM. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 3 + arch/sh/kernel/cpu/clock.c | 543 +------------------------------------------ drivers/sh/Makefile | 1 + drivers/sh/clk.c | 548 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/sh_clk.h | 2 +- 5 files changed, 561 insertions(+), 536 deletions(-) create mode 100644 drivers/sh/clk.c (limited to 'arch') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index f387e5caee16..803d4c7f09dc 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -10,4 +10,7 @@ int __init arch_clk_init(void); /* arch/sh/kernel/cpu/clock-cpg.c */ int __init __deprecated cpg_clk_init(void); +/* arch/sh/kernel/cpu/clock.c */ +int clk_init(void); + #endif /* __ASM_SH_CLOCK_H */ diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 8cc6935d91ae..50f887dda565 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -16,467 +16,10 @@ */ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include -static LIST_HEAD(clock_list); -static DEFINE_SPINLOCK(clock_lock); -static DEFINE_MUTEX(clock_list_sem); - -void clk_rate_table_build(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - int nr_freqs, - struct clk_div_mult_table *src_table, - unsigned long *bitmap) -{ - unsigned long mult, div; - unsigned long freq; - int i; - - for (i = 0; i < nr_freqs; i++) { - div = 1; - mult = 1; - - if (src_table->divisors && i < src_table->nr_divisors) - div = src_table->divisors[i]; - - if (src_table->multipliers && i < src_table->nr_multipliers) - mult = src_table->multipliers[i]; - - if (!div || !mult || (bitmap && !test_bit(i, bitmap))) - freq = CPUFREQ_ENTRY_INVALID; - else - freq = clk->parent->rate * mult / div; - - freq_table[i].index = i; - freq_table[i].frequency = freq; - } - - /* Termination entry */ - freq_table[i].index = i; - freq_table[i].frequency = CPUFREQ_TABLE_END; -} - -long clk_rate_table_round(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - unsigned long rate) -{ - unsigned long rate_error, rate_error_prev = ~0UL; - unsigned long rate_best_fit = rate; - unsigned long highest, lowest; - int i; - - highest = lowest = 0; - - for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { - unsigned long freq = freq_table[i].frequency; - - if (freq == CPUFREQ_ENTRY_INVALID) - continue; - - if (freq > highest) - highest = freq; - if (freq < lowest) - lowest = freq; - - rate_error = abs(freq - rate); - if (rate_error < rate_error_prev) { - rate_best_fit = freq; - rate_error_prev = rate_error; - } - - if (rate_error == 0) - break; - } - - if (rate >= highest) - rate_best_fit = highest; - if (rate <= lowest) - rate_best_fit = lowest; - - return rate_best_fit; -} - -int clk_rate_table_find(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - unsigned long rate) -{ - int i; - - for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { - unsigned long freq = freq_table[i].frequency; - - if (freq == CPUFREQ_ENTRY_INVALID) - continue; - - if (freq == rate) - return i; - } - - return -ENOENT; -} - -/* Used for clocks that always have same value as the parent clock */ -unsigned long followparent_recalc(struct clk *clk) -{ - return clk->parent ? clk->parent->rate : 0; -} - -int clk_reparent(struct clk *child, struct clk *parent) -{ - list_del_init(&child->sibling); - if (parent) - list_add(&child->sibling, &parent->children); - child->parent = parent; - - /* now do the debugfs renaming to reattach the child - to the proper parent */ - - return 0; -} - -/* Propagate rate to children */ -void propagate_rate(struct clk *tclk) -{ - struct clk *clkp; - - list_for_each_entry(clkp, &tclk->children, sibling) { - if (clkp->ops && clkp->ops->recalc) - clkp->rate = clkp->ops->recalc(clkp); - - propagate_rate(clkp); - } -} - -static void __clk_disable(struct clk *clk) -{ - if (clk->usecount == 0) { - printk(KERN_ERR "Trying disable clock %s with 0 usecount\n", - clk->name); - WARN_ON(1); - return; - } - - if (!(--clk->usecount)) { - if (likely(clk->ops && clk->ops->disable)) - clk->ops->disable(clk); - if (likely(clk->parent)) - __clk_disable(clk->parent); - } -} - -void clk_disable(struct clk *clk) -{ - unsigned long flags; - - if (!clk) - return; - - spin_lock_irqsave(&clock_lock, flags); - __clk_disable(clk); - spin_unlock_irqrestore(&clock_lock, flags); -} -EXPORT_SYMBOL_GPL(clk_disable); - -static int __clk_enable(struct clk *clk) -{ - int ret = 0; - - if (clk->usecount++ == 0) { - if (clk->parent) { - ret = __clk_enable(clk->parent); - if (unlikely(ret)) - goto err; - } - - if (clk->ops && clk->ops->enable) { - ret = clk->ops->enable(clk); - if (ret) { - if (clk->parent) - __clk_disable(clk->parent); - goto err; - } - } - } - - return ret; -err: - clk->usecount--; - return ret; -} - -int clk_enable(struct clk *clk) -{ - unsigned long flags; - int ret; - - if (!clk) - return -EINVAL; - - spin_lock_irqsave(&clock_lock, flags); - ret = __clk_enable(clk); - spin_unlock_irqrestore(&clock_lock, flags); - - return ret; -} -EXPORT_SYMBOL_GPL(clk_enable); - -static LIST_HEAD(root_clks); - -/** - * recalculate_root_clocks - recalculate and propagate all root clocks - * - * Recalculates all root clocks (clocks with no parent), which if the - * clock's .recalc is set correctly, should also propagate their rates. - * Called at init. - */ -void recalculate_root_clocks(void) -{ - struct clk *clkp; - - list_for_each_entry(clkp, &root_clks, sibling) { - if (clkp->ops && clkp->ops->recalc) - clkp->rate = clkp->ops->recalc(clkp); - propagate_rate(clkp); - } -} - -int clk_register(struct clk *clk) -{ - if (clk == NULL || IS_ERR(clk)) - return -EINVAL; - - /* - * trap out already registered clocks - */ - if (clk->node.next || clk->node.prev) - return 0; - - mutex_lock(&clock_list_sem); - - INIT_LIST_HEAD(&clk->children); - clk->usecount = 0; - - if (clk->parent) - list_add(&clk->sibling, &clk->parent->children); - else - list_add(&clk->sibling, &root_clks); - - list_add(&clk->node, &clock_list); - if (clk->ops && clk->ops->init) - clk->ops->init(clk); - mutex_unlock(&clock_list_sem); - - return 0; -} -EXPORT_SYMBOL_GPL(clk_register); - -void clk_unregister(struct clk *clk) -{ - mutex_lock(&clock_list_sem); - list_del(&clk->sibling); - list_del(&clk->node); - mutex_unlock(&clock_list_sem); -} -EXPORT_SYMBOL_GPL(clk_unregister); - -static void clk_enable_init_clocks(void) -{ - struct clk *clkp; - - list_for_each_entry(clkp, &clock_list, node) - if (clkp->flags & CLK_ENABLE_ON_INIT) - clk_enable(clkp); -} - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL_GPL(clk_get_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - return clk_set_rate_ex(clk, rate, 0); -} -EXPORT_SYMBOL_GPL(clk_set_rate); - -int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) -{ - int ret = -EOPNOTSUPP; - unsigned long flags; - - spin_lock_irqsave(&clock_lock, flags); - - if (likely(clk->ops && clk->ops->set_rate)) { - ret = clk->ops->set_rate(clk, rate, algo_id); - if (ret != 0) - goto out_unlock; - } else { - clk->rate = rate; - ret = 0; - } - - if (clk->ops && clk->ops->recalc) - clk->rate = clk->ops->recalc(clk); - - propagate_rate(clk); - -out_unlock: - spin_unlock_irqrestore(&clock_lock, flags); - - return ret; -} -EXPORT_SYMBOL_GPL(clk_set_rate_ex); - -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - unsigned long flags; - int ret = -EINVAL; - - if (!parent || !clk) - return ret; - if (clk->parent == parent) - return 0; - - spin_lock_irqsave(&clock_lock, flags); - if (clk->usecount == 0) { - if (clk->ops->set_parent) - ret = clk->ops->set_parent(clk, parent); - else - ret = clk_reparent(clk, parent); - - if (ret == 0) { - pr_debug("clock: set parent of %s to %s (new rate %ld)\n", - clk->name, clk->parent->name, clk->rate); - if (clk->ops->recalc) - clk->rate = clk->ops->recalc(clk); - propagate_rate(clk); - } - } else - ret = -EBUSY; - spin_unlock_irqrestore(&clock_lock, flags); - - return ret; -} -EXPORT_SYMBOL_GPL(clk_set_parent); - -struct clk *clk_get_parent(struct clk *clk) -{ - return clk->parent; -} -EXPORT_SYMBOL_GPL(clk_get_parent); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - if (likely(clk->ops && clk->ops->round_rate)) { - unsigned long flags, rounded; - - spin_lock_irqsave(&clock_lock, flags); - rounded = clk->ops->round_rate(clk, rate); - spin_unlock_irqrestore(&clock_lock, flags); - - return rounded; - } - - return clk_get_rate(clk); -} -EXPORT_SYMBOL_GPL(clk_round_rate); - -/* - * Returns a clock. Note that we first try to use device id on the bus - * and clock name. If this fails, we try to use clock name only. - */ -struct clk *clk_get(struct device *dev, const char *con_id) -{ - const char *dev_id = dev ? dev_name(dev) : NULL; - - return clk_get_sys(dev_id, con_id); -} -EXPORT_SYMBOL_GPL(clk_get); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL_GPL(clk_put); - -#ifdef CONFIG_PM -static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) -{ - static pm_message_t prev_state; - struct clk *clkp; - - switch (state.event) { - case PM_EVENT_ON: - /* Resumeing from hibernation */ - if (prev_state.event != PM_EVENT_FREEZE) - break; - - list_for_each_entry(clkp, &clock_list, node) { - if (likely(clkp->ops)) { - unsigned long rate = clkp->rate; - - if (likely(clkp->ops->set_parent)) - clkp->ops->set_parent(clkp, - clkp->parent); - if (likely(clkp->ops->set_rate)) - clkp->ops->set_rate(clkp, - rate, NO_CHANGE); - else if (likely(clkp->ops->recalc)) - clkp->rate = clkp->ops->recalc(clkp); - } - } - break; - case PM_EVENT_FREEZE: - break; - case PM_EVENT_SUSPEND: - break; - } - - prev_state = state; - return 0; -} - -static int clks_sysdev_resume(struct sys_device *dev) -{ - return clks_sysdev_suspend(dev, PMSG_ON); -} - -static struct sysdev_class clks_sysdev_class = { - .name = "clks", -}; - -static struct sysdev_driver clks_sysdev_driver = { - .suspend = clks_sysdev_suspend, - .resume = clks_sysdev_resume, -}; - -static struct sys_device clks_sysdev_dev = { - .cls = &clks_sysdev_class, -}; - -static int __init clk_sysdev_init(void) -{ - sysdev_class_register(&clks_sysdev_class); - sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver); - sysdev_register(&clks_sysdev_dev); - - return 0; -} -subsys_initcall(clk_sysdev_init); -#endif - int __init clk_init(void) { int ret; @@ -506,89 +49,19 @@ int __init clk_init(void) } /* - * debugfs support to trace clock tree hierarchy and attributes + * Returns a clock. Note that we first try to use device id on the bus + * and clock name. If this fails, we try to use clock name only. */ -static struct dentry *clk_debugfs_root; - -static int clk_debugfs_register_one(struct clk *c) +struct clk *clk_get(struct device *dev, const char *con_id) { - int err; - struct dentry *d, *child, *child_tmp; - struct clk *pa = c->parent; - char s[255]; - char *p = s; - - p += sprintf(p, "%s", c->name); - if (c->id >= 0) - sprintf(p, ":%d", c->id); - d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root); - if (!d) - return -ENOMEM; - c->dentry = d; - - d = debugfs_create_u8("usecount", S_IRUGO, c->dentry, (u8 *)&c->usecount); - if (!d) { - err = -ENOMEM; - goto err_out; - } - d = debugfs_create_u32("rate", S_IRUGO, c->dentry, (u32 *)&c->rate); - if (!d) { - err = -ENOMEM; - goto err_out; - } - d = debugfs_create_x32("flags", S_IRUGO, c->dentry, (u32 *)&c->flags); - if (!d) { - err = -ENOMEM; - goto err_out; - } - return 0; + const char *dev_id = dev ? dev_name(dev) : NULL; -err_out: - d = c->dentry; - list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) - debugfs_remove(child); - debugfs_remove(c->dentry); - return err; + return clk_get_sys(dev_id, con_id); } +EXPORT_SYMBOL_GPL(clk_get); -static int clk_debugfs_register(struct clk *c) +void clk_put(struct clk *clk) { - int err; - struct clk *pa = c->parent; - - if (pa && !pa->dentry) { - err = clk_debugfs_register(pa); - if (err) - return err; - } - - if (!c->dentry && c->name) { - err = clk_debugfs_register_one(c); - if (err) - return err; - } - return 0; } +EXPORT_SYMBOL_GPL(clk_put); -static int __init clk_debugfs_init(void) -{ - struct clk *c; - struct dentry *d; - int err; - - d = debugfs_create_dir("clock", NULL); - if (!d) - return -ENOMEM; - clk_debugfs_root = d; - - list_for_each_entry(c, &clock_list, node) { - err = clk_debugfs_register(c); - if (err) - goto err_out; - } - return 0; -err_out: - debugfs_remove_recursive(clk_debugfs_root); - return err; -} -late_initcall(clk_debugfs_init); diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index 4956bf1f2134..033a949c496a 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile @@ -4,4 +4,5 @@ obj-$(CONFIG_SUPERHYWAY) += superhyway/ obj-$(CONFIG_MAPLE) += maple/ obj-$(CONFIG_GENERIC_GPIO) += pfc.o +obj-$(CONFIG_SUPERH) += clk.o obj-y += intc.o diff --git a/drivers/sh/clk.c b/drivers/sh/clk.c new file mode 100644 index 000000000000..c90a3e1e1085 --- /dev/null +++ b/drivers/sh/clk.c @@ -0,0 +1,548 @@ +/* + * drivers/sh/clk.c - SuperH clock framework + * + * Copyright (C) 2005 - 2009 Paul Mundt + * + * This clock framework is derived from the OMAP version by: + * + * Copyright (C) 2004 - 2008 Nokia Corporation + * Written by Tuukka Tikkanen + * + * Modified for omap shared clock framework by Tony Lindgren + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static LIST_HEAD(clock_list); +static DEFINE_SPINLOCK(clock_lock); +static DEFINE_MUTEX(clock_list_sem); + +void clk_rate_table_build(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + int nr_freqs, + struct clk_div_mult_table *src_table, + unsigned long *bitmap) +{ + unsigned long mult, div; + unsigned long freq; + int i; + + for (i = 0; i < nr_freqs; i++) { + div = 1; + mult = 1; + + if (src_table->divisors && i < src_table->nr_divisors) + div = src_table->divisors[i]; + + if (src_table->multipliers && i < src_table->nr_multipliers) + mult = src_table->multipliers[i]; + + if (!div || !mult || (bitmap && !test_bit(i, bitmap))) + freq = CPUFREQ_ENTRY_INVALID; + else + freq = clk->parent->rate * mult / div; + + freq_table[i].index = i; + freq_table[i].frequency = freq; + } + + /* Termination entry */ + freq_table[i].index = i; + freq_table[i].frequency = CPUFREQ_TABLE_END; +} + +long clk_rate_table_round(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + unsigned long rate) +{ + unsigned long rate_error, rate_error_prev = ~0UL; + unsigned long rate_best_fit = rate; + unsigned long highest, lowest; + int i; + + highest = lowest = 0; + + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { + unsigned long freq = freq_table[i].frequency; + + if (freq == CPUFREQ_ENTRY_INVALID) + continue; + + if (freq > highest) + highest = freq; + if (freq < lowest) + lowest = freq; + + rate_error = abs(freq - rate); + if (rate_error < rate_error_prev) { + rate_best_fit = freq; + rate_error_prev = rate_error; + } + + if (rate_error == 0) + break; + } + + if (rate >= highest) + rate_best_fit = highest; + if (rate <= lowest) + rate_best_fit = lowest; + + return rate_best_fit; +} + +int clk_rate_table_find(struct clk *clk, + struct cpufreq_frequency_table *freq_table, + unsigned long rate) +{ + int i; + + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { + unsigned long freq = freq_table[i].frequency; + + if (freq == CPUFREQ_ENTRY_INVALID) + continue; + + if (freq == rate) + return i; + } + + return -ENOENT; +} + +/* Used for clocks that always have same value as the parent clock */ +unsigned long followparent_recalc(struct clk *clk) +{ + return clk->parent ? clk->parent->rate : 0; +} + +int clk_reparent(struct clk *child, struct clk *parent) +{ + list_del_init(&child->sibling); + if (parent) + list_add(&child->sibling, &parent->children); + child->parent = parent; + + /* now do the debugfs renaming to reattach the child + to the proper parent */ + + return 0; +} + +/* Propagate rate to children */ +void propagate_rate(struct clk *tclk) +{ + struct clk *clkp; + + list_for_each_entry(clkp, &tclk->children, sibling) { + if (clkp->ops && clkp->ops->recalc) + clkp->rate = clkp->ops->recalc(clkp); + + propagate_rate(clkp); + } +} + +static void __clk_disable(struct clk *clk) +{ + if (clk->usecount == 0) { + printk(KERN_ERR "Trying disable clock %s with 0 usecount\n", + clk->name); + WARN_ON(1); + return; + } + + if (!(--clk->usecount)) { + if (likely(clk->ops && clk->ops->disable)) + clk->ops->disable(clk); + if (likely(clk->parent)) + __clk_disable(clk->parent); + } +} + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + + if (!clk) + return; + + spin_lock_irqsave(&clock_lock, flags); + __clk_disable(clk); + spin_unlock_irqrestore(&clock_lock, flags); +} +EXPORT_SYMBOL_GPL(clk_disable); + +static int __clk_enable(struct clk *clk) +{ + int ret = 0; + + if (clk->usecount++ == 0) { + if (clk->parent) { + ret = __clk_enable(clk->parent); + if (unlikely(ret)) + goto err; + } + + if (clk->ops && clk->ops->enable) { + ret = clk->ops->enable(clk); + if (ret) { + if (clk->parent) + __clk_disable(clk->parent); + goto err; + } + } + } + + return ret; +err: + clk->usecount--; + return ret; +} + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + int ret; + + if (!clk) + return -EINVAL; + + spin_lock_irqsave(&clock_lock, flags); + ret = __clk_enable(clk); + spin_unlock_irqrestore(&clock_lock, flags); + + return ret; +} +EXPORT_SYMBOL_GPL(clk_enable); + +static LIST_HEAD(root_clks); + +/** + * recalculate_root_clocks - recalculate and propagate all root clocks + * + * Recalculates all root clocks (clocks with no parent), which if the + * clock's .recalc is set correctly, should also propagate their rates. + * Called at init. + */ +void recalculate_root_clocks(void) +{ + struct clk *clkp; + + list_for_each_entry(clkp, &root_clks, sibling) { + if (clkp->ops && clkp->ops->recalc) + clkp->rate = clkp->ops->recalc(clkp); + propagate_rate(clkp); + } +} + +int clk_register(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + /* + * trap out already registered clocks + */ + if (clk->node.next || clk->node.prev) + return 0; + + mutex_lock(&clock_list_sem); + + INIT_LIST_HEAD(&clk->children); + clk->usecount = 0; + + if (clk->parent) + list_add(&clk->sibling, &clk->parent->children); + else + list_add(&clk->sibling, &root_clks); + + list_add(&clk->node, &clock_list); + if (clk->ops && clk->ops->init) + clk->ops->init(clk); + mutex_unlock(&clock_list_sem); + + return 0; +} +EXPORT_SYMBOL_GPL(clk_register); + +void clk_unregister(struct clk *clk) +{ + mutex_lock(&clock_list_sem); + list_del(&clk->sibling); + list_del(&clk->node); + mutex_unlock(&clock_list_sem); +} +EXPORT_SYMBOL_GPL(clk_unregister); + +void clk_enable_init_clocks(void) +{ + struct clk *clkp; + + list_for_each_entry(clkp, &clock_list, node) + if (clkp->flags & CLK_ENABLE_ON_INIT) + clk_enable(clkp); +} + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL_GPL(clk_get_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return clk_set_rate_ex(clk, rate, 0); +} +EXPORT_SYMBOL_GPL(clk_set_rate); + +int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) +{ + int ret = -EOPNOTSUPP; + unsigned long flags; + + spin_lock_irqsave(&clock_lock, flags); + + if (likely(clk->ops && clk->ops->set_rate)) { + ret = clk->ops->set_rate(clk, rate, algo_id); + if (ret != 0) + goto out_unlock; + } else { + clk->rate = rate; + ret = 0; + } + + if (clk->ops && clk->ops->recalc) + clk->rate = clk->ops->recalc(clk); + + propagate_rate(clk); + +out_unlock: + spin_unlock_irqrestore(&clock_lock, flags); + + return ret; +} +EXPORT_SYMBOL_GPL(clk_set_rate_ex); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + unsigned long flags; + int ret = -EINVAL; + + if (!parent || !clk) + return ret; + if (clk->parent == parent) + return 0; + + spin_lock_irqsave(&clock_lock, flags); + if (clk->usecount == 0) { + if (clk->ops->set_parent) + ret = clk->ops->set_parent(clk, parent); + else + ret = clk_reparent(clk, parent); + + if (ret == 0) { + pr_debug("clock: set parent of %s to %s (new rate %ld)\n", + clk->name, clk->parent->name, clk->rate); + if (clk->ops->recalc) + clk->rate = clk->ops->recalc(clk); + propagate_rate(clk); + } + } else + ret = -EBUSY; + spin_unlock_irqrestore(&clock_lock, flags); + + return ret; +} +EXPORT_SYMBOL_GPL(clk_set_parent); + +struct clk *clk_get_parent(struct clk *clk) +{ + return clk->parent; +} +EXPORT_SYMBOL_GPL(clk_get_parent); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (likely(clk->ops && clk->ops->round_rate)) { + unsigned long flags, rounded; + + spin_lock_irqsave(&clock_lock, flags); + rounded = clk->ops->round_rate(clk, rate); + spin_unlock_irqrestore(&clock_lock, flags); + + return rounded; + } + + return clk_get_rate(clk); +} +EXPORT_SYMBOL_GPL(clk_round_rate); + +#ifdef CONFIG_PM +static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) +{ + static pm_message_t prev_state; + struct clk *clkp; + + switch (state.event) { + case PM_EVENT_ON: + /* Resumeing from hibernation */ + if (prev_state.event != PM_EVENT_FREEZE) + break; + + list_for_each_entry(clkp, &clock_list, node) { + if (likely(clkp->ops)) { + unsigned long rate = clkp->rate; + + if (likely(clkp->ops->set_parent)) + clkp->ops->set_parent(clkp, + clkp->parent); + if (likely(clkp->ops->set_rate)) + clkp->ops->set_rate(clkp, + rate, NO_CHANGE); + else if (likely(clkp->ops->recalc)) + clkp->rate = clkp->ops->recalc(clkp); + } + } + break; + case PM_EVENT_FREEZE: + break; + case PM_EVENT_SUSPEND: + break; + } + + prev_state = state; + return 0; +} + +static int clks_sysdev_resume(struct sys_device *dev) +{ + return clks_sysdev_suspend(dev, PMSG_ON); +} + +static struct sysdev_class clks_sysdev_class = { + .name = "clks", +}; + +static struct sysdev_driver clks_sysdev_driver = { + .suspend = clks_sysdev_suspend, + .resume = clks_sysdev_resume, +}; + +static struct sys_device clks_sysdev_dev = { + .cls = &clks_sysdev_class, +}; + +static int __init clk_sysdev_init(void) +{ + sysdev_class_register(&clks_sysdev_class); + sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver); + sysdev_register(&clks_sysdev_dev); + + return 0; +} +subsys_initcall(clk_sysdev_init); +#endif + +/* + * debugfs support to trace clock tree hierarchy and attributes + */ +static struct dentry *clk_debugfs_root; + +static int clk_debugfs_register_one(struct clk *c) +{ + int err; + struct dentry *d, *child, *child_tmp; + struct clk *pa = c->parent; + char s[255]; + char *p = s; + + p += sprintf(p, "%s", c->name); + if (c->id >= 0) + sprintf(p, ":%d", c->id); + d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root); + if (!d) + return -ENOMEM; + c->dentry = d; + + d = debugfs_create_u8("usecount", S_IRUGO, c->dentry, (u8 *)&c->usecount); + if (!d) { + err = -ENOMEM; + goto err_out; + } + d = debugfs_create_u32("rate", S_IRUGO, c->dentry, (u32 *)&c->rate); + if (!d) { + err = -ENOMEM; + goto err_out; + } + d = debugfs_create_x32("flags", S_IRUGO, c->dentry, (u32 *)&c->flags); + if (!d) { + err = -ENOMEM; + goto err_out; + } + return 0; + +err_out: + d = c->dentry; + list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) + debugfs_remove(child); + debugfs_remove(c->dentry); + return err; +} + +static int clk_debugfs_register(struct clk *c) +{ + int err; + struct clk *pa = c->parent; + + if (pa && !pa->dentry) { + err = clk_debugfs_register(pa); + if (err) + return err; + } + + if (!c->dentry && c->name) { + err = clk_debugfs_register_one(c); + if (err) + return err; + } + return 0; +} + +static int __init clk_debugfs_init(void) +{ + struct clk *c; + struct dentry *d; + int err; + + d = debugfs_create_dir("clock", NULL); + if (!d) + return -ENOMEM; + clk_debugfs_root = d; + + list_for_each_entry(c, &clock_list, node) { + err = clk_debugfs_register(c); + if (err) + goto err_out; + } + return 0; +err_out: + debugfs_remove_recursive(clk_debugfs_root); + return err; +} +late_initcall(clk_debugfs_init); diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index de911451c216..6d7de242be1d 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -47,13 +47,13 @@ struct clk { #define CLK_ENABLE_ON_INIT (1 << 0) /* arch/sh/kernel/cpu/clock.c */ -int clk_init(void); unsigned long followparent_recalc(struct clk *); void recalculate_root_clocks(void); void propagate_rate(struct clk *); int clk_reparent(struct clk *child, struct clk *parent); int clk_register(struct clk *); void clk_unregister(struct clk *); +void clk_enable_init_clocks(void); /* the exported API, in addition to clk_set_rate */ /** -- cgit v1.2.3-59-g8ed1b From fa676ca3944e4459ea3d133eabc923c8ab5d2576 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 11 May 2010 13:29:34 +0000 Subject: sh: move sh clock-cpg.c contents to drivers/sh/clk-cpg.c Move the CPG helpers to drivers/sh/clk-cpg.c V2. This to allow SH-Mobile ARM to share the code with SH. All functions except the legacy CPG stuff is moved. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/Makefile | 2 +- arch/sh/kernel/cpu/clock-cpg.c | 295 ---------------------------------------- drivers/sh/Makefile | 1 + drivers/sh/clk-cpg.c | 298 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 300 insertions(+), 296 deletions(-) create mode 100644 drivers/sh/clk-cpg.c (limited to 'arch') diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index 0e48bc61c272..4edcb60a1355 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -16,7 +16,7 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/ # Common interfaces. obj-$(CONFIG_SH_ADC) += adc.o -obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o +obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o obj-$(CONFIG_SH_FPU) += fpu.o obj-$(CONFIG_SH_FPU_EMU) += fpu.o diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index 69c6472cdf58..e2f63d68da51 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -5,300 +5,6 @@ #include #include -static int sh_clk_mstp32_enable(struct clk *clk) -{ - __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit), - clk->enable_reg); - return 0; -} - -static void sh_clk_mstp32_disable(struct clk *clk) -{ - __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit), - clk->enable_reg); -} - -static struct clk_ops sh_clk_mstp32_clk_ops = { - .enable = sh_clk_mstp32_enable, - .disable = sh_clk_mstp32_disable, - .recalc = followparent_recalc, -}; - -int __init sh_clk_mstp32_register(struct clk *clks, int nr) -{ - struct clk *clkp; - int ret = 0; - int k; - - for (k = 0; !ret && (k < nr); k++) { - clkp = clks + k; - clkp->ops = &sh_clk_mstp32_clk_ops; - ret |= clk_register(clkp); - } - - return ret; -} - -static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) -{ - return clk_rate_table_round(clk, clk->freq_table, rate); -} - -static int sh_clk_div6_divisors[64] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 -}; - -static struct clk_div_mult_table sh_clk_div6_table = { - .divisors = sh_clk_div6_divisors, - .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors), -}; - -static unsigned long sh_clk_div6_recalc(struct clk *clk) -{ - struct clk_div_mult_table *table = &sh_clk_div6_table; - unsigned int idx; - - clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, - table, NULL); - - idx = __raw_readl(clk->enable_reg) & 0x003f; - - return clk->freq_table[idx].frequency; -} - -static int sh_clk_div6_set_rate(struct clk *clk, - unsigned long rate, int algo_id) -{ - unsigned long value; - int idx; - - idx = clk_rate_table_find(clk, clk->freq_table, rate); - if (idx < 0) - return idx; - - value = __raw_readl(clk->enable_reg); - value &= ~0x3f; - value |= idx; - __raw_writel(value, clk->enable_reg); - return 0; -} - -static int sh_clk_div6_enable(struct clk *clk) -{ - unsigned long value; - int ret; - - ret = sh_clk_div6_set_rate(clk, clk->rate, 0); - if (ret == 0) { - value = __raw_readl(clk->enable_reg); - value &= ~0x100; /* clear stop bit to enable clock */ - __raw_writel(value, clk->enable_reg); - } - return ret; -} - -static void sh_clk_div6_disable(struct clk *clk) -{ - unsigned long value; - - value = __raw_readl(clk->enable_reg); - value |= 0x100; /* stop clock */ - value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */ - __raw_writel(value, clk->enable_reg); -} - -static struct clk_ops sh_clk_div6_clk_ops = { - .recalc = sh_clk_div6_recalc, - .round_rate = sh_clk_div_round_rate, - .set_rate = sh_clk_div6_set_rate, - .enable = sh_clk_div6_enable, - .disable = sh_clk_div6_disable, -}; - -int __init sh_clk_div6_register(struct clk *clks, int nr) -{ - struct clk *clkp; - void *freq_table; - int nr_divs = sh_clk_div6_table.nr_divisors; - int freq_table_size = sizeof(struct cpufreq_frequency_table); - int ret = 0; - int k; - - freq_table_size *= (nr_divs + 1); - freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); - if (!freq_table) { - pr_err("sh_clk_div6_register: unable to alloc memory\n"); - return -ENOMEM; - } - - for (k = 0; !ret && (k < nr); k++) { - clkp = clks + k; - - clkp->ops = &sh_clk_div6_clk_ops; - clkp->id = -1; - clkp->freq_table = freq_table + (k * freq_table_size); - clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; - - ret = clk_register(clkp); - } - - return ret; -} - -static unsigned long sh_clk_div4_recalc(struct clk *clk) -{ - struct clk_div4_table *d4t = clk->priv; - struct clk_div_mult_table *table = d4t->div_mult_table; - unsigned int idx; - - clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, - table, &clk->arch_flags); - - idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f; - - return clk->freq_table[idx].frequency; -} - -static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) -{ - struct clk_div4_table *d4t = clk->priv; - struct clk_div_mult_table *table = d4t->div_mult_table; - u32 value; - int ret; - - /* we really need a better way to determine parent index, but for - * now assume internal parent comes with CLK_ENABLE_ON_INIT set, - * no CLK_ENABLE_ON_INIT means external clock... - */ - - if (parent->flags & CLK_ENABLE_ON_INIT) - value = __raw_readl(clk->enable_reg) & ~(1 << 7); - else - value = __raw_readl(clk->enable_reg) | (1 << 7); - - ret = clk_reparent(clk, parent); - if (ret < 0) - return ret; - - __raw_writel(value, clk->enable_reg); - - /* Rebiuld the frequency table */ - clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, - table, &clk->arch_flags); - - return 0; -} - -static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id) -{ - struct clk_div4_table *d4t = clk->priv; - unsigned long value; - int idx = clk_rate_table_find(clk, clk->freq_table, rate); - if (idx < 0) - return idx; - - value = __raw_readl(clk->enable_reg); - value &= ~(0xf << clk->enable_bit); - value |= (idx << clk->enable_bit); - __raw_writel(value, clk->enable_reg); - - if (d4t->kick) - d4t->kick(clk); - - return 0; -} - -static int sh_clk_div4_enable(struct clk *clk) -{ - __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg); - return 0; -} - -static void sh_clk_div4_disable(struct clk *clk) -{ - __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg); -} - -static struct clk_ops sh_clk_div4_clk_ops = { - .recalc = sh_clk_div4_recalc, - .set_rate = sh_clk_div4_set_rate, - .round_rate = sh_clk_div_round_rate, -}; - -static struct clk_ops sh_clk_div4_enable_clk_ops = { - .recalc = sh_clk_div4_recalc, - .set_rate = sh_clk_div4_set_rate, - .round_rate = sh_clk_div_round_rate, - .enable = sh_clk_div4_enable, - .disable = sh_clk_div4_disable, -}; - -static struct clk_ops sh_clk_div4_reparent_clk_ops = { - .recalc = sh_clk_div4_recalc, - .set_rate = sh_clk_div4_set_rate, - .round_rate = sh_clk_div_round_rate, - .enable = sh_clk_div4_enable, - .disable = sh_clk_div4_disable, - .set_parent = sh_clk_div4_set_parent, -}; - -static int __init sh_clk_div4_register_ops(struct clk *clks, int nr, - struct clk_div4_table *table, struct clk_ops *ops) -{ - struct clk *clkp; - void *freq_table; - int nr_divs = table->div_mult_table->nr_divisors; - int freq_table_size = sizeof(struct cpufreq_frequency_table); - int ret = 0; - int k; - - freq_table_size *= (nr_divs + 1); - freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); - if (!freq_table) { - pr_err("sh_clk_div4_register: unable to alloc memory\n"); - return -ENOMEM; - } - - for (k = 0; !ret && (k < nr); k++) { - clkp = clks + k; - - clkp->ops = ops; - clkp->id = -1; - clkp->priv = table; - - clkp->freq_table = freq_table + (k * freq_table_size); - clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; - - ret = clk_register(clkp); - } - - return ret; -} - -int __init sh_clk_div4_register(struct clk *clks, int nr, - struct clk_div4_table *table) -{ - return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops); -} - -int __init sh_clk_div4_enable_register(struct clk *clks, int nr, - struct clk_div4_table *table) -{ - return sh_clk_div4_register_ops(clks, nr, table, - &sh_clk_div4_enable_clk_ops); -} - -int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, - struct clk_div4_table *table) -{ - return sh_clk_div4_register_ops(clks, nr, table, - &sh_clk_div4_reparent_clk_ops); -} - -#ifdef CONFIG_SH_CLK_CPG_LEGACY static struct clk master_clk = { .flags = CLK_ENABLE_ON_INIT, .rate = CONFIG_SH_PCLK_FREQ, @@ -368,4 +74,3 @@ int __init __weak arch_clk_init(void) { return cpg_clk_init(); } -#endif /* CONFIG_SH_CPG_CLK_LEGACY */ diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index 033a949c496a..78bb5127abd0 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_SUPERHYWAY) += superhyway/ obj-$(CONFIG_MAPLE) += maple/ obj-$(CONFIG_GENERIC_GPIO) += pfc.o obj-$(CONFIG_SUPERH) += clk.o +obj-$(CONFIG_SH_CLK_CPG) += clk-cpg.o obj-y += intc.o diff --git a/drivers/sh/clk-cpg.c b/drivers/sh/clk-cpg.c new file mode 100644 index 000000000000..f5c80ba9ab1c --- /dev/null +++ b/drivers/sh/clk-cpg.c @@ -0,0 +1,298 @@ +#include +#include +#include +#include +#include + +static int sh_clk_mstp32_enable(struct clk *clk) +{ + __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit), + clk->enable_reg); + return 0; +} + +static void sh_clk_mstp32_disable(struct clk *clk) +{ + __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit), + clk->enable_reg); +} + +static struct clk_ops sh_clk_mstp32_clk_ops = { + .enable = sh_clk_mstp32_enable, + .disable = sh_clk_mstp32_disable, + .recalc = followparent_recalc, +}; + +int __init sh_clk_mstp32_register(struct clk *clks, int nr) +{ + struct clk *clkp; + int ret = 0; + int k; + + for (k = 0; !ret && (k < nr); k++) { + clkp = clks + k; + clkp->ops = &sh_clk_mstp32_clk_ops; + ret |= clk_register(clkp); + } + + return ret; +} + +static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) +{ + return clk_rate_table_round(clk, clk->freq_table, rate); +} + +static int sh_clk_div6_divisors[64] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 +}; + +static struct clk_div_mult_table sh_clk_div6_table = { + .divisors = sh_clk_div6_divisors, + .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors), +}; + +static unsigned long sh_clk_div6_recalc(struct clk *clk) +{ + struct clk_div_mult_table *table = &sh_clk_div6_table; + unsigned int idx; + + clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, + table, NULL); + + idx = __raw_readl(clk->enable_reg) & 0x003f; + + return clk->freq_table[idx].frequency; +} + +static int sh_clk_div6_set_rate(struct clk *clk, + unsigned long rate, int algo_id) +{ + unsigned long value; + int idx; + + idx = clk_rate_table_find(clk, clk->freq_table, rate); + if (idx < 0) + return idx; + + value = __raw_readl(clk->enable_reg); + value &= ~0x3f; + value |= idx; + __raw_writel(value, clk->enable_reg); + return 0; +} + +static int sh_clk_div6_enable(struct clk *clk) +{ + unsigned long value; + int ret; + + ret = sh_clk_div6_set_rate(clk, clk->rate, 0); + if (ret == 0) { + value = __raw_readl(clk->enable_reg); + value &= ~0x100; /* clear stop bit to enable clock */ + __raw_writel(value, clk->enable_reg); + } + return ret; +} + +static void sh_clk_div6_disable(struct clk *clk) +{ + unsigned long value; + + value = __raw_readl(clk->enable_reg); + value |= 0x100; /* stop clock */ + value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */ + __raw_writel(value, clk->enable_reg); +} + +static struct clk_ops sh_clk_div6_clk_ops = { + .recalc = sh_clk_div6_recalc, + .round_rate = sh_clk_div_round_rate, + .set_rate = sh_clk_div6_set_rate, + .enable = sh_clk_div6_enable, + .disable = sh_clk_div6_disable, +}; + +int __init sh_clk_div6_register(struct clk *clks, int nr) +{ + struct clk *clkp; + void *freq_table; + int nr_divs = sh_clk_div6_table.nr_divisors; + int freq_table_size = sizeof(struct cpufreq_frequency_table); + int ret = 0; + int k; + + freq_table_size *= (nr_divs + 1); + freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); + if (!freq_table) { + pr_err("sh_clk_div6_register: unable to alloc memory\n"); + return -ENOMEM; + } + + for (k = 0; !ret && (k < nr); k++) { + clkp = clks + k; + + clkp->ops = &sh_clk_div6_clk_ops; + clkp->id = -1; + clkp->freq_table = freq_table + (k * freq_table_size); + clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; + + ret = clk_register(clkp); + } + + return ret; +} + +static unsigned long sh_clk_div4_recalc(struct clk *clk) +{ + struct clk_div4_table *d4t = clk->priv; + struct clk_div_mult_table *table = d4t->div_mult_table; + unsigned int idx; + + clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, + table, &clk->arch_flags); + + idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f; + + return clk->freq_table[idx].frequency; +} + +static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk_div4_table *d4t = clk->priv; + struct clk_div_mult_table *table = d4t->div_mult_table; + u32 value; + int ret; + + /* we really need a better way to determine parent index, but for + * now assume internal parent comes with CLK_ENABLE_ON_INIT set, + * no CLK_ENABLE_ON_INIT means external clock... + */ + + if (parent->flags & CLK_ENABLE_ON_INIT) + value = __raw_readl(clk->enable_reg) & ~(1 << 7); + else + value = __raw_readl(clk->enable_reg) | (1 << 7); + + ret = clk_reparent(clk, parent); + if (ret < 0) + return ret; + + __raw_writel(value, clk->enable_reg); + + /* Rebiuld the frequency table */ + clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, + table, &clk->arch_flags); + + return 0; +} + +static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id) +{ + struct clk_div4_table *d4t = clk->priv; + unsigned long value; + int idx = clk_rate_table_find(clk, clk->freq_table, rate); + if (idx < 0) + return idx; + + value = __raw_readl(clk->enable_reg); + value &= ~(0xf << clk->enable_bit); + value |= (idx << clk->enable_bit); + __raw_writel(value, clk->enable_reg); + + if (d4t->kick) + d4t->kick(clk); + + return 0; +} + +static int sh_clk_div4_enable(struct clk *clk) +{ + __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg); + return 0; +} + +static void sh_clk_div4_disable(struct clk *clk) +{ + __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg); +} + +static struct clk_ops sh_clk_div4_clk_ops = { + .recalc = sh_clk_div4_recalc, + .set_rate = sh_clk_div4_set_rate, + .round_rate = sh_clk_div_round_rate, +}; + +static struct clk_ops sh_clk_div4_enable_clk_ops = { + .recalc = sh_clk_div4_recalc, + .set_rate = sh_clk_div4_set_rate, + .round_rate = sh_clk_div_round_rate, + .enable = sh_clk_div4_enable, + .disable = sh_clk_div4_disable, +}; + +static struct clk_ops sh_clk_div4_reparent_clk_ops = { + .recalc = sh_clk_div4_recalc, + .set_rate = sh_clk_div4_set_rate, + .round_rate = sh_clk_div_round_rate, + .enable = sh_clk_div4_enable, + .disable = sh_clk_div4_disable, + .set_parent = sh_clk_div4_set_parent, +}; + +static int __init sh_clk_div4_register_ops(struct clk *clks, int nr, + struct clk_div4_table *table, struct clk_ops *ops) +{ + struct clk *clkp; + void *freq_table; + int nr_divs = table->div_mult_table->nr_divisors; + int freq_table_size = sizeof(struct cpufreq_frequency_table); + int ret = 0; + int k; + + freq_table_size *= (nr_divs + 1); + freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); + if (!freq_table) { + pr_err("sh_clk_div4_register: unable to alloc memory\n"); + return -ENOMEM; + } + + for (k = 0; !ret && (k < nr); k++) { + clkp = clks + k; + + clkp->ops = ops; + clkp->id = -1; + clkp->priv = table; + + clkp->freq_table = freq_table + (k * freq_table_size); + clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; + + ret = clk_register(clkp); + } + + return ret; +} + +int __init sh_clk_div4_register(struct clk *clks, int nr, + struct clk_div4_table *table) +{ + return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops); +} + +int __init sh_clk_div4_enable_register(struct clk *clks, int nr, + struct clk_div4_table *table) +{ + return sh_clk_div4_register_ops(clks, nr, table, + &sh_clk_div4_enable_clk_ops); +} + +int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, + struct clk_div4_table *table) +{ + return sh_clk_div4_register_ops(clks, nr, table, + &sh_clk_div4_reparent_clk_ops); +} -- cgit v1.2.3-59-g8ed1b From 103058536300f80ec54f2a8c9209d066925416fd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 13 May 2010 01:08:33 +0000 Subject: sh: Check return value of clk_get on ecovec24 Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 1850c087a93b..62123885a6fa 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -1136,16 +1136,20 @@ static int __init arch_setup(void) /* set SPU2 clock to 83.4 MHz */ clk = clk_get(NULL, "spu_clk"); - clk_set_rate(clk, clk_round_rate(clk, 83333333)); - clk_put(clk); + if (clk) { + clk_set_rate(clk, clk_round_rate(clk, 83333333)); + clk_put(clk); + } /* change parent of FSI B */ clk = clk_get(NULL, "fsib_clk"); - clk_register(&fsimckb_clk); - clk_set_parent(clk, &fsimckb_clk); - clk_set_rate(clk, 11000); - clk_set_rate(&fsimckb_clk, 11000); - clk_put(clk); + if (clk) { + clk_register(&fsimckb_clk); + clk_set_parent(clk, &fsimckb_clk); + clk_set_rate(clk, 11000); + clk_set_rate(&fsimckb_clk, 11000); + clk_put(clk); + } gpio_request(GPIO_PTU0, NULL); gpio_direction_output(GPIO_PTU0, 0); @@ -1157,8 +1161,10 @@ static int __init arch_setup(void) /* set VPU clock to 166 MHz */ clk = clk_get(NULL, "vpu_clk"); - clk_set_rate(clk, clk_round_rate(clk, 166000000)); - clk_put(clk); + if (clk) { + clk_set_rate(clk, clk_round_rate(clk, 166000000)); + clk_put(clk); + } /* enable IrDA */ gpio_request(GPIO_FN_IRDA_OUT, NULL); -- cgit v1.2.3-59-g8ed1b From 03c5ecd13cfe308a521e40e6dec6059314f3341b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 13 May 2010 01:08:37 +0000 Subject: sh: Check return value of clk_get on ms7724 Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/setup.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 20b6053f714a..e74ae7b0d8bf 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -769,16 +769,20 @@ static int __init devices_setup(void) /* set SPU2 clock to 83.4 MHz */ clk = clk_get(NULL, "spu_clk"); - clk_set_rate(clk, clk_round_rate(clk, 83333333)); - clk_put(clk); + if (clk) { + clk_set_rate(clk, clk_round_rate(clk, 83333333)); + clk_put(clk); + } /* change parent of FSI A */ clk = clk_get(NULL, "fsia_clk"); - clk_register(&fsimcka_clk); - clk_set_parent(clk, &fsimcka_clk); - clk_set_rate(clk, 11000); - clk_set_rate(&fsimcka_clk, 11000); - clk_put(clk); + if (clk) { + clk_register(&fsimcka_clk); + clk_set_parent(clk, &fsimcka_clk); + clk_set_rate(clk, 11000); + clk_set_rate(&fsimcka_clk, 11000); + clk_put(clk); + } /* SDHI0 connected to cn7 */ gpio_request(GPIO_FN_SDHI0CD, NULL); -- cgit v1.2.3-59-g8ed1b From 4fec9978822a66b25f5645eb20c115034a18cfd1 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 11 May 2010 15:34:54 +0100 Subject: ARM: 6124/1: ep93xx: SPI driver platform support code This patch adds platform side support code for the EP93xx SPI driver. This includes clock, resources and muxing. There is a new function: ep93xx_register_spi() which can be used by board support code to register new SPI devices for the board. This patch depends on patch 5998/1 ep93xx: added chip revision reading function Cc: Ryan Mallon Cc: David Brownell Cc: Grant Likely Signed-off-by: Mika Westerberg Acked-by: H Hartley Sweeten Acked-by: Martin Guy Signed-off-by: Russell King --- arch/arm/mach-ep93xx/clock.c | 13 +++++++ arch/arm/mach-ep93xx/core.c | 52 +++++++++++++++++++++++++ arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | 1 + arch/arm/mach-ep93xx/include/mach/platform.h | 4 ++ 4 files changed, 70 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 5f80092b6ace..e29bdef9b2e2 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -96,6 +96,10 @@ static struct clk clk_keypad = { .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN, .set_rate = set_keytchclk_rate, }; +static struct clk clk_spi = { + .parent = &clk_xtali, + .rate = EP93XX_EXT_CLK_RATE, +}; static struct clk clk_pwm = { .parent = &clk_xtali, .rate = EP93XX_EXT_CLK_RATE, @@ -186,6 +190,7 @@ static struct clk_lookup clocks[] = { INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), INIT_CK("ep93xx-keypad", NULL, &clk_keypad), INIT_CK("ep93xx-fb", NULL, &clk_video), + INIT_CK("ep93xx-spi.0", NULL, &clk_spi), INIT_CK(NULL, "pwm_clk", &clk_pwm), INIT_CK(NULL, "m2p0", &clk_m2p0), INIT_CK(NULL, "m2p1", &clk_m2p1), @@ -473,6 +478,14 @@ static int __init ep93xx_clock_init(void) /* Initialize the pll2 derived clocks */ clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1); + /* + * EP93xx SSP clock rate was doubled in version E2. For more information + * see: + * http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf + */ + if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2) + clk_spi.rate /= 2; + pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n", clk_pll1.rate / 1000000, clk_pll2.rate / 1000000); pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n", diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 8d3f77e9fa86..9092677f63eb 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -31,10 +31,12 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -430,6 +432,56 @@ void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data, platform_device_register(&ep93xx_i2c_device); } +/************************************************************************* + * EP93xx SPI peripheral handling + *************************************************************************/ +static struct ep93xx_spi_info ep93xx_spi_master_data; + +static struct resource ep93xx_spi_resources[] = { + { + .start = EP93XX_SPI_PHYS_BASE, + .end = EP93XX_SPI_PHYS_BASE + 0x18 - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_EP93XX_SSP, + .end = IRQ_EP93XX_SSP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ep93xx_spi_device = { + .name = "ep93xx-spi", + .id = 0, + .dev = { + .platform_data = &ep93xx_spi_master_data, + }, + .num_resources = ARRAY_SIZE(ep93xx_spi_resources), + .resource = ep93xx_spi_resources, +}; + +/** + * ep93xx_register_spi() - registers spi platform device + * @info: ep93xx board specific spi master info (__initdata) + * @devices: SPI devices to register (__initdata) + * @num: number of SPI devices to register + * + * This function registers platform device for the EP93xx SPI controller and + * also makes sure that SPI pins are muxed so that I2S is not using those pins. + */ +void __init ep93xx_register_spi(struct ep93xx_spi_info *info, + struct spi_board_info *devices, int num) +{ + /* + * When SPI is used, we need to make sure that I2S is muxed off from + * SPI pins. + */ + ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2SONSSP); + + ep93xx_spi_master_data = *info; + spi_register_board_info(devices, num); + platform_device_register(&ep93xx_spi_device); +} /************************************************************************* * EP93xx LEDs diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index 93e2ecc79ceb..b1e096f0c2d2 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -106,6 +106,7 @@ #define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000) +#define EP93XX_SPI_PHYS_BASE EP93XX_APB_PHYS(0x000a0000) #define EP93XX_SPI_BASE EP93XX_APB_IOMEM(0x000a0000) #define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000) diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index b663390b4d87..9a4413dd44bb 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -6,9 +6,11 @@ struct i2c_gpio_platform_data; struct i2c_board_info; +struct spi_board_info; struct platform_device; struct ep93xxfb_mach_info; struct ep93xx_keypad_platform_data; +struct ep93xx_spi_info; struct ep93xx_eth_data { @@ -44,6 +46,8 @@ unsigned int ep93xx_chip_revision(void); void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); void ep93xx_register_i2c(struct i2c_gpio_platform_data *data, struct i2c_board_info *devices, int num); +void ep93xx_register_spi(struct ep93xx_spi_info *info, + struct spi_board_info *devices, int num); void ep93xx_register_fb(struct ep93xxfb_mach_info *data); void ep93xx_register_pwm(int pwm0, int pwm1); int ep93xx_pwm_acquire_gpio(struct platform_device *pdev); -- cgit v1.2.3-59-g8ed1b From 2a847513cdecd517f7efc06296c539c3a936cf98 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 7 May 2010 10:03:02 +0100 Subject: ARM: 6107/1: plat-nomadik: use the MTU clocksrc for sched_clock This provides some serious scheduling for the Nomadik family by introducing a sched_clock() using the MTU clock source in the same manner as e.g. OMAP or U300. This type of solutions has been discussed at no end in the past, however we need this resolution for making measurements and using HRTimers. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/plat-nomadik/timer.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index db67402518a6..0ff3798769ab 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c @@ -20,6 +20,15 @@ void __iomem *mtu_base; /* ssigned by machine code */ +/* + * Kernel assumes that sched_clock can be called early + * but the MTU may not yet be initialized. + */ +static cycle_t nmdk_read_timer_dummy(struct clocksource *cs) +{ + return 0; +} + /* clocksource: MTU decrements, so we negate the value being read. */ static cycle_t nmdk_read_timer(struct clocksource *cs) { @@ -29,12 +38,27 @@ static cycle_t nmdk_read_timer(struct clocksource *cs) static struct clocksource nmdk_clksrc = { .name = "mtu_0", .rating = 200, - .read = nmdk_read_timer, + .read = nmdk_read_timer_dummy, .mask = CLOCKSOURCE_MASK(32), .shift = 20, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +/* + * Override the global weak sched_clock symbol with this + * local implementation which uses the clocksource to get some + * better resolution when scheduling the kernel. We accept that + * this wraps around for now, since it is just a relative time + * stamp. (Inspired by OMAP implementation.) + */ +unsigned long long notrace sched_clock(void) +{ + return clocksource_cyc2ns(nmdk_clksrc.read( + &nmdk_clksrc), + nmdk_clksrc.mult, + nmdk_clksrc.shift); +} + /* Clockevent device: use one-shot mode */ static void nmdk_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) @@ -121,6 +145,8 @@ void __init nmdk_timer_init(void) writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift); + /* Now the scheduling clock is ready */ + nmdk_clksrc.read = nmdk_read_timer; if (clocksource_register(&nmdk_clksrc)) pr_err("timer: failed to initialize clock source %s\n", -- cgit v1.2.3-59-g8ed1b From d78a9494fe8b63e2ec1e2284e45a8d709c4d02c0 Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Mon, 10 May 2010 12:41:18 +0530 Subject: davinci: edma: use BIT() wherever possible This patch replaces occurences of (1 << x) with BIT(x) as it makes for much better reading. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dma.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index cc5fcdad9b92..1922d461387e 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -312,16 +312,16 @@ setup_dma_interrupt(unsigned lch, if (!callback) edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5, - (1 << (lch & 0x1f))); + BIT(lch & 0x1f)); edma_cc[ctlr]->intr_data[lch].callback = callback; edma_cc[ctlr]->intr_data[lch].data = data; if (callback) { edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5, - (1 << (lch & 0x1f))); + BIT(lch & 0x1f)); edma_shadow0_write_array(ctlr, SH_IESR, lch >> 5, - (1 << (lch & 0x1f))); + BIT(lch & 0x1f)); } } @@ -374,7 +374,7 @@ static irqreturn_t dma_irq_handler(int irq, void *data) SH_IER, j) & BIT(i))) { /* Clear the corresponding IPR bits */ edma_shadow0_write_array(ctlr, SH_ICR, j, - (1 << i)); + BIT(i)); if (edma_cc[ctlr]->intr_data[k].callback) edma_cc[ctlr]->intr_data[k].callback( k, DMA_COMPLETE, @@ -423,13 +423,13 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) for (i = 0; i < 32; i++) { int k = (j << 5) + i; if (edma_read_array(ctlr, EDMA_EMR, j) & - (1 << i)) { + BIT(i)) { /* Clear the corresponding EMR bits */ edma_write_array(ctlr, EDMA_EMCR, j, - 1 << i); + BIT(i)); /* Clear any SER */ edma_shadow0_write_array(ctlr, SH_SECR, - j, (1 << i)); + j, BIT(i)); if (edma_cc[ctlr]->intr_data[k]. callback) { edma_cc[ctlr]->intr_data[k]. @@ -444,11 +444,11 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) dev_dbg(data, "QEMR %02x\n", edma_read(ctlr, EDMA_QEMR)); for (i = 0; i < 8; i++) { - if (edma_read(ctlr, EDMA_QEMR) & (1 << i)) { + if (edma_read(ctlr, EDMA_QEMR) & BIT(i)) { /* Clear the corresponding IPR bits */ - edma_write(ctlr, EDMA_QEMCR, 1 << i); + edma_write(ctlr, EDMA_QEMCR, BIT(i)); edma_shadow0_write(ctlr, SH_QSECR, - (1 << i)); + BIT(i)); /* NOTE: not reported!! */ } @@ -460,9 +460,9 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) * to just write CCERRCLR with CCERR value... */ for (i = 0; i < 8; i++) { - if (edma_read(ctlr, EDMA_CCERR) & (1 << i)) { + if (edma_read(ctlr, EDMA_CCERR) & BIT(i)) { /* Clear the corresponding IPR bits */ - edma_write(ctlr, EDMA_CCERRCLR, 1 << i); + edma_write(ctlr, EDMA_CCERRCLR, BIT(i)); /* NOTE: not reported!! */ } @@ -666,7 +666,7 @@ int edma_alloc_channel(int channel, } /* ensure access through shadow region 0 */ - edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, 1 << (channel & 0x1f)); + edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, BIT(channel & 0x1f)); /* ensure no events are pending */ edma_stop(EDMA_CTLR_CHAN(ctlr, channel)); @@ -1204,7 +1204,7 @@ void edma_pause(unsigned channel) channel = EDMA_CHAN_SLOT(channel); if (channel < edma_cc[ctlr]->num_channels) { - unsigned int mask = (1 << (channel & 0x1f)); + unsigned int mask = BIT(channel & 0x1f); edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask); } @@ -1225,7 +1225,7 @@ void edma_resume(unsigned channel) channel = EDMA_CHAN_SLOT(channel); if (channel < edma_cc[ctlr]->num_channels) { - unsigned int mask = (1 << (channel & 0x1f)); + unsigned int mask = BIT(channel & 0x1f); edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask); } @@ -1252,7 +1252,7 @@ int edma_start(unsigned channel) if (channel < edma_cc[ctlr]->num_channels) { int j = channel >> 5; - unsigned int mask = (1 << (channel & 0x1f)); + unsigned int mask = BIT(channel & 0x1f); /* EDMA channels without event association */ if (test_bit(channel, edma_cc[ctlr]->edma_unused)) { @@ -1298,7 +1298,7 @@ void edma_stop(unsigned channel) if (channel < edma_cc[ctlr]->num_channels) { int j = channel >> 5; - unsigned int mask = (1 << (channel & 0x1f)); + unsigned int mask = BIT(channel & 0x1f); edma_shadow0_write_array(ctlr, SH_EECR, j, mask); edma_shadow0_write_array(ctlr, SH_ECR, j, mask); @@ -1337,7 +1337,7 @@ void edma_clean_channel(unsigned channel) if (channel < edma_cc[ctlr]->num_channels) { int j = (channel >> 5); - unsigned int mask = 1 << (channel & 0x1f); + unsigned int mask = BIT(channel & 0x1f); pr_debug("EDMA: EMR%d %08x\n", j, edma_read_array(ctlr, EDMA_EMR, j)); @@ -1346,7 +1346,7 @@ void edma_clean_channel(unsigned channel) edma_write_array(ctlr, EDMA_EMCR, j, mask); /* Clear any SER */ edma_shadow0_write_array(ctlr, SH_SECR, j, mask); - edma_write(ctlr, EDMA_CCERRCLR, (1 << 16) | 0x3); + edma_write(ctlr, EDMA_CCERRCLR, BIT(16) | BIT(1) | BIT(0)); } } EXPORT_SYMBOL(edma_clean_channel); @@ -1366,9 +1366,9 @@ void edma_clear_event(unsigned channel) if (channel >= edma_cc[ctlr]->num_channels) return; if (channel < 32) - edma_write(ctlr, EDMA_ECR, 1 << channel); + edma_write(ctlr, EDMA_ECR, BIT(channel)); else - edma_write(ctlr, EDMA_ECRH, 1 << (channel - 32)); + edma_write(ctlr, EDMA_ECRH, BIT(channel - 32)); } EXPORT_SYMBOL(edma_clear_event); -- cgit v1.2.3-59-g8ed1b From a6374f53405b719c767c6318fe052a6d8f32cd89 Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Mon, 10 May 2010 12:41:19 +0530 Subject: davinci: edma: fix coding style issue related to breaking lines In the edma driver, most of the long lines in 'if condition' are broken after the logical operator '&&' except two instances. This patch fixes that to bring consistency across the file. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dma.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index 1922d461387e..d33827aadda7 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -351,8 +351,8 @@ static irqreturn_t dma_irq_handler(int irq, void *data) dev_dbg(data, "dma_irq_handler\n"); - if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0) - && (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0)) + if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0) && + (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0)) return IRQ_NONE; while (1) { @@ -468,10 +468,10 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) } } } - if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) - && (edma_read_array(ctlr, EDMA_EMR, 1) == 0) - && (edma_read(ctlr, EDMA_QEMR) == 0) - && (edma_read(ctlr, EDMA_CCERR) == 0)) + if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) && + (edma_read_array(ctlr, EDMA_EMR, 1) == 0) && + (edma_read(ctlr, EDMA_QEMR) == 0) && + (edma_read(ctlr, EDMA_CCERR) == 0)) break; cnt++; if (cnt > 10) -- cgit v1.2.3-59-g8ed1b From b8d44293952e4b32b8595d924a377351f3cd1565 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Fri, 7 May 2010 17:06:32 -0400 Subject: Davinci: gpio - use ioremap() This patch modifies the gpio_base definition in davinci_soc_info to be a physical address, which is then ioremap()ed by the gpio initialization function. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/da830.c | 2 +- arch/arm/mach-davinci/da850.c | 2 +- arch/arm/mach-davinci/dm355.c | 2 +- arch/arm/mach-davinci/dm365.c | 2 +- arch/arm/mach-davinci/dm644x.c | 2 +- arch/arm/mach-davinci/dm646x.c | 2 +- arch/arm/mach-davinci/gpio.c | 18 +++++++++++------- arch/arm/mach-davinci/include/mach/common.h | 2 +- 8 files changed, 18 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 83879f894a21..4f5727f0dd11 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -1201,7 +1201,7 @@ static struct davinci_soc_info davinci_soc_info_da830 = { .intc_irq_num = DA830_N_CP_INTC_IRQ, .timer_info = &da830_timer_info, .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = IO_ADDRESS(DA8XX_GPIO_BASE), + .gpio_base = DA8XX_GPIO_BASE, .gpio_num = 128, .gpio_irq = IRQ_DA8XX_GPIO0, .serial_dev = &da8xx_serial_device, diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 2b6dd59d72f2..cb7f66300525 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1086,7 +1086,7 @@ static struct davinci_soc_info davinci_soc_info_da850 = { .intc_irq_num = DA850_N_CP_INTC_IRQ, .timer_info = &da850_timer_info, .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = IO_ADDRESS(DA8XX_GPIO_BASE), + .gpio_base = DA8XX_GPIO_BASE, .gpio_num = 144, .gpio_irq = IRQ_DA8XX_GPIO0, .serial_dev = &da8xx_serial_device, diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 0c62a68a90a3..277041dcd9a1 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -855,7 +855,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm355_timer_info, .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), + .gpio_base = DAVINCI_GPIO_BASE, .gpio_num = 104, .gpio_irq = IRQ_DM355_GPIOBNK0, .serial_dev = &dm355_serial_device, diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index ed7645088052..ecdbc676b4dd 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1060,7 +1060,7 @@ static struct davinci_soc_info davinci_soc_info_dm365 = { .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm365_timer_info, .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), + .gpio_base = DAVINCI_GPIO_BASE, .gpio_num = 104, .gpio_irq = IRQ_DM365_GPIO0, .gpio_unbanked = 8, /* really 16 ... skip muxed GPIOs */ diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 7f36c22a2684..beb315c04b75 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -746,7 +746,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm644x_timer_info, .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), + .gpio_base = DAVINCI_GPIO_BASE, .gpio_num = 71, .gpio_irq = IRQ_GPIOBNK0, .serial_dev = &dm644x_serial_device, diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 8dd0afee7593..95fc981e45af 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -830,7 +830,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm646x_timer_info, .gpio_type = GPIO_TYPE_DAVINCI, - .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), + .gpio_base = DAVINCI_GPIO_BASE, .gpio_num = 43, /* Only 33 usable */ .gpio_irq = IRQ_DM646X_GPIOBNK0, .serial_dev = &dm646x_serial_device, diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 2efb4468ebd0..bf0ff587e46a 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -37,22 +37,22 @@ struct davinci_gpio_regs { container_of(chip, struct davinci_gpio_controller, chip) static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; +static void __iomem *gpio_base; static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio) { void __iomem *ptr; - void __iomem *base = davinci_soc_info.gpio_base; if (gpio < 32 * 1) - ptr = base + 0x10; + ptr = gpio_base + 0x10; else if (gpio < 32 * 2) - ptr = base + 0x38; + ptr = gpio_base + 0x38; else if (gpio < 32 * 3) - ptr = base + 0x60; + ptr = gpio_base + 0x60; else if (gpio < 32 * 4) - ptr = base + 0x88; + ptr = gpio_base + 0x88; else if (gpio < 32 * 5) - ptr = base + 0xb0; + ptr = gpio_base + 0xb0; else ptr = NULL; return ptr; @@ -157,6 +157,10 @@ static int __init davinci_gpio_setup(void) if (WARN_ON(DAVINCI_N_GPIO < ngpio)) ngpio = DAVINCI_N_GPIO; + gpio_base = ioremap(soc_info->gpio_base, SZ_4K); + if (WARN_ON(!gpio_base)) + return -ENOMEM; + for (i = 0, base = 0; base < ngpio; i++, base += 32) { chips[i].chip.label = "DaVinci"; @@ -445,7 +449,7 @@ done: /* BINTEN -- per-bank interrupt enable. genirq would also let these * bits be set/cleared dynamically. */ - __raw_writel(binten, soc_info->gpio_base + 0x08); + __raw_writel(binten, gpio_base + 0x08); printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index a58bd88ba02d..2dd2226507a7 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -60,7 +60,7 @@ struct davinci_soc_info { unsigned long intc_irq_num; struct davinci_timer_info *timer_info; int gpio_type; - void __iomem *gpio_base; + u32 gpio_base; unsigned gpio_num; unsigned gpio_irq; unsigned gpio_unbanked; -- cgit v1.2.3-59-g8ed1b From db6db5d8474b16811566e0e919d060e2856d5ad9 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Fri, 7 May 2010 17:06:33 -0400 Subject: Davinci: da8xx: rtc - use ioremap This patch modifies the RTC unlock code to use ioremap() maps instead of IO_ADDRESS() translation. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/devices-da8xx.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 67a6fbcb2e09..8cda729be273 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -584,10 +584,17 @@ static struct platform_device da8xx_rtc_device = { int da8xx_register_rtc(void) { int ret; + void __iomem *base; + + base = ioremap(DA8XX_RTC_BASE, SZ_4K); + if (WARN_ON(!base)) + return -ENOMEM; /* Unlock the rtc's registers */ - __raw_writel(0x83e70b13, IO_ADDRESS(DA8XX_RTC_BASE + 0x6c)); - __raw_writel(0x95a4f1e0, IO_ADDRESS(DA8XX_RTC_BASE + 0x70)); + __raw_writel(0x83e70b13, base + 0x6c); + __raw_writel(0x95a4f1e0, base + 0x70); + + iounmap(base); ret = platform_device_register(&da8xx_rtc_device); if (!ret) -- cgit v1.2.3-59-g8ed1b From 3347db8392486a1b52aab980cc445cf505c36d45 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Fri, 7 May 2010 17:06:34 -0400 Subject: Davinci: jtag_id - use ioremap() This patch replaces the jtag id base info in davinci_soc_info with a physical address which is then ioremap()ed within common code. This patch (in combination with a similar change for PSC) will allow us to eliminate the SYSCFG nastiness in DA8xx code. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/common.c | 52 +++++++++++++++++------------ arch/arm/mach-davinci/da830.c | 3 +- arch/arm/mach-davinci/da850.c | 3 +- arch/arm/mach-davinci/dm355.c | 2 +- arch/arm/mach-davinci/dm365.c | 2 +- arch/arm/mach-davinci/dm644x.c | 2 +- arch/arm/mach-davinci/dm646x.c | 2 +- arch/arm/mach-davinci/include/mach/common.h | 2 +- 8 files changed, 37 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index f8221c5ee380..65e073df5bc9 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -37,26 +37,43 @@ void davinci_get_mac_addr(struct memory_accessor *mem_acc, void *context) pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr); } -static struct davinci_id * __init davinci_get_id(u32 jtag_id) +static int __init davinci_init_id(struct davinci_soc_info *soc_info) { - int i; - struct davinci_id *dip; - u8 variant = (jtag_id & 0xf0000000) >> 28; - u16 part_no = (jtag_id & 0x0ffff000) >> 12; + int i; + struct davinci_id *dip; + u8 variant; + u16 part_no; + void __iomem *base; + + base = ioremap(soc_info->jtag_id_reg, SZ_4K); + if (!base) { + pr_err("Unable to map JTAG ID register\n"); + return -ENOMEM; + } + + soc_info->jtag_id = __raw_readl(base); + iounmap(base); - for (i = 0, dip = davinci_soc_info.ids; i < davinci_soc_info.ids_num; + variant = (soc_info->jtag_id & 0xf0000000) >> 28; + part_no = (soc_info->jtag_id & 0x0ffff000) >> 12; + + for (i = 0, dip = soc_info->ids; i < soc_info->ids_num; i++, dip++) /* Don't care about the manufacturer right now */ - if ((dip->part_no == part_no) && (dip->variant == variant)) - return dip; - - return NULL; + if ((dip->part_no == part_no) && (dip->variant == variant)) { + soc_info->cpu_id = dip->cpu_id; + pr_info("DaVinci %s variant 0x%x\n", dip->name, + dip->variant); + return 0; + } + + pr_err("Unknown DaVinci JTAG ID 0x%x\n", soc_info->jtag_id); + return -EINVAL; } void __init davinci_common_init(struct davinci_soc_info *soc_info) { int ret; - struct davinci_id *dip; if (!soc_info) { ret = -EINVAL; @@ -84,18 +101,9 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) * We want to check CPU revision early for cpu_is_xxxx() macros. * IO space mapping must be initialized before we can do that. */ - davinci_soc_info.jtag_id = __raw_readl(davinci_soc_info.jtag_id_base); - - dip = davinci_get_id(davinci_soc_info.jtag_id); - if (!dip) { - ret = -EINVAL; - pr_err("Unknown DaVinci JTAG ID 0x%x\n", - davinci_soc_info.jtag_id); + ret = davinci_init_id(&davinci_soc_info); + if (ret < 0) goto err; - } - - davinci_soc_info.cpu_id = dip->cpu_id; - pr_info("DaVinci %s variant 0x%x\n", dip->name, dip->variant); if (davinci_soc_info.cpu_clks) { ret = davinci_clk_init(davinci_soc_info.cpu_clks); diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 4f5727f0dd11..c5600b89f628 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -1188,6 +1188,7 @@ static struct davinci_timer_info da830_timer_info = { static struct davinci_soc_info davinci_soc_info_da830 = { .io_desc = da830_io_desc, .io_desc_num = ARRAY_SIZE(da830_io_desc), + .jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG, .ids = da830_ids, .ids_num = ARRAY_SIZE(da830_ids), .cpu_clks = da830_clks, @@ -1215,8 +1216,6 @@ void __init da830_init(void) if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module")) return; - davinci_soc_info_da830.jtag_id_base = - DA8XX_SYSCFG0_VIRT(DA8XX_JTAG_ID_REG); davinci_soc_info_da830.pinmux_base = DA8XX_SYSCFG0_VIRT(0x120); davinci_common_init(&davinci_soc_info_da830); diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index cb7f66300525..fcf701628590 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1073,6 +1073,7 @@ no_ddrpll_mem: static struct davinci_soc_info davinci_soc_info_da850 = { .io_desc = da850_io_desc, .io_desc_num = ARRAY_SIZE(da850_io_desc), + .jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG, .ids = da850_ids, .ids_num = ARRAY_SIZE(da850_ids), .cpu_clks = da850_clks, @@ -1108,8 +1109,6 @@ void __init da850_init(void) if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module")) return; - davinci_soc_info_da850.jtag_id_base = - DA8XX_SYSCFG0_VIRT(DA8XX_JTAG_ID_REG); davinci_soc_info_da850.pinmux_base = DA8XX_SYSCFG0_VIRT(0x120); davinci_common_init(&davinci_soc_info_da850); diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 277041dcd9a1..228b6d1460e5 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -840,7 +840,7 @@ static struct platform_device dm355_serial_device = { static struct davinci_soc_info davinci_soc_info_dm355 = { .io_desc = dm355_io_desc, .io_desc_num = ARRAY_SIZE(dm355_io_desc), - .jtag_id_base = IO_ADDRESS(0x01c40028), + .jtag_id_reg = 0x01c40028, .ids = dm355_ids, .ids_num = ARRAY_SIZE(dm355_ids), .cpu_clks = dm355_clks, diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index ecdbc676b4dd..b396d58f130a 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1045,7 +1045,7 @@ static struct platform_device dm365_serial_device = { static struct davinci_soc_info davinci_soc_info_dm365 = { .io_desc = dm365_io_desc, .io_desc_num = ARRAY_SIZE(dm365_io_desc), - .jtag_id_base = IO_ADDRESS(0x01c40028), + .jtag_id_reg = 0x01c40028, .ids = dm365_ids, .ids_num = ARRAY_SIZE(dm365_ids), .cpu_clks = dm365_clks, diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index beb315c04b75..9859567788c9 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -731,7 +731,7 @@ static struct platform_device dm644x_serial_device = { static struct davinci_soc_info davinci_soc_info_dm644x = { .io_desc = dm644x_io_desc, .io_desc_num = ARRAY_SIZE(dm644x_io_desc), - .jtag_id_base = IO_ADDRESS(0x01c40028), + .jtag_id_reg = 0x01c40028, .ids = dm644x_ids, .ids_num = ARRAY_SIZE(dm644x_ids), .cpu_clks = dm644x_clks, diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 95fc981e45af..f9a8cc46eafd 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -815,7 +815,7 @@ static struct platform_device dm646x_serial_device = { static struct davinci_soc_info davinci_soc_info_dm646x = { .io_desc = dm646x_io_desc, .io_desc_num = ARRAY_SIZE(dm646x_io_desc), - .jtag_id_base = IO_ADDRESS(0x01c40028), + .jtag_id_reg = 0x01c40028, .ids = dm646x_ids, .ids_num = ARRAY_SIZE(dm646x_ids), .cpu_clks = dm646x_clks, diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 2dd2226507a7..1078458bdd54 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -45,7 +45,7 @@ struct davinci_soc_info { unsigned long io_desc_num; u32 cpu_id; u32 jtag_id; - void __iomem *jtag_id_base; + u32 jtag_id_reg; struct davinci_id *ids; unsigned long ids_num; struct clk_lookup *cpu_clks; -- cgit v1.2.3-59-g8ed1b From 1bcd38ad2de4c1cd30387c588dfb28d637d4111d Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Fri, 7 May 2010 17:06:35 -0400 Subject: Davinci: timer - use ioremap() This patch eliminates IO_ADDRESS() usage for Davinci timer definitions. The timer code has correspondingly been modified to ioremap() MMRs instead. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/da830.c | 4 ++-- arch/arm/mach-davinci/da850.c | 8 ++++---- arch/arm/mach-davinci/devices.c | 4 ++-- arch/arm/mach-davinci/include/mach/common.h | 2 +- arch/arm/mach-davinci/time.c | 22 ++++++++++++++-------- 5 files changed, 23 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index c5600b89f628..8a2510c5236f 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -1159,14 +1159,14 @@ static struct davinci_id da830_ids[] = { static struct davinci_timer_instance da830_timer_instance[2] = { { - .base = IO_ADDRESS(DA8XX_TIMER64P0_BASE), + .base = DA8XX_TIMER64P0_BASE, .bottom_irq = IRQ_DA8XX_TINT12_0, .top_irq = IRQ_DA8XX_TINT34_0, .cmp_off = DA830_CMP12_0, .cmp_irq = IRQ_DA830_T12CMPINT0_0, }, { - .base = IO_ADDRESS(DA8XX_TIMER64P1_BASE), + .base = DA8XX_TIMER64P1_BASE, .bottom_irq = IRQ_DA8XX_TINT12_1, .top_irq = IRQ_DA8XX_TINT34_1, .cmp_off = DA830_CMP12_0, diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index fcf701628590..ebfa5ca29a81 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -800,22 +800,22 @@ static struct davinci_id da850_ids[] = { static struct davinci_timer_instance da850_timer_instance[4] = { { - .base = IO_ADDRESS(DA8XX_TIMER64P0_BASE), + .base = DA8XX_TIMER64P0_BASE, .bottom_irq = IRQ_DA8XX_TINT12_0, .top_irq = IRQ_DA8XX_TINT34_0, }, { - .base = IO_ADDRESS(DA8XX_TIMER64P1_BASE), + .base = DA8XX_TIMER64P1_BASE, .bottom_irq = IRQ_DA8XX_TINT12_1, .top_irq = IRQ_DA8XX_TINT34_1, }, { - .base = IO_ADDRESS(DA850_TIMER64P2_BASE), + .base = DA850_TIMER64P2_BASE, .bottom_irq = IRQ_DA850_TINT12_2, .top_irq = IRQ_DA850_TINT34_2, }, { - .base = IO_ADDRESS(DA850_TIMER64P3_BASE), + .base = DA850_TIMER64P3_BASE, .bottom_irq = IRQ_DA850_TINT12_3, .top_irq = IRQ_DA850_TINT34_3, }, diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index d9c82ee434e0..8b7201e4c79c 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -297,12 +297,12 @@ static void davinci_init_wdt(void) struct davinci_timer_instance davinci_timer_instance[2] = { { - .base = IO_ADDRESS(DAVINCI_TIMER0_BASE), + .base = DAVINCI_TIMER0_BASE, .bottom_irq = IRQ_TINT0_TINT12, .top_irq = IRQ_TINT0_TINT34, }, { - .base = IO_ADDRESS(DAVINCI_TIMER1_BASE), + .base = DAVINCI_TIMER1_BASE, .bottom_irq = IRQ_TINT1_TINT12, .top_irq = IRQ_TINT1_TINT34, }, diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 1078458bdd54..2e1546401397 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -24,7 +24,7 @@ extern void __iomem *davinci_intc_base; extern int davinci_intc_type; struct davinci_timer_instance { - void __iomem *base; + u32 base; u32 bottom_irq; u32 top_irq; unsigned long cmp_off; diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index e5c598a387be..0f21c36e65dd 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -197,32 +197,36 @@ static void __init timer_init(void) { struct davinci_soc_info *soc_info = &davinci_soc_info; struct davinci_timer_instance *dtip = soc_info->timer_info->timers; + void __iomem *base[2]; int i; /* Global init of each 64-bit timer as a whole */ for(i=0; i<2; i++) { u32 tgcr; - void __iomem *base = dtip[i].base; + + base[i] = ioremap(dtip[i].base, SZ_4K); + if (WARN_ON(!base[i])) + continue; /* Disabled, Internal clock source */ - __raw_writel(0, base + TCR); + __raw_writel(0, base[i] + TCR); /* reset both timers, no pre-scaler for timer34 */ tgcr = 0; - __raw_writel(tgcr, base + TGCR); + __raw_writel(tgcr, base[i] + TGCR); /* Set both timers to unchained 32-bit */ tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT; - __raw_writel(tgcr, base + TGCR); + __raw_writel(tgcr, base[i] + TGCR); /* Unreset timers */ tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) | (TGCR_UNRESET << TGCR_TIM34RS_SHIFT); - __raw_writel(tgcr, base + TGCR); + __raw_writel(tgcr, base[i] + TGCR); /* Init both counters to zero */ - __raw_writel(0, base + TIM12); - __raw_writel(0, base + TIM34); + __raw_writel(0, base[i] + TIM12); + __raw_writel(0, base[i] + TIM34); } /* Init of each timer as a 32-bit timer */ @@ -231,7 +235,9 @@ static void __init timer_init(void) int timer = ID_TO_TIMER(t->id); u32 irq; - t->base = dtip[timer].base; + t->base = base[timer]; + if (!t->base) + continue; if (IS_TIMER_BOT(t->id)) { t->enamode_shift = 6; -- cgit v1.2.3-59-g8ed1b From e4c822c7e98cdda78b10a696b030fc20b22dcab4 Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Fri, 7 May 2010 17:06:36 -0400 Subject: Davinci: psc - use ioremap() This patch modifies the psc and clock control code to use ioremap()ed registers. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/clock.c | 14 +++++++++++--- arch/arm/mach-davinci/da830.c | 5 +---- arch/arm/mach-davinci/da850.c | 5 +---- arch/arm/mach-davinci/dm355.c | 4 +--- arch/arm/mach-davinci/dm365.c | 4 +--- arch/arm/mach-davinci/dm644x.c | 4 +--- arch/arm/mach-davinci/dm646x.c | 4 +--- arch/arm/mach-davinci/include/mach/common.h | 2 +- arch/arm/mach-davinci/psc.c | 7 +++++-- 9 files changed, 23 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 868cb7693499..054c303caead 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -302,7 +302,6 @@ static unsigned long clk_pllclk_recalc(struct clk *clk) struct pll_data *pll = clk->pll_data; unsigned long rate = clk->rate; - pll->base = IO_ADDRESS(pll->phys_base); ctrl = __raw_readl(pll->base + PLLCTL); rate = pll->input_rate = clk->parent->rate; @@ -458,8 +457,17 @@ int __init davinci_clk_init(struct clk_lookup *clocks) clk->recalc = clk_leafclk_recalc; } - if (clk->pll_data && !clk->pll_data->div_ratio_mask) - clk->pll_data->div_ratio_mask = PLLDIV_RATIO_MASK; + if (clk->pll_data) { + struct pll_data *pll = clk->pll_data; + + if (!pll->div_ratio_mask) + pll->div_ratio_mask = PLLDIV_RATIO_MASK; + + if (pll->phys_base && !pll->base) { + pll->base = ioremap(pll->phys_base, SZ_4K); + WARN_ON(!pll->base); + } + } if (clk->recalc) clk->rate = clk->recalc(clk); diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 8a2510c5236f..47a7f490cf6a 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -1127,10 +1127,7 @@ static struct map_desc da830_io_desc[] = { }, }; -static void __iomem *da830_psc_bases[] = { - IO_ADDRESS(DA8XX_PSC0_BASE), - IO_ADDRESS(DA8XX_PSC1_BASE), -}; +static u32 da830_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE }; /* Contents of JTAG ID register used to identify exact cpu type */ static struct davinci_id da830_ids[] = { diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index ebfa5ca29a81..2a430bbbd393 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -782,10 +782,7 @@ static struct map_desc da850_io_desc[] = { }, }; -static void __iomem *da850_psc_bases[] = { - IO_ADDRESS(DA8XX_PSC0_BASE), - IO_ADDRESS(DA8XX_PSC1_BASE), -}; +static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE }; /* Contents of JTAG ID register used to identify exact cpu type */ static struct davinci_id da850_ids[] = { diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 228b6d1460e5..70a18275c5da 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -783,9 +783,7 @@ static struct davinci_id dm355_ids[] = { }, }; -static void __iomem *dm355_psc_bases[] = { - IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), -}; +static u32 dm355_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE }; /* * T0_BOT: Timer 0, bottom: clockevent source for hrtimers diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index b396d58f130a..451a4efb7ddf 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1002,9 +1002,7 @@ static struct davinci_id dm365_ids[] = { }, }; -static void __iomem *dm365_psc_bases[] = { - IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), -}; +static u32 dm365_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE }; static struct davinci_timer_info dm365_timer_info = { .timers = davinci_timer_instance, diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 9859567788c9..ee654de38f34 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -674,9 +674,7 @@ static struct davinci_id dm644x_ids[] = { }, }; -static void __iomem *dm644x_psc_bases[] = { - IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), -}; +static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE }; /* * T0_BOT: Timer 0, bottom: clockevent source for hrtimers diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index f9a8cc46eafd..4c98ef003c47 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -758,9 +758,7 @@ static struct davinci_id dm646x_ids[] = { }, }; -static void __iomem *dm646x_psc_bases[] = { - IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), -}; +static u32 dm646x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE }; /* * T0_BOT: Timer 0, bottom: clockevent source for hrtimers diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 2e1546401397..4c8dfcb4d930 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -49,7 +49,7 @@ struct davinci_soc_info { struct davinci_id *ids; unsigned long ids_num; struct clk_lookup *cpu_clks; - void __iomem **psc_bases; + u32 *psc_bases; unsigned long psc_bases_num; void __iomem *pinmux_base; const struct mux_config *pinmux_pins; diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index d7cb438c4df6..1b15dbd0a77b 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c @@ -38,8 +38,9 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) return 0; } - psc_base = soc_info->psc_bases[ctlr]; + psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K); mdstat = __raw_readl(psc_base + MDSTAT + 4 * id); + iounmap(psc_base); /* if clocked, state can be "Enable" or "SyncReset" */ return mdstat & BIT(12); @@ -59,7 +60,7 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, return; } - psc_base = soc_info->psc_bases[ctlr]; + psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K); mdctl = __raw_readl(psc_base + MDCTL + 4 * id); mdctl &= ~MDSTAT_STATE_MASK; @@ -99,4 +100,6 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, do { mdstat = __raw_readl(psc_base + MDSTAT + 4 * id); } while (!((mdstat & MDSTAT_STATE_MASK) == next_state)); + + iounmap(psc_base); } -- cgit v1.2.3-59-g8ed1b From bd808947040ba53b2b0e52dde598a9414fb27bba Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Fri, 7 May 2010 17:06:37 -0400 Subject: Davinci: aintc/cpintc - use ioremap() This patch implements the following: - interrupt initialization uses ioremap() instead of passing a virtual address via davinci_soc_info. - machine definitions directly point to cp_intc_init() or davinci_irq_init() - davinci_intc_type and davinci_intc_base now get initialized in controller specific init functions instead of davinci_common_init() - minor fix in davinci_irq_init() to use intc_irq_num instead of DAVINCI_N_AINTC_IRQ Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da830-evm.c | 10 +--------- arch/arm/mach-davinci/board-da850-evm.c | 10 +--------- arch/arm/mach-davinci/board-dm355-evm.c | 7 +------ arch/arm/mach-davinci/board-dm355-leopard.c | 7 +------ arch/arm/mach-davinci/board-dm365-evm.c | 7 +------ arch/arm/mach-davinci/board-dm644x-evm.c | 7 +------ arch/arm/mach-davinci/board-dm646x-evm.c | 9 ++------- arch/arm/mach-davinci/board-neuros-osd2.c | 7 +------ arch/arm/mach-davinci/board-sffsdr.c | 7 +------ arch/arm/mach-davinci/common.c | 2 -- arch/arm/mach-davinci/cp_intc.c | 18 +++++++++++------- arch/arm/mach-davinci/da830.c | 2 +- arch/arm/mach-davinci/da850.c | 2 +- arch/arm/mach-davinci/dm355.c | 2 +- arch/arm/mach-davinci/dm365.c | 2 +- arch/arm/mach-davinci/dm644x.c | 2 +- arch/arm/mach-davinci/dm646x.c | 2 +- arch/arm/mach-davinci/include/mach/common.h | 3 ++- arch/arm/mach-davinci/include/mach/cp_intc.h | 3 +-- arch/arm/mach-davinci/irq.c | 7 ++++++- 20 files changed, 36 insertions(+), 80 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 8f079d2f1af9..212d97084bd7 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -561,14 +561,6 @@ static int __init da830_evm_console_init(void) console_initcall(da830_evm_console_init); #endif -static __init void da830_evm_irq_init(void) -{ - struct davinci_soc_info *soc_info = &davinci_soc_info; - - cp_intc_init((void __iomem *)DA8XX_CP_INTC_VIRT, DA830_N_CP_INTC_IRQ, - soc_info->intc_irq_prios, NULL); -} - static void __init da830_evm_map_io(void) { da830_init(); @@ -579,7 +571,7 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137 EVM") .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (DA8XX_DDR_BASE + 0x100), .map_io = da830_evm_map_io, - .init_irq = da830_evm_irq_init, + .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = da830_evm_init, MACHINE_END diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 6c137e0492ff..abd04932917b 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -736,14 +736,6 @@ static int __init da850_evm_console_init(void) console_initcall(da850_evm_console_init); #endif -static __init void da850_evm_irq_init(void) -{ - struct davinci_soc_info *soc_info = &davinci_soc_info; - - cp_intc_init((void __iomem *)DA8XX_CP_INTC_VIRT, DA850_N_CP_INTC_IRQ, - soc_info->intc_irq_prios, NULL); -} - static void __init da850_evm_map_io(void) { da850_init(); @@ -754,7 +746,7 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138 EVM") .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (DA8XX_DDR_BASE + 0x100), .map_io = da850_evm_map_io, - .init_irq = da850_evm_irq_init, + .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = da850_evm_init, MACHINE_END diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index a0ad7d9f5c85..a3191015efee 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -350,17 +350,12 @@ static __init void dm355_evm_init(void) dm355_init_asp1(ASP1_TX_EVT_EN | ASP1_RX_EVT_EN, &dm355_evm_snd_data); } -static __init void dm355_evm_irq_init(void) -{ - davinci_irq_init(); -} - MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM") .phys_io = IO_PHYS, .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (0x80000100), .map_io = dm355_evm_map_io, - .init_irq = dm355_evm_irq_init, + .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = dm355_evm_init, MACHINE_END diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index c3d5a70a7f38..f1d8132cf0c3 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -269,17 +269,12 @@ static __init void dm355_leopard_init(void) ARRAY_SIZE(dm355_leopard_spi_info)); } -static __init void dm355_leopard_irq_init(void) -{ - davinci_irq_init(); -} - MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard") .phys_io = IO_PHYS, .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (0x80000100), .map_io = dm355_leopard_map_io, - .init_irq = dm355_leopard_irq_init, + .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = dm355_leopard_init, MACHINE_END diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index b98b35c9e0e2..98814e6a5987 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -608,17 +608,12 @@ static __init void dm365_evm_init(void) ARRAY_SIZE(dm365_evm_spi_info)); } -static __init void dm365_evm_irq_init(void) -{ - davinci_irq_init(); -} - MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM") .phys_io = IO_PHYS, .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (0x80000100), .map_io = dm365_evm_map_io, - .init_irq = dm365_evm_irq_init, + .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = dm365_evm_init, MACHINE_END diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 73c0b04a75ff..34c8b418cd72 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -704,18 +704,13 @@ static __init void davinci_evm_init(void) } -static __init void davinci_evm_irq_init(void) -{ - davinci_irq_init(); -} - MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM") /* Maintainer: MontaVista Software */ .phys_io = IO_PHYS, .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (DAVINCI_DDR_BASE + 0x100), .map_io = davinci_evm_map_io, - .init_irq = davinci_evm_irq_init, + .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = davinci_evm_init, MACHINE_END diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index e2ac06fac02a..6d8889342c9f 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -739,11 +739,6 @@ static __init void evm_init(void) soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY; } -static __init void davinci_dm646x_evm_irq_init(void) -{ - davinci_irq_init(); -} - #define DM646X_EVM_REF_FREQ 27000000 #define DM6467T_EVM_REF_FREQ 33000000 @@ -760,7 +755,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM") .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (0x80000100), .map_io = davinci_map_io, - .init_irq = davinci_dm646x_evm_irq_init, + .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = evm_init, MACHINE_END @@ -770,7 +765,7 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM") .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (0x80000100), .map_io = davinci_map_io, - .init_irq = davinci_dm646x_evm_irq_init, + .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = evm_init, MACHINE_END diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 875770cdea0a..4c30e929bbf9 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -273,18 +273,13 @@ static __init void davinci_ntosd2_init(void) davinci_setup_mmc(0, &davinci_ntosd2_mmc_config); } -static __init void davinci_ntosd2_irq_init(void) -{ - davinci_irq_init(); -} - MACHINE_START(NEUROS_OSD2, "Neuros OSD2") /* Maintainer: Neuros Technologies */ .phys_io = IO_PHYS, .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (DAVINCI_DDR_BASE + 0x100), .map_io = davinci_ntosd2_map_io, - .init_irq = davinci_ntosd2_irq_init, + .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = davinci_ntosd2_init, MACHINE_END diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index 1ed0662cc0e4..23e664a1a802 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -152,18 +152,13 @@ static __init void davinci_sffsdr_init(void) davinci_cfg_reg(DM644X_VLYNQWD); } -static __init void davinci_sffsdr_irq_init(void) -{ - davinci_irq_init(); -} - MACHINE_START(SFFSDR, "Lyrtech SFFSDR") /* Maintainer: Hugo Villeneuve hugo.villeneuve@lyrtech.com */ .phys_io = IO_PHYS, .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (DAVINCI_DDR_BASE + 0x100), .map_io = davinci_sffsdr_map_io, - .init_irq = davinci_sffsdr_irq_init, + .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = davinci_sffsdr_init, MACHINE_END diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 65e073df5bc9..1d2557394235 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -112,8 +112,6 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) goto err; } - davinci_intc_base = davinci_soc_info.intc_base; - davinci_intc_type = davinci_soc_info.intc_type; return; err: diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c index 2a8d26ee4bbf..bb4c40ecb803 100644 --- a/arch/arm/mach-davinci/cp_intc.c +++ b/arch/arm/mach-davinci/cp_intc.c @@ -13,18 +13,17 @@ #include #include +#include #include -static void __iomem *cp_intc_base; - static inline unsigned int cp_intc_read(unsigned offset) { - return __raw_readl(cp_intc_base + offset); + return __raw_readl(davinci_intc_base + offset); } static inline void cp_intc_write(unsigned long value, unsigned offset) { - __raw_writel(value, cp_intc_base + offset); + __raw_writel(value, davinci_intc_base + offset); } static void cp_intc_ack_irq(unsigned int irq) @@ -100,13 +99,18 @@ static struct irq_chip cp_intc_irq_chip = { .set_wake = cp_intc_set_wake, }; -void __init cp_intc_init(void __iomem *base, unsigned short num_irq, - u8 *irq_prio, u32 *host_map) +void __init cp_intc_init(void) { + unsigned long 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; - cp_intc_base = base; + davinci_intc_type = DAVINCI_INTC_TYPE_CP_INTC; + davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K); + if (WARN_ON(!davinci_intc_base)) + return; cp_intc_write(0, CP_INTC_GLOBAL_ENABLE); diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 47a7f490cf6a..2c84f0702088 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -1193,7 +1193,7 @@ static struct davinci_soc_info davinci_soc_info_da830 = { .psc_bases_num = ARRAY_SIZE(da830_psc_bases), .pinmux_pins = da830_pins, .pinmux_pins_num = ARRAY_SIZE(da830_pins), - .intc_base = (void __iomem *)DA8XX_CP_INTC_VIRT, + .intc_base = DA8XX_CP_INTC_BASE, .intc_type = DAVINCI_INTC_TYPE_CP_INTC, .intc_irq_prios = da830_default_priorities, .intc_irq_num = DA830_N_CP_INTC_IRQ, diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 2a430bbbd393..6f5ea2aa1c4a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1078,7 +1078,7 @@ static struct davinci_soc_info davinci_soc_info_da850 = { .psc_bases_num = ARRAY_SIZE(da850_psc_bases), .pinmux_pins = da850_pins, .pinmux_pins_num = ARRAY_SIZE(da850_pins), - .intc_base = (void __iomem *)DA8XX_CP_INTC_VIRT, + .intc_base = DA8XX_CP_INTC_BASE, .intc_type = DAVINCI_INTC_TYPE_CP_INTC, .intc_irq_prios = da850_default_priorities, .intc_irq_num = DA850_N_CP_INTC_IRQ, diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 70a18275c5da..5ab39f6360f9 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -847,7 +847,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), .pinmux_pins = dm355_pins, .pinmux_pins_num = ARRAY_SIZE(dm355_pins), - .intc_base = IO_ADDRESS(DAVINCI_ARM_INTC_BASE), + .intc_base = DAVINCI_ARM_INTC_BASE, .intc_type = DAVINCI_INTC_TYPE_AINTC, .intc_irq_prios = dm355_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 451a4efb7ddf..be340ed1b707 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1052,7 +1052,7 @@ static struct davinci_soc_info davinci_soc_info_dm365 = { .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), .pinmux_pins = dm365_pins, .pinmux_pins_num = ARRAY_SIZE(dm365_pins), - .intc_base = IO_ADDRESS(DAVINCI_ARM_INTC_BASE), + .intc_base = DAVINCI_ARM_INTC_BASE, .intc_type = DAVINCI_INTC_TYPE_AINTC, .intc_irq_prios = dm365_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index ee654de38f34..d3aa1f7d0ab8 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -738,7 +738,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), .pinmux_pins = dm644x_pins, .pinmux_pins_num = ARRAY_SIZE(dm644x_pins), - .intc_base = IO_ADDRESS(DAVINCI_ARM_INTC_BASE), + .intc_base = DAVINCI_ARM_INTC_BASE, .intc_type = DAVINCI_INTC_TYPE_AINTC, .intc_irq_prios = dm644x_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 4c98ef003c47..e0153b30f446 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -822,7 +822,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), .pinmux_pins = dm646x_pins, .pinmux_pins_num = ARRAY_SIZE(dm646x_pins), - .intc_base = IO_ADDRESS(DAVINCI_ARM_INTC_BASE), + .intc_base = DAVINCI_ARM_INTC_BASE, .intc_type = DAVINCI_INTC_TYPE_AINTC, .intc_irq_prios = dm646x_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 4c8dfcb4d930..005f6242e0ba 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -54,10 +54,11 @@ struct davinci_soc_info { void __iomem *pinmux_base; const struct mux_config *pinmux_pins; unsigned long pinmux_pins_num; - void __iomem *intc_base; + u32 intc_base; int intc_type; u8 *intc_irq_prios; unsigned long intc_irq_num; + u32 *intc_host_map; struct davinci_timer_info *timer_info; int gpio_type; u32 gpio_base; diff --git a/arch/arm/mach-davinci/include/mach/cp_intc.h b/arch/arm/mach-davinci/include/mach/cp_intc.h index 121b114df755..4e8190eed673 100644 --- a/arch/arm/mach-davinci/include/mach/cp_intc.h +++ b/arch/arm/mach-davinci/include/mach/cp_intc.h @@ -51,7 +51,6 @@ #define CP_INTC_HOST_PRIO_VECTOR(n) (0x1600 + (n << 2)) #define CP_INTC_VECTOR_ADDR(n) (0x2000 + (n << 2)) -void __init cp_intc_init(void __iomem *base, unsigned short num_irq, - u8 *irq_prio, u32 *host_map); +void __init cp_intc_init(void); #endif /* __ASM_HARDWARE_CP_INTC_H */ diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c index af92ffee8471..784ddf3c5ad4 100644 --- a/arch/arm/mach-davinci/irq.c +++ b/arch/arm/mach-davinci/irq.c @@ -116,6 +116,11 @@ void __init davinci_irq_init(void) unsigned i; const u8 *davinci_def_priorities = davinci_soc_info.intc_irq_prios; + davinci_intc_type = DAVINCI_INTC_TYPE_AINTC; + davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_4K); + if (WARN_ON(!davinci_intc_base)) + return; + /* Clear all interrupt requests */ davinci_irq_writel(~0x0, FIQ_REG0_OFFSET); davinci_irq_writel(~0x0, FIQ_REG1_OFFSET); @@ -148,7 +153,7 @@ void __init davinci_irq_init(void) } /* set up genirq dispatch for ARM INTC */ - for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) { + for (i = 0; i < davinci_soc_info.intc_irq_num; i++) { set_irq_chip(i, &davinci_irq_chip_0); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); if (i != IRQ_TINT1_TINT34) -- cgit v1.2.3-59-g8ed1b From 779b0d53ca41873d59225eb776c5d4493a0abd0f Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Fri, 7 May 2010 17:06:38 -0400 Subject: Davinci: pinmux - use ioremap() This patch modifies the pinmux implementation so as to ioremap() the pinmux register area on first use. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/da830.c | 3 +-- arch/arm/mach-davinci/da850.c | 3 +-- arch/arm/mach-davinci/dm355.c | 2 +- arch/arm/mach-davinci/dm365.c | 2 +- arch/arm/mach-davinci/dm644x.c | 2 +- arch/arm/mach-davinci/dm646x.c | 2 +- arch/arm/mach-davinci/include/mach/common.h | 2 +- arch/arm/mach-davinci/mux.c | 17 ++++++++++++----- 8 files changed, 19 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 2c84f0702088..94fe971f276a 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -1191,6 +1191,7 @@ static struct davinci_soc_info davinci_soc_info_da830 = { .cpu_clks = da830_clks, .psc_bases = da830_psc_bases, .psc_bases_num = ARRAY_SIZE(da830_psc_bases), + .pinmux_base = DA8XX_SYSCFG0_BASE + 0x120, .pinmux_pins = da830_pins, .pinmux_pins_num = ARRAY_SIZE(da830_pins), .intc_base = DA8XX_CP_INTC_BASE, @@ -1213,7 +1214,5 @@ void __init da830_init(void) if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module")) return; - davinci_soc_info_da830.pinmux_base = DA8XX_SYSCFG0_VIRT(0x120); - davinci_common_init(&davinci_soc_info_da830); } diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 6f5ea2aa1c4a..74d4e49d4064 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1076,6 +1076,7 @@ static struct davinci_soc_info davinci_soc_info_da850 = { .cpu_clks = da850_clks, .psc_bases = da850_psc_bases, .psc_bases_num = ARRAY_SIZE(da850_psc_bases), + .pinmux_base = DA8XX_SYSCFG0_BASE + 0x120, .pinmux_pins = da850_pins, .pinmux_pins_num = ARRAY_SIZE(da850_pins), .intc_base = DA8XX_CP_INTC_BASE, @@ -1106,8 +1107,6 @@ void __init da850_init(void) if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module")) return; - davinci_soc_info_da850.pinmux_base = DA8XX_SYSCFG0_VIRT(0x120); - davinci_common_init(&davinci_soc_info_da850); /* diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 5ab39f6360f9..383478116ef5 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -844,7 +844,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .cpu_clks = dm355_clks, .psc_bases = dm355_psc_bases, .psc_bases_num = ARRAY_SIZE(dm355_psc_bases), - .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), + .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, .pinmux_pins = dm355_pins, .pinmux_pins_num = ARRAY_SIZE(dm355_pins), .intc_base = DAVINCI_ARM_INTC_BASE, diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index be340ed1b707..e5e3dce4cfba 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1049,7 +1049,7 @@ static struct davinci_soc_info davinci_soc_info_dm365 = { .cpu_clks = dm365_clks, .psc_bases = dm365_psc_bases, .psc_bases_num = ARRAY_SIZE(dm365_psc_bases), - .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), + .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, .pinmux_pins = dm365_pins, .pinmux_pins_num = ARRAY_SIZE(dm365_pins), .intc_base = DAVINCI_ARM_INTC_BASE, diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index d3aa1f7d0ab8..7ad15208b841 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -735,7 +735,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .cpu_clks = dm644x_clks, .psc_bases = dm644x_psc_bases, .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases), - .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), + .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, .pinmux_pins = dm644x_pins, .pinmux_pins_num = ARRAY_SIZE(dm644x_pins), .intc_base = DAVINCI_ARM_INTC_BASE, diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index e0153b30f446..94045656cff6 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -819,7 +819,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .cpu_clks = dm646x_clks, .psc_bases = dm646x_psc_bases, .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases), - .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), + .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, .pinmux_pins = dm646x_pins, .pinmux_pins_num = ARRAY_SIZE(dm646x_pins), .intc_base = DAVINCI_ARM_INTC_BASE, diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 005f6242e0ba..2e072482c119 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -51,7 +51,7 @@ struct davinci_soc_info { struct clk_lookup *cpu_clks; u32 *psc_bases; unsigned long psc_bases_num; - void __iomem *pinmux_base; + u32 pinmux_base; const struct mux_config *pinmux_pins; unsigned long pinmux_pins_num; u32 intc_base; diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c index e9d530a8f79f..f34a8dcdae2b 100644 --- a/arch/arm/mach-davinci/mux.c +++ b/arch/arm/mach-davinci/mux.c @@ -22,6 +22,8 @@ #include #include +static void __iomem *pinmux_base; + /* * Sets the DAVINCI MUX register based on the table */ @@ -29,14 +31,19 @@ int __init_or_module davinci_cfg_reg(const unsigned long index) { static DEFINE_SPINLOCK(mux_spin_lock); struct davinci_soc_info *soc_info = &davinci_soc_info; - void __iomem *base = soc_info->pinmux_base; unsigned long flags; const struct mux_config *cfg; unsigned int reg_orig = 0, reg = 0; unsigned int mask, warn = 0; - if (!soc_info->pinmux_pins) - BUG(); + if (WARN_ON(!soc_info->pinmux_pins)) + return -ENODEV; + + if (!pinmux_base) { + pinmux_base = ioremap(soc_info->pinmux_base, SZ_4K); + if (WARN_ON(!pinmux_base)) + return -ENOMEM; + } if (index >= soc_info->pinmux_pins_num) { printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n", @@ -57,7 +64,7 @@ int __init_or_module davinci_cfg_reg(const unsigned long index) unsigned tmp1, tmp2; spin_lock_irqsave(&mux_spin_lock, flags); - reg_orig = __raw_readl(base + cfg->mux_reg); + reg_orig = __raw_readl(pinmux_base + cfg->mux_reg); mask = (cfg->mask << cfg->mask_offset); tmp1 = reg_orig & mask; @@ -69,7 +76,7 @@ int __init_or_module davinci_cfg_reg(const unsigned long index) if (tmp1 != tmp2) warn = 1; - __raw_writel(reg, base + cfg->mux_reg); + __raw_writel(reg, pinmux_base + cfg->mux_reg); spin_unlock_irqrestore(&mux_spin_lock, flags); } -- cgit v1.2.3-59-g8ed1b From bcd6a1c695c8b404bfde22b276186ac52a20291b Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Fri, 7 May 2010 17:06:39 -0400 Subject: Davinci: iotable based ioremap() interception This patch allows for a more flexible ioremap() interception based on iotable contents. With this patch, the ioremap() interception code can properly translate addresses only after davinci_soc_info has been initialized. Consequently, in soc-specific init functions, davinci_common_init() has to happen before any ioremap() attempts. The da8xx init sequence has been suitably modified to meet this restriction. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/da830.c | 7 +++---- arch/arm/mach-davinci/da850.c | 4 ++-- arch/arm/mach-davinci/include/mach/common.h | 8 +++++++- arch/arm/mach-davinci/io.c | 20 +++++++++++++++----- 4 files changed, 27 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 94fe971f276a..3a7a96fe7b84 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -1210,9 +1210,8 @@ static struct davinci_soc_info davinci_soc_info_da830 = { void __init da830_init(void) { - da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); - if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module")) - return; - davinci_common_init(&davinci_soc_info_da830); + + da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); + WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"); } diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 74d4e49d4064..6b8331bf8cf3 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1099,6 +1099,8 @@ void __init da850_init(void) { unsigned int v; + davinci_common_init(&davinci_soc_info_da850); + da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module")) return; @@ -1107,8 +1109,6 @@ void __init da850_init(void) if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module")) return; - davinci_common_init(&davinci_soc_info_da850); - /* * Move the clock source of Async3 domain to PLL1 SYSCLK2. * This helps keeping the peripherals on this domain insulated diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 2e072482c119..a57cba21e21e 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -39,7 +39,13 @@ struct davinci_timer_info { struct davinci_gpio_controller; -/* SoC specific init support */ +/* + * SoC info passed into common davinci modules. + * + * Base addresses in this structure should be physical and not virtual. + * Modules that take such base addresses, should internally ioremap() them to + * use. + */ struct davinci_soc_info { struct map_desc *io_desc; unsigned long io_desc_num; diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c index a1c0b6b99edf..8ea60a8b2495 100644 --- a/arch/arm/mach-davinci/io.c +++ b/arch/arm/mach-davinci/io.c @@ -12,19 +12,29 @@ #include #include +#include -#define BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) -#define XLATE(p, pst, vst) ((void __iomem *)((p) - (pst) + (vst))) +#include /* * Intercept ioremap() requests for addresses in our fixed mapping regions. */ void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type) { - if (BETWEEN(p, IO_PHYS, IO_SIZE)) - return XLATE(p, IO_PHYS, IO_VIRT); + struct map_desc *desc = davinci_soc_info.io_desc; + int desc_num = davinci_soc_info.io_desc_num; + int i; - return __arm_ioremap_caller(p, size, type, __builtin_return_address(0)); + for (i = 0; i < desc_num; i++, desc++) { + unsigned long iophys = __pfn_to_phys(desc->pfn); + unsigned long iosize = desc->length; + + if (p >= iophys && (p + size) <= (iophys + iosize)) + return __io(desc->virtual + p - iophys); + } + + return __arm_ioremap_caller(p, size, type, + __builtin_return_address(0)); } EXPORT_SYMBOL(davinci_ioremap); -- cgit v1.2.3-59-g8ed1b From 2168e76d6ba061fcc95095a3f54ceef8588cbb90 Mon Sep 17 00:00:00 2001 From: Thomas Koeller Date: Tue, 11 May 2010 17:06:47 +0200 Subject: DM365: Added PINMUX definitions for GPIO30..32 Board code may want to use them. Signed-off-by: Thomas Koeller Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm365.c | 3 +++ arch/arm/mach-davinci/include/mach/mux.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index e5e3dce4cfba..dd7c204dff28 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -569,6 +569,9 @@ MUX_CFG(DM365, SPI4_SDENA0, 4, 20, 3, 1, false) MUX_CFG(DM365, SPI4_SDENA1, 4, 16, 3, 2, false) MUX_CFG(DM365, GPIO20, 3, 21, 3, 0, false) +MUX_CFG(DM365, GPIO30, 4, 6, 3, 0, false) +MUX_CFG(DM365, GPIO31, 4, 8, 3, 0, false) +MUX_CFG(DM365, GPIO32, 4, 10, 3, 0, false) MUX_CFG(DM365, GPIO33, 4, 12, 3, 0, false) MUX_CFG(DM365, GPIO40, 4, 26, 3, 0, false) MUX_CFG(DM365, GPIO64_57, 2, 6, 1, 0, false) diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index 743dbd2e0ea3..4a1fdd3475aa 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -289,6 +289,9 @@ enum davinci_dm365_index { /* GPIO */ DM365_GPIO20, + DM365_GPIO30, + DM365_GPIO31, + DM365_GPIO32, DM365_GPIO33, DM365_GPIO40, DM365_GPIO64_57, -- cgit v1.2.3-59-g8ed1b From 0efe2b7442caaf087e56ae9b68fa5f61f4761fa8 Mon Sep 17 00:00:00 2001 From: Thomas Koeller Date: Tue, 11 May 2010 17:06:48 +0200 Subject: DM365: Make CLKOUTx available Added PINMUX configurations for the CLKOUT0 .. CLKOUT2 functions, for boards that want to use these clocks. Signed-off-by: Thomas Koeller Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm365.c | 4 ++++ arch/arm/mach-davinci/include/mach/mux.h | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index dd7c204dff28..d0d24d4e9503 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -568,6 +568,10 @@ MUX_CFG(DM365, SPI4_SDO, 4, 16, 3, 1, false) MUX_CFG(DM365, SPI4_SDENA0, 4, 20, 3, 1, false) MUX_CFG(DM365, SPI4_SDENA1, 4, 16, 3, 2, false) +MUX_CFG(DM365, CLKOUT0, 4, 20, 3, 3, false) +MUX_CFG(DM365, CLKOUT1, 4, 16, 3, 3, false) +MUX_CFG(DM365, CLKOUT2, 4, 8, 3, 3, false) + MUX_CFG(DM365, GPIO20, 3, 21, 3, 0, false) MUX_CFG(DM365, GPIO30, 4, 6, 3, 0, false) MUX_CFG(DM365, GPIO31, 4, 8, 3, 0, false) diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index 4a1fdd3475aa..07ef83bf5a1f 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -287,6 +287,11 @@ enum davinci_dm365_index { DM365_SPI4_SDENA0, DM365_SPI4_SDENA1, + /* Clock */ + DM365_CLKOUT0, + DM365_CLKOUT1, + DM365_CLKOUT2, + /* GPIO */ DM365_GPIO20, DM365_GPIO30, -- cgit v1.2.3-59-g8ed1b From 7735227e76e1660e448ec66c30e7bfd06f7cd9b7 Mon Sep 17 00:00:00 2001 From: Thomas Koeller Date: Tue, 11 May 2010 17:06:49 +0200 Subject: DM365: Added more PINMUX configurations for AEMIF More complete AEMIF support for boards. Signed-off-by: Thomas Koeller Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm365.c | 5 ++++- arch/arm/mach-davinci/include/mach/mux.h | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index d0d24d4e9503..a146849d78f0 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -485,11 +485,14 @@ MUX_CFG(DM365, SD1_DATA0, 4, 22, 3, 1, false) MUX_CFG(DM365, I2C_SDA, 3, 23, 3, 2, false) MUX_CFG(DM365, I2C_SCL, 3, 21, 3, 2, false) -MUX_CFG(DM365, AEMIF_AR, 2, 0, 3, 1, false) +MUX_CFG(DM365, AEMIF_AR_A14, 2, 0, 3, 1, false) +MUX_CFG(DM365, AEMIF_AR_BA0, 2, 0, 3, 2, false) MUX_CFG(DM365, AEMIF_A3, 2, 2, 3, 1, false) MUX_CFG(DM365, AEMIF_A7, 2, 4, 3, 1, false) MUX_CFG(DM365, AEMIF_D15_8, 2, 6, 1, 1, false) MUX_CFG(DM365, AEMIF_CE0, 2, 7, 1, 0, false) +MUX_CFG(DM365, AEMIF_CE1, 2, 8, 1, 0, false) +MUX_CFG(DM365, AEMIF_WE_OE, 2, 9, 1, 0, false) MUX_CFG(DM365, MCBSP0_BDX, 0, 23, 1, 1, false) MUX_CFG(DM365, MCBSP0_X, 0, 22, 1, 1, false) diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index 07ef83bf5a1f..de11aac76a80 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -194,11 +194,14 @@ enum davinci_dm365_index { DM365_I2C_SCL, /* AEMIF */ - DM365_AEMIF_AR, + DM365_AEMIF_AR_A14, + DM365_AEMIF_AR_BA0, DM365_AEMIF_A3, DM365_AEMIF_A7, DM365_AEMIF_D15_8, DM365_AEMIF_CE0, + DM365_AEMIF_CE1, + DM365_AEMIF_WE_OE, /* ASP0 function */ DM365_MCBSP0_BDX, -- cgit v1.2.3-59-g8ed1b From 0a8cff388a3841ec2e6c71d1f3c2535b24811c7d Mon Sep 17 00:00:00 2001 From: Gregory Bean Date: Fri, 30 Apr 2010 21:21:24 -0700 Subject: msm: generalization to support multiple SOCs. devices.c is specific to the MSM7x00 series of SOCs. Rename appropriately in preparation to support more devices. Signed-off-by: Gregory Bean Signed-off-by: David Brown Signed-off-by: Daniel Walker Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/Makefile | 5 +- arch/arm/mach-msm/devices-msm7x00.c | 346 ++++++++++++++++++++++++++++++++++++ arch/arm/mach-msm/devices.c | 346 ------------------------------------ 3 files changed, 348 insertions(+), 349 deletions(-) create mode 100644 arch/arm/mach-msm/devices-msm7x00.c delete mode 100644 arch/arm/mach-msm/devices.c (limited to 'arch') diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 147339c87277..435d83cd52c2 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,5 +1,4 @@ obj-y += io.o idle.o irq.o timer.o dma.o -obj-y += devices.o obj-y += proc_comm.o obj-y += vreg.o obj-y += acpuclock-arm11.o @@ -8,5 +7,5 @@ obj-y += clock.o clock-7x01a.o obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o obj-$(CONFIG_MSM_SMD) += last_radio_log.o -obj-$(CONFIG_MACH_TROUT) += board-trout.o -obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o +obj-$(CONFIG_MACH_TROUT) += board-trout.o devices-msm7x00.o +obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c new file mode 100644 index 000000000000..982f1da60160 --- /dev/null +++ b/arch/arm/mach-msm/devices-msm7x00.c @@ -0,0 +1,346 @@ +/* linux/arch/arm/mach-msm/devices.c + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include + +#include +#include +#include "devices.h" + +#include +#include +#include + +#include + +static struct resource resources_uart1[] = { + { + .start = INT_UART1, + .end = INT_UART1, + .flags = IORESOURCE_IRQ, + }, + { + .start = MSM_UART1_PHYS, + .end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource resources_uart2[] = { + { + .start = INT_UART2, + .end = INT_UART2, + .flags = IORESOURCE_IRQ, + }, + { + .start = MSM_UART2_PHYS, + .end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource resources_uart3[] = { + { + .start = INT_UART3, + .end = INT_UART3, + .flags = IORESOURCE_IRQ, + }, + { + .start = MSM_UART3_PHYS, + .end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device msm_device_uart1 = { + .name = "msm_serial", + .id = 0, + .num_resources = ARRAY_SIZE(resources_uart1), + .resource = resources_uart1, +}; + +struct platform_device msm_device_uart2 = { + .name = "msm_serial", + .id = 1, + .num_resources = ARRAY_SIZE(resources_uart2), + .resource = resources_uart2, +}; + +struct platform_device msm_device_uart3 = { + .name = "msm_serial", + .id = 2, + .num_resources = ARRAY_SIZE(resources_uart3), + .resource = resources_uart3, +}; + +static struct resource resources_i2c[] = { + { + .start = MSM_I2C_PHYS, + .end = MSM_I2C_PHYS + MSM_I2C_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_PWB_I2C, + .end = INT_PWB_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device msm_device_i2c = { + .name = "msm_i2c", + .id = 0, + .num_resources = ARRAY_SIZE(resources_i2c), + .resource = resources_i2c, +}; + +static struct resource resources_hsusb[] = { + { + .start = MSM_HSUSB_PHYS, + .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_USB_HS, + .end = INT_USB_HS, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device msm_device_hsusb = { + .name = "msm_hsusb", + .id = -1, + .num_resources = ARRAY_SIZE(resources_hsusb), + .resource = resources_hsusb, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; + +struct flash_platform_data msm_nand_data = { + .parts = NULL, + .nr_parts = 0, +}; + +static struct resource resources_nand[] = { + [0] = { + .start = 7, + .end = 7, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device msm_device_nand = { + .name = "msm_nand", + .id = -1, + .num_resources = ARRAY_SIZE(resources_nand), + .resource = resources_nand, + .dev = { + .platform_data = &msm_nand_data, + }, +}; + +struct platform_device msm_device_smd = { + .name = "msm_smd", + .id = -1, +}; + +static struct resource resources_sdc1[] = { + { + .start = MSM_SDC1_PHYS, + .end = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_SDC1_0, + .end = INT_SDC1_0, + .flags = IORESOURCE_IRQ, + .name = "cmd_irq", + }, + { + .start = INT_SDC1_1, + .end = INT_SDC1_1, + .flags = IORESOURCE_IRQ, + .name = "pio_irq", + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, + .name = "status_irq" + }, + { + .start = 8, + .end = 8, + .flags = IORESOURCE_DMA, + }, +}; + +static struct resource resources_sdc2[] = { + { + .start = MSM_SDC2_PHYS, + .end = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_SDC2_0, + .end = INT_SDC2_0, + .flags = IORESOURCE_IRQ, + .name = "cmd_irq", + }, + { + .start = INT_SDC2_1, + .end = INT_SDC2_1, + .flags = IORESOURCE_IRQ, + .name = "pio_irq", + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, + .name = "status_irq" + }, + { + .start = 8, + .end = 8, + .flags = IORESOURCE_DMA, + }, +}; + +static struct resource resources_sdc3[] = { + { + .start = MSM_SDC3_PHYS, + .end = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_SDC3_0, + .end = INT_SDC3_0, + .flags = IORESOURCE_IRQ, + .name = "cmd_irq", + }, + { + .start = INT_SDC3_1, + .end = INT_SDC3_1, + .flags = IORESOURCE_IRQ, + .name = "pio_irq", + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, + .name = "status_irq" + }, + { + .start = 8, + .end = 8, + .flags = IORESOURCE_DMA, + }, +}; + +static struct resource resources_sdc4[] = { + { + .start = MSM_SDC4_PHYS, + .end = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_SDC4_0, + .end = INT_SDC4_0, + .flags = IORESOURCE_IRQ, + .name = "cmd_irq", + }, + { + .start = INT_SDC4_1, + .end = INT_SDC4_1, + .flags = IORESOURCE_IRQ, + .name = "pio_irq", + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, + .name = "status_irq" + }, + { + .start = 8, + .end = 8, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device msm_device_sdc1 = { + .name = "msm_sdcc", + .id = 1, + .num_resources = ARRAY_SIZE(resources_sdc1), + .resource = resources_sdc1, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; + +struct platform_device msm_device_sdc2 = { + .name = "msm_sdcc", + .id = 2, + .num_resources = ARRAY_SIZE(resources_sdc2), + .resource = resources_sdc2, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; + +struct platform_device msm_device_sdc3 = { + .name = "msm_sdcc", + .id = 3, + .num_resources = ARRAY_SIZE(resources_sdc3), + .resource = resources_sdc3, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; + +struct platform_device msm_device_sdc4 = { + .name = "msm_sdcc", + .id = 4, + .num_resources = ARRAY_SIZE(resources_sdc4), + .resource = resources_sdc4, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; + +static struct platform_device *msm_sdcc_devices[] __initdata = { + &msm_device_sdc1, + &msm_device_sdc2, + &msm_device_sdc3, + &msm_device_sdc4, +}; + +int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat, + unsigned int stat_irq, unsigned long stat_irq_flags) +{ + struct platform_device *pdev; + struct resource *res; + + if (controller < 1 || controller > 4) + return -EINVAL; + + pdev = msm_sdcc_devices[controller-1]; + pdev->dev.platform_data = plat; + + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq"); + if (!res) + return -EINVAL; + else if (stat_irq) { + res->start = res->end = stat_irq; + res->flags &= ~IORESOURCE_DISABLED; + res->flags |= stat_irq_flags; + } + + return platform_device_register(pdev); +} + diff --git a/arch/arm/mach-msm/devices.c b/arch/arm/mach-msm/devices.c deleted file mode 100644 index 982f1da60160..000000000000 --- a/arch/arm/mach-msm/devices.c +++ /dev/null @@ -1,346 +0,0 @@ -/* linux/arch/arm/mach-msm/devices.c - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#include -#include - -#include -#include -#include "devices.h" - -#include -#include -#include - -#include - -static struct resource resources_uart1[] = { - { - .start = INT_UART1, - .end = INT_UART1, - .flags = IORESOURCE_IRQ, - }, - { - .start = MSM_UART1_PHYS, - .end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource resources_uart2[] = { - { - .start = INT_UART2, - .end = INT_UART2, - .flags = IORESOURCE_IRQ, - }, - { - .start = MSM_UART2_PHYS, - .end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource resources_uart3[] = { - { - .start = INT_UART3, - .end = INT_UART3, - .flags = IORESOURCE_IRQ, - }, - { - .start = MSM_UART3_PHYS, - .end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -struct platform_device msm_device_uart1 = { - .name = "msm_serial", - .id = 0, - .num_resources = ARRAY_SIZE(resources_uart1), - .resource = resources_uart1, -}; - -struct platform_device msm_device_uart2 = { - .name = "msm_serial", - .id = 1, - .num_resources = ARRAY_SIZE(resources_uart2), - .resource = resources_uart2, -}; - -struct platform_device msm_device_uart3 = { - .name = "msm_serial", - .id = 2, - .num_resources = ARRAY_SIZE(resources_uart3), - .resource = resources_uart3, -}; - -static struct resource resources_i2c[] = { - { - .start = MSM_I2C_PHYS, - .end = MSM_I2C_PHYS + MSM_I2C_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_PWB_I2C, - .end = INT_PWB_I2C, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device msm_device_i2c = { - .name = "msm_i2c", - .id = 0, - .num_resources = ARRAY_SIZE(resources_i2c), - .resource = resources_i2c, -}; - -static struct resource resources_hsusb[] = { - { - .start = MSM_HSUSB_PHYS, - .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_USB_HS, - .end = INT_USB_HS, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device msm_device_hsusb = { - .name = "msm_hsusb", - .id = -1, - .num_resources = ARRAY_SIZE(resources_hsusb), - .resource = resources_hsusb, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - -struct flash_platform_data msm_nand_data = { - .parts = NULL, - .nr_parts = 0, -}; - -static struct resource resources_nand[] = { - [0] = { - .start = 7, - .end = 7, - .flags = IORESOURCE_DMA, - }, -}; - -struct platform_device msm_device_nand = { - .name = "msm_nand", - .id = -1, - .num_resources = ARRAY_SIZE(resources_nand), - .resource = resources_nand, - .dev = { - .platform_data = &msm_nand_data, - }, -}; - -struct platform_device msm_device_smd = { - .name = "msm_smd", - .id = -1, -}; - -static struct resource resources_sdc1[] = { - { - .start = MSM_SDC1_PHYS, - .end = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_SDC1_0, - .end = INT_SDC1_0, - .flags = IORESOURCE_IRQ, - .name = "cmd_irq", - }, - { - .start = INT_SDC1_1, - .end = INT_SDC1_1, - .flags = IORESOURCE_IRQ, - .name = "pio_irq", - }, - { - .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, - .name = "status_irq" - }, - { - .start = 8, - .end = 8, - .flags = IORESOURCE_DMA, - }, -}; - -static struct resource resources_sdc2[] = { - { - .start = MSM_SDC2_PHYS, - .end = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_SDC2_0, - .end = INT_SDC2_0, - .flags = IORESOURCE_IRQ, - .name = "cmd_irq", - }, - { - .start = INT_SDC2_1, - .end = INT_SDC2_1, - .flags = IORESOURCE_IRQ, - .name = "pio_irq", - }, - { - .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, - .name = "status_irq" - }, - { - .start = 8, - .end = 8, - .flags = IORESOURCE_DMA, - }, -}; - -static struct resource resources_sdc3[] = { - { - .start = MSM_SDC3_PHYS, - .end = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_SDC3_0, - .end = INT_SDC3_0, - .flags = IORESOURCE_IRQ, - .name = "cmd_irq", - }, - { - .start = INT_SDC3_1, - .end = INT_SDC3_1, - .flags = IORESOURCE_IRQ, - .name = "pio_irq", - }, - { - .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, - .name = "status_irq" - }, - { - .start = 8, - .end = 8, - .flags = IORESOURCE_DMA, - }, -}; - -static struct resource resources_sdc4[] = { - { - .start = MSM_SDC4_PHYS, - .end = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_SDC4_0, - .end = INT_SDC4_0, - .flags = IORESOURCE_IRQ, - .name = "cmd_irq", - }, - { - .start = INT_SDC4_1, - .end = INT_SDC4_1, - .flags = IORESOURCE_IRQ, - .name = "pio_irq", - }, - { - .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, - .name = "status_irq" - }, - { - .start = 8, - .end = 8, - .flags = IORESOURCE_DMA, - }, -}; - -struct platform_device msm_device_sdc1 = { - .name = "msm_sdcc", - .id = 1, - .num_resources = ARRAY_SIZE(resources_sdc1), - .resource = resources_sdc1, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - -struct platform_device msm_device_sdc2 = { - .name = "msm_sdcc", - .id = 2, - .num_resources = ARRAY_SIZE(resources_sdc2), - .resource = resources_sdc2, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - -struct platform_device msm_device_sdc3 = { - .name = "msm_sdcc", - .id = 3, - .num_resources = ARRAY_SIZE(resources_sdc3), - .resource = resources_sdc3, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - -struct platform_device msm_device_sdc4 = { - .name = "msm_sdcc", - .id = 4, - .num_resources = ARRAY_SIZE(resources_sdc4), - .resource = resources_sdc4, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - -static struct platform_device *msm_sdcc_devices[] __initdata = { - &msm_device_sdc1, - &msm_device_sdc2, - &msm_device_sdc3, - &msm_device_sdc4, -}; - -int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat, - unsigned int stat_irq, unsigned long stat_irq_flags) -{ - struct platform_device *pdev; - struct resource *res; - - if (controller < 1 || controller > 4) - return -EINVAL; - - pdev = msm_sdcc_devices[controller-1]; - pdev->dev.platform_data = plat; - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq"); - if (!res) - return -EINVAL; - else if (stat_irq) { - res->start = res->end = stat_irq; - res->flags &= ~IORESOURCE_DISABLED; - res->flags |= stat_irq_flags; - } - - return platform_device_register(pdev); -} - -- cgit v1.2.3-59-g8ed1b From 8f90c7b60d487866841bfa2fd51792873e54a3a5 Mon Sep 17 00:00:00 2001 From: Gregory Bean Date: Fri, 30 Apr 2010 21:33:38 -0700 Subject: msm: generialize IRQ to support multiple SOCs. irqs.h is specific to the MSM7x00 series devices. Generalize this in preparation to support more devices. Signed-off-by: Gregory Bean Signed-off-by: David Brown Signed-off-by: Daniel Walker Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/irqs-7x00.h | 75 +++++++++++++++++++++++++++++ arch/arm/mach-msm/include/mach/irqs.h | 76 ++++-------------------------- 2 files changed, 84 insertions(+), 67 deletions(-) create mode 100644 arch/arm/mach-msm/include/mach/irqs-7x00.h (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/irqs-7x00.h b/arch/arm/mach-msm/include/mach/irqs-7x00.h new file mode 100644 index 000000000000..f1fe70612fe9 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/irqs-7x00.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * Author: Brian Swetland + */ + +#ifndef __ASM_ARCH_MSM_IRQS_7X00_H +#define __ASM_ARCH_MSM_IRQS_7X00_H + +/* MSM ARM11 Interrupt Numbers */ +/* See 80-VE113-1 A, pp219-221 */ + +#define INT_A9_M2A_0 0 +#define INT_A9_M2A_1 1 +#define INT_A9_M2A_2 2 +#define INT_A9_M2A_3 3 +#define INT_A9_M2A_4 4 +#define INT_A9_M2A_5 5 +#define INT_A9_M2A_6 6 +#define INT_GP_TIMER_EXP 7 +#define INT_DEBUG_TIMER_EXP 8 +#define INT_UART1 9 +#define INT_UART2 10 +#define INT_UART3 11 +#define INT_UART1_RX 12 +#define INT_UART2_RX 13 +#define INT_UART3_RX 14 +#define INT_USB_OTG 15 +#define INT_MDDI_PRI 16 +#define INT_MDDI_EXT 17 +#define INT_MDDI_CLIENT 18 +#define INT_MDP 19 +#define INT_GRAPHICS 20 +#define INT_ADM_AARM 21 +#define INT_ADSP_A11 22 +#define INT_ADSP_A9_A11 23 +#define INT_SDC1_0 24 +#define INT_SDC1_1 25 +#define INT_SDC2_0 26 +#define INT_SDC2_1 27 +#define INT_KEYSENSE 28 +#define INT_TCHSCRN_SSBI 29 +#define INT_TCHSCRN1 30 +#define INT_TCHSCRN2 31 + +#define INT_GPIO_GROUP1 (32 + 0) +#define INT_GPIO_GROUP2 (32 + 1) +#define INT_PWB_I2C (32 + 2) +#define INT_SOFTRESET (32 + 3) +#define INT_NAND_WR_ER_DONE (32 + 4) +#define INT_NAND_OP_DONE (32 + 5) +#define INT_PBUS_ARM11 (32 + 6) +#define INT_AXI_MPU_SMI (32 + 7) +#define INT_AXI_MPU_EBI1 (32 + 8) +#define INT_AD_HSSD (32 + 9) +#define INT_ARM11_PMU (32 + 10) +#define INT_ARM11_DMA (32 + 11) +#define INT_TSIF_IRQ (32 + 12) +#define INT_UART1DM_IRQ (32 + 13) +#define INT_UART1DM_RX (32 + 14) +#define INT_USB_HS (32 + 15) +#define INT_SDC3_0 (32 + 16) +#define INT_SDC3_1 (32 + 17) +#define INT_SDC4_0 (32 + 18) +#define INT_SDC4_1 (32 + 19) +#define INT_UART2DM_RX (32 + 20) +#define INT_UART2DM_IRQ (32 + 21) + +/* 22-31 are reserved */ + +#define NR_MSM_IRQS 64 +#define NR_GPIO_IRQS 122 +#define NR_BOARD_IRQS 64 + +#endif diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h index 9dd4cf8a2693..b8995607f74c 100644 --- a/arch/arm/mach-msm/include/mach/irqs.h +++ b/arch/arm/mach-msm/include/mach/irqs.h @@ -1,6 +1,6 @@ -/* arch/arm/mach-msm/include/mach/irqs.h - * +/* * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -17,74 +17,16 @@ #ifndef __ASM_ARCH_MSM_IRQS_H #define __ASM_ARCH_MSM_IRQS_H -/* MSM ARM11 Interrupt Numbers */ -/* See 80-VE113-1 A, pp219-221 */ - -#define INT_A9_M2A_0 0 -#define INT_A9_M2A_1 1 -#define INT_A9_M2A_2 2 -#define INT_A9_M2A_3 3 -#define INT_A9_M2A_4 4 -#define INT_A9_M2A_5 5 -#define INT_A9_M2A_6 6 -#define INT_GP_TIMER_EXP 7 -#define INT_DEBUG_TIMER_EXP 8 -#define INT_UART1 9 -#define INT_UART2 10 -#define INT_UART3 11 -#define INT_UART1_RX 12 -#define INT_UART2_RX 13 -#define INT_UART3_RX 14 -#define INT_USB_OTG 15 -#define INT_MDDI_PRI 16 -#define INT_MDDI_EXT 17 -#define INT_MDDI_CLIENT 18 -#define INT_MDP 19 -#define INT_GRAPHICS 20 -#define INT_ADM_AARM 21 -#define INT_ADSP_A11 22 -#define INT_ADSP_A9_A11 23 -#define INT_SDC1_0 24 -#define INT_SDC1_1 25 -#define INT_SDC2_0 26 -#define INT_SDC2_1 27 -#define INT_KEYSENSE 28 -#define INT_TCHSCRN_SSBI 29 -#define INT_TCHSCRN1 30 -#define INT_TCHSCRN2 31 - -#define INT_GPIO_GROUP1 (32 + 0) -#define INT_GPIO_GROUP2 (32 + 1) -#define INT_PWB_I2C (32 + 2) -#define INT_SOFTRESET (32 + 3) -#define INT_NAND_WR_ER_DONE (32 + 4) -#define INT_NAND_OP_DONE (32 + 5) -#define INT_PBUS_ARM11 (32 + 6) -#define INT_AXI_MPU_SMI (32 + 7) -#define INT_AXI_MPU_EBI1 (32 + 8) -#define INT_AD_HSSD (32 + 9) -#define INT_ARM11_PMU (32 + 10) -#define INT_ARM11_DMA (32 + 11) -#define INT_TSIF_IRQ (32 + 12) -#define INT_UART1DM_IRQ (32 + 13) -#define INT_UART1DM_RX (32 + 14) -#define INT_USB_HS (32 + 15) -#define INT_SDC3_0 (32 + 16) -#define INT_SDC3_1 (32 + 17) -#define INT_SDC4_0 (32 + 18) -#define INT_SDC4_1 (32 + 19) -#define INT_UART2DM_RX (32 + 20) -#define INT_UART2DM_IRQ (32 + 21) - -/* 22-31 are reserved */ - #define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) -#define NR_MSM_IRQS 64 -#define NR_GPIO_IRQS 122 -#define NR_BOARD_IRQS 64 -#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS) +#if defined(CONFIG_ARCH_MSM_ARM11) +#include "irqs-7x00.h" +#else +#error "Unknown architecture specification" +#endif +#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS) #define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n)) +#define MSM_INT_TO_REG(base, irq) (base + irq / 32) #endif -- cgit v1.2.3-59-g8ed1b From d2e753bf935bb67fcddfd64017d2b302d6e2330d Mon Sep 17 00:00:00 2001 From: Gregory Bean Date: Fri, 30 Apr 2010 21:33:38 -0700 Subject: msm: generialize iomap to support multiple SOCs. msm_iomap.h is specific to the MSM7x00 series devices. Generalize this in preparation to support more devices. Signed-off-by: Gregory Bean Signed-off-by: David Brown Signed-off-by: Daniel Walker Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/msm_iomap-7x00.h | 139 ++++++++++++++++++++++++ arch/arm/mach-msm/include/mach/msm_iomap.h | 97 +---------------- 2 files changed, 142 insertions(+), 94 deletions(-) create mode 100644 arch/arm/mach-msm/include/mach/msm_iomap-7x00.h (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h new file mode 100644 index 000000000000..cfff0e74f128 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h @@ -0,0 +1,139 @@ +/* arch/arm/mach-msm/include/mach/msm_iomap.h + * + * Copyright (C) 2007 Google, Inc. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + * + * The MSM peripherals are spread all over across 768MB of physical + * space, which makes just having a simple IO_ADDRESS macro to slide + * them into the right virtual location rough. Instead, we will + * provide a master phys->virt mapping for peripherals here. + * + */ + +#ifndef __ASM_ARCH_MSM_IOMAP_7X00_H +#define __ASM_ARCH_MSM_IOMAP_7X00_H + +#include + +/* Physical base address and size of peripherals. + * Ordered by the virtual base addresses they will be mapped at. + * + * MSM_VIC_BASE must be an value that can be loaded via a "mov" + * instruction, otherwise entry-macro.S will not compile. + * + * If you add or remove entries here, you'll want to edit the + * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your + * changes. + * + */ + +#ifdef __ASSEMBLY__ +#define IOMEM(x) x +#else +#define IOMEM(x) ((void __force __iomem *)(x)) +#endif + +#define MSM_VIC_BASE IOMEM(0xE0000000) +#define MSM_VIC_PHYS 0xC0000000 +#define MSM_VIC_SIZE SZ_4K + +#define MSM_CSR_BASE IOMEM(0xE0001000) +#define MSM_CSR_PHYS 0xC0100000 +#define MSM_CSR_SIZE SZ_4K + +#define MSM_GPT_PHYS MSM_CSR_PHYS +#define MSM_GPT_BASE MSM_CSR_BASE +#define MSM_GPT_SIZE SZ_4K + +#define MSM_DMOV_BASE IOMEM(0xE0002000) +#define MSM_DMOV_PHYS 0xA9700000 +#define MSM_DMOV_SIZE SZ_4K + +#define MSM_GPIO1_BASE IOMEM(0xE0003000) +#define MSM_GPIO1_PHYS 0xA9200000 +#define MSM_GPIO1_SIZE SZ_4K + +#define MSM_GPIO2_BASE IOMEM(0xE0004000) +#define MSM_GPIO2_PHYS 0xA9300000 +#define MSM_GPIO2_SIZE SZ_4K + +#define MSM_CLK_CTL_BASE IOMEM(0xE0005000) +#define MSM_CLK_CTL_PHYS 0xA8600000 +#define MSM_CLK_CTL_SIZE SZ_4K + +#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000) +#define MSM_SHARED_RAM_PHYS 0x01F00000 +#define MSM_SHARED_RAM_SIZE SZ_1M + +#define MSM_UART1_PHYS 0xA9A00000 +#define MSM_UART1_SIZE SZ_4K + +#define MSM_UART2_PHYS 0xA9B00000 +#define MSM_UART2_SIZE SZ_4K + +#define MSM_UART3_PHYS 0xA9C00000 +#define MSM_UART3_SIZE SZ_4K + +#ifdef CONFIG_MSM_DEBUG_UART +#define MSM_DEBUG_UART_BASE 0xE1000000 +#if CONFIG_MSM_DEBUG_UART == 1 +#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS +#elif CONFIG_MSM_DEBUG_UART == 2 +#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS +#elif CONFIG_MSM_DEBUG_UART == 3 +#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS +#endif +#define MSM_DEBUG_UART_SIZE SZ_4K +#endif + +#define MSM_SDC1_PHYS 0xA0400000 +#define MSM_SDC1_SIZE SZ_4K + +#define MSM_SDC2_PHYS 0xA0500000 +#define MSM_SDC2_SIZE SZ_4K + +#define MSM_SDC3_PHYS 0xA0600000 +#define MSM_SDC3_SIZE SZ_4K + +#define MSM_SDC4_PHYS 0xA0700000 +#define MSM_SDC4_SIZE SZ_4K + +#define MSM_I2C_PHYS 0xA9900000 +#define MSM_I2C_SIZE SZ_4K + +#define MSM_HSUSB_PHYS 0xA0800000 +#define MSM_HSUSB_SIZE SZ_4K + +#define MSM_PMDH_PHYS 0xAA600000 +#define MSM_PMDH_SIZE SZ_4K + +#define MSM_EMDH_PHYS 0xAA700000 +#define MSM_EMDH_SIZE SZ_4K + +#define MSM_MDP_PHYS 0xAA200000 +#define MSM_MDP_SIZE 0x000F0000 + +#define MSM_MDC_PHYS 0xAA500000 +#define MSM_MDC_SIZE SZ_1M + +#define MSM_AD5_PHYS 0xAC000000 +#define MSM_AD5_SIZE (SZ_1M*13) + + +#if defined(CONFIG_ARCH_MSM7X30) +#define MSM_GCC_BASE IOMEM(0xF8009000) +#define MSM_GCC_PHYS 0xC0182000 +#define MSM_GCC_SIZE SZ_4K +#endif + +#endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index ce1effed5894..81da6b8e25a0 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -1,6 +1,6 @@ -/* arch/arm/mach-msm/include/mach/msm_iomap.h - * +/* * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -43,97 +43,6 @@ #define IOMEM(x) ((void __force __iomem *)(x)) #endif -#define MSM_VIC_BASE IOMEM(0xE0000000) -#define MSM_VIC_PHYS 0xC0000000 -#define MSM_VIC_SIZE SZ_4K - -#define MSM_CSR_BASE IOMEM(0xE0001000) -#define MSM_CSR_PHYS 0xC0100000 -#define MSM_CSR_SIZE SZ_4K - -#define MSM_GPT_PHYS MSM_CSR_PHYS -#define MSM_GPT_BASE MSM_CSR_BASE -#define MSM_GPT_SIZE SZ_4K - -#define MSM_DMOV_BASE IOMEM(0xE0002000) -#define MSM_DMOV_PHYS 0xA9700000 -#define MSM_DMOV_SIZE SZ_4K - -#define MSM_GPIO1_BASE IOMEM(0xE0003000) -#define MSM_GPIO1_PHYS 0xA9200000 -#define MSM_GPIO1_SIZE SZ_4K - -#define MSM_GPIO2_BASE IOMEM(0xE0004000) -#define MSM_GPIO2_PHYS 0xA9300000 -#define MSM_GPIO2_SIZE SZ_4K - -#define MSM_CLK_CTL_BASE IOMEM(0xE0005000) -#define MSM_CLK_CTL_PHYS 0xA8600000 -#define MSM_CLK_CTL_SIZE SZ_4K - -#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000) -#define MSM_SHARED_RAM_PHYS 0x01F00000 -#define MSM_SHARED_RAM_SIZE SZ_1M - -#define MSM_UART1_PHYS 0xA9A00000 -#define MSM_UART1_SIZE SZ_4K - -#define MSM_UART2_PHYS 0xA9B00000 -#define MSM_UART2_SIZE SZ_4K - -#define MSM_UART3_PHYS 0xA9C00000 -#define MSM_UART3_SIZE SZ_4K - -#ifdef CONFIG_MSM_DEBUG_UART -#define MSM_DEBUG_UART_BASE 0xE1000000 -#if CONFIG_MSM_DEBUG_UART == 1 -#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS -#elif CONFIG_MSM_DEBUG_UART == 2 -#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS -#elif CONFIG_MSM_DEBUG_UART == 3 -#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS -#endif -#define MSM_DEBUG_UART_SIZE SZ_4K -#endif - -#define MSM_SDC1_PHYS 0xA0400000 -#define MSM_SDC1_SIZE SZ_4K - -#define MSM_SDC2_PHYS 0xA0500000 -#define MSM_SDC2_SIZE SZ_4K - -#define MSM_SDC3_PHYS 0xA0600000 -#define MSM_SDC3_SIZE SZ_4K - -#define MSM_SDC4_PHYS 0xA0700000 -#define MSM_SDC4_SIZE SZ_4K - -#define MSM_I2C_PHYS 0xA9900000 -#define MSM_I2C_SIZE SZ_4K - -#define MSM_HSUSB_PHYS 0xA0800000 -#define MSM_HSUSB_SIZE SZ_4K - -#define MSM_PMDH_PHYS 0xAA600000 -#define MSM_PMDH_SIZE SZ_4K - -#define MSM_EMDH_PHYS 0xAA700000 -#define MSM_EMDH_SIZE SZ_4K - -#define MSM_MDP_PHYS 0xAA200000 -#define MSM_MDP_SIZE 0x000F0000 - -#define MSM_MDC_PHYS 0xAA500000 -#define MSM_MDC_SIZE SZ_1M - -#define MSM_AD5_PHYS 0xAC000000 -#define MSM_AD5_SIZE (SZ_1M*13) - - -#if defined(CONFIG_ARCH_MSM7X30) -#define MSM_GCC_BASE IOMEM(0xF8009000) -#define MSM_GCC_PHYS 0xC0182000 -#define MSM_GCC_SIZE SZ_4K -#endif +#include "msm_iomap-7x00.h" #endif -- cgit v1.2.3-59-g8ed1b From ec4d79255c684a74ade2f2394b9f9a669cee0036 Mon Sep 17 00:00:00 2001 From: Gregory Bean Date: Fri, 30 Apr 2010 21:59:38 -0700 Subject: msm: add sirc interrupt controller driver. Scorpion-based SOCs from Qualcomm use a different interrupt controller 'sirc'. Signed-off-by: Gregory Bean Signed-off-by: David Brown Signed-off-by: Daniel Walker Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/sirc.h | 115 ++++++++++++++++++++++ arch/arm/mach-msm/sirc.c | 177 ++++++++++++++++++++++++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 arch/arm/mach-msm/include/mach/sirc.h create mode 100644 arch/arm/mach-msm/sirc.c (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/sirc.h b/arch/arm/mach-msm/include/mach/sirc.h new file mode 100644 index 000000000000..7281337ee28d --- /dev/null +++ b/arch/arm/mach-msm/include/mach/sirc.h @@ -0,0 +1,115 @@ +/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __ASM_ARCH_MSM_SIRC_H +#define __ASM_ARCH_MSM_SIRC_H + +struct sirc_regs_t { + void *int_enable; + void *int_enable_clear; + void *int_enable_set; + void *int_type; + void *int_polarity; + void *int_clear; +}; + +struct sirc_cascade_regs { + void *int_status; + unsigned int cascade_irq; +}; + +void msm_init_sirc(void); +void msm_sirc_enter_sleep(void); +void msm_sirc_exit_sleep(void); + +#if defined(CONFIG_ARCH_MSM_SCORPION) + +#include + +/* + * Secondary interrupt controller interrupts + */ + +#define FIRST_SIRC_IRQ (NR_MSM_IRQS + NR_GPIO_IRQS) + +#define INT_UART1 (FIRST_SIRC_IRQ + 0) +#define INT_UART2 (FIRST_SIRC_IRQ + 1) +#define INT_UART3 (FIRST_SIRC_IRQ + 2) +#define INT_UART1_RX (FIRST_SIRC_IRQ + 3) +#define INT_UART2_RX (FIRST_SIRC_IRQ + 4) +#define INT_UART3_RX (FIRST_SIRC_IRQ + 5) +#define INT_SPI_INPUT (FIRST_SIRC_IRQ + 6) +#define INT_SPI_OUTPUT (FIRST_SIRC_IRQ + 7) +#define INT_SPI_ERROR (FIRST_SIRC_IRQ + 8) +#define INT_GPIO_GROUP1 (FIRST_SIRC_IRQ + 9) +#define INT_GPIO_GROUP2 (FIRST_SIRC_IRQ + 10) +#define INT_GPIO_GROUP1_SECURE (FIRST_SIRC_IRQ + 11) +#define INT_GPIO_GROUP2_SECURE (FIRST_SIRC_IRQ + 12) +#define INT_AVS_SVIC (FIRST_SIRC_IRQ + 13) +#define INT_AVS_REQ_UP (FIRST_SIRC_IRQ + 14) +#define INT_AVS_REQ_DOWN (FIRST_SIRC_IRQ + 15) +#define INT_PBUS_ERR (FIRST_SIRC_IRQ + 16) +#define INT_AXI_ERR (FIRST_SIRC_IRQ + 17) +#define INT_SMI_ERR (FIRST_SIRC_IRQ + 18) +#define INT_EBI1_ERR (FIRST_SIRC_IRQ + 19) +#define INT_IMEM_ERR (FIRST_SIRC_IRQ + 20) +#define INT_TEMP_SENSOR (FIRST_SIRC_IRQ + 21) +#define INT_TV_ENC (FIRST_SIRC_IRQ + 22) +#define INT_GRP2D (FIRST_SIRC_IRQ + 23) +#define INT_GSBI_QUP (FIRST_SIRC_IRQ + 24) +#define INT_SC_ACG (FIRST_SIRC_IRQ + 25) +#define INT_WDT0 (FIRST_SIRC_IRQ + 26) +#define INT_WDT1 (FIRST_SIRC_IRQ + 27) + +#if defined(CONFIG_MSM_SOC_REV_A) +#define NR_SIRC_IRQS 28 +#define SIRC_MASK 0x0FFFFFFF +#else +#define NR_SIRC_IRQS 23 +#define SIRC_MASK 0x007FFFFF +#endif + +#define LAST_SIRC_IRQ (FIRST_SIRC_IRQ + NR_SIRC_IRQS - 1) + +#define SPSS_SIRC_INT_SELECT (MSM_SIRC_BASE + 0x00) +#define SPSS_SIRC_INT_ENABLE (MSM_SIRC_BASE + 0x04) +#define SPSS_SIRC_INT_ENABLE_CLEAR (MSM_SIRC_BASE + 0x08) +#define SPSS_SIRC_INT_ENABLE_SET (MSM_SIRC_BASE + 0x0C) +#define SPSS_SIRC_INT_TYPE (MSM_SIRC_BASE + 0x10) +#define SPSS_SIRC_INT_POLARITY (MSM_SIRC_BASE + 0x14) +#define SPSS_SIRC_SECURITY (MSM_SIRC_BASE + 0x18) +#define SPSS_SIRC_IRQ_STATUS (MSM_SIRC_BASE + 0x1C) +#define SPSS_SIRC_IRQ1_STATUS (MSM_SIRC_BASE + 0x20) +#define SPSS_SIRC_RAW_STATUS (MSM_SIRC_BASE + 0x24) +#define SPSS_SIRC_INT_CLEAR (MSM_SIRC_BASE + 0x28) +#define SPSS_SIRC_SOFT_INT (MSM_SIRC_BASE + 0x2C) + +#endif + +#endif diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c new file mode 100644 index 000000000000..b0794524ba6e --- /dev/null +++ b/arch/arm/mach-msm/sirc.c @@ -0,0 +1,177 @@ +/* Copyright (c) 2008-2009, Code Aurora Forum. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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 +#include +#include +#include + +static unsigned int int_enable; +static unsigned int wake_enable; + +static struct sirc_regs_t sirc_regs = { + .int_enable = SPSS_SIRC_INT_ENABLE, + .int_enable_clear = SPSS_SIRC_INT_ENABLE_CLEAR, + .int_enable_set = SPSS_SIRC_INT_ENABLE_SET, + .int_type = SPSS_SIRC_INT_TYPE, + .int_polarity = SPSS_SIRC_INT_POLARITY, + .int_clear = SPSS_SIRC_INT_CLEAR, +}; + +static struct sirc_cascade_regs sirc_reg_table[] = { + { + .int_status = SPSS_SIRC_IRQ_STATUS, + .cascade_irq = INT_SIRC_0, + } +}; + +static unsigned int save_type; +static unsigned int save_polarity; + +/* Mask off the given interrupt. Keep the int_enable mask in sync with + the enable reg, so it can be restored after power collapse. */ +static void sirc_irq_mask(unsigned int irq) +{ + unsigned int mask; + + + mask = 1 << (irq - FIRST_SIRC_IRQ); + writel(mask, sirc_regs.int_enable_clear); + int_enable &= ~mask; + return; +} + +/* Unmask the given interrupt. Keep the int_enable mask in sync with + the enable reg, so it can be restored after power collapse. */ +static void sirc_irq_unmask(unsigned int irq) +{ + unsigned int mask; + + mask = 1 << (irq - FIRST_SIRC_IRQ); + writel(mask, sirc_regs.int_enable_set); + int_enable |= mask; + return; +} + +static void sirc_irq_ack(unsigned int irq) +{ + unsigned int mask; + + mask = 1 << (irq - FIRST_SIRC_IRQ); + writel(mask, sirc_regs.int_clear); + return; +} + +static int sirc_irq_set_wake(unsigned int irq, unsigned int on) +{ + unsigned int mask; + + /* Used to set the interrupt enable mask during power collapse. */ + mask = 1 << (irq - FIRST_SIRC_IRQ); + if (on) + wake_enable |= mask; + else + wake_enable &= ~mask; + + return 0; +} + +static int sirc_irq_set_type(unsigned int irq, unsigned int flow_type) +{ + unsigned int mask; + unsigned int val; + + mask = 1 << (irq - FIRST_SIRC_IRQ); + val = readl(sirc_regs.int_polarity); + + if (flow_type & (IRQF_TRIGGER_LOW | IRQF_TRIGGER_FALLING)) + val |= mask; + else + val &= ~mask; + + writel(val, sirc_regs.int_polarity); + + val = readl(sirc_regs.int_type); + if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { + val |= mask; + irq_desc[irq].handle_irq = handle_edge_irq; + } else { + val &= ~mask; + irq_desc[irq].handle_irq = handle_level_irq; + } + + writel(val, sirc_regs.int_type); + + return 0; +} + +/* Finds the pending interrupt on the passed cascade irq and redrives it */ +static void sirc_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + unsigned int reg = 0; + unsigned int sirq; + unsigned int status; + + while ((reg < ARRAY_SIZE(sirc_reg_table)) && + (sirc_reg_table[reg].cascade_irq != irq)) + reg++; + + status = readl(sirc_reg_table[reg].int_status); + status &= SIRC_MASK; + if (status == 0) + return; + + for (sirq = 0; + (sirq < NR_SIRC_IRQS) && ((status & (1U << sirq)) == 0); + sirq++) + ; + generic_handle_irq(sirq+FIRST_SIRC_IRQ); + + desc->chip->ack(irq); +} + +static struct irq_chip sirc_irq_chip = { + .name = "sirc", + .ack = sirc_irq_ack, + .mask = sirc_irq_mask, + .unmask = sirc_irq_unmask, + .set_wake = sirc_irq_set_wake, + .set_type = sirc_irq_set_type, +}; + +void __init msm_init_sirc(void) +{ + int i; + + int_enable = 0; + wake_enable = 0; + + for (i = FIRST_SIRC_IRQ; i < LAST_SIRC_IRQ; i++) { + set_irq_chip(i, &sirc_irq_chip); + set_irq_handler(i, handle_edge_irq); + set_irq_flags(i, IRQF_VALID); + } + + for (i = 0; i < ARRAY_SIZE(sirc_reg_table); i++) { + set_irq_chained_handler(sirc_reg_table[i].cascade_irq, + sirc_irq_handler); + set_irq_wake(sirc_reg_table[i].cascade_irq, 1); + } + return; +} + -- cgit v1.2.3-59-g8ed1b From 5e96da5d5074eae3b94d4abadfc114febb6e2a51 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 12 May 2010 13:43:28 -0700 Subject: msm: generalize clock support. The 'PCOM' method of clock control (commands issued to the radio CPU) is shared across several (but not all) Qualcomm SOCs. Generalize this clock mechanism so these other SOCs can be added. Signed-off-by: Gregory Bean Signed-off-by: David Brown Signed-off-by: Daniel Walker Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/Makefile | 2 +- arch/arm/mach-msm/board-halibut.c | 2 +- arch/arm/mach-msm/board-trout.c | 2 +- arch/arm/mach-msm/clock-7x01a.c | 126 ---------------- arch/arm/mach-msm/clock-pcom.c | 131 +++++++++++++++++ arch/arm/mach-msm/clock-pcom.h | 153 ++++++++++++++++++++ arch/arm/mach-msm/clock.c | 257 ++++++++++++++++++++++++--------- arch/arm/mach-msm/clock.h | 70 ++++++++- arch/arm/mach-msm/devices-msm7x00.c | 47 ++++++ arch/arm/mach-msm/devices.h | 5 + arch/arm/mach-msm/include/mach/board.h | 5 +- arch/arm/mach-msm/include/mach/clk.h | 57 ++++++++ 12 files changed, 651 insertions(+), 206 deletions(-) delete mode 100644 arch/arm/mach-msm/clock-7x01a.c create mode 100644 arch/arm/mach-msm/clock-pcom.c create mode 100644 arch/arm/mach-msm/clock-pcom.h create mode 100644 arch/arm/mach-msm/include/mach/clk.h (limited to 'arch') diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 435d83cd52c2..70fa9703f437 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -2,7 +2,7 @@ obj-y += io.o idle.o irq.o timer.o dma.o obj-y += proc_comm.o obj-y += vreg.o obj-y += acpuclock-arm11.o -obj-y += clock.o clock-7x01a.o +obj-y += clock.o clock-pcom.o obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o obj-$(CONFIG_MSM_SMD) += last_radio_log.o diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index acc22886e340..7bd72e8f127e 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c @@ -90,7 +90,7 @@ static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags, static void __init halibut_map_io(void) { msm_map_common_io(); - msm_clock_init(); + msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a); } MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index b88aec269df5..dca5a5f062dc 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c @@ -78,7 +78,7 @@ static void __init trout_map_io(void) writeb(0x80, TROUT_CPLD_BASE + 0x00); #endif - msm_clock_init(); + msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a); } MACHINE_START(TROUT, "HTC Dream") diff --git a/arch/arm/mach-msm/clock-7x01a.c b/arch/arm/mach-msm/clock-7x01a.c deleted file mode 100644 index 62230a3428ee..000000000000 --- a/arch/arm/mach-msm/clock-7x01a.c +++ /dev/null @@ -1,126 +0,0 @@ -/* arch/arm/mach-msm/clock-7x01a.c - * - * Clock tables for MSM7X01A - * - * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2007 QUALCOMM Incorporated - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#include -#include - -#include "clock.h" -#include "devices.h" - -/* clock IDs used by the modem processor */ - -#define ACPU_CLK 0 /* Applications processor clock */ -#define ADM_CLK 1 /* Applications data mover clock */ -#define ADSP_CLK 2 /* ADSP clock */ -#define EBI1_CLK 3 /* External bus interface 1 clock */ -#define EBI2_CLK 4 /* External bus interface 2 clock */ -#define ECODEC_CLK 5 /* External CODEC clock */ -#define EMDH_CLK 6 /* External MDDI host clock */ -#define GP_CLK 7 /* General purpose clock */ -#define GRP_CLK 8 /* Graphics clock */ -#define I2C_CLK 9 /* I2C clock */ -#define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */ -#define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */ -#define IMEM_CLK 12 /* Internal graphics memory clock */ -#define MDC_CLK 13 /* MDDI client clock */ -#define MDP_CLK 14 /* Mobile display processor clock */ -#define PBUS_CLK 15 /* Peripheral bus clock */ -#define PCM_CLK 16 /* PCM clock */ -#define PMDH_CLK 17 /* Primary MDDI host clock */ -#define SDAC_CLK 18 /* Stereo DAC clock */ -#define SDC1_CLK 19 /* Secure Digital Card clocks */ -#define SDC1_PCLK 20 -#define SDC2_CLK 21 -#define SDC2_PCLK 22 -#define SDC3_CLK 23 -#define SDC3_PCLK 24 -#define SDC4_CLK 25 -#define SDC4_PCLK 26 -#define TSIF_CLK 27 /* Transport Stream Interface clocks */ -#define TSIF_REF_CLK 28 -#define TV_DAC_CLK 29 /* TV clocks */ -#define TV_ENC_CLK 30 -#define UART1_CLK 31 /* UART clocks */ -#define UART2_CLK 32 -#define UART3_CLK 33 -#define UART1DM_CLK 34 -#define UART2DM_CLK 35 -#define USB_HS_CLK 36 /* High speed USB core clock */ -#define USB_HS_PCLK 37 /* High speed USB pbus clock */ -#define USB_OTG_CLK 38 /* Full speed USB clock */ -#define VDC_CLK 39 /* Video controller clock */ -#define VFE_CLK 40 /* Camera / Video Front End clock */ -#define VFE_MDC_CLK 41 /* VFE MDDI client clock */ - -#define NR_CLKS 42 - -#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \ - .name = clk_name, \ - .id = clk_id, \ - .flags = clk_flags, \ - .dev = clk_dev, \ - } - -#define OFF CLKFLAG_AUTO_OFF -#define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET - -struct clk msm_clocks[] = { - CLOCK("adm_clk", ADM_CLK, NULL, 0), - CLOCK("adsp_clk", ADSP_CLK, NULL, 0), - CLOCK("ebi1_clk", EBI1_CLK, NULL, 0), - CLOCK("ebi2_clk", EBI2_CLK, NULL, 0), - CLOCK("ecodec_clk", ECODEC_CLK, NULL, 0), - CLOCK("emdh_clk", EMDH_CLK, NULL, OFF), - CLOCK("gp_clk", GP_CLK, NULL, 0), - CLOCK("grp_clk", GRP_CLK, NULL, OFF), - CLOCK("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0), - CLOCK("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0), - CLOCK("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0), - CLOCK("imem_clk", IMEM_CLK, NULL, OFF), - CLOCK("mdc_clk", MDC_CLK, NULL, 0), - CLOCK("mdp_clk", MDP_CLK, NULL, OFF), - CLOCK("pbus_clk", PBUS_CLK, NULL, 0), - CLOCK("pcm_clk", PCM_CLK, NULL, 0), - CLOCK("pmdh_clk", PMDH_CLK, NULL, OFF | MINMAX), - CLOCK("sdac_clk", SDAC_CLK, NULL, OFF), - CLOCK("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), - CLOCK("sdc_pclk", SDC1_PCLK, &msm_device_sdc1.dev, OFF), - CLOCK("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF), - CLOCK("sdc_pclk", SDC2_PCLK, &msm_device_sdc2.dev, OFF), - CLOCK("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF), - CLOCK("sdc_pclk", SDC3_PCLK, &msm_device_sdc3.dev, OFF), - CLOCK("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF), - CLOCK("sdc_pclk", SDC4_PCLK, &msm_device_sdc4.dev, OFF), - CLOCK("tsif_clk", TSIF_CLK, NULL, 0), - CLOCK("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), - CLOCK("tv_dac_clk", TV_DAC_CLK, NULL, 0), - CLOCK("tv_enc_clk", TV_ENC_CLK, NULL, 0), - CLOCK("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF), - CLOCK("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0), - CLOCK("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), - CLOCK("uart1dm_clk", UART1DM_CLK, NULL, OFF), - CLOCK("uart2dm_clk", UART2DM_CLK, NULL, 0), - CLOCK("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF), - CLOCK("usb_hs_pclk", USB_HS_PCLK, &msm_device_hsusb.dev, OFF), - CLOCK("usb_otg_clk", USB_OTG_CLK, NULL, 0), - CLOCK("vdc_clk", VDC_CLK, NULL, OFF | MINMAX), - CLOCK("vfe_clk", VFE_CLK, NULL, OFF), - CLOCK("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), -}; - -unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks); diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c new file mode 100644 index 000000000000..a3b45627eb4a --- /dev/null +++ b/arch/arm/mach-msm/clock-pcom.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include + +#include "proc_comm.h" +#include "clock.h" + +/* + * glue for the proc_comm interface + */ +int pc_clk_enable(unsigned id) +{ + int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL); + if (rc < 0) + return rc; + else + return (int)id < 0 ? -EINVAL : 0; +} + +void pc_clk_disable(unsigned id) +{ + msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL); +} + +int pc_clk_reset(unsigned id, enum clk_reset_action action) +{ + int rc; + + if (action == CLK_RESET_ASSERT) + rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL); + else + rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_DEASSERT, &id, NULL); + + if (rc < 0) + return rc; + else + return (int)id < 0 ? -EINVAL : 0; +} + +int pc_clk_set_rate(unsigned id, unsigned rate) +{ + /* The rate _might_ be rounded off to the nearest KHz value by the + * remote function. So a return value of 0 doesn't necessarily mean + * that the exact rate was set successfully. + */ + int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate); + if (rc < 0) + return rc; + else + return (int)id < 0 ? -EINVAL : 0; +} + +int pc_clk_set_min_rate(unsigned id, unsigned rate) +{ + int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate); + if (rc < 0) + return rc; + else + return (int)id < 0 ? -EINVAL : 0; +} + +int pc_clk_set_max_rate(unsigned id, unsigned rate) +{ + int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate); + if (rc < 0) + return rc; + else + return (int)id < 0 ? -EINVAL : 0; +} + +int pc_clk_set_flags(unsigned id, unsigned flags) +{ + int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags); + if (rc < 0) + return rc; + else + return (int)id < 0 ? -EINVAL : 0; +} + +unsigned pc_clk_get_rate(unsigned id) +{ + if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL)) + return 0; + else + return id; +} + +unsigned pc_clk_is_enabled(unsigned id) +{ + if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL)) + return 0; + else + return id; +} + +long pc_clk_round_rate(unsigned id, unsigned rate) +{ + + /* Not really supported; pc_clk_set_rate() does rounding on it's own. */ + return rate; +} + +struct clk_ops clk_ops_pcom = { + .enable = pc_clk_enable, + .disable = pc_clk_disable, + .auto_off = pc_clk_disable, + .reset = pc_clk_reset, + .set_rate = pc_clk_set_rate, + .set_min_rate = pc_clk_set_min_rate, + .set_max_rate = pc_clk_set_max_rate, + .set_flags = pc_clk_set_flags, + .get_rate = pc_clk_get_rate, + .is_enabled = pc_clk_is_enabled, + .round_rate = pc_clk_round_rate, +}; diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h new file mode 100644 index 000000000000..17d027b23501 --- /dev/null +++ b/arch/arm/mach-msm/clock-pcom.h @@ -0,0 +1,153 @@ +/* Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H +#define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H + +/* clock IDs used by the modem processor */ + +#define P_ACPU_CLK 0 /* Applications processor clock */ +#define P_ADM_CLK 1 /* Applications data mover clock */ +#define P_ADSP_CLK 2 /* ADSP clock */ +#define P_EBI1_CLK 3 /* External bus interface 1 clock */ +#define P_EBI2_CLK 4 /* External bus interface 2 clock */ +#define P_ECODEC_CLK 5 /* External CODEC clock */ +#define P_EMDH_CLK 6 /* External MDDI host clock */ +#define P_GP_CLK 7 /* General purpose clock */ +#define P_GRP_3D_CLK 8 /* Graphics clock */ +#define P_I2C_CLK 9 /* I2C clock */ +#define P_ICODEC_RX_CLK 10 /* Internal CODEX RX clock */ +#define P_ICODEC_TX_CLK 11 /* Internal CODEX TX clock */ +#define P_IMEM_CLK 12 /* Internal graphics memory clock */ +#define P_MDC_CLK 13 /* MDDI client clock */ +#define P_MDP_CLK 14 /* Mobile display processor clock */ +#define P_PBUS_CLK 15 /* Peripheral bus clock */ +#define P_PCM_CLK 16 /* PCM clock */ +#define P_PMDH_CLK 17 /* Primary MDDI host clock */ +#define P_SDAC_CLK 18 /* Stereo DAC clock */ +#define P_SDC1_CLK 19 /* Secure Digital Card clocks */ +#define P_SDC1_P_CLK 20 +#define P_SDC2_CLK 21 +#define P_SDC2_P_CLK 22 +#define P_SDC3_CLK 23 +#define P_SDC3_P_CLK 24 +#define P_SDC4_CLK 25 +#define P_SDC4_P_CLK 26 +#define P_TSIF_CLK 27 /* Transport Stream Interface clocks */ +#define P_TSIF_REF_CLK 28 +#define P_TV_DAC_CLK 29 /* TV clocks */ +#define P_TV_ENC_CLK 30 +#define P_UART1_CLK 31 /* UART clocks */ +#define P_UART2_CLK 32 +#define P_UART3_CLK 33 +#define P_UART1DM_CLK 34 +#define P_UART2DM_CLK 35 +#define P_USB_HS_CLK 36 /* High speed USB core clock */ +#define P_USB_HS_P_CLK 37 /* High speed USB pbus clock */ +#define P_USB_OTG_CLK 38 /* Full speed USB clock */ +#define P_VDC_CLK 39 /* Video controller clock */ +#define P_VFE_MDC_CLK 40 /* Camera / Video Front End clock */ +#define P_VFE_CLK 41 /* VFE MDDI client clock */ +#define P_MDP_LCDC_PCLK_CLK 42 +#define P_MDP_LCDC_PAD_PCLK_CLK 43 +#define P_MDP_VSYNC_CLK 44 +#define P_SPI_CLK 45 +#define P_VFE_AXI_CLK 46 +#define P_USB_HS2_CLK 47 /* High speed USB 2 core clock */ +#define P_USB_HS2_P_CLK 48 /* High speed USB 2 pbus clock */ +#define P_USB_HS3_CLK 49 /* High speed USB 3 core clock */ +#define P_USB_HS3_P_CLK 50 /* High speed USB 3 pbus clock */ +#define P_GRP_3D_P_CLK 51 /* Graphics pbus clock */ +#define P_USB_PHY_CLK 52 /* USB PHY clock */ +#define P_USB_HS_CORE_CLK 53 /* High speed USB 1 core clock */ +#define P_USB_HS2_CORE_CLK 54 /* High speed USB 2 core clock */ +#define P_USB_HS3_CORE_CLK 55 /* High speed USB 3 core clock */ +#define P_CAM_M_CLK 56 +#define P_CAMIF_PAD_P_CLK 57 +#define P_GRP_2D_CLK 58 +#define P_GRP_2D_P_CLK 59 +#define P_I2S_CLK 60 +#define P_JPEG_CLK 61 +#define P_JPEG_P_CLK 62 +#define P_LPA_CODEC_CLK 63 +#define P_LPA_CORE_CLK 64 +#define P_LPA_P_CLK 65 +#define P_MDC_IO_CLK 66 +#define P_MDC_P_CLK 67 +#define P_MFC_CLK 68 +#define P_MFC_DIV2_CLK 69 +#define P_MFC_P_CLK 70 +#define P_QUP_I2C_CLK 71 +#define P_ROTATOR_IMEM_CLK 72 +#define P_ROTATOR_P_CLK 73 +#define P_VFE_CAMIF_CLK 74 +#define P_VFE_P_CLK 75 +#define P_VPE_CLK 76 +#define P_I2C_2_CLK 77 +#define P_MI2S_CODEC_RX_S_CLK 78 +#define P_MI2S_CODEC_RX_M_CLK 79 +#define P_MI2S_CODEC_TX_S_CLK 80 +#define P_MI2S_CODEC_TX_M_CLK 81 +#define P_PMDH_P_CLK 82 +#define P_EMDH_P_CLK 83 +#define P_SPI_P_CLK 84 +#define P_TSIF_P_CLK 85 +#define P_MDP_P_CLK 86 +#define P_SDAC_M_CLK 87 +#define P_MI2S_S_CLK 88 +#define P_MI2S_M_CLK 89 +#define P_AXI_ROTATOR_CLK 90 +#define P_HDMI_CLK 91 +#define P_CSI0_CLK 92 +#define P_CSI0_VFE_CLK 93 +#define P_CSI0_P_CLK 94 +#define P_CSI1_CLK 95 +#define P_CSI1_VFE_CLK 96 +#define P_CSI1_P_CLK 97 +#define P_GSBI_CLK 98 +#define P_GSBI_P_CLK 99 + +#define P_NR_CLKS 100 + +struct clk_ops; +extern struct clk_ops clk_ops_pcom; + +int pc_clk_reset(unsigned id, enum clk_reset_action action); + +#define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) { \ + .name = clk_name, \ + .id = P_##clk_id, \ + .remote_id = P_##clk_id, \ + .ops = &clk_ops_pcom, \ + .flags = clk_flags, \ + .dev = clk_dev, \ + .dbg_name = #clk_id, \ + } + +#endif diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c index 3b1ce36f1032..34c6a52af060 100644 --- a/arch/arm/mach-msm/clock.c +++ b/arch/arm/mach-msm/clock.c @@ -1,7 +1,7 @@ /* arch/arm/mach-msm/clock.c * * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2007 QUALCOMM Incorporated + * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -22,6 +22,10 @@ #include #include #include +#include +#include +#include +#include #include "clock.h" #include "proc_comm.h" @@ -29,61 +33,15 @@ static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clocks_lock); static LIST_HEAD(clocks); +struct clk *msm_clocks; +unsigned msm_num_clocks; /* - * glue for the proc_comm interface + * Bitmap of enabled clocks, excluding ACPU which is always + * enabled */ -static inline int pc_clk_enable(unsigned id) -{ - return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL); -} - -static inline void pc_clk_disable(unsigned id) -{ - msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL); -} - -static inline int pc_clk_set_rate(unsigned id, unsigned rate) -{ - return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate); -} - -static inline int pc_clk_set_min_rate(unsigned id, unsigned rate) -{ - return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate); -} - -static inline int pc_clk_set_max_rate(unsigned id, unsigned rate) -{ - return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate); -} - -static inline int pc_clk_set_flags(unsigned id, unsigned flags) -{ - return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags); -} - -static inline unsigned pc_clk_get_rate(unsigned id) -{ - if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL)) - return 0; - else - return id; -} - -static inline unsigned pc_clk_is_enabled(unsigned id) -{ - if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL)) - return 0; - else - return id; -} - -static inline int pc_pll_request(unsigned id, unsigned on) -{ - on = !!on; - return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on); -} +static DECLARE_BITMAP(clock_map_enabled, NR_CLKS); +static DEFINE_SPINLOCK(clock_map_lock); /* * Standard clock functions defined in include/linux/clk.h @@ -119,8 +77,12 @@ int clk_enable(struct clk *clk) unsigned long flags; spin_lock_irqsave(&clocks_lock, flags); clk->count++; - if (clk->count == 1) - pc_clk_enable(clk->id); + if (clk->count == 1) { + clk->ops->enable(clk->id); + spin_lock(&clock_map_lock); + clock_map_enabled[BIT_WORD(clk->id)] |= BIT_MASK(clk->id); + spin_unlock(&clock_map_lock); + } spin_unlock_irqrestore(&clocks_lock, flags); return 0; } @@ -132,31 +94,54 @@ void clk_disable(struct clk *clk) spin_lock_irqsave(&clocks_lock, flags); BUG_ON(clk->count == 0); clk->count--; - if (clk->count == 0) - pc_clk_disable(clk->id); + if (clk->count == 0) { + clk->ops->disable(clk->id); + spin_lock(&clock_map_lock); + clock_map_enabled[BIT_WORD(clk->id)] &= ~BIT_MASK(clk->id); + spin_unlock(&clock_map_lock); + } spin_unlock_irqrestore(&clocks_lock, flags); } EXPORT_SYMBOL(clk_disable); +int clk_reset(struct clk *clk, enum clk_reset_action action) +{ + if (!clk->ops->reset) + clk->ops->reset = &pc_clk_reset; + return clk->ops->reset(clk->remote_id, action); +} +EXPORT_SYMBOL(clk_reset); + unsigned long clk_get_rate(struct clk *clk) { - return pc_clk_get_rate(clk->id); + return clk->ops->get_rate(clk->id); } EXPORT_SYMBOL(clk_get_rate); int clk_set_rate(struct clk *clk, unsigned long rate) { - int ret; - if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) { - ret = pc_clk_set_max_rate(clk->id, rate); - if (ret) - return ret; - return pc_clk_set_min_rate(clk->id, rate); - } - return pc_clk_set_rate(clk->id, rate); + return clk->ops->set_rate(clk->id, rate); } EXPORT_SYMBOL(clk_set_rate); +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return clk->ops->round_rate(clk->id, rate); +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_min_rate(struct clk *clk, unsigned long rate) +{ + return clk->ops->set_min_rate(clk->id, rate); +} +EXPORT_SYMBOL(clk_set_min_rate); + +int clk_set_max_rate(struct clk *clk, unsigned long rate) +{ + return clk->ops->set_max_rate(clk->id, rate); +} +EXPORT_SYMBOL(clk_set_max_rate); + int clk_set_parent(struct clk *clk, struct clk *parent) { return -ENOSYS; @@ -173,22 +158,153 @@ int clk_set_flags(struct clk *clk, unsigned long flags) { if (clk == NULL || IS_ERR(clk)) return -EINVAL; - return pc_clk_set_flags(clk->id, flags); + return clk->ops->set_flags(clk->id, flags); } EXPORT_SYMBOL(clk_set_flags); +/* EBI1 is the only shared clock that several clients want to vote on as of + * this commit. If this changes in the future, then it might be better to + * make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more + * generic to support different clocks. + */ +static struct clk *ebi1_clk; -void __init msm_clock_init(void) +static void __init set_clock_ops(struct clk *clk) +{ + if (!clk->ops) { + clk->ops = &clk_ops_pcom; + clk->id = clk->remote_id; + } +} + +void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks) { unsigned n; spin_lock_init(&clocks_lock); mutex_lock(&clocks_mutex); - for (n = 0; n < msm_num_clocks; n++) + msm_clocks = clock_tbl; + msm_num_clocks = num_clocks; + for (n = 0; n < msm_num_clocks; n++) { + set_clock_ops(&msm_clocks[n]); list_add_tail(&msm_clocks[n].list, &clocks); + } mutex_unlock(&clocks_mutex); + + ebi1_clk = clk_get(NULL, "ebi1_clk"); + BUG_ON(ebi1_clk == NULL); + +} + +#if defined(CONFIG_DEBUG_FS) +static struct clk *msm_clock_get_nth(unsigned index) +{ + if (index < msm_num_clocks) + return msm_clocks + index; + else + return 0; +} + +static int clock_debug_rate_set(void *data, u64 val) +{ + struct clk *clock = data; + int ret; + + /* Only increases to max rate will succeed, but that's actually good + * for debugging purposes. So we don't check for error. */ + if (clock->flags & CLK_MAX) + clk_set_max_rate(clock, val); + if (clock->flags & CLK_MIN) + ret = clk_set_min_rate(clock, val); + else + ret = clk_set_rate(clock, val); + if (ret != 0) + printk(KERN_ERR "clk_set%s_rate failed (%d)\n", + (clock->flags & CLK_MIN) ? "_min" : "", ret); + return ret; +} + +static int clock_debug_rate_get(void *data, u64 *val) +{ + struct clk *clock = data; + *val = clk_get_rate(clock); + return 0; +} + +static int clock_debug_enable_set(void *data, u64 val) +{ + struct clk *clock = data; + int rc = 0; + + if (val) + rc = clock->ops->enable(clock->id); + else + clock->ops->disable(clock->id); + + return rc; } +static int clock_debug_enable_get(void *data, u64 *val) +{ + struct clk *clock = data; + + *val = clock->ops->is_enabled(clock->id); + + return 0; +} + +static int clock_debug_local_get(void *data, u64 *val) +{ + struct clk *clock = data; + + *val = clock->ops != &clk_ops_pcom; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get, + clock_debug_rate_set, "%llu\n"); +DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get, + clock_debug_enable_set, "%llu\n"); +DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get, + NULL, "%llu\n"); + +static int __init clock_debug_init(void) +{ + struct dentry *dent_rate, *dent_enable, *dent_local; + struct clk *clock; + unsigned n = 0; + char temp[50], *ptr; + + dent_rate = debugfs_create_dir("clk_rate", 0); + if (IS_ERR(dent_rate)) + return PTR_ERR(dent_rate); + + dent_enable = debugfs_create_dir("clk_enable", 0); + if (IS_ERR(dent_enable)) + return PTR_ERR(dent_enable); + + dent_local = debugfs_create_dir("clk_local", NULL); + if (IS_ERR(dent_local)) + return PTR_ERR(dent_local); + + while ((clock = msm_clock_get_nth(n++)) != 0) { + strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1); + for (ptr = temp; *ptr; ptr++) + *ptr = tolower(*ptr); + debugfs_create_file(temp, 0644, dent_rate, + clock, &clock_rate_fops); + debugfs_create_file(temp, 0644, dent_enable, + clock, &clock_enable_fops); + debugfs_create_file(temp, S_IRUGO, dent_local, + clock, &clock_local_fops); + } + return 0; +} + +device_initcall(clock_debug_init); +#endif + /* The bootloader and/or AMSS may have left various clocks enabled. * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have * not been explicitly enabled by a clk_enable() call. @@ -205,7 +321,7 @@ static int __init clock_late_init(void) spin_lock_irqsave(&clocks_lock, flags); if (!clk->count) { count++; - pc_clk_disable(clk->id); + clk->ops->auto_off(clk->id); } spin_unlock_irqrestore(&clocks_lock, flags); } @@ -216,3 +332,4 @@ static int __init clock_late_init(void) } late_initcall(clock_late_init); + diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h index f875e1544e5f..598db9290422 100644 --- a/arch/arm/mach-msm/clock.h +++ b/arch/arm/mach-msm/clock.h @@ -1,7 +1,7 @@ /* arch/arm/mach-msm/clock.h * * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2007 QUALCOMM Incorporated + * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -18,6 +18,9 @@ #define __ARCH_ARM_MACH_MSM_CLOCK_H #include +#include + +#include "clock-pcom.h" #define CLKFLAG_INVERT 0x00000001 #define CLKFLAG_NOINVERT 0x00000002 @@ -25,14 +28,32 @@ #define CLKFLAG_NORESET 0x00000008 #define CLK_FIRST_AVAILABLE_FLAG 0x00000100 -#define CLKFLAG_USE_MIN_MAX_TO_SET 0x00000200 -#define CLKFLAG_AUTO_OFF 0x00000400 +#define CLKFLAG_AUTO_OFF 0x00000200 +#define CLKFLAG_MIN 0x00000400 +#define CLKFLAG_MAX 0x00000800 + +struct clk_ops { + int (*enable)(unsigned id); + void (*disable)(unsigned id); + void (*auto_off)(unsigned id); + int (*reset)(unsigned id, enum clk_reset_action action); + int (*set_rate)(unsigned id, unsigned rate); + int (*set_min_rate)(unsigned id, unsigned rate); + int (*set_max_rate)(unsigned id, unsigned rate); + int (*set_flags)(unsigned id, unsigned flags); + unsigned (*get_rate)(unsigned id); + unsigned (*is_enabled)(unsigned id); + long (*round_rate)(unsigned id, unsigned rate); +}; struct clk { uint32_t id; + uint32_t remote_id; uint32_t count; uint32_t flags; const char *name; + struct clk_ops *ops; + const char *dbg_name; struct list_head list; struct device *dev; }; @@ -41,8 +62,47 @@ struct clk { #define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) #define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) -extern struct clk msm_clocks[]; -extern unsigned msm_num_clocks; +#ifdef CONFIG_DEBUG_FS +#define CLOCK_DBG_NAME(x) .dbg_name = x, +#else +#define CLOCK_DBG_NAME(x) +#endif + +#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \ + .name = clk_name, \ + .id = clk_id, \ + .flags = clk_flags, \ + .dev = clk_dev, \ + CLOCK_DBG_NAME(#clk_id) \ + } + +#define OFF CLKFLAG_AUTO_OFF +#define CLK_MIN CLKFLAG_MIN +#define CLK_MAX CLKFLAG_MAX +#define CLK_MINMAX (CLK_MIN | CLK_MAX) +#define NR_CLKS P_NR_CLKS + +enum { + PLL_0 = 0, + PLL_1, + PLL_2, + PLL_3, + PLL_4, + PLL_5, + PLL_6, + NUM_PLL +}; + +enum clkvote_client { + CLKVOTE_ACPUCLK = 0, + CLKVOTE_PMQOS, + CLKVOTE_MAX, +}; + +int msm_clock_require_tcxo(unsigned long *reason, int nbits); +int msm_clock_get_name(uint32_t id, char *name, uint32_t size); +int ebi1_clk_set_min_rate(enum clkvote_client client, unsigned long rate); +unsigned long clk_get_max_axi_khz(void); #endif diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c index 982f1da60160..fde9d8f69f10 100644 --- a/arch/arm/mach-msm/devices-msm7x00.c +++ b/arch/arm/mach-msm/devices-msm7x00.c @@ -24,6 +24,8 @@ #include #include + +#include "clock.h" #include static struct resource resources_uart1[] = { @@ -344,3 +346,48 @@ int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat, return platform_device_register(pdev); } +struct clk msm_clocks_7x01a[] = { + CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), + CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), + CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0), + CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0), + CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0), + CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF), + CLK_PCOM("gp_clk", GP_CLK, NULL, 0), + CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, OFF), + CLK_PCOM("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0), + CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0), + CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0), + CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF), + CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0), + CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), + CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0), + CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), + CLK_PCOM("pmdh_clk", PMDH_CLK, NULL, OFF ), + CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), + CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), + CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF), + CLK_PCOM("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF), + CLK_PCOM("sdc_pclk", SDC2_P_CLK, &msm_device_sdc2.dev, OFF), + CLK_PCOM("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF), + CLK_PCOM("sdc_pclk", SDC3_P_CLK, &msm_device_sdc3.dev, OFF), + CLK_PCOM("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF), + CLK_PCOM("sdc_pclk", SDC4_P_CLK, &msm_device_sdc4.dev, OFF), + CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0), + CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), + CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), + CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), + CLK_PCOM("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF), + CLK_PCOM("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0), + CLK_PCOM("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), + CLK_PCOM("uart1dm_clk", UART1DM_CLK, NULL, OFF), + CLK_PCOM("uart2dm_clk", UART2DM_CLK, NULL, 0), + CLK_PCOM("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF), + CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, &msm_device_hsusb.dev, OFF), + CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0), + CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF ), + CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF), + CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), +}; + +unsigned msm_num_clocks_7x01a = ARRAY_SIZE(msm_clocks_7x01a); diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h index 0744c4a27d6a..19c5de99e20c 100644 --- a/arch/arm/mach-msm/devices.h +++ b/arch/arm/mach-msm/devices.h @@ -16,6 +16,8 @@ #ifndef __ARCH_ARM_MACH_MSM_DEVICES_H #define __ARCH_ARM_MACH_MSM_DEVICES_H +#include "clock.h" + extern struct platform_device msm_device_uart1; extern struct platform_device msm_device_uart2; extern struct platform_device msm_device_uart3; @@ -33,4 +35,7 @@ extern struct platform_device msm_device_smd; extern struct platform_device msm_device_nand; +extern struct clk msm_clocks_7x01a[]; +extern unsigned msm_num_clocks_7x01a; + #endif diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h index 7933641c4761..e302fbdc439b 100644 --- a/arch/arm/mach-msm/include/mach/board.h +++ b/arch/arm/mach-msm/include/mach/board.h @@ -30,14 +30,15 @@ struct msm_acpu_clock_platform_data unsigned long wait_for_irq_khz; }; - +struct clk; + /* common init routines for use by arch/arm/mach-msm/board-*.c */ void __init msm_add_devices(void); void __init msm_map_common_io(void); void __init msm_init_irq(void); void __init msm_init_gpio(void); -void __init msm_clock_init(void); +void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks); void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *); #endif diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h new file mode 100644 index 000000000000..c05ca40478c7 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/clk.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef __MACH_CLK_H +#define __MACH_CLK_H + +/* Magic rate value for use with PM QOS to request the board's maximum + * supported AXI rate. PM QOS will only pass positive s32 rate values + * through to the clock driver, so INT_MAX is used. + */ +#define MSM_AXI_MAX_FREQ LONG_MAX + +enum clk_reset_action { + CLK_RESET_DEASSERT = 0, + CLK_RESET_ASSERT = 1 +}; + +struct clk; + +/* Rate is minimum clock rate in Hz */ +int clk_set_min_rate(struct clk *clk, unsigned long rate); + +/* Rate is maximum clock rate in Hz */ +int clk_set_max_rate(struct clk *clk, unsigned long rate); + +/* Assert/Deassert reset to a hardware block associated with a clock */ +int clk_reset(struct clk *clk, enum clk_reset_action action); + +/* Set clock-specific configuration parameters */ +int clk_set_flags(struct clk *clk, unsigned long flags); + +#endif -- cgit v1.2.3-59-g8ed1b From 1de238e0eb5181bdeb842d7ea8edebd52c2a9c3a Mon Sep 17 00:00:00 2001 From: Gregory Bean Date: Fri, 30 Apr 2010 22:15:16 -0700 Subject: msm: add tlmm support for gpio. GPIO support for Qualcomm SOCs requires interaction with the radio (baseband processor). This API allows the different boards to enable GPIO through the radio processor in a generic way. Signed-off-by: Gregory Bean Signed-off-by: David Brown Signed-off-by: Daniel Walker Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/gpio.c | 85 ++++++++++++++++++++ arch/arm/mach-msm/include/mach/gpio.h | 142 ++++++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 arch/arm/mach-msm/gpio.c create mode 100644 arch/arm/mach-msm/include/mach/gpio.h (limited to 'arch') diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c new file mode 100644 index 000000000000..bc32c845c7b0 --- /dev/null +++ b/arch/arm/mach-msm/gpio.c @@ -0,0 +1,85 @@ +/* linux/arch/arm/mach-msm/gpio.c + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include "proc_comm.h" + +int gpio_tlmm_config(unsigned config, unsigned disable) +{ + return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable); +} +EXPORT_SYMBOL(gpio_tlmm_config); + +int msm_gpios_enable(const struct msm_gpio *table, int size) +{ + int rc; + int i; + const struct msm_gpio *g; + for (i = 0; i < size; i++) { + g = table + i; + rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE); + if (rc) { + pr_err("gpio_tlmm_config(0x%08x, GPIO_ENABLE)" + " <%s> failed: %d\n", + g->gpio_cfg, g->label ?: "?", rc); + pr_err("pin %d func %d dir %d pull %d drvstr %d\n", + GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg), + GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg), + GPIO_DRVSTR(g->gpio_cfg)); + goto err; + } + } + return 0; +err: + msm_gpios_disable(table, i); + return rc; +} +EXPORT_SYMBOL(msm_gpios_enable); + +void msm_gpios_disable(const struct msm_gpio *table, int size) +{ + int rc; + int i; + const struct msm_gpio *g; + for (i = size-1; i >= 0; i--) { + g = table + i; + rc = gpio_tlmm_config(g->gpio_cfg, GPIO_DISABLE); + if (rc) { + pr_err("gpio_tlmm_config(0x%08x, GPIO_DISABLE)" + " <%s> failed: %d\n", + g->gpio_cfg, g->label ?: "?", rc); + pr_err("pin %d func %d dir %d pull %d drvstr %d\n", + GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg), + GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg), + GPIO_DRVSTR(g->gpio_cfg)); + } + } +} +EXPORT_SYMBOL(msm_gpios_disable); + +int msm_gpios_request_enable(const struct msm_gpio *table, int size) +{ + int rc = msm_gpios_enable(table, size); + return rc; +} +EXPORT_SYMBOL(msm_gpios_request_enable); + +void msm_gpios_disable_free(const struct msm_gpio *table, int size) +{ + msm_gpios_disable(table, size); +} +EXPORT_SYMBOL(msm_gpios_disable_free); diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h new file mode 100644 index 000000000000..262b441b4374 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/gpio.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. + * Author: Mike Lockwood + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ +#ifndef __ASM_ARCH_MSM_GPIO_H +#define __ASM_ARCH_MSM_GPIO_H + +/** + * struct msm_gpio - GPIO pin description + * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config() + * @label - textual label + * + * Usually, GPIO's are operated by sets. + * This struct accumulate all GPIO information in single source + * and facilitete group operations provided by msm_gpios_xxx() + */ +struct msm_gpio { + u32 gpio_cfg; + const char *label; +}; + +/** + * msm_gpios_request_enable() - request and enable set of GPIOs + * + * Request and configure set of GPIO's + * In case of error, all operations rolled back. + * Return error code. + * + * @table: GPIO table + * @size: number of entries in @table + */ +int msm_gpios_request_enable(const struct msm_gpio *table, int size); + +/** + * msm_gpios_disable_free() - disable and free set of GPIOs + * + * @table: GPIO table + * @size: number of entries in @table + */ +void msm_gpios_disable_free(const struct msm_gpio *table, int size); + +/** + * msm_gpios_request() - request set of GPIOs + * In case of error, all operations rolled back. + * Return error code. + * + * @table: GPIO table + * @size: number of entries in @table + */ +int msm_gpios_request(const struct msm_gpio *table, int size); + +/** + * msm_gpios_free() - free set of GPIOs + * + * @table: GPIO table + * @size: number of entries in @table + */ +void msm_gpios_free(const struct msm_gpio *table, int size); + +/** + * msm_gpios_enable() - enable set of GPIOs + * In case of error, all operations rolled back. + * Return error code. + * + * @table: GPIO table + * @size: number of entries in @table + */ +int msm_gpios_enable(const struct msm_gpio *table, int size); + +/** + * msm_gpios_disable() - disable set of GPIOs + * + * @table: GPIO table + * @size: number of entries in @table + */ +void msm_gpios_disable(const struct msm_gpio *table, int size); + +/* GPIO TLMM (Top Level Multiplexing) Definitions */ + +/* GPIO TLMM: Function -- GPIO specific */ + +/* GPIO TLMM: Direction */ +enum { + GPIO_INPUT, + GPIO_OUTPUT, +}; + +/* GPIO TLMM: Pullup/Pulldown */ +enum { + GPIO_NO_PULL, + GPIO_PULL_DOWN, + GPIO_KEEPER, + GPIO_PULL_UP, +}; + +/* GPIO TLMM: Drive Strength */ +enum { + GPIO_2MA, + GPIO_4MA, + GPIO_6MA, + GPIO_8MA, + GPIO_10MA, + GPIO_12MA, + GPIO_14MA, + GPIO_16MA, +}; + +enum { + GPIO_ENABLE, + GPIO_DISABLE, +}; + +#define GPIO_CFG(gpio, func, dir, pull, drvstr) \ + ((((gpio) & 0x3FF) << 4) | \ + ((func) & 0xf) | \ + (((dir) & 0x1) << 14) | \ + (((pull) & 0x3) << 15) | \ + (((drvstr) & 0xF) << 17)) + +/** + * extract GPIO pin from bit-field used for gpio_tlmm_config + */ +#define GPIO_PIN(gpio_cfg) (((gpio_cfg) >> 4) & 0x3ff) +#define GPIO_FUNC(gpio_cfg) (((gpio_cfg) >> 0) & 0xf) +#define GPIO_DIR(gpio_cfg) (((gpio_cfg) >> 14) & 0x1) +#define GPIO_PULL(gpio_cfg) (((gpio_cfg) >> 15) & 0x3) +#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf) + +int gpio_tlmm_config(unsigned config, unsigned disable); + +#endif /* __ASM_ARCH_MSM_GPIO_H */ -- cgit v1.2.3-59-g8ed1b From f9f3d3131879b0bb137084f4ca8ba67d2120b003 Mon Sep 17 00:00:00 2001 From: Gregory Bean Date: Fri, 30 Apr 2010 22:06:50 -0700 Subject: msm: add Qualcomm 7x30 interrupt controller driver. Signed-off-by: Gregory Bean Signed-off-by: David Brown Signed-off-by: Daniel Walker Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/Kconfig | 2 + arch/arm/mach-msm/Makefile | 8 +- arch/arm/mach-msm/irq-vic.c | 365 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 374 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-msm/irq-vic.c (limited to 'arch') diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 69cc693aa51e..b983d786177e 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -16,6 +16,8 @@ endchoice config ARCH_MSM_ARM11 bool +config MSM_VIC + bool comment "MSM Board Type" depends on ARCH_MSM diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 70fa9703f437..48a5fafd673b 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,9 +1,15 @@ -obj-y += io.o idle.o irq.o timer.o dma.o obj-y += proc_comm.o +obj-y += io.o idle.o timer.o dma.o obj-y += vreg.o obj-y += acpuclock-arm11.o obj-y += clock.o clock-pcom.o +ifdef CONFIG_MSM_VIC +obj-y += irq-vic.o +else +obj-y += irq.o +endif + obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o obj-$(CONFIG_MSM_SMD) += last_radio_log.o diff --git a/arch/arm/mach-msm/irq-vic.c b/arch/arm/mach-msm/irq-vic.c new file mode 100644 index 000000000000..99f2c3473033 --- /dev/null +++ b/arch/arm/mach-msm/irq-vic.c @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include "smd_private.h" + +enum { + IRQ_DEBUG_SLEEP_INT_TRIGGER = 1U << 0, + IRQ_DEBUG_SLEEP_INT = 1U << 1, + IRQ_DEBUG_SLEEP_ABORT = 1U << 2, + IRQ_DEBUG_SLEEP = 1U << 3, + IRQ_DEBUG_SLEEP_REQUEST = 1U << 4, +}; +static int msm_irq_debug_mask; +module_param_named(debug_mask, msm_irq_debug_mask, int, + S_IRUGO | S_IWUSR | S_IWGRP); + +#define VIC_REG(off) (MSM_VIC_BASE + (off)) +#define VIC_INT_TO_REG_ADDR(base, irq) (base + (irq / 32) * 4) +#define VIC_INT_TO_REG_INDEX(irq) ((irq >> 5) & 3) + +#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_SELECT2 VIC_REG(0x0008) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_SELECT3 VIC_REG(0x000C) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_EN0 VIC_REG(0x0010) +#define VIC_INT_EN1 VIC_REG(0x0014) +#define VIC_INT_EN2 VIC_REG(0x0018) +#define VIC_INT_EN3 VIC_REG(0x001C) +#define VIC_INT_ENCLEAR0 VIC_REG(0x0020) +#define VIC_INT_ENCLEAR1 VIC_REG(0x0024) +#define VIC_INT_ENCLEAR2 VIC_REG(0x0028) +#define VIC_INT_ENCLEAR3 VIC_REG(0x002C) +#define VIC_INT_ENSET0 VIC_REG(0x0030) +#define VIC_INT_ENSET1 VIC_REG(0x0034) +#define VIC_INT_ENSET2 VIC_REG(0x0038) +#define VIC_INT_ENSET3 VIC_REG(0x003C) +#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_TYPE2 VIC_REG(0x0048) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_TYPE3 VIC_REG(0x004C) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */ +#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */ +#define VIC_INT_POLARITY2 VIC_REG(0x0058) /* 1: NEG, 0: POS */ +#define VIC_INT_POLARITY3 VIC_REG(0x005C) /* 1: NEG, 0: POS */ +#define VIC_NO_PEND_VAL VIC_REG(0x0060) + +#if defined(CONFIG_ARCH_MSM_SCORPION) +#define VIC_NO_PEND_VAL_FIQ VIC_REG(0x0064) +#define VIC_INT_MASTEREN VIC_REG(0x0068) /* 1: IRQ, 2: FIQ */ +#define VIC_CONFIG VIC_REG(0x006C) /* 1: USE SC VIC */ +#else +#define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */ +#define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */ +#define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */ +#endif + +#define VIC_IRQ_STATUS0 VIC_REG(0x0080) +#define VIC_IRQ_STATUS1 VIC_REG(0x0084) +#define VIC_IRQ_STATUS2 VIC_REG(0x0088) +#define VIC_IRQ_STATUS3 VIC_REG(0x008C) +#define VIC_FIQ_STATUS0 VIC_REG(0x0090) +#define VIC_FIQ_STATUS1 VIC_REG(0x0094) +#define VIC_FIQ_STATUS2 VIC_REG(0x0098) +#define VIC_FIQ_STATUS3 VIC_REG(0x009C) +#define VIC_RAW_STATUS0 VIC_REG(0x00A0) +#define VIC_RAW_STATUS1 VIC_REG(0x00A4) +#define VIC_RAW_STATUS2 VIC_REG(0x00A8) +#define VIC_RAW_STATUS3 VIC_REG(0x00AC) +#define VIC_INT_CLEAR0 VIC_REG(0x00B0) +#define VIC_INT_CLEAR1 VIC_REG(0x00B4) +#define VIC_INT_CLEAR2 VIC_REG(0x00B8) +#define VIC_INT_CLEAR3 VIC_REG(0x00BC) +#define VIC_SOFTINT0 VIC_REG(0x00C0) +#define VIC_SOFTINT1 VIC_REG(0x00C4) +#define VIC_SOFTINT2 VIC_REG(0x00C8) +#define VIC_SOFTINT3 VIC_REG(0x00CC) +#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */ +#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */ +#define VIC_IRQ_VEC_WR VIC_REG(0x00D8) + +#if defined(CONFIG_ARCH_MSM_SCORPION) +#define VIC_FIQ_VEC_RD VIC_REG(0x00DC) +#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0) +#define VIC_FIQ_VEC_WR VIC_REG(0x00E4) +#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E8) +#define VIC_IRQ_IN_STACK VIC_REG(0x00EC) +#define VIC_FIQ_IN_SERVICE VIC_REG(0x00F0) +#define VIC_FIQ_IN_STACK VIC_REG(0x00F4) +#define VIC_TEST_BUS_SEL VIC_REG(0x00F8) +#define VIC_IRQ_CTRL_CONFIG VIC_REG(0x00FC) +#else +#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0) +#define VIC_IRQ_IN_STACK VIC_REG(0x00E4) +#define VIC_TEST_BUS_SEL VIC_REG(0x00E8) +#endif + +#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4)) +#define VIC_VECTADDR(n) VIC_REG(0x0400+((n) * 4)) + +#if defined(CONFIG_ARCH_MSM7X30) +#define VIC_NUM_REGS 4 +#else +#define VIC_NUM_REGS 2 +#endif + +#if VIC_NUM_REGS == 2 +#define DPRINT_REGS(base_reg, format, ...) \ + printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__, \ + readl(base_reg ## 0), readl(base_reg ## 1)) +#define DPRINT_ARRAY(array, format, ...) \ + printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__, \ + array[0], array[1]) +#elif VIC_NUM_REGS == 4 +#define DPRINT_REGS(base_reg, format, ...) \ + printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__, \ + readl(base_reg ## 0), readl(base_reg ## 1), \ + readl(base_reg ## 2), readl(base_reg ## 3)) +#define DPRINT_ARRAY(array, format, ...) \ + printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__, \ + array[0], array[1], \ + array[2], array[3]) +#else +#error "VIC_NUM_REGS set to illegal value" +#endif + +static uint32_t msm_irq_smsm_wake_enable[2]; +static struct { + uint32_t int_en[2]; + uint32_t int_type; + uint32_t int_polarity; + uint32_t int_select; +} msm_irq_shadow_reg[VIC_NUM_REGS]; +static uint32_t msm_irq_idle_disable[VIC_NUM_REGS]; + +#define SMSM_FAKE_IRQ (0xff) +static uint8_t msm_irq_to_smsm[NR_IRQS] = { + [INT_MDDI_EXT] = 1, + [INT_MDDI_PRI] = 2, + [INT_MDDI_CLIENT] = 3, + [INT_USB_OTG] = 4, + + [INT_PWB_I2C] = 5, + [INT_SDC1_0] = 6, + [INT_SDC1_1] = 7, + [INT_SDC2_0] = 8, + + [INT_SDC2_1] = 9, + [INT_ADSP_A9_A11] = 10, + [INT_UART1] = 11, + [INT_UART2] = 12, + + [INT_UART3] = 13, + [INT_UART1_RX] = 14, + [INT_UART2_RX] = 15, + [INT_UART3_RX] = 16, + + [INT_UART1DM_IRQ] = 17, + [INT_UART1DM_RX] = 18, + [INT_KEYSENSE] = 19, +#if !defined(CONFIG_ARCH_MSM7X30) + [INT_AD_HSSD] = 20, +#endif + + [INT_NAND_WR_ER_DONE] = 21, + [INT_NAND_OP_DONE] = 22, + [INT_TCHSCRN1] = 23, + [INT_TCHSCRN2] = 24, + + [INT_TCHSCRN_SSBI] = 25, + [INT_USB_HS] = 26, + [INT_UART2DM_RX] = 27, + [INT_UART2DM_IRQ] = 28, + + [INT_SDC4_1] = 29, + [INT_SDC4_0] = 30, + [INT_SDC3_1] = 31, + [INT_SDC3_0] = 32, + + /* fake wakeup interrupts */ + [INT_GPIO_GROUP1] = SMSM_FAKE_IRQ, + [INT_GPIO_GROUP2] = SMSM_FAKE_IRQ, + [INT_A9_M2A_0] = SMSM_FAKE_IRQ, + [INT_A9_M2A_1] = SMSM_FAKE_IRQ, + [INT_A9_M2A_5] = SMSM_FAKE_IRQ, + [INT_GP_TIMER_EXP] = SMSM_FAKE_IRQ, + [INT_DEBUG_TIMER_EXP] = SMSM_FAKE_IRQ, + [INT_ADSP_A11] = SMSM_FAKE_IRQ, +#ifdef CONFIG_ARCH_QSD8X50 + [INT_SIRC_0] = SMSM_FAKE_IRQ, + [INT_SIRC_1] = SMSM_FAKE_IRQ, +#endif +}; + +static inline void msm_irq_write_all_regs(void __iomem *base, unsigned int val) +{ + int i; + + for (i = 0; i < VIC_NUM_REGS; i++) + writel(val, base + (i * 4)); +} + +static void msm_irq_ack(unsigned int irq) +{ + void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_CLEAR0, irq); + irq = 1 << (irq & 31); + writel(irq, reg); +} + +static void msm_irq_mask(unsigned int irq) +{ + void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENCLEAR0, irq); + unsigned index = VIC_INT_TO_REG_INDEX(irq); + uint32_t mask = 1UL << (irq & 31); + int smsm_irq = msm_irq_to_smsm[irq]; + + msm_irq_shadow_reg[index].int_en[0] &= ~mask; + writel(mask, reg); + if (smsm_irq == 0) + msm_irq_idle_disable[index] &= ~mask; + else { + mask = 1UL << (smsm_irq - 1); + msm_irq_smsm_wake_enable[0] &= ~mask; + } +} + +static void msm_irq_unmask(unsigned int irq) +{ + void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENSET0, irq); + unsigned index = VIC_INT_TO_REG_INDEX(irq); + uint32_t mask = 1UL << (irq & 31); + int smsm_irq = msm_irq_to_smsm[irq]; + + msm_irq_shadow_reg[index].int_en[0] |= mask; + writel(mask, reg); + + if (smsm_irq == 0) + msm_irq_idle_disable[index] |= mask; + else { + mask = 1UL << (smsm_irq - 1); + msm_irq_smsm_wake_enable[0] |= mask; + } +} + +static int msm_irq_set_wake(unsigned int irq, unsigned int on) +{ + unsigned index = VIC_INT_TO_REG_INDEX(irq); + uint32_t mask = 1UL << (irq & 31); + int smsm_irq = msm_irq_to_smsm[irq]; + + if (smsm_irq == 0) { + printk(KERN_ERR "msm_irq_set_wake: bad wakeup irq %d\n", irq); + return -EINVAL; + } + if (on) + msm_irq_shadow_reg[index].int_en[1] |= mask; + else + msm_irq_shadow_reg[index].int_en[1] &= ~mask; + + if (smsm_irq == SMSM_FAKE_IRQ) + return 0; + + mask = 1UL << (smsm_irq - 1); + if (on) + msm_irq_smsm_wake_enable[1] |= mask; + else + msm_irq_smsm_wake_enable[1] &= ~mask; + return 0; +} + +static int msm_irq_set_type(unsigned int irq, unsigned int flow_type) +{ + void __iomem *treg = VIC_INT_TO_REG_ADDR(VIC_INT_TYPE0, irq); + void __iomem *preg = VIC_INT_TO_REG_ADDR(VIC_INT_POLARITY0, irq); + unsigned index = VIC_INT_TO_REG_INDEX(irq); + int b = 1 << (irq & 31); + uint32_t polarity; + uint32_t type; + + polarity = msm_irq_shadow_reg[index].int_polarity; + if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW)) + polarity |= b; + if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) + polarity &= ~b; + writel(polarity, preg); + msm_irq_shadow_reg[index].int_polarity = polarity; + + type = msm_irq_shadow_reg[index].int_type; + if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { + type |= b; + irq_desc[irq].handle_irq = handle_edge_irq; + } + if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { + type &= ~b; + irq_desc[irq].handle_irq = handle_level_irq; + } + writel(type, treg); + msm_irq_shadow_reg[index].int_type = type; + return 0; +} + +static struct irq_chip msm_irq_chip = { + .name = "msm", + .disable = msm_irq_mask, + .ack = msm_irq_ack, + .mask = msm_irq_mask, + .unmask = msm_irq_unmask, + .set_wake = msm_irq_set_wake, + .set_type = msm_irq_set_type, +}; + +void __init msm_init_irq(void) +{ + unsigned n; + + /* select level interrupts */ + msm_irq_write_all_regs(VIC_INT_TYPE0, 0); + + /* select highlevel interrupts */ + msm_irq_write_all_regs(VIC_INT_POLARITY0, 0); + + /* select IRQ for all INTs */ + msm_irq_write_all_regs(VIC_INT_SELECT0, 0); + + /* disable all INTs */ + msm_irq_write_all_regs(VIC_INT_EN0, 0); + + /* don't use vic */ + writel(0, VIC_CONFIG); + + /* enable interrupt controller */ + writel(3, VIC_INT_MASTEREN); + + for (n = 0; n < NR_MSM_IRQS; n++) { + set_irq_chip(n, &msm_irq_chip); + set_irq_handler(n, handle_level_irq); + set_irq_flags(n, IRQF_VALID); + } +} -- cgit v1.2.3-59-g8ed1b From 83a2c0e4bd9065cbd7a179abfaace2f55b742302 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 13 May 2010 15:39:52 -0700 Subject: msm: timer: allow MSM_DGT_BASE to be overriden Some SoC need to redefine MSM_DGT_BASE from it's default. This allows it to be defined in a header to override the default value. Signed-off-by: Daniel Walker --- arch/arm/mach-msm/timer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 4855b8ca5101..dec5ca622d7d 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -25,7 +25,9 @@ #include #include +#ifndef MSM_DGT_BASE #define MSM_DGT_BASE (MSM_GPT_BASE + 0x10) +#endif #define MSM_DGT_SHIFT (5) #define TIMER_MATCH_VAL 0x0000 -- cgit v1.2.3-59-g8ed1b From e502c3777fb97453fb95c1479cac20ef58f53709 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 5 May 2010 06:45:20 -0700 Subject: msm: irqs: add irqs-8x50.h for QSD8x50 support Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/irqs-8x50.h | 105 +++++++++++++++++++++++++++++ arch/arm/mach-msm/include/mach/irqs.h | 5 +- 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-msm/include/mach/irqs-8x50.h (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/irqs-8x50.h b/arch/arm/mach-msm/include/mach/irqs-8x50.h new file mode 100644 index 000000000000..de3d8fe24e4e --- /dev/null +++ b/arch/arm/mach-msm/include/mach/irqs-8x50.h @@ -0,0 +1,105 @@ +/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __ASM_ARCH_MSM_IRQS_8XXX_H +#define __ASM_ARCH_MSM_IRQS_8XXX_H + +/* MSM ACPU Interrupt Numbers */ + +#define INT_A9_M2A_0 0 +#define INT_A9_M2A_1 1 +#define INT_A9_M2A_2 2 +#define INT_A9_M2A_3 3 +#define INT_A9_M2A_4 4 +#define INT_A9_M2A_5 5 +#define INT_A9_M2A_6 6 +#define INT_GP_TIMER_EXP 7 +#define INT_DEBUG_TIMER_EXP 8 +#define INT_SIRC_0 9 +#define INT_SDC3_0 10 +#define INT_SDC3_1 11 +#define INT_SDC4_0 12 +#define INT_SDC4_1 13 +#define INT_AD6_EXT_VFR 14 +#define INT_USB_OTG 15 +#define INT_MDDI_PRI 16 +#define INT_MDDI_EXT 17 +#define INT_MDDI_CLIENT 18 +#define INT_MDP 19 +#define INT_GRAPHICS 20 +#define INT_ADM_AARM 21 +#define INT_ADSP_A11 22 +#define INT_ADSP_A9_A11 23 +#define INT_SDC1_0 24 +#define INT_SDC1_1 25 +#define INT_SDC2_0 26 +#define INT_SDC2_1 27 +#define INT_KEYSENSE 28 +#define INT_TCHSCRN_SSBI 29 +#define INT_TCHSCRN1 30 +#define INT_TCHSCRN2 31 + +#define INT_TCSR_MPRPH_SC1 (32 + 0) +#define INT_USB_FS2 (32 + 1) +#define INT_PWB_I2C (32 + 2) +#define INT_SOFTRESET (32 + 3) +#define INT_NAND_WR_ER_DONE (32 + 4) +#define INT_NAND_OP_DONE (32 + 5) +#define INT_TCSR_MPRPH_SC2 (32 + 6) +#define INT_OP_PEN (32 + 7) +#define INT_AD_HSSD (32 + 8) +#define INT_ARM11_PM (32 + 9) +#define INT_SDMA_NON_SECURE (32 + 10) +#define INT_TSIF_IRQ (32 + 11) +#define INT_UART1DM_IRQ (32 + 12) +#define INT_UART1DM_RX (32 + 13) +#define INT_SDMA_SECURE (32 + 14) +#define INT_SI2S_SLAVE (32 + 15) +#define INT_SC_I2CPU (32 + 16) +#define INT_SC_DBG_RDTRFULL (32 + 17) +#define INT_SC_DBG_WDTRFULL (32 + 18) +#define INT_SCPLL_CTL_DONE (32 + 19) +#define INT_UART2DM_IRQ (32 + 20) +#define INT_UART2DM_RX (32 + 21) +#define INT_VDC_MEC (32 + 22) +#define INT_VDC_DB (32 + 23) +#define INT_VDC_AXI (32 + 24) +#define INT_VFE (32 + 25) +#define INT_USB_HS (32 + 26) +#define INT_AUDIO_OUT0 (32 + 27) +#define INT_AUDIO_OUT1 (32 + 28) +#define INT_CRYPTO (32 + 29) +#define INT_AD6M_IDLE (32 + 30) +#define INT_SIRC_1 (32 + 31) + +#define NR_GPIO_IRQS 165 +#define NR_MSM_IRQS 64 +#define NR_BOARD_IRQS 64 + +#endif diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h index b8995607f74c..38a3528b664f 100644 --- a/arch/arm/mach-msm/include/mach/irqs.h +++ b/arch/arm/mach-msm/include/mach/irqs.h @@ -19,7 +19,10 @@ #define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) -#if defined(CONFIG_ARCH_MSM_ARM11) +#if defined(CONFIG_ARCH_QSD8X50) +#include "irqs-8x50.h" +#include "sirc.h" +#elif defined(CONFIG_ARCH_MSM_ARM11) #include "irqs-7x00.h" #else #error "Unknown architecture specification" -- cgit v1.2.3-59-g8ed1b From eb61bf85595f7ebb789ca71e590773ff3aa0c10f Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 5 May 2010 07:03:55 -0700 Subject: msm: add msm_iomap-8x50.h for QSD8x50 support Add a header describing the io regions for QSD8x50. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/msm_iomap-8x50.h | 147 ++++++++++++++++++++++++ arch/arm/mach-msm/include/mach/msm_iomap.h | 4 + 2 files changed, 151 insertions(+) create mode 100644 arch/arm/mach-msm/include/mach/msm_iomap-8x50.h (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h new file mode 100644 index 000000000000..acc819eb76e5 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + * + * The MSM peripherals are spread all over across 768MB of physical + * space, which makes just having a simple IO_ADDRESS macro to slide + * them into the right virtual location rough. Instead, we will + * provide a master phys->virt mapping for peripherals here. + * + */ + +#ifndef __ASM_ARCH_MSM_IOMAP_8X50_H +#define __ASM_ARCH_MSM_IOMAP_8X50_H + +/* Physical base address and size of peripherals. + * Ordered by the virtual base addresses they will be mapped at. + * + * MSM_VIC_BASE must be an value that can be loaded via a "mov" + * instruction, otherwise entry-macro.S will not compile. + * + * If you add or remove entries here, you'll want to edit the + * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your + * changes. + * + */ + +#define MSM_VIC_BASE IOMEM(0xE0000000) +#define MSM_VIC_PHYS 0xAC000000 +#define MSM_VIC_SIZE SZ_4K + +#define MSM_CSR_BASE IOMEM(0xE0001000) +#define MSM_CSR_PHYS 0xAC100000 +#define MSM_CSR_SIZE SZ_4K + +#define MSM_TMR_PHYS MSM_CSR_PHYS +#define MSM_TMR_BASE MSM_CSR_BASE +#define MSM_TMR_SIZE SZ_4K + +#define MSM_GPT_BASE MSM_TMR_BASE +#define MSM_DGT_BASE (MSM_TMR_BASE + 0x10) + +#define MSM_DMOV_BASE IOMEM(0xE0002000) +#define MSM_DMOV_PHYS 0xA9700000 +#define MSM_DMOV_SIZE SZ_4K + +#define MSM_GPIO1_BASE IOMEM(0xE0003000) +#define MSM_GPIO1_PHYS 0xA9000000 +#define MSM_GPIO1_SIZE SZ_4K + +#define MSM_GPIO2_BASE IOMEM(0xE0004000) +#define MSM_GPIO2_PHYS 0xA9100000 +#define MSM_GPIO2_SIZE SZ_4K + +#define MSM_CLK_CTL_BASE IOMEM(0xE0005000) +#define MSM_CLK_CTL_PHYS 0xA8600000 +#define MSM_CLK_CTL_SIZE SZ_4K + +#define MSM_SIRC_BASE IOMEM(0xE1006000) +#define MSM_SIRC_PHYS 0xAC200000 +#define MSM_SIRC_SIZE SZ_4K + +#define MSM_SCPLL_BASE IOMEM(0xE1007000) +#define MSM_SCPLL_PHYS 0xA8800000 +#define MSM_SCPLL_SIZE SZ_4K + +#ifdef CONFIG_MSM_SOC_REV_A +#define MSM_SMI_BASE 0xE0000000 +#else +#define MSM_SMI_BASE 0x00000000 +#endif + +#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000) +#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000) +#define MSM_SHARED_RAM_SIZE SZ_1M + +#define MSM_UART1_PHYS 0xA9A00000 +#define MSM_UART1_SIZE SZ_4K + +#define MSM_UART2_PHYS 0xA9B00000 +#define MSM_UART2_SIZE SZ_4K + +#define MSM_UART3_PHYS 0xA9C00000 +#define MSM_UART3_SIZE SZ_4K + +#ifdef CONFIG_MSM_DEBUG_UART +#define MSM_DEBUG_UART_BASE 0xE1000000 +#if CONFIG_MSM_DEBUG_UART == 1 +#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS +#elif CONFIG_MSM_DEBUG_UART == 2 +#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS +#elif CONFIG_MSM_DEBUG_UART == 3 +#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS +#endif +#define MSM_DEBUG_UART_SIZE SZ_4K +#endif + +#define MSM_MDC_BASE IOMEM(0xE0200000) +#define MSM_MDC_PHYS 0xAA500000 +#define MSM_MDC_SIZE SZ_1M + +#define MSM_AD5_BASE IOMEM(0xE0300000) +#define MSM_AD5_PHYS 0xAC000000 +#define MSM_AD5_SIZE (SZ_1M*13) + + +#define MSM_I2C_SIZE SZ_4K +#define MSM_I2C_PHYS 0xA9900000 + +#define MSM_HSUSB_PHYS 0xA0800000 +#define MSM_HSUSB_SIZE SZ_1K + +#define MSM_NAND_PHYS 0xA0A00000 + + +#define MSM_TSIF_PHYS (0xa0100000) +#define MSM_TSIF_SIZE (0x200) + +#define MSM_TSSC_PHYS 0xAA300000 + +#define MSM_UART1DM_PHYS 0xA0200000 +#define MSM_UART2DM_PHYS 0xA0900000 + + +#define MSM_SDC1_PHYS 0xA0400000 +#define MSM_SDC1_SIZE SZ_4K + +#define MSM_SDC2_PHYS 0xA0500000 +#define MSM_SDC2_SIZE SZ_4K + +#define MSM_SDC3_PHYS 0xA0600000 +#define MSM_SDC3_SIZE SZ_4K + +#define MSM_SDC4_PHYS 0xA0700000 +#define MSM_SDC4_SIZE SZ_4K + +#endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index 81da6b8e25a0..7043d7ac4ac2 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -43,6 +43,10 @@ #define IOMEM(x) ((void __force __iomem *)(x)) #endif +#if defined(CONFIG_ARCH_QSD8X50) +#include "msm_iomap-8x50.h" +#else #include "msm_iomap-7x00.h" +#endif #endif -- cgit v1.2.3-59-g8ed1b From d1c0d43d40a625345634d2b08325fb9e8be41534 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 5 May 2010 07:17:31 -0700 Subject: msm: update basic board layout for QSD8x50 Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/board-qsd8x50.c | 120 ++++++-------------------------------- 1 file changed, 19 insertions(+), 101 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index a5e862c6ef7b..ec4606643d2c 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c @@ -27,106 +27,48 @@ #include #include -#include -#include -#include #include -#include -#include +#include +#include +#include #include "devices.h" -#include "timer.h" -#include "socinfo.h" -#include "proc_comm.h" - -#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000) -static struct resource smc91x_resources[] = { - [0] = { - .flags = IORESOURCE_MEM, - }, - [1] = { - .flags = IORESOURCE_IRQ, - }, -}; +extern struct sys_timer msm_timer; -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, +static struct msm_gpio uart3_config_data[] = { + { GPIO_CFG(86, 1, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"}, + { GPIO_CFG(87, 1, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"}, }; static struct platform_device *devices[] __initdata = { - &smc91x_device, - &msm_device_smd, - &msm_device_dmov, - &msm_device_nand, + &msm_device_uart3, }; -static void __init qsd8x50_init_irq(void) +static void msm8x50_init_uart3(void) { - msm_init_irq(); + msm_gpios_request_enable(uart3_config_data, + ARRAY_SIZE(uart3_config_data)); } -static void __init qsd8x50_init_host(void) +static void __init qsd8x50_map_io(void) { - if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa()) - return; - - vreg_usb = vreg_get(NULL, "boost"); - - if (IS_ERR(vreg_usb)) { - printk(KERN_ERR "%s: vreg get failed (%ld)\n", - __func__, PTR_ERR(vreg_usb)); - return; - } - - platform_device_register(&msm_device_hsusb_otg); + msm_map_qsd8x50_io(); + msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50); } -static void __init qsd8x50_cfg_smc91x(void) +static void __init qsd8x50_init_irq(void) { - int rc = 0; - - if (machine_is_qsd8x50_surf() || machine_is_qsd8x50a_surf()) { - smc91x_resources[0].start = 0x70000300; - smc91x_resources[0].end = 0x700003ff; - smc91x_resources[1].start = MSM_GPIO_TO_INT(156); - smc91x_resources[1].end = MSM_GPIO_TO_INT(156); - } else if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa()) { - smc91x_resources[0].start = 0x84000300; - smc91x_resources[0].end = 0x840003ff; - smc91x_resources[1].start = MSM_GPIO_TO_INT(87); - smc91x_resources[1].end = MSM_GPIO_TO_INT(87); - - rc = gpio_tlmm_config(GPIO_CFG(87, 0, GPIO_INPUT, - GPIO_PULL_DOWN, GPIO_2MA), - GPIO_ENABLE); - if (rc) { - printk(KERN_ERR "%s: gpio_tlmm_config=%d\n", - __func__, rc); - } - } else - printk(KERN_ERR "%s: invalid machine type\n", __func__); + msm_init_irq(); + msm_init_sirc(); } static void __init qsd8x50_init(void) { - if (socinfo_init() < 0) - printk(KERN_ERR "%s: socinfo_init() failed!\n", - __func__); - qsd8x50_cfg_smc91x(); + msm8x50_init_uart3(); platform_add_devices(devices, ARRAY_SIZE(devices)); } -static void __init qsd8x50_map_io(void) -{ - msm_shared_ram_phys = MSM_SHARED_RAM_PHYS; - msm_map_qsd8x50_io(); - msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50); -} - MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF") #ifdef CONFIG_MSM_DEBUG_UART .phys_io = MSM_DEBUG_UART_PHYS, @@ -139,31 +81,7 @@ MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF") .timer = &msm_timer, MACHINE_END -MACHINE_START(QSD8X50_FFA, "QCT QSD8X50 FFA") -#ifdef CONFIG_MSM_DEBUG_UART - .phys_io = MSM_DEBUG_UART_PHYS, - .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, -#endif - .boot_params = PHYS_OFFSET + 0x100, - .map_io = qsd8x50_map_io, - .init_irq = qsd8x50_init_irq, - .init_machine = qsd8x50_init, - .timer = &msm_timer, -MACHINE_END - -MACHINE_START(QSD8X50A_SURF, "QCT QSD8X50A SURF") -#ifdef CONFIG_MSM_DEBUG_UART - .phys_io = MSM_DEBUG_UART_PHYS, - .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, -#endif - .boot_params = PHYS_OFFSET + 0x100, - .map_io = qsd8x50_map_io, - .init_irq = qsd8x50_init_irq, - .init_machine = qsd8x50_init, - .timer = &msm_timer, -MACHINE_END - -MACHINE_START(QSD8X50A_FFA, "QCT QSD8X50A FFA") +MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5") #ifdef CONFIG_MSM_DEBUG_UART .phys_io = MSM_DEBUG_UART_PHYS, .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, -- cgit v1.2.3-59-g8ed1b From 62a6cc578cb2b1cdbaaf764ca245ad64da800235 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 5 May 2010 07:27:16 -0700 Subject: msm: add devices-qsd8x50.c This adds a clock list, and common resource structures for QSD8x50. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/devices-qsd8x50.c | 92 +++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 arch/arm/mach-msm/devices-qsd8x50.c (limited to 'arch') diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c new file mode 100644 index 000000000000..4d4a50785e34 --- /dev/null +++ b/arch/arm/mach-msm/devices-qsd8x50.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2008 Google, Inc. + * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "devices.h" + +#include + +#include + +static struct resource resources_uart3[] = { + { + .start = INT_UART3, + .end = INT_UART3, + .flags = IORESOURCE_IRQ, + }, + { + .start = MSM_UART3_PHYS, + .end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device msm_device_uart3 = { + .name = "msm_serial", + .id = 2, + .num_resources = ARRAY_SIZE(resources_uart3), + .resource = resources_uart3, +}; + +struct clk msm_clocks_8x50[] = { + CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), + CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN), + CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0), + CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0), + CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | CLK_MINMAX), + CLK_PCOM("gp_clk", GP_CLK, NULL, 0), + CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0), + CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0), + CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0), + CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF), + CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0), + CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX), + CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), + CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0), + CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0), + CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0), + CLK_PCOM("pbus_clk", PBUS_CLK, NULL, CLK_MIN), + CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), + CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), + CLK_PCOM("spi_clk", SPI_CLK, NULL, 0), + CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0), + CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), + CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), + CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), + CLK_PCOM("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), + CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF), + CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF), + CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0), + CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | CLK_MIN), + CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF), + CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), + CLK_PCOM("vfe_axi_clk", VFE_AXI_CLK, NULL, OFF), + CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, OFF), + CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, OFF), + CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, OFF), + CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, OFF), + CLK_PCOM("usb_phy_clk", USB_PHY_CLK, NULL, 0), +}; + +unsigned msm_num_clocks_8x50 = ARRAY_SIZE(msm_clocks_8x50); + -- cgit v1.2.3-59-g8ed1b From acb241cb61945d9943e89da51e33bf4b71104164 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 5 May 2010 07:48:32 -0700 Subject: msm: add extern for 8x50 clock list. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/devices.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h index 19c5de99e20c..d2095547fce8 100644 --- a/arch/arm/mach-msm/devices.h +++ b/arch/arm/mach-msm/devices.h @@ -38,4 +38,7 @@ extern struct platform_device msm_device_nand; extern struct clk msm_clocks_7x01a[]; extern unsigned msm_num_clocks_7x01a; +extern struct clk msm_clocks_8x50[]; +extern unsigned msm_num_clocks_8x50; + #endif -- cgit v1.2.3-59-g8ed1b From cf62ffae2550102557c0848ab63a771e032fcfd3 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Tue, 4 May 2010 15:12:27 -0700 Subject: msm: io: add io support for 8x50 Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/io.h | 3 +++ arch/arm/mach-msm/io.c | 39 ++++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/io.h b/arch/arm/mach-msm/include/mach/io.h index aab964591db4..dbfb01304c82 100644 --- a/arch/arm/mach-msm/include/mach/io.h +++ b/arch/arm/mach-msm/include/mach/io.h @@ -26,4 +26,7 @@ void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int m #define __io(a) __typesafe_io(a) #define __mem_pci(a) (a) +void msm_map_qsd8x50_io(void); +extern unsigned int msm_shared_ram_phys; + #endif diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index fde5e58b51c3..c94ba336c7fd 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -1,8 +1,9 @@ /* arch/arm/mach-msm/io.c * - * MSM7K io support + * MSM7K, QSD io support * * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -34,6 +35,8 @@ .type = MT_DEVICE_NONSHARED, \ } +#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27) \ + || defined(CONFIG_ARCH_MSM7X25) static struct map_desc msm_io_desc[] __initdata = { MSM_DEVICE(VIC), MSM_DEVICE(CSR), @@ -50,7 +53,7 @@ static struct map_desc msm_io_desc[] __initdata = { #endif { .virtual = (unsigned long) MSM_SHARED_RAM_BASE, - .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), + .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), .length = MSM_SHARED_RAM_SIZE, .type = MT_DEVICE, }, @@ -63,9 +66,39 @@ void __init msm_map_common_io(void) * pages are peripheral interface or not. */ asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0)); - iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc)); } +#endif + +#ifdef CONFIG_ARCH_QSD8X50 +static struct map_desc qsd8x50_io_desc[] __initdata = { + MSM_DEVICE(VIC), + MSM_DEVICE(CSR), + MSM_DEVICE(TMR), + MSM_DEVICE(DMOV), + MSM_DEVICE(GPIO1), + MSM_DEVICE(GPIO2), + MSM_DEVICE(CLK_CTL), + MSM_DEVICE(SIRC), + MSM_DEVICE(SCPLL), + MSM_DEVICE(AD5), + MSM_DEVICE(MDC), +#ifdef CONFIG_MSM_DEBUG_UART + MSM_DEVICE(DEBUG_UART), +#endif + { + .virtual = (unsigned long) MSM_SHARED_RAM_BASE, + .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), + .length = MSM_SHARED_RAM_SIZE, + .type = MT_DEVICE, + }, +}; + +void __init msm_map_qsd8x50_io(void) +{ + iotable_init(qsd8x50_io_desc, ARRAY_SIZE(qsd8x50_io_desc)); +} +#endif /* CONFIG_ARCH_QSD8X50 */ void __iomem * __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) -- cgit v1.2.3-59-g8ed1b From 81d658ac64000758c198c6b31fed505ec284e165 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 6 May 2010 14:16:04 -0700 Subject: msm: physical offset for QSD8x50 Support different RAM base addresses used by Qualcomm SOCs, with QSD8x50 as the first addtional one. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/memory.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h index f4698baec976..cfee996a47d5 100644 --- a/arch/arm/mach-msm/include/mach/memory.h +++ b/arch/arm/mach-msm/include/mach/memory.h @@ -17,7 +17,13 @@ #define __ASM_ARCH_MEMORY_H /* physical offset of RAM */ +#if defined(CONFIG_ARCH_QSD8X50) && defined(CONFIG_MSM_SOC_REV_A) +#define PHYS_OFFSET UL(0x00000000) +#elif defined(CONFIG_ARCH_QSD8X50) +#define PHYS_OFFSET UL(0x20000000) +#else #define PHYS_OFFSET UL(0x10000000) +#endif #endif -- cgit v1.2.3-59-g8ed1b From 4ad15e6f56983e6df7cdca499ba89188b65f8e4e Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 6 May 2010 13:54:17 -0700 Subject: msm: 8x50 Kconfig changes Enable CONFIG_ARCH_QSD8X50. This is the first SOC with the Scorpion processor. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/Kconfig | 58 +++++++++++++++++++++++++++++++++------------- arch/arm/mach-msm/Makefile | 4 ++++ 2 files changed, 46 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index b983d786177e..3dbad24cc62c 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -11,16 +11,56 @@ config ARCH_MSM7X00A select MSM_SMD_PKG3 select CPU_V6 +config ARCH_QSD8X50 + bool "QSD8X50" + select ARCH_MSM_SCORPION + select MSM_SMD + select MSM_VIC + select CPU_V7 + select MSM_REMOTE_SPINLOCK_LDREX endchoice -config ARCH_MSM_ARM11 +config MSM_SOC_REV_A + bool + +config ARCH_MSM_ARM11 + bool +config ARCH_MSM_SCORPION bool config MSM_VIC bool -comment "MSM Board Type" +menu "Qualcomm MSM Board Type" + +config MACH_HALIBUT depends on ARCH_MSM + depends on ARCH_MSM7X00A + bool "Halibut Board (QCT SURF7201A)" + help + Support for the Qualcomm SURF7201A eval board. + +config MACH_TROUT + depends on ARCH_MSM + depends on ARCH_MSM7X00A + bool "HTC Dream (aka trout)" + help + Support for the HTC Dream, T-Mobile G1, Android ADP1 devices. + +config MACH_QSD8X50_SURF + depends on ARCH_QSD8X50 + bool "QSD8x50 SURF" + help + Support for the Qualcomm QSD8x50 SURF eval board. + +config MACH_QSD8X50A_ST1_5 + depends on ARCH_QSD8X50 + select MSM_SOC_REV_A + bool "QSD8x50A ST1.5" + help + Support for the Qualcomm ST1.5. + +endmenu config MSM_DEBUG_UART int @@ -46,20 +86,6 @@ choice bool "UART3" endchoice -config MACH_HALIBUT - depends on ARCH_MSM7X00A - default y - bool "Halibut Board (QCT SURF7201A)" - help - Support for the Qualcomm SURF7201A eval board. - -config MACH_TROUT - depends on ARCH_MSM7X00A - default y - bool "HTC Dream (aka trout)" - help - Support for the HTC Dream, T-Mobile G1, Android ADP1 devices. - config MSM_SMD_PKG3 bool diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 48a5fafd673b..df95f574f1f9 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -3,6 +3,7 @@ obj-y += io.o idle.o timer.o dma.o obj-y += vreg.o obj-y += acpuclock-arm11.o obj-y += clock.o clock-pcom.o +obj-y += gpio.o ifdef CONFIG_MSM_VIC obj-y += irq-vic.o @@ -10,8 +11,11 @@ else obj-y += irq.o endif +obj-$(CONFIG_ARCH_QSD8X50) += sirc.o obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o obj-$(CONFIG_MSM_SMD) += last_radio_log.o obj-$(CONFIG_MACH_TROUT) += board-trout.o devices-msm7x00.o obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o +obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o + -- cgit v1.2.3-59-g8ed1b From 1b54b39eafa234da53d6739d877bae9c710017a4 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 5 May 2010 06:53:23 -0700 Subject: msm: irqs: add irqs-7x30.h for MSM7x30 support Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/irqs-7x30.h | 170 +++++++++++++++++++++++++++++ arch/arm/mach-msm/include/mach/irqs.h | 4 +- 2 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-msm/include/mach/irqs-7x30.h (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/irqs-7x30.h b/arch/arm/mach-msm/include/mach/irqs-7x30.h new file mode 100644 index 000000000000..67c5396514fe --- /dev/null +++ b/arch/arm/mach-msm/include/mach/irqs-7x30.h @@ -0,0 +1,170 @@ +/* Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __ASM_ARCH_MSM_IRQS_7X30_H +#define __ASM_ARCH_MSM_IRQS_7X30_H + +/* MSM ACPU Interrupt Numbers */ + +#define INT_DEBUG_TIMER_EXP 0 +#define INT_GPT0_TIMER_EXP 1 +#define INT_GPT1_TIMER_EXP 2 +#define INT_WDT0_ACCSCSSBARK 3 +#define INT_WDT1_ACCSCSSBARK 4 +#define INT_AVS_SVIC 5 +#define INT_AVS_SVIC_SW_DONE 6 +#define INT_SC_DBG_RX_FULL 7 +#define INT_SC_DBG_TX_EMPTY 8 +#define INT_ARM11_PM 9 +#define INT_AVS_REQ_DOWN 10 +#define INT_AVS_REQ_UP 11 +#define INT_SC_ACG 12 +/* SCSS_VICFIQSTS0[13:15] are RESERVED */ +#define INT_L2_SVICCPUIRPTREQ 16 +#define INT_L2_SVICDMANSIRPTREQ 17 +#define INT_L2_SVICDMASIRPTREQ 18 +#define INT_L2_SVICSLVIRPTREQ 19 +#define INT_AD5A_MPROC_APPS_0 20 +#define INT_AD5A_MPROC_APPS_1 21 +#define INT_A9_M2A_0 22 +#define INT_A9_M2A_1 23 +#define INT_A9_M2A_2 24 +#define INT_A9_M2A_3 25 +#define INT_A9_M2A_4 26 +#define INT_A9_M2A_5 27 +#define INT_A9_M2A_6 28 +#define INT_A9_M2A_7 29 +#define INT_A9_M2A_8 30 +#define INT_A9_M2A_9 31 + +#define INT_AXI_EBI1_SC (32 + 0) +#define INT_IMEM_ERR (32 + 1) +#define INT_AXI_EBI0_SC (32 + 2) +#define INT_PBUS_SC_IRQC (32 + 3) +#define INT_PERPH_BUS_BPM (32 + 4) +#define INT_CC_TEMP_SENSE (32 + 5) +#define INT_UXMC_EBI0 (32 + 6) +#define INT_UXMC_EBI1 (32 + 7) +#define INT_EBI2_OP_DONE (32 + 8) +#define INT_EBI2_WR_ER_DONE (32 + 9) +#define INT_TCSR_SPSS_CE (32 + 10) +#define INT_EMDH (32 + 11) +#define INT_PMDH (32 + 12) +#define INT_MDC (32 + 13) +#define INT_MIDI_TO_SUPSS (32 + 14) +#define INT_LPA_2 (32 + 15) +#define INT_GPIO_GROUP1_SECURE (32 + 16) +#define INT_GPIO_GROUP2_SECURE (32 + 17) +#define INT_GPIO_GROUP1 (32 + 18) +#define INT_GPIO_GROUP2 (32 + 19) +#define INT_MPRPH_SOFTRESET (32 + 20) +#define INT_PWB_I2C (32 + 21) +#define INT_PWB_I2C_2 (32 + 22) +#define INT_TSSC_SAMPLE (32 + 23) +#define INT_TSSC_PENUP (32 + 24) +#define INT_TCHSCRN_SSBI (32 + 25) +#define INT_FM_RDS (32 + 26) +#define INT_KEYSENSE (32 + 27) +#define INT_USB_OTG_HS (32 + 28) +#define INT_USB_OTG_HS2 (32 + 29) +#define INT_USB_OTG_HS3 (32 + 30) +#define INT_CSI (32 + 31) + +#define INT_SPI_OUTPUT (64 + 0) +#define INT_SPI_INPUT (64 + 1) +#define INT_SPI_ERROR (64 + 2) +#define INT_UART1 (64 + 3) +#define INT_UART1_RX (64 + 4) +#define INT_UART2 (64 + 5) +#define INT_UART2_RX (64 + 6) +#define INT_UART3 (64 + 7) +#define INT_UART3_RX (64 + 8) +#define INT_UART1DM_IRQ (64 + 9) +#define INT_UART1DM_RX (64 + 10) +#define INT_UART2DM_IRQ (64 + 11) +#define INT_UART2DM_RX (64 + 12) +#define INT_TSIF (64 + 13) +#define INT_ADM_SC1 (64 + 14) +#define INT_ADM_SC2 (64 + 15) +#define INT_MDP (64 + 16) +#define INT_VPE (64 + 17) +#define INT_GRP_2D (64 + 18) +#define INT_GRP_3D (64 + 19) +#define INT_ROTATOR (64 + 20) +#define INT_MFC720 (64 + 21) +#define INT_JPEG (64 + 22) +#define INT_VFE (64 + 23) +#define INT_TV_ENC (64 + 24) +#define INT_PMIC_SSBI (64 + 25) +#define INT_MPM_1 (64 + 26) +#define INT_TCSR_SPSS_SAMPLE (64 + 27) +#define INT_TCSR_SPSS_PENUP (64 + 28) +#define INT_MPM_2 (64 + 29) +#define INT_SDC1_0 (64 + 30) +#define INT_SDC1_1 (64 + 31) + +#define INT_SDC3_0 (96 + 0) +#define INT_SDC3_1 (96 + 1) +#define INT_SDC2_0 (96 + 2) +#define INT_SDC2_1 (96 + 3) +#define INT_SDC4_0 (96 + 4) +#define INT_SDC4_1 (96 + 5) +#define INT_PWB_QUP_IN (96 + 6) +#define INT_PWB_QUP_OUT (96 + 7) +#define INT_PWB_QUP_ERR (96 + 8) +#define INT_SCSS_WDT0_BITE (96 + 9) +/* SCSS_VICFIQSTS3[10:31] are RESERVED */ + +/* Retrofit universal macro names */ +#define INT_ADM_AARM INT_ADM_SC2 +#define INT_USB_HS INT_USB_OTG_HS +#define INT_USB_OTG INT_USB_OTG_HS +#define INT_TCHSCRN1 INT_TSSC_SAMPLE +#define INT_TCHSCRN2 INT_TSSC_PENUP +#define INT_GP_TIMER_EXP INT_GPT0_TIMER_EXP +#define INT_ADSP_A11 INT_AD5A_MPROC_APPS_0 +#define INT_ADSP_A9_A11 INT_AD5A_MPROC_APPS_1 +#define INT_MDDI_EXT INT_EMDH +#define INT_MDDI_PRI INT_PMDH +#define INT_MDDI_CLIENT INT_MDC +#define INT_NAND_WR_ER_DONE INT_EBI2_WR_ER_DONE +#define INT_NAND_OP_DONE INT_EBI2_OP_DONE + +#define NR_MSM_IRQS 128 +#define NR_GPIO_IRQS 182 +#define PMIC8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS) +#define NR_PMIC8058_GPIO_IRQS 40 +#define NR_PMIC8058_MPP_IRQS 12 +#define NR_PMIC8058_MISC_IRQS 8 +#define NR_PMIC8058_IRQS (NR_PMIC8058_GPIO_IRQS +\ + NR_PMIC8058_MPP_IRQS +\ + NR_PMIC8058_MISC_IRQS) +#define NR_BOARD_IRQS NR_PMIC8058_IRQS + +#endif /* __ASM_ARCH_MSM_IRQS_7X30_H */ diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h index 38a3528b664f..164d355c96ea 100644 --- a/arch/arm/mach-msm/include/mach/irqs.h +++ b/arch/arm/mach-msm/include/mach/irqs.h @@ -19,7 +19,9 @@ #define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) -#if defined(CONFIG_ARCH_QSD8X50) +#if defined(CONFIG_ARCH_MSM7X30) +#include "irqs-7x30.h" +#elif defined(CONFIG_ARCH_QSD8X50) #include "irqs-8x50.h" #include "sirc.h" #elif defined(CONFIG_ARCH_MSM_ARM11) -- cgit v1.2.3-59-g8ed1b From 184d252acd155da1c9112831543c99f301b3cc64 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 5 May 2010 07:08:13 -0700 Subject: msm: add msm_iomap-7x30.h for MSM7x30 support Add a header describing the io regions for MSM7x30. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/msm_iomap-7x30.h | 122 ++++++++++++++++++++++++ arch/arm/mach-msm/include/mach/msm_iomap.h | 4 +- 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-msm/include/mach/msm_iomap-7x30.h (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h new file mode 100644 index 000000000000..8a00c2defbc1 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + * + * The MSM peripherals are spread all over across 768MB of physical + * space, which makes just having a simple IO_ADDRESS macro to slide + * them into the right virtual location rough. Instead, we will + * provide a master phys->virt mapping for peripherals here. + * + */ + +#ifndef __ASM_ARCH_MSM_IOMAP_7X30_H +#define __ASM_ARCH_MSM_IOMAP_7X30_H + +/* Physical base address and size of peripherals. + * Ordered by the virtual base addresses they will be mapped at. + * + * MSM_VIC_BASE must be an value that can be loaded via a "mov" + * instruction, otherwise entry-macro.S will not compile. + * + * If you add or remove entries here, you'll want to edit the + * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your + * changes. + * + */ + +#define MSM_VIC_BASE IOMEM(0xE0000000) +#define MSM_VIC_PHYS 0xC0080000 +#define MSM_VIC_SIZE SZ_4K + +#define MSM_CSR_BASE IOMEM(0xE0001000) +#define MSM_CSR_PHYS 0xC0100000 +#define MSM_CSR_SIZE SZ_4K + +#define MSM_TMR_PHYS MSM_CSR_PHYS +#define MSM_TMR_BASE MSM_CSR_BASE +#define MSM_TMR_SIZE SZ_4K + +#define MSM_GPT_BASE (MSM_TMR_BASE + 0x4) +#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24) + +#define MSM_DMOV_BASE IOMEM(0xE0002000) +#define MSM_DMOV_PHYS 0xAC400000 +#define MSM_DMOV_SIZE SZ_4K + +#define MSM_GPIO1_BASE IOMEM(0xE0003000) +#define MSM_GPIO1_PHYS 0xAC001000 +#define MSM_GPIO1_SIZE SZ_4K + +#define MSM_GPIO2_BASE IOMEM(0xE0004000) +#define MSM_GPIO2_PHYS 0xAC101000 +#define MSM_GPIO2_SIZE SZ_4K + +#define MSM_CLK_CTL_BASE IOMEM(0xE0005000) +#define MSM_CLK_CTL_PHYS 0xAB800000 +#define MSM_CLK_CTL_SIZE SZ_4K + +#define MSM_CLK_CTL_SH2_BASE IOMEM(0xE0006000) +#define MSM_CLK_CTL_SH2_PHYS 0xABA01000 +#define MSM_CLK_CTL_SH2_SIZE SZ_4K + +#define MSM_ACC_BASE IOMEM(0xE0007000) +#define MSM_ACC_PHYS 0xC0101000 +#define MSM_ACC_SIZE SZ_4K + +#define MSM_SAW_BASE IOMEM(0xE0008000) +#define MSM_SAW_PHYS 0xC0102000 +#define MSM_SAW_SIZE SZ_4K + +#define MSM_GCC_BASE IOMEM(0xE0009000) +#define MSM_GCC_PHYS 0xC0182000 +#define MSM_GCC_SIZE SZ_4K + +#define MSM_TCSR_BASE IOMEM(0xE000A000) +#define MSM_TCSR_PHYS 0xAB600000 +#define MSM_TCSR_SIZE SZ_4K + +#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000) +#define MSM_SHARED_RAM_PHYS 0x00100000 +#define MSM_SHARED_RAM_SIZE SZ_1M + +#define MSM_UART1_PHYS 0xACA00000 +#define MSM_UART1_SIZE SZ_4K + +#define MSM_UART2_PHYS 0xACB00000 +#define MSM_UART2_SIZE SZ_4K + +#define MSM_UART3_PHYS 0xACC00000 +#define MSM_UART3_SIZE SZ_4K + +#ifdef CONFIG_MSM_DEBUG_UART +#define MSM_DEBUG_UART_BASE 0xE1000000 +#if CONFIG_MSM_DEBUG_UART == 1 +#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS +#elif CONFIG_MSM_DEBUG_UART == 2 +#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS +#elif CONFIG_MSM_DEBUG_UART == 3 +#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS +#endif +#define MSM_DEBUG_UART_SIZE SZ_4K +#endif + +#define MSM_MDC_BASE IOMEM(0xE0200000) +#define MSM_MDC_PHYS 0xAA500000 +#define MSM_MDC_SIZE SZ_1M + +#define MSM_AD5_BASE IOMEM(0xE0300000) +#define MSM_AD5_PHYS 0xA7000000 +#define MSM_AD5_SIZE (SZ_1M*13) + +#endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index 7043d7ac4ac2..e6b1821cc4ea 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -43,7 +43,9 @@ #define IOMEM(x) ((void __force __iomem *)(x)) #endif -#if defined(CONFIG_ARCH_QSD8X50) +#if defined(CONFIG_ARCH_MSM7X30) +#include "msm_iomap-7x30.h" +#elif defined(CONFIG_ARCH_QSD8X50) #include "msm_iomap-8x50.h" #else #include "msm_iomap-7x00.h" -- cgit v1.2.3-59-g8ed1b From 10932767d215d35acc7facd01b2bb3d77dbc0f4b Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 12 May 2010 12:02:25 -0700 Subject: msm: add devices-msm7x30.c This adds a clock list, and common resource structures for MSM7x30. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/devices-msm7x30.c | 128 ++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 arch/arm/mach-msm/devices-msm7x30.c (limited to 'arch') diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c new file mode 100644 index 000000000000..b449e8ad2904 --- /dev/null +++ b/arch/arm/mach-msm/devices-msm7x30.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008 Google, Inc. + * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "devices.h" +#include "smd_private.h" + +#include + +#include "clock-pcom.h" + +#include + +static struct resource resources_uart2[] = { + { + .start = INT_UART2, + .end = INT_UART2, + .flags = IORESOURCE_IRQ, + }, + { + .start = MSM_UART2_PHYS, + .end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device msm_device_uart2 = { + .name = "msm_serial", + .id = 1, + .num_resources = ARRAY_SIZE(resources_uart2), + .resource = resources_uart2, +}; + +struct clk msm_clocks_7x30[] = { + CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), + CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), + CLK_PCOM("cam_m_clk", CAM_M_CLK, NULL, 0), + CLK_PCOM("camif_pad_pclk", CAMIF_PAD_P_CLK, NULL, OFF), + CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN), + CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0), + CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | CLK_MINMAX), + CLK_PCOM("emdh_pclk", EMDH_P_CLK, NULL, OFF), + CLK_PCOM("gp_clk", GP_CLK, NULL, 0), + CLK_PCOM("grp_2d_clk", GRP_2D_CLK, NULL, 0), + CLK_PCOM("grp_2d_pclk", GRP_2D_P_CLK, NULL, 0), + CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0), + CLK_PCOM("grp_pclk", GRP_3D_P_CLK, NULL, 0), + CLK_7X30S("grp_src_clk", GRP_3D_SRC_CLK, GRP_3D_CLK, NULL, 0), + CLK_PCOM("hdmi_clk", HDMI_CLK, NULL, 0), + CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF), + CLK_PCOM("jpeg_clk", JPEG_CLK, NULL, OFF), + CLK_PCOM("jpeg_pclk", JPEG_P_CLK, NULL, OFF), + CLK_PCOM("lpa_codec_clk", LPA_CODEC_CLK, NULL, 0), + CLK_PCOM("lpa_core_clk", LPA_CORE_CLK, NULL, 0), + CLK_PCOM("lpa_pclk", LPA_P_CLK, NULL, 0), + CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0), + CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX), + CLK_PCOM("mddi_pclk", PMDH_P_CLK, NULL, 0), + CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), + CLK_PCOM("mdp_pclk", MDP_P_CLK, NULL, 0), + CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0), + CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0), + CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0), + CLK_PCOM("mfc_clk", MFC_CLK, NULL, 0), + CLK_PCOM("mfc_div2_clk", MFC_DIV2_CLK, NULL, 0), + CLK_PCOM("mfc_pclk", MFC_P_CLK, NULL, 0), + CLK_PCOM("mi2s_m_clk", MI2S_M_CLK, NULL, 0), + CLK_PCOM("mi2s_s_clk", MI2S_S_CLK, NULL, 0), + CLK_PCOM("mi2s_codec_rx_m_clk", MI2S_CODEC_RX_M_CLK, NULL, 0), + CLK_PCOM("mi2s_codec_rx_s_clk", MI2S_CODEC_RX_S_CLK, NULL, 0), + CLK_PCOM("mi2s_codec_tx_m_clk", MI2S_CODEC_TX_M_CLK, NULL, 0), + CLK_PCOM("mi2s_codec_tx_s_clk", MI2S_CODEC_TX_S_CLK, NULL, 0), + CLK_PCOM("pbus_clk", PBUS_CLK, NULL, CLK_MIN), + CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), + CLK_PCOM("rotator_clk", AXI_ROTATOR_CLK, NULL, 0), + CLK_PCOM("rotator_imem_clk", ROTATOR_IMEM_CLK, NULL, OFF), + CLK_PCOM("rotator_pclk", ROTATOR_P_CLK, NULL, OFF), + CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), + CLK_PCOM("spi_clk", SPI_CLK, NULL, 0), + CLK_PCOM("spi_pclk", SPI_P_CLK, NULL, 0), + CLK_7X30S("tv_src_clk", TV_CLK, TV_ENC_CLK, NULL, 0), + CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), + CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), + CLK_PCOM("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0), + CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF), + CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF), + CLK_PCOM("usb_hs_core_clk", USB_HS_CORE_CLK, NULL, OFF), + CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, OFF), + CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, OFF), + CLK_PCOM("usb_hs2_core_clk", USB_HS2_CORE_CLK, NULL, OFF), + CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, OFF), + CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, OFF), + CLK_PCOM("usb_hs3_core_clk", USB_HS3_CORE_CLK, NULL, OFF), + CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | CLK_MIN), + CLK_PCOM("vfe_camif_clk", VFE_CAMIF_CLK, NULL, 0), + CLK_PCOM("vfe_clk", VFE_CLK, NULL, 0), + CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, 0), + CLK_PCOM("vfe_pclk", VFE_P_CLK, NULL, OFF), + CLK_PCOM("vpe_clk", VPE_CLK, NULL, 0), + + /* 7x30 v2 hardware only. */ + CLK_PCOM("csi_clk", CSI0_CLK, NULL, 0), + CLK_PCOM("csi_pclk", CSI0_P_CLK, NULL, 0), + CLK_PCOM("csi_vfe_clk", CSI0_VFE_CLK, NULL, 0), +}; + +unsigned msm_num_clocks_7x30 = ARRAY_SIZE(msm_clocks_7x30); + -- cgit v1.2.3-59-g8ed1b From 90e37c57bab2876c50fe479d26e228c9aa871556 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 12 May 2010 14:24:15 -0700 Subject: msm: update basic board layout for MSM7x30 Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/board-msm7x30.c | 116 +++++++------------------------------- 1 file changed, 20 insertions(+), 96 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c index af132ebd86c5..bac1f3c38a3b 100644 --- a/arch/arm/mach-msm/board-msm7x30.c +++ b/arch/arm/mach-msm/board-msm7x30.c @@ -30,96 +30,37 @@ #include #include -#include #include #include -#include #include #include - #include "devices.h" -#include "timer.h" -#include "socinfo.h" - -static struct resource smc91x_resources[] = { - [0] = { - .start = 0x8A000300, - .end = 0x8A0003ff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = MSM_GPIO_TO_INT(156), - .end = MSM_GPIO_TO_INT(156), - .flags = IORESOURCE_IRQ, - }, -}; +#include "proc_comm.h" -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; - -static struct smsc911x_platform_config smsc911x_config = { - .phy_interface = PHY_INTERFACE_MODE_MII, - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, - .flags = SMSC911X_USE_32BIT, -}; - -static struct resource smsc911x_resources[] = { - [0] = { - .start = 0x8D000000, - .end = 0x8D000100, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = MSM_GPIO_TO_INT(88), - .end = MSM_GPIO_TO_INT(88), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device smsc911x_device = { - .name = "smsc911x", - .id = -1, - .num_resources = ARRAY_SIZE(smsc911x_resources), - .resource = smsc911x_resources, - .dev = { - .platform_data = &smsc911x_config, - }, -}; +extern struct sys_timer msm_timer; -static struct msm_gpio smsc911x_gpios[] = { - { GPIO_CFG(172, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr6" }, - { GPIO_CFG(173, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr5" }, - { GPIO_CFG(174, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr4" }, - { GPIO_CFG(175, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr3" }, - { GPIO_CFG(176, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr2" }, - { GPIO_CFG(177, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr1" }, - { GPIO_CFG(178, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "ebi2_addr0" }, - { GPIO_CFG(88, 2, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA), "smsc911x_irq" }, +#ifdef CONFIG_SERIAL_MSM_CONSOLE +static struct msm_gpio uart2_config_data[] = { + { GPIO_CFG(49, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_RFR"}, + { GPIO_CFG(50, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_CTS"}, + { GPIO_CFG(51, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"}, + { GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"}, }; -static void msm7x30_cfg_smsc911x(void) +static void msm7x30_init_uart2(void) { - int rc; + msm_gpios_request_enable(uart2_config_data, + ARRAY_SIZE(uart2_config_data)); - rc = msm_gpios_request_enable(smsc911x_gpios, - ARRAY_SIZE(smsc911x_gpios)); - if (rc) - pr_err("%s: unable to enable gpios\n", __func__); } +#endif static struct platform_device *devices[] __initdata = { - &msm_device_smd, - &msm_device_dmov, - &smc91x_device, - &smsc911x_device, - &msm_device_nand, - &msm_device_uart_dm1, +#if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER) + &msm_device_uart2, +#endif + }; static void __init msm7x30_init_irq(void) @@ -127,35 +68,18 @@ static void __init msm7x30_init_irq(void) msm_init_irq(); } -static void __init msm_7x30_init_nand(void) -{ - int rc; - /* Enable GPIO 86 & 115 */ - rc = msm_gpios_request_enable(msm_nand_ebi2_cfg_data, - ARRAY_SIZE(msm_nand_ebi2_cfg_data)); - if (rc) - printk(KERN_ERR "%s: Failed to enable GPIO 86 & 115\n", - __func__); -} - static void __init msm7x30_init(void) { - if (socinfo_init() < 0) - printk(KERN_ERR "%s: socinfo_init() failed!\n", - __func__); - msm_acpu_clock_init(&msm7x30_clock_data); - if (machine_is_msm7x30_surf() || machine_is_msm7x30_fluid()) - msm7x30_cfg_smsc911x(); platform_add_devices(devices, ARRAY_SIZE(devices)); - msm_7x30_init_nand(); - buses_init(); +#ifdef CONFIG_SERIAL_MSM_CONSOLE + msm7x30_init_uart2(); +#endif + } static void __init msm7x30_map_io(void) { - msm_shared_ram_phys = 0x00000000; msm_map_msm7x30_io(); - msm7x30_allocate_memory_regions(); msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30); } -- cgit v1.2.3-59-g8ed1b From 2f2a74e637b7ea4a52a7aea82f2a1835749d3a35 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Tue, 4 May 2010 11:29:54 -0700 Subject: msm: dma: add 7x30 security domain abstraction The MSM SOC's DMA controller contains several security domains. On the MSM7x00, only security domain 3 is accessible to our CPU. The 7x30, however, uses security domain 2. Fix up the register definition macros to select this appropriately, based on configured target. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/dma.h | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h index 5ab5bdffab07..04c51cc04f31 100644 --- a/arch/arm/mach-msm/include/mach/dma.h +++ b/arch/arm/mach-msm/include/mach/dma.h @@ -41,40 +41,42 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr); #define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2)) #define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2)) -/* only security domain 3 is available to the ARM11 - * SD0 -> mARM trusted, SD1 -> mARM nontrusted, SD2 -> aDSP, SD3 -> aARM - */ +#if defined(CONFIG_ARCH_MSM7X30) +#define DMOV_SD_AARM DMOV_SD2 +#else +#define DMOV_SD_AARM DMOV_SD3 +#endif -#define DMOV_CMD_PTR(ch) DMOV_SD3(0x000, ch) +#define DMOV_CMD_PTR(ch) DMOV_SD_AARM(0x000, ch) #define DMOV_CMD_LIST (0 << 29) /* does not work */ #define DMOV_CMD_PTR_LIST (1 << 29) /* works */ #define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */ #define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */ #define DMOV_CMD_ADDR(addr) ((addr) >> 3) -#define DMOV_RSLT(ch) DMOV_SD3(0x040, ch) +#define DMOV_RSLT(ch) DMOV_SD_AARM(0x040, ch) #define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */ #define DMOV_RSLT_ERROR (1 << 3) #define DMOV_RSLT_FLUSH (1 << 2) #define DMOV_RSLT_DONE (1 << 1) /* top pointer done */ #define DMOV_RSLT_USER (1 << 0) /* command with FR force result */ -#define DMOV_FLUSH0(ch) DMOV_SD3(0x080, ch) -#define DMOV_FLUSH1(ch) DMOV_SD3(0x0C0, ch) -#define DMOV_FLUSH2(ch) DMOV_SD3(0x100, ch) -#define DMOV_FLUSH3(ch) DMOV_SD3(0x140, ch) -#define DMOV_FLUSH4(ch) DMOV_SD3(0x180, ch) -#define DMOV_FLUSH5(ch) DMOV_SD3(0x1C0, ch) +#define DMOV_FLUSH0(ch) DMOV_SD_AARM(0x080, ch) +#define DMOV_FLUSH1(ch) DMOV_SD_AARM(0x0C0, ch) +#define DMOV_FLUSH2(ch) DMOV_SD_AARM(0x100, ch) +#define DMOV_FLUSH3(ch) DMOV_SD_AARM(0x140, ch) +#define DMOV_FLUSH4(ch) DMOV_SD_AARM(0x180, ch) +#define DMOV_FLUSH5(ch) DMOV_SD_AARM(0x1C0, ch) -#define DMOV_STATUS(ch) DMOV_SD3(0x200, ch) +#define DMOV_STATUS(ch) DMOV_SD_AARM(0x200, ch) #define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29)) #define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3) #define DMOV_STATUS_RSLT_VALID (1 << 1) #define DMOV_STATUS_CMD_PTR_RDY (1 << 0) -#define DMOV_ISR DMOV_SD3(0x380, 0) - -#define DMOV_CONFIG(ch) DMOV_SD3(0x300, ch) +#define DMOV_ISR DMOV_SD_AARM(0x380, 0) + +#define DMOV_CONFIG(ch) DMOV_SD_AARM(0x300, ch) #define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2) #define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1) #define DMOV_CONFIG_IRQ_EN (1 << 0) -- cgit v1.2.3-59-g8ed1b From 1ed8d58fcba4cda3e492f085d217c76ba6e8cb14 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 5 May 2010 07:49:05 -0700 Subject: msm: Add extern for 7x30 clock list. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/devices.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h index d2095547fce8..568443e76423 100644 --- a/arch/arm/mach-msm/devices.h +++ b/arch/arm/mach-msm/devices.h @@ -38,6 +38,9 @@ extern struct platform_device msm_device_nand; extern struct clk msm_clocks_7x01a[]; extern unsigned msm_num_clocks_7x01a; +extern struct clk msm_clocks_7x30[]; +extern unsigned msm_num_clocks_7x30; + extern struct clk msm_clocks_8x50[]; extern unsigned msm_num_clocks_8x50; -- cgit v1.2.3-59-g8ed1b From c83b2bf66a40cd9bb3af3f6e28d36babb6748d73 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Tue, 4 May 2010 15:26:13 -0700 Subject: msm: io: add io support for 7x30 Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/io.h | 2 ++ arch/arm/mach-msm/io.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/io.h b/arch/arm/mach-msm/include/mach/io.h index dbfb01304c82..c35b29f9ac0f 100644 --- a/arch/arm/mach-msm/include/mach/io.h +++ b/arch/arm/mach-msm/include/mach/io.h @@ -27,6 +27,8 @@ void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int m #define __mem_pci(a) (a) void msm_map_qsd8x50_io(void); +void msm_map_msm7x30_io(void); + extern unsigned int msm_shared_ram_phys; #endif diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index c94ba336c7fd..1c05060b5f3b 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -100,6 +100,39 @@ void __init msm_map_qsd8x50_io(void) } #endif /* CONFIG_ARCH_QSD8X50 */ +#ifdef CONFIG_ARCH_MSM7X30 +static struct map_desc msm7x30_io_desc[] __initdata = { + MSM_DEVICE(VIC), + MSM_DEVICE(CSR), + MSM_DEVICE(TMR), + MSM_DEVICE(DMOV), + MSM_DEVICE(GPIO1), + MSM_DEVICE(GPIO2), + MSM_DEVICE(CLK_CTL), + MSM_DEVICE(CLK_CTL_SH2), + MSM_DEVICE(AD5), + MSM_DEVICE(MDC), + MSM_DEVICE(ACC), + MSM_DEVICE(SAW), + MSM_DEVICE(GCC), + MSM_DEVICE(TCSR), +#ifdef CONFIG_MSM_DEBUG_UART + MSM_DEVICE(DEBUG_UART), +#endif + { + .virtual = (unsigned long) MSM_SHARED_RAM_BASE, + .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), + .length = MSM_SHARED_RAM_SIZE, + .type = MT_DEVICE, + }, +}; + +void __init msm_map_msm7x30_io(void) +{ + iotable_init(msm7x30_io_desc, ARRAY_SIZE(msm7x30_io_desc)); +} +#endif /* CONFIG_ARCH_MSM7X30 */ + void __iomem * __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) { -- cgit v1.2.3-59-g8ed1b From 41f04b17b6409026fda01942628496ec7dca2f06 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 6 May 2010 14:18:06 -0700 Subject: msm: physical offset for MSM7X30 The MSM7x30 does not have a separate bank of memory for shared memory communication with the radio CPU. Set the kernel base address 2MB in, to use this first 2MB for this purpose. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/include/mach/memory.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h index cfee996a47d5..50c7847e6002 100644 --- a/arch/arm/mach-msm/include/mach/memory.h +++ b/arch/arm/mach-msm/include/mach/memory.h @@ -21,6 +21,8 @@ #define PHYS_OFFSET UL(0x00000000) #elif defined(CONFIG_ARCH_QSD8X50) #define PHYS_OFFSET UL(0x20000000) +#elif defined(CONFIG_ARCH_MSM7X30) +#define PHYS_OFFSET UL(0x00200000) #else #define PHYS_OFFSET UL(0x10000000) #endif -- cgit v1.2.3-59-g8ed1b From 37a298fb6ad5134e52cff5a114a44c47fff51d77 Mon Sep 17 00:00:00 2001 From: Gregory Bean Date: Fri, 30 Apr 2010 22:22:07 -0700 Subject: msm: clock support for the MSM7x30 CPU. Signed-off-by: Gregory Bean Signed-off-by: David Brown Signed-off-by: Daniel Walker Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/clock-7x30.h | 168 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-msm/clock.c | 1 + arch/arm/mach-msm/clock.h | 1 + 3 files changed, 170 insertions(+) create mode 100644 arch/arm/mach-msm/clock-7x30.h (limited to 'arch') diff --git a/arch/arm/mach-msm/clock-7x30.h b/arch/arm/mach-msm/clock-7x30.h new file mode 100644 index 000000000000..e16f72f32829 --- /dev/null +++ b/arch/arm/mach-msm/clock-7x30.h @@ -0,0 +1,168 @@ +/* Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __ARCH_ARM_MACH_MSM_CLOCK_7X30_H +#define __ARCH_ARM_MACH_MSM_CLOCK_7X30_H + +enum { + L_7X30_NONE_CLK = -1, + L_7X30_ADM_CLK, + L_7X30_I2C_CLK, + L_7X30_I2C_2_CLK, + L_7X30_QUP_I2C_CLK, + L_7X30_UART1DM_CLK, + L_7X30_UART1DM_P_CLK, + L_7X30_UART2DM_CLK, + L_7X30_UART2DM_P_CLK, + L_7X30_EMDH_CLK, + L_7X30_EMDH_P_CLK, + L_7X30_PMDH_CLK, + L_7X30_PMDH_P_CLK, + L_7X30_GRP_2D_CLK, + L_7X30_GRP_2D_P_CLK, + L_7X30_GRP_3D_SRC_CLK, + L_7X30_GRP_3D_CLK, + L_7X30_GRP_3D_P_CLK, + L_7X30_IMEM_CLK, + L_7X30_SDC1_CLK, + L_7X30_SDC1_P_CLK, + L_7X30_SDC2_CLK, + L_7X30_SDC2_P_CLK, + L_7X30_SDC3_CLK, + L_7X30_SDC3_P_CLK, + L_7X30_SDC4_CLK, + L_7X30_SDC4_P_CLK, + L_7X30_MDP_CLK, + L_7X30_MDP_P_CLK, + L_7X30_MDP_LCDC_PCLK_CLK, + L_7X30_MDP_LCDC_PAD_PCLK_CLK, + L_7X30_MDP_VSYNC_CLK, + L_7X30_MI2S_CODEC_RX_M_CLK, + L_7X30_MI2S_CODEC_RX_S_CLK, + L_7X30_MI2S_CODEC_TX_M_CLK, + L_7X30_MI2S_CODEC_TX_S_CLK, + L_7X30_MI2S_M_CLK, + L_7X30_MI2S_S_CLK, + L_7X30_LPA_CODEC_CLK, + L_7X30_LPA_CORE_CLK, + L_7X30_LPA_P_CLK, + L_7X30_MIDI_CLK, + L_7X30_MDC_CLK, + L_7X30_ROTATOR_IMEM_CLK, + L_7X30_ROTATOR_P_CLK, + L_7X30_SDAC_M_CLK, + L_7X30_SDAC_CLK, + L_7X30_UART1_CLK, + L_7X30_UART2_CLK, + L_7X30_UART3_CLK, + L_7X30_TV_CLK, + L_7X30_TV_DAC_CLK, + L_7X30_TV_ENC_CLK, + L_7X30_HDMI_CLK, + L_7X30_TSIF_REF_CLK, + L_7X30_TSIF_P_CLK, + L_7X30_USB_HS_SRC_CLK, + L_7X30_USB_HS_CLK, + L_7X30_USB_HS_CORE_CLK, + L_7X30_USB_HS_P_CLK, + L_7X30_USB_HS2_CLK, + L_7X30_USB_HS2_CORE_CLK, + L_7X30_USB_HS2_P_CLK, + L_7X30_USB_HS3_CLK, + L_7X30_USB_HS3_CORE_CLK, + L_7X30_USB_HS3_P_CLK, + L_7X30_VFE_CLK, + L_7X30_VFE_P_CLK, + L_7X30_VFE_MDC_CLK, + L_7X30_VFE_CAMIF_CLK, + L_7X30_CAMIF_PAD_P_CLK, + L_7X30_CAM_M_CLK, + L_7X30_JPEG_CLK, + L_7X30_JPEG_P_CLK, + L_7X30_VPE_CLK, + L_7X30_MFC_CLK, + L_7X30_MFC_DIV2_CLK, + L_7X30_MFC_P_CLK, + L_7X30_SPI_CLK, + L_7X30_SPI_P_CLK, + L_7X30_CSI0_CLK, + L_7X30_CSI0_VFE_CLK, + L_7X30_CSI0_P_CLK, + L_7X30_CSI1_CLK, + L_7X30_CSI1_VFE_CLK, + L_7X30_CSI1_P_CLK, + L_7X30_GLBL_ROOT_CLK, + + L_7X30_AXI_LI_VG_CLK, + L_7X30_AXI_LI_GRP_CLK, + L_7X30_AXI_LI_JPEG_CLK, + L_7X30_AXI_GRP_2D_CLK, + L_7X30_AXI_MFC_CLK, + L_7X30_AXI_VPE_CLK, + L_7X30_AXI_LI_VFE_CLK, + L_7X30_AXI_LI_APPS_CLK, + L_7X30_AXI_MDP_CLK, + L_7X30_AXI_IMEM_CLK, + L_7X30_AXI_LI_ADSP_A_CLK, + L_7X30_AXI_ROTATOR_CLK, + + L_7X30_NR_CLKS +}; + +struct clk_ops; +extern struct clk_ops clk_ops_7x30; + +struct clk_ops *clk_7x30_is_local(uint32_t id); +int clk_7x30_init(void); + +void pll_enable(uint32_t pll); +void pll_disable(uint32_t pll); + +extern int internal_pwr_rail_ctl_auto(unsigned rail_id, bool enable); + +#define CLK_7X30(clk_name, clk_id, clk_dev, clk_flags) { \ + .name = clk_name, \ + .id = L_7X30_##clk_id, \ + .remote_id = P_##clk_id, \ + .flags = clk_flags, \ + .dev = clk_dev, \ + .dbg_name = #clk_id, \ + } + +#define CLK_7X30S(clk_name, l_id, r_id, clk_dev, clk_flags) { \ + .name = clk_name, \ + .id = L_7X30_##l_id, \ + .remote_id = P_##r_id, \ + .flags = clk_flags, \ + .dev = clk_dev, \ + .dbg_name = #l_id, \ + } + +#endif + diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c index 34c6a52af060..9cb1276ab749 100644 --- a/arch/arm/mach-msm/clock.c +++ b/arch/arm/mach-msm/clock.c @@ -29,6 +29,7 @@ #include "clock.h" #include "proc_comm.h" +#include "clock-7x30.h" static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clocks_lock); diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h index 598db9290422..c270b552ed13 100644 --- a/arch/arm/mach-msm/clock.h +++ b/arch/arm/mach-msm/clock.h @@ -21,6 +21,7 @@ #include #include "clock-pcom.h" +#include "clock-7x30.h" #define CLKFLAG_INVERT 0x00000001 #define CLKFLAG_NOINVERT 0x00000002 -- cgit v1.2.3-59-g8ed1b From 7b52161d14fa8a22a2387f4aa2fb7b854587830d Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 6 May 2010 12:44:57 -0700 Subject: msm: 7x30 Kconfig and makefile changes Enables basic boot support for the MSM7x30 SURF development board. Signed-off-by: Daniel Walker Signed-off-by: David Brown Signed-off-by: Gregory Bean Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Stepan Moskovchenko --- arch/arm/mach-msm/Kconfig | 14 ++++++++++++++ arch/arm/mach-msm/Makefile | 1 + 2 files changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 3dbad24cc62c..47264a76eeb3 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -11,6 +11,14 @@ config ARCH_MSM7X00A select MSM_SMD_PKG3 select CPU_V6 +config ARCH_MSM7X30 + bool "MSM7x30" + select ARCH_MSM_SCORPION + select MSM_SMD + select MSM_VIC + select CPU_V7 + select MSM_REMOTE_SPINLOCK_DEKKERS + config ARCH_QSD8X50 bool "QSD8X50" select ARCH_MSM_SCORPION @@ -47,6 +55,12 @@ config MACH_TROUT help Support for the HTC Dream, T-Mobile G1, Android ADP1 devices. +config MACH_MSM7X30_SURF + depends on ARCH_MSM7X30 + bool "MSM7x30 SURF" + help + Support for the Qualcomm MSM7x30 SURF eval board. + config MACH_QSD8X50_SURF depends on ARCH_QSD8X50 bool "QSD8x50 SURF" diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index df95f574f1f9..66677f0acaed 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -17,5 +17,6 @@ obj-$(CONFIG_MSM_SMD) += last_radio_log.o obj-$(CONFIG_MACH_TROUT) += board-trout.o devices-msm7x00.o obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o +obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o -- cgit v1.2.3-59-g8ed1b From eedfea252690435858722a8da1109d104d639087 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 20 Apr 2010 10:26:18 +0100 Subject: mtd: orion/kirkwood: add RnB line support to orion mtd driver Add support for a board to register a callback to get the state of the RnB line if it has it attached. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- arch/arm/plat-orion/include/plat/orion_nand.h | 1 + drivers/mtd/nand/orion_nand.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-orion/include/plat/orion_nand.h b/arch/arm/plat-orion/include/plat/orion_nand.h index d6a4cfa37785..9f3c180834d1 100644 --- a/arch/arm/plat-orion/include/plat/orion_nand.h +++ b/arch/arm/plat-orion/include/plat/orion_nand.h @@ -14,6 +14,7 @@ */ struct orion_nand_data { struct mtd_partition *parts; + int (*dev_ready)(struct mtd_info *mtd); u32 nr_parts; u8 ale; /* address line number connected to ALE */ u8 cle; /* address line number connected to CLE */ diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index f4444fe960a1..da6e75343052 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -126,6 +126,9 @@ static int __init orion_nand_probe(struct platform_device *pdev) if (board->width == 16) nc->options |= NAND_BUSWIDTH_16; + if (board->dev_ready) + nc->dev_ready = board->dev_ready; + platform_set_drvdata(pdev, mtd); if (nand_scan(mtd, 1)) { -- cgit v1.2.3-59-g8ed1b From 010937ec9a550e2df97f87252a9d12d8a534c6d8 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 20 Apr 2010 10:26:19 +0100 Subject: mtd: kirkwood: allow machines to register RnB callback Add a kirkwood_nand_init_rnb() call to allow boards which have RnB line detection to register this instead of a static delay. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- arch/arm/mach-kirkwood/common.c | 9 +++++++++ arch/arm/mach-kirkwood/common.h | 2 ++ 2 files changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index f759ca243925..6072eaa5e66a 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -305,6 +305,15 @@ void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, platform_device_register(&kirkwood_nand_flash); } +void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, + int (*dev_ready)(struct mtd_info *)) +{ + kirkwood_clk_ctrl |= CGC_RUNIT; + kirkwood_nand_data.parts = parts; + kirkwood_nand_data.nr_parts = nr_parts; + kirkwood_nand_data.dev_ready = dev_ready; + platform_device_register(&kirkwood_nand_flash); +} /***************************************************************************** * SoC RTC diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index d7de43464358..05e8a8a5692e 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -16,6 +16,7 @@ struct mv643xx_eth_platform_data; struct mv_sata_platform_data; struct mvsdio_platform_data; struct mtd_partition; +struct mtd_info; /* * Basic Kirkwood init functions used early by machine-setup. @@ -41,6 +42,7 @@ void kirkwood_i2c_init(void); void kirkwood_uart0_init(void); void kirkwood_uart1_init(void); void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay); +void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *)); extern int kirkwood_tclk; extern struct sys_timer kirkwood_timer; -- cgit v1.2.3-59-g8ed1b From df3c6b08d01581052040611f2dced989b83244c9 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 9 Mar 2010 15:10:31 +0900 Subject: ARM: S3C6410: Define clk_src2 register Define S3C6410 specific register - CLK_SRC2 Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/include/mach/regs-clock.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h index 3ef62741e5d1..0114eb0c1fe7 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h @@ -33,6 +33,7 @@ #define S3C_PCLK_GATE S3C_CLKREG(0x34) #define S3C_SCLK_GATE S3C_CLKREG(0x38) #define S3C_MEM0_GATE S3C_CLKREG(0x3C) +#define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C) /* CLKDIV0 */ #define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12) -- cgit v1.2.3-59-g8ed1b From bc8eb1e2fa23ff433531c8b631f76302843f52e6 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 9 Mar 2010 15:10:32 +0900 Subject: ARM: S3C6410: Declare IISCDCLK_V4 Clock Declare the source of clock provided at Xi2sCDCLK2 pin for IISv4 controller. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/clock.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index 2ac2e7d73e53..c0041eb2fdcd 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -518,6 +518,11 @@ static struct clk clk_iis_cd1 = { .id = -1, }; +static struct clk clk_iisv4_cd = { + .name = "iis_cdclk_v4", + .id = -1, +}; + static struct clk clk_pcm_cd = { .name = "pcm_cdclk", .id = -1, @@ -749,6 +754,7 @@ static struct clk *clks1[] __initdata = { &clk_ext_xtal_mux, &clk_iis_cd0, &clk_iis_cd1, + &clk_iisv4_cd, &clk_pcm_cd, &clk_mout_epll.clk, &clk_mout_mpll.clk, -- cgit v1.2.3-59-g8ed1b From 1aede2ea50a56a83dd95e7d1139a948212be2446 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 9 Mar 2010 15:10:33 +0900 Subject: ARM: S3C6410: Declare possible sources of audio-bus2 Declare possible sources of CLKAUDIO[2]/audio-bus for IISv4 controller. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/clock.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index c0041eb2fdcd..6c286d551e0b 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -554,6 +554,19 @@ static struct clksrc_sources clkset_audio1 = { .nr_sources = ARRAY_SIZE(clkset_audio1_list), }; +static struct clk *clkset_audio2_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_dout_mpll, + [2] = &clk_fin_epll, + [3] = &clk_iisv4_cd, + [4] = &clk_pcm_cd, +}; + +static struct clksrc_sources clkset_audio2 = { + .sources = clkset_audio2_list, + .nr_sources = ARRAY_SIZE(clkset_audio2_list), +}; + static struct clk *clkset_camif_list[] = { &clk_h2, }; -- cgit v1.2.3-59-g8ed1b From 835879a8848e9de93d38cdae99bda18d08545586 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 9 Mar 2010 15:10:34 +0900 Subject: ARM: S3C6410: Declare IISv4 audio-bus clock Declare 'audio-bus' clock for IISv4 controller of S3C6410. Even though the name is same as that for IISv3, the id is set to -1(just one instance of the controller is available) which helps always fetch the correct clock. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/clock.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index 6c286d551e0b..da8359589019 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -668,6 +668,16 @@ static struct clksrc_clk clksrcs[] = { .reg_src = { .reg = S3C_CLK_SRC, .shift = 10, .size = 3 }, .reg_div = { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4 }, .sources = &clkset_audio1, + }, { + .clk = { + .name = "audio-bus", + .id = -1, /* There's only one IISv4 port */ + .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C6410_CLK_SRC2, .shift = 0, .size = 3 }, + .reg_div = { .reg = S3C_CLK_DIV2, .shift = 24, .size = 4 }, + .sources = &clkset_audio2, }, { .clk = { .name = "irda-bus", -- cgit v1.2.3-59-g8ed1b From edc774ed0c7d75e92b53105b386a5b0ce94d4525 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 14 May 2010 14:45:08 +1000 Subject: crypto: omap - OMAP macros corrected Signed-off-by: Dmitry Kasatkin Acked-by: Tony Lindgren Signed-off-by: Herbert Xu --- arch/arm/mach-omap2/devices.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index beac46c48c5a..79dbf04cbaaf 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -456,7 +456,7 @@ static inline void omap_init_mcspi(void) {} #if defined(CONFIG_CRYPTO_DEV_OMAP_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP_SHAM_MODULE) -#ifdef CONFIG_ARCH_OMAP24XX +#ifdef CONFIG_ARCH_OMAP2 static struct resource omap2_sham_resources[] = { { .start = OMAP24XX_SEC_SHA1MD5_BASE, @@ -474,7 +474,7 @@ static int omap2_sham_resources_sz = ARRAY_SIZE(omap2_sham_resources); #define omap2_sham_resources_sz 0 #endif -#ifdef CONFIG_ARCH_OMAP34XX +#ifdef CONFIG_ARCH_OMAP3 static struct resource omap3_sham_resources[] = { { .start = OMAP34XX_SEC_SHA1MD5_BASE, -- cgit v1.2.3-59-g8ed1b From 9e565292270a2d55524be38835104c564ac8f795 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 13 May 2010 21:43:03 -0700 Subject: x86: Use .cfi_sections for assembly code The newer assemblers support the .cfi_sections directive so we can put the CFI from .S files into the .debug_frame section that is preserved in unstripped vmlinux and in separate debuginfo, rather than the .eh_frame section that is now discarded by vmlinux.lds.S. Signed-off-by: Roland McGrath LKML-Reference: <20100514044303.A6FE7400BE@magilla.sf.frob.com> Signed-off-by: H. Peter Anvin --- arch/x86/Makefile | 5 +++-- arch/x86/include/asm/dwarf2.h | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 0a43dc515e4c..8aa1b59b9074 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -95,8 +95,9 @@ sp-$(CONFIG_X86_64) := rsp cfi := $(call as-instr,.cfi_startproc\n.cfi_rel_offset $(sp-y)$(comma)0\n.cfi_endproc,-DCONFIG_AS_CFI=1) # is .cfi_signal_frame supported too? cfi-sigframe := $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1) -KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) -KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) +cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTIONS=1) +KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) +KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) LDFLAGS := -m elf_$(UTS_MACHINE) diff --git a/arch/x86/include/asm/dwarf2.h b/arch/x86/include/asm/dwarf2.h index ae6253ab9029..733f7e91e7a9 100644 --- a/arch/x86/include/asm/dwarf2.h +++ b/arch/x86/include/asm/dwarf2.h @@ -34,6 +34,18 @@ #define CFI_SIGNAL_FRAME #endif +#if defined(CONFIG_AS_CFI_SECTIONS) && defined(__ASSEMBLY__) + /* + * Emit CFI data in .debug_frame sections, not .eh_frame sections. + * The latter we currently just discard since we don't do DWARF + * unwinding at runtime. So only the offline DWARF information is + * useful to anyone. Note we should not use this directive if this + * file is used in the vDSO assembly, or if vmlinux.lds.S gets + * changed so it doesn't discard .eh_frame. + */ + .cfi_sections .debug_frame +#endif + #else /* -- cgit v1.2.3-59-g8ed1b From 44da397fadf19928838aaa58317a5827dd6c1ec6 Mon Sep 17 00:00:00 2001 From: "Kanigeri, Hari" Date: Thu, 22 Apr 2010 23:26:08 +0000 Subject: omap iommu: renamed omap3-iommu to omap-iommu This patch includes changes to omap3-iommu.c file to make it generic for all OMAPs. Renamed omap3-iommu.c to omap-iommu.c [Hiroshi DOYU: Remove unnecessary "iommu-y" in Makefile] Signed-off-by: Hari Kanigeri Signed-off-by: Hiroshi DOYU --- arch/arm/mach-omap2/Makefile | 5 +- arch/arm/mach-omap2/omap-iommu.c | 108 ++++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/omap3-iommu.c | 105 ------------------------------------ 3 files changed, 109 insertions(+), 109 deletions(-) create mode 100644 arch/arm/mach-omap2/omap-iommu.c delete mode 100644 arch/arm/mach-omap2/omap3-iommu.c (limited to 'arch') diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 4b9fc57770db..7d2cf0f714c0 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -89,10 +89,7 @@ obj-$(CONFIG_OMAP3_EMU) += emu.o obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o mailbox_mach-objs := mailbox.o -iommu-y += iommu2.o -iommu-$(CONFIG_ARCH_OMAP3) += omap3-iommu.o - -obj-$(CONFIG_OMAP_IOMMU) += $(iommu-y) +obj-$(CONFIG_OMAP_IOMMU) := iommu2.o omap-iommu.o i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o obj-y += $(i2c-omap-m) $(i2c-omap-y) diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c new file mode 100644 index 000000000000..416a65d5c4a9 --- /dev/null +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -0,0 +1,108 @@ +/* + * omap iommu: omap device registration + * + * Copyright (C) 2008-2009 Nokia Corporation + * + * Written by Hiroshi DOYU + * + * 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 + +#include + +struct iommu_device { + resource_size_t base; + int irq; + struct iommu_platform_data pdata; + struct resource res[2]; +}; + +#ifdef CONFIG_ARCH_OMAP3 +static struct iommu_device devices[] = { + { + .base = 0x480bd400, + .irq = 24, + .pdata = { + .name = "isp", + .nr_tlb_entries = 8, + .clk_name = "cam_ick", + }, + }, +#if defined(CONFIG_MPU_BRIDGE_IOMMU) + { + .base = 0x5d000000, + .irq = 28, + .pdata = { + .name = "iva2", + .nr_tlb_entries = 32, + .clk_name = "iva2_ck", + }, + }, +#endif +}; +#endif + +#define NR_IOMMU_DEVICES ARRAY_SIZE(devices) + +static struct platform_device *omap_iommu_pdev[NR_IOMMU_DEVICES]; + +static int __init omap_iommu_init(void) +{ + int i, err; + struct resource res[] = { + { .flags = IORESOURCE_MEM }, + { .flags = IORESOURCE_IRQ }, + }; + + for (i = 0; i < NR_IOMMU_DEVICES; i++) { + struct platform_device *pdev; + const struct iommu_device *d = &devices[i]; + + pdev = platform_device_alloc("omap-iommu", i); + if (!pdev) { + err = -ENOMEM; + goto err_out; + } + + res[0].start = d->base; + res[0].end = d->base + MMU_REG_SIZE - 1; + res[1].start = res[1].end = d->irq; + + err = platform_device_add_resources(pdev, res, + ARRAY_SIZE(res)); + if (err) + goto err_out; + err = platform_device_add_data(pdev, &d->pdata, + sizeof(d->pdata)); + if (err) + goto err_out; + err = platform_device_add(pdev); + if (err) + goto err_out; + omap_iommu_pdev[i] = pdev; + } + return 0; + +err_out: + while (i--) + platform_device_put(omap_iommu_pdev[i]); + return err; +} +module_init(omap_iommu_init); + +static void __exit omap_iommu_exit(void) +{ + int i; + + for (i = 0; i < NR_IOMMU_DEVICES; i++) + platform_device_unregister(omap_iommu_pdev[i]); +} +module_exit(omap_iommu_exit); + +MODULE_AUTHOR("Hiroshi DOYU"); +MODULE_DESCRIPTION("omap iommu: omap device registration"); +MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-omap2/omap3-iommu.c b/arch/arm/mach-omap2/omap3-iommu.c deleted file mode 100644 index fbbcb5c83367..000000000000 --- a/arch/arm/mach-omap2/omap3-iommu.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * omap iommu: omap3 device registration - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Written by Hiroshi DOYU - * - * 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 - -#include - -struct iommu_device { - resource_size_t base; - int irq; - struct iommu_platform_data pdata; - struct resource res[2]; -}; - -static struct iommu_device devices[] = { - { - .base = 0x480bd400, - .irq = 24, - .pdata = { - .name = "isp", - .nr_tlb_entries = 8, - .clk_name = "cam_ick", - }, - }, -#if defined(CONFIG_MPU_BRIDGE_IOMMU) - { - .base = 0x5d000000, - .irq = 28, - .pdata = { - .name = "iva2", - .nr_tlb_entries = 32, - .clk_name = "iva2_ck", - }, - }, -#endif -}; -#define NR_IOMMU_DEVICES ARRAY_SIZE(devices) - -static struct platform_device *omap3_iommu_pdev[NR_IOMMU_DEVICES]; - -static int __init omap3_iommu_init(void) -{ - int i, err; - struct resource res[] = { - { .flags = IORESOURCE_MEM }, - { .flags = IORESOURCE_IRQ }, - }; - - for (i = 0; i < NR_IOMMU_DEVICES; i++) { - struct platform_device *pdev; - const struct iommu_device *d = &devices[i]; - - pdev = platform_device_alloc("omap-iommu", i); - if (!pdev) { - err = -ENOMEM; - goto err_out; - } - - res[0].start = d->base; - res[0].end = d->base + MMU_REG_SIZE - 1; - res[1].start = res[1].end = d->irq; - - err = platform_device_add_resources(pdev, res, - ARRAY_SIZE(res)); - if (err) - goto err_out; - err = platform_device_add_data(pdev, &d->pdata, - sizeof(d->pdata)); - if (err) - goto err_out; - err = platform_device_add(pdev); - if (err) - goto err_out; - omap3_iommu_pdev[i] = pdev; - } - return 0; - -err_out: - while (i--) - platform_device_put(omap3_iommu_pdev[i]); - return err; -} -module_init(omap3_iommu_init); - -static void __exit omap3_iommu_exit(void) -{ - int i; - - for (i = 0; i < NR_IOMMU_DEVICES; i++) - platform_device_unregister(omap3_iommu_pdev[i]); -} -module_exit(omap3_iommu_exit); - -MODULE_AUTHOR("Hiroshi DOYU"); -MODULE_DESCRIPTION("omap iommu: omap3 device registration"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-59-g8ed1b From f779f9235f5fcaa887747ee13195efd81d09acce Mon Sep 17 00:00:00 2001 From: "Kanigeri, Hari" Date: Thu, 22 Apr 2010 23:26:09 +0000 Subject: omap iommu: support for OMAP4 This patch provides the iommu support for OMAP4 co-processors. Signed-off-by: Hari Kanigeri Signed-off-by: Hiroshi DOYU --- arch/arm/mach-omap2/omap-iommu.c | 59 +++++++++++++++++++++++++++--- arch/arm/plat-omap/include/plat/omap44xx.h | 3 ++ 2 files changed, 57 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index 416a65d5c4a9..eb9bee73e0cb 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -13,6 +13,7 @@ #include #include +#include struct iommu_device { resource_size_t base; @@ -20,9 +21,11 @@ struct iommu_device { struct iommu_platform_data pdata; struct resource res[2]; }; +static struct iommu_device *devices; +static int num_iommu_devices; #ifdef CONFIG_ARCH_OMAP3 -static struct iommu_device devices[] = { +static struct iommu_device omap3_devices[] = { { .base = 0x480bd400, .irq = 24, @@ -44,11 +47,46 @@ static struct iommu_device devices[] = { }, #endif }; +#define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices) +static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES]; +#else +#define omap3_devices NULL +#define NR_OMAP3_IOMMU_DEVICES 0 +#define omap3_iommu_pdev NULL #endif -#define NR_IOMMU_DEVICES ARRAY_SIZE(devices) +#ifdef CONFIG_ARCH_OMAP4 +static struct iommu_device omap4_devices[] = { + { + .base = OMAP4_MMU1_BASE, + .irq = INT_44XX_DUCATI_MMU_IRQ, + .pdata = { + .name = "ducati", + .nr_tlb_entries = 32, + .clk_name = "ducati_ick", + }, + }, +#if defined(CONFIG_MPU_TESLA_IOMMU) + { + .base = OMAP4_MMU2_BASE, + .irq = INT_44XX_DSP_MMU, + .pdata = { + .name = "tesla", + .nr_tlb_entries = 32, + .clk_name = "tesla_ick", + }, + }, +#endif +}; +#define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices) +static struct platform_device *omap4_iommu_pdev[NR_OMAP4_IOMMU_DEVICES]; +#else +#define omap4_devices NULL +#define NR_OMAP4_IOMMU_DEVICES 0 +#define omap4_iommu_pdev NULL +#endif -static struct platform_device *omap_iommu_pdev[NR_IOMMU_DEVICES]; +static struct platform_device **omap_iommu_pdev; static int __init omap_iommu_init(void) { @@ -58,7 +96,18 @@ static int __init omap_iommu_init(void) { .flags = IORESOURCE_IRQ }, }; - for (i = 0; i < NR_IOMMU_DEVICES; i++) { + if (cpu_is_omap34xx()) { + devices = omap3_devices; + omap_iommu_pdev = omap3_iommu_pdev; + num_iommu_devices = NR_OMAP3_IOMMU_DEVICES; + } else if (cpu_is_omap44xx()) { + devices = omap4_devices; + omap_iommu_pdev = omap4_iommu_pdev; + num_iommu_devices = NR_OMAP4_IOMMU_DEVICES; + } else + return -ENODEV; + + for (i = 0; i < num_iommu_devices; i++) { struct platform_device *pdev; const struct iommu_device *d = &devices[i]; @@ -98,7 +147,7 @@ static void __exit omap_iommu_exit(void) { int i; - for (i = 0; i < NR_IOMMU_DEVICES; i++) + for (i = 0; i < num_iommu_devices; i++) platform_device_unregister(omap_iommu_pdev[i]); } module_exit(omap_iommu_exit); diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h index b3ef1a7f53cc..bb94a0baee8a 100644 --- a/arch/arm/plat-omap/include/plat/omap44xx.h +++ b/arch/arm/plat-omap/include/plat/omap44xx.h @@ -48,5 +48,8 @@ #define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000) #define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000) +#define OMAP4_MMU1_BASE 0x55082000 +#define OMAP4_MMU2_BASE 0x4A066000 + #endif /* __ASM_ARCH_OMAP44XX_H */ -- cgit v1.2.3-59-g8ed1b From 77bc5abb70ad8d99a38fc8dd56393eaa8882881c Mon Sep 17 00:00:00 2001 From: "Kanigeri, Hari" Date: Thu, 22 Apr 2010 23:26:10 +0000 Subject: omap iommu: missing check for TLB valid entry Added the missing TLB valid entry setting for cam register Signed-off-by: Hari Kanigeri Signed-off-by: Hiroshi DOYU --- arch/arm/mach-omap2/iommu2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index 4f63dc6859a4..d29ebff6fde3 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -184,7 +184,7 @@ static struct cr_regs *omap2_alloc_cr(struct iommu *obj, struct iotlb_entry *e) if (!cr) return ERR_PTR(-ENOMEM); - cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz; + cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz | e->valid; cr->ram = e->pa | e->endian | e->elsz | e->mixed; return cr; -- cgit v1.2.3-59-g8ed1b From be6d8026a276e35cce1a2effaf5cd8bf6bd04814 Mon Sep 17 00:00:00 2001 From: "Kanigeri, Hari" Date: Thu, 22 Apr 2010 23:26:11 +0000 Subject: omap iommu: add TLB preservation support This patch adds TLB preservation support to IOMMU module Signed-off-by: Hari Kanigeri Signed-off-by: Hiroshi DOYU --- arch/arm/mach-omap2/iommu2.c | 4 +++- arch/arm/plat-omap/iommu.c | 43 ++++++++++++++++++++++++++----------------- 2 files changed, 29 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index d29ebff6fde3..e82da680d908 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -147,6 +147,7 @@ static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) printk("\n"); iommu_write_reg(obj, stat, MMU_IRQSTATUS); + omap2_iommu_disable(obj); return stat; } @@ -212,7 +213,8 @@ static ssize_t omap2_dump_cr(struct iommu *obj, struct cr_regs *cr, char *buf) char *p = buf; /* FIXME: Need more detail analysis of cam/ram */ - p += sprintf(p, "%08x %08x\n", cr->cam, cr->ram); + p += sprintf(p, "%08x %08x %01x\n", cr->cam, cr->ram, + (cr->cam & MMU_CAM_P) ? 1 : 0); return p - buf; } diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 0e137663349c..1e83facb6b77 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -172,15 +172,12 @@ static void iotlb_lock_get(struct iommu *obj, struct iotlb_lock *l) l->base = MMU_LOCK_BASE(val); l->vict = MMU_LOCK_VICT(val); - BUG_ON(l->base != 0); /* Currently no preservation is used */ } static void iotlb_lock_set(struct iommu *obj, struct iotlb_lock *l) { u32 val; - BUG_ON(l->base != 0); /* Currently no preservation is used */ - val = (l->base << MMU_LOCK_BASE_SHIFT); val |= (l->vict << MMU_LOCK_VICT_SHIFT); @@ -231,22 +228,32 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) clk_enable(obj->clk); - for (i = 0; i < obj->nr_tlb_entries; i++) { - struct cr_regs tmp; - - iotlb_lock_get(obj, &l); - l.vict = i; - iotlb_lock_set(obj, &l); - iotlb_read_cr(obj, &tmp); - if (!iotlb_cr_valid(&tmp)) - break; - } - - if (i == obj->nr_tlb_entries) { - dev_dbg(obj->dev, "%s: full: no entry\n", __func__); + iotlb_lock_get(obj, &l); + if (l.base == obj->nr_tlb_entries) { + dev_warn(obj->dev, "%s: preserve entries full\n", __func__); err = -EBUSY; goto out; } + if (!e->prsvd) { + for (i = l.base; i < obj->nr_tlb_entries; i++) { + struct cr_regs tmp; + + iotlb_lock_get(obj, &l); + l.vict = i; + iotlb_lock_set(obj, &l); + iotlb_read_cr(obj, &tmp); + if (!iotlb_cr_valid(&tmp)) + break; + } + if (i == obj->nr_tlb_entries) { + dev_dbg(obj->dev, "%s: full: no entry\n", __func__); + err = -EBUSY; + goto out; + } + } else { + l.vict = l.base; + iotlb_lock_set(obj, &l); + } cr = iotlb_alloc_cr(obj, e); if (IS_ERR(cr)) { @@ -257,9 +264,11 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) iotlb_load_cr(obj, cr); kfree(cr); + if (e->prsvd) + l.base++; /* increment victim for next tlb load */ if (++l.vict == obj->nr_tlb_entries) - l.vict = 0; + l.vict = l.base; iotlb_lock_set(obj, &l); out: clk_disable(obj->clk); -- cgit v1.2.3-59-g8ed1b From 37c2836c459181cc2ec24827f549a7238e7db39c Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Tue, 27 Apr 2010 05:37:12 +0000 Subject: omap iommu: Introduce iteration macro for iotlb entry scan There are some places to scan iotlb entries. This iteration macro could make these code a bit simpler with proceeding iotlb entries transparently. Signed-off-by: Hiroshi DOYU Tested-by: Hari Kanigeri --- arch/arm/plat-omap/iommu.c | 58 +++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 1e83facb6b77..9598d40e2763 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -25,6 +25,11 @@ #include "iopgtable.h" +#define for_each_iotlb_cr(obj, n, __i, cr) \ + for (__i = 0; \ + (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ + __i++) + /* accommodate the difference between omap1 and omap2/3 */ static const struct iommu_functions *arch_iommu; @@ -211,6 +216,20 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr, return arch_iommu->dump_cr(obj, cr, buf); } +/* only used in iotlb iteration for-loop */ +static struct cr_regs __iotlb_read_cr(struct iommu *obj, int n) +{ + struct cr_regs cr; + struct iotlb_lock l; + + iotlb_lock_get(obj, &l); + l.vict = n; + iotlb_lock_set(obj, &l); + iotlb_read_cr(obj, &cr); + + return cr; +} + /** * load_iotlb_entry - Set an iommu tlb entry * @obj: target iommu @@ -218,7 +237,6 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr, **/ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) { - int i; int err = 0; struct iotlb_lock l; struct cr_regs *cr; @@ -235,21 +253,20 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) goto out; } if (!e->prsvd) { - for (i = l.base; i < obj->nr_tlb_entries; i++) { - struct cr_regs tmp; + int i; + struct cr_regs tmp; - iotlb_lock_get(obj, &l); - l.vict = i; - iotlb_lock_set(obj, &l); - iotlb_read_cr(obj, &tmp); + for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, tmp) if (!iotlb_cr_valid(&tmp)) break; - } + if (i == obj->nr_tlb_entries) { dev_dbg(obj->dev, "%s: full: no entry\n", __func__); err = -EBUSY; goto out; } + + iotlb_lock_get(obj, &l); } else { l.vict = l.base; iotlb_lock_set(obj, &l); @@ -285,20 +302,15 @@ EXPORT_SYMBOL_GPL(load_iotlb_entry); **/ void flush_iotlb_page(struct iommu *obj, u32 da) { - struct iotlb_lock l; int i; + struct cr_regs cr; clk_enable(obj->clk); - for (i = 0; i < obj->nr_tlb_entries; i++) { - struct cr_regs cr; + for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr) { u32 start; size_t bytes; - iotlb_lock_get(obj, &l); - l.vict = i; - iotlb_lock_set(obj, &l); - iotlb_read_cr(obj, &cr); if (!iotlb_cr_valid(&cr)) continue; @@ -308,7 +320,6 @@ void flush_iotlb_page(struct iommu *obj, u32 da) if ((start <= da) && (da < start + bytes)) { dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n", __func__, start, da, bytes); - iotlb_load_cr(obj, &cr); iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); } } @@ -379,26 +390,19 @@ EXPORT_SYMBOL_GPL(iommu_dump_ctx); static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs, int num) { int i; - struct iotlb_lock saved, l; + struct iotlb_lock saved; + struct cr_regs tmp; struct cr_regs *p = crs; clk_enable(obj->clk); - iotlb_lock_get(obj, &saved); - memcpy(&l, &saved, sizeof(saved)); - for (i = 0; i < num; i++) { - struct cr_regs tmp; - - iotlb_lock_get(obj, &l); - l.vict = i; - iotlb_lock_set(obj, &l); - iotlb_read_cr(obj, &tmp); + for_each_iotlb_cr(obj, num, i, tmp) { if (!iotlb_cr_valid(&tmp)) continue; - *p++ = tmp; } + iotlb_lock_set(obj, &saved); clk_disable(obj->clk); -- cgit v1.2.3-59-g8ed1b From 347815fcc63ac4c4a975bf3ca2c889c2f843ae0d Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Tue, 4 May 2010 14:52:17 +0300 Subject: omap iommu: Make CONFIG_OMAP_IOMMU_DEBUG selectable This CONFIG_OMAP_IOMMU_DEBUG option cannot be selected because it's not visible on menu. Make this option selectable. Signed-off-by: Hiroshi DOYU Cc: Laurent Pinchart --- arch/arm/plat-omap/Kconfig | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 6da796ef82bd..78b49a626d06 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -110,8 +110,13 @@ config OMAP_IOMMU tristate config OMAP_IOMMU_DEBUG - depends on OMAP_IOMMU - tristate + tristate "Export OMAP IOMMU internals in DebugFS" + depends on OMAP_IOMMU && DEBUG_FS + help + Select this to see extensive information about + the internal state of OMAP IOMMU in debugfs. + + Say N unless you know you need this. choice prompt "System timer" -- cgit v1.2.3-59-g8ed1b From fa460b88e0cc2b4254271be2da49e68d748db727 Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Thu, 6 May 2010 16:10:18 +0300 Subject: omap iommu: Insert a gap page between IOVMAs against override Inserting a gap page between IOVMAs could detect an override on other IOVMA with iommu fault. This was originally suggested by Sakari Ailus and based on the work and comment by David Cohen. Signed-off-by: Hiroshi DOYU Cc: David Cohen Cc: Sakari Ailus --- arch/arm/plat-omap/iovmm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 65c6d1ff7237..5afe0135b979 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -287,16 +287,16 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = 0; list_for_each_entry(tmp, &obj->mmap, list) { - if ((prev_end <= start) && (start + bytes < tmp->da_start)) + if ((prev_end < start) && (start + bytes < tmp->da_start)) goto found; if (flags & IOVMF_DA_ANON) - start = roundup(tmp->da_end, alignement); + start = roundup(tmp->da_end + 1, alignement); prev_end = tmp->da_end; } - if ((start >= prev_end) && (ULONG_MAX - start >= bytes)) + if ((start > prev_end) && (ULONG_MAX - start >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- cgit v1.2.3-59-g8ed1b From e0a42e4fcb6bf9f93c7e63246738333040263e3e Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Thu, 6 May 2010 17:09:25 +0300 Subject: omap iommu: Exit iteration if no possibility of available area Searching avaialable spaces should be stopped as soon as it turns out that there's no possibility with the rest of it. Signed-off-by: Hiroshi DOYU --- arch/arm/plat-omap/iovmm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 5afe0135b979..e43983ba59c5 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -287,7 +287,10 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = 0; list_for_each_entry(tmp, &obj->mmap, list) { - if ((prev_end < start) && (start + bytes < tmp->da_start)) + if (prev_end >= start) + break; + + if (start + bytes < tmp->da_start) goto found; if (flags & IOVMF_DA_ANON) -- cgit v1.2.3-59-g8ed1b From 4abb761749abfb4ec403e4054f9dae2ee604e54f Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Thu, 6 May 2010 18:24:04 +0300 Subject: omap iommu: Reject unaligned addresses at setting page table entry This rejects unaligned device virtual address('da') and physical address('pa') and informs error to caller when a page table entry is set. Otherwise, a wrong address can be used by IO device. Signed-off-by: Hiroshi DOYU Cc: Hari Kanigeri --- arch/arm/plat-omap/iommu.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 9598d40e2763..bc094dbacee6 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -516,6 +516,12 @@ static int iopgd_alloc_section(struct iommu *obj, u32 da, u32 pa, u32 prot) { u32 *iopgd = iopgd_offset(obj, da); + if ((da | pa) & ~IOSECTION_MASK) { + dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", + __func__, da, pa, IOSECTION_SIZE); + return -EINVAL; + } + *iopgd = (pa & IOSECTION_MASK) | prot | IOPGD_SECTION; flush_iopgd_range(iopgd, iopgd); return 0; @@ -526,6 +532,12 @@ static int iopgd_alloc_super(struct iommu *obj, u32 da, u32 pa, u32 prot) u32 *iopgd = iopgd_offset(obj, da); int i; + if ((da | pa) & ~IOSUPER_MASK) { + dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", + __func__, da, pa, IOSUPER_SIZE); + return -EINVAL; + } + for (i = 0; i < 16; i++) *(iopgd + i) = (pa & IOSUPER_MASK) | prot | IOPGD_SUPER; flush_iopgd_range(iopgd, iopgd + 15); @@ -555,6 +567,12 @@ static int iopte_alloc_large(struct iommu *obj, u32 da, u32 pa, u32 prot) u32 *iopte = iopte_alloc(obj, iopgd, da); int i; + if ((da | pa) & ~IOLARGE_MASK) { + dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", + __func__, da, pa, IOLARGE_SIZE); + return -EINVAL; + } + if (IS_ERR(iopte)) return PTR_ERR(iopte); -- cgit v1.2.3-59-g8ed1b From 0ddc9324b1a842afd77e8e86698b1d1d2ffed022 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Fri, 14 May 2010 11:13:27 +0200 Subject: add descriptive comment for TIF_MEMDIE task flag declaration. Signed-off-by: Andreas Dilger Acked-by: KOSAKI Motohiro Signed-off-by: Jiri Kosina --- arch/alpha/include/asm/thread_info.h | 2 +- arch/arm/include/asm/thread_info.h | 2 +- arch/avr32/include/asm/thread_info.h | 2 +- arch/blackfin/include/asm/thread_info.h | 2 +- arch/cris/include/asm/thread_info.h | 2 +- arch/frv/include/asm/thread_info.h | 2 +- arch/h8300/include/asm/thread_info.h | 2 +- arch/ia64/include/asm/thread_info.h | 2 +- arch/m32r/include/asm/thread_info.h | 2 +- arch/m68k/include/asm/thread_info_mm.h | 2 +- arch/m68k/include/asm/thread_info_no.h | 2 +- arch/microblaze/include/asm/thread_info.h | 2 +- arch/mips/include/asm/thread_info.h | 2 +- arch/mn10300/include/asm/thread_info.h | 2 +- arch/parisc/include/asm/thread_info.h | 2 +- arch/powerpc/include/asm/thread_info.h | 2 +- arch/s390/include/asm/thread_info.h | 2 +- arch/score/include/asm/thread_info.h | 2 +- arch/sh/include/asm/thread_info.h | 2 +- arch/sparc/include/asm/thread_info_32.h | 2 +- arch/sparc/include/asm/thread_info_64.h | 2 +- arch/um/include/asm/thread_info.h | 7 +++---- arch/x86/include/asm/thread_info.h | 2 +- arch/xtensa/include/asm/thread_info.h | 2 +- 24 files changed, 26 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h index b3e888638bb7..6f32f9c84a2d 100644 --- a/arch/alpha/include/asm/thread_info.h +++ b/arch/alpha/include/asm/thread_info.h @@ -77,7 +77,7 @@ register struct thread_info *__current_thread_info __asm__("$8"); #define TIF_UAC_NOPRINT 10 /* see sysinfo.h */ #define TIF_UAC_NOFIX 11 #define TIF_UAC_SIGBUS 12 -#define TIF_MEMDIE 13 +#define TIF_MEMDIE 13 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */ #define TIF_FREEZE 16 /* is freezing for suspend */ diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index b74970ec02c4..763e29fa8530 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -141,7 +141,7 @@ extern void vfp_flush_hwstate(struct thread_info *); #define TIF_SYSCALL_TRACE 8 #define TIF_POLLING_NRFLAG 16 #define TIF_USING_IWMMXT 17 -#define TIF_MEMDIE 18 +#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_FREEZE 19 #define TIF_RESTORE_SIGMASK 20 diff --git a/arch/avr32/include/asm/thread_info.h b/arch/avr32/include/asm/thread_info.h index fd0c5d7e9337..7a9c03dcb0b6 100644 --- a/arch/avr32/include/asm/thread_info.h +++ b/arch/avr32/include/asm/thread_info.h @@ -81,7 +81,7 @@ static inline struct thread_info *current_thread_info(void) TIF_NEED_RESCHED */ #define TIF_BREAKPOINT 4 /* enter monitor mode on return */ #define TIF_SINGLE_STEP 5 /* single step in progress */ -#define TIF_MEMDIE 6 +#define TIF_MEMDIE 6 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */ #define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */ #define TIF_NOTIFY_RESUME 9 /* callback before returning to user */ diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h index e9a5614cdbb1..02560fd8a121 100644 --- a/arch/blackfin/include/asm/thread_info.h +++ b/arch/blackfin/include/asm/thread_info.h @@ -98,7 +98,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling TIF_NEED_RESCHED */ -#define TIF_MEMDIE 4 +#define TIF_MEMDIE 4 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ #define TIF_FREEZE 6 /* is freezing for suspend */ #define TIF_IRQ_SYNC 7 /* sync pipeline stage */ diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h index c3aade36c330..91776069ca80 100644 --- a/arch/cris/include/asm/thread_info.h +++ b/arch/cris/include/asm/thread_info.h @@ -85,7 +85,7 @@ struct thread_info { #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ -#define TIF_MEMDIE 17 +#define TIF_MEMDIE 17 /* is terminating due to OOM killer */ #define TIF_FREEZE 18 /* is freezing for suspend */ #define _TIF_SYSCALL_TRACE (1< Date: Wed, 12 May 2010 12:18:39 -0500 Subject: ARM: McBSP: Fix request for irq in OMAP4 In OMAP4, there is only one irq line for TX and RX paths. Use the correct irq line to avoid errors at runtime. Also, request irq line only once (instead of requesting for TX and RX). Signed-off-by: Jorge Eduardo Candelaria Acked-by: Jarkko Nikula Acked-by: Mark Brown Acked-by: Tony Lindgren Signed-off-by: Liam Girdwood --- arch/arm/mach-omap2/mcbsp.c | 12 ++++-------- arch/arm/plat-omap/mcbsp.c | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index be8fce395a58..016fe60c71ad 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -186,32 +186,28 @@ static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = { .phys_base = OMAP44XX_MCBSP1_BASE, .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX, .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX, - .rx_irq = INT_24XX_MCBSP1_IRQ_RX, - .tx_irq = INT_24XX_MCBSP1_IRQ_TX, + .tx_irq = OMAP44XX_IRQ_MCBSP1, .ops = &omap2_mcbsp_ops, }, { .phys_base = OMAP44XX_MCBSP2_BASE, .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, - .rx_irq = INT_24XX_MCBSP2_IRQ_RX, - .tx_irq = INT_24XX_MCBSP2_IRQ_TX, + .tx_irq = OMAP44XX_IRQ_MCBSP2, .ops = &omap2_mcbsp_ops, }, { .phys_base = OMAP44XX_MCBSP3_BASE, .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, - .rx_irq = INT_24XX_MCBSP3_IRQ_RX, - .tx_irq = INT_24XX_MCBSP3_IRQ_TX, + .tx_irq = OMAP44XX_IRQ_MCBSP3, .ops = &omap2_mcbsp_ops, }, { .phys_base = OMAP44XX_MCBSP4_BASE, .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, - .rx_irq = INT_24XX_MCBSP4_IRQ_RX, - .tx_irq = INT_24XX_MCBSP4_IRQ_TX, + .tx_irq = OMAP44XX_IRQ_MCBSP4, .ops = &omap2_mcbsp_ops, }, }; diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 4ff7a11b1838..8bbbb93e2128 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -778,14 +778,17 @@ int omap_mcbsp_request(unsigned int id) goto err_clk_disable; } - init_completion(&mcbsp->rx_irq_completion); - err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler, + if (mcbsp->rx_irq) { + init_completion(&mcbsp->rx_irq_completion); + err = request_irq(mcbsp->rx_irq, + omap_mcbsp_rx_irq_handler, 0, "McBSP", (void *)mcbsp); - if (err != 0) { - dev_err(mcbsp->dev, "Unable to request RX IRQ %d " - "for McBSP%d\n", mcbsp->rx_irq, - mcbsp->id); - goto err_free_irq; + if (err != 0) { + dev_err(mcbsp->dev, "Unable to request RX IRQ %d " + "for McBSP%d\n", mcbsp->rx_irq, + mcbsp->id); + goto err_free_irq; + } } } @@ -835,7 +838,8 @@ void omap_mcbsp_free(unsigned int id) if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { /* Free IRQs */ - free_irq(mcbsp->rx_irq, (void *)mcbsp); + if (mcbsp->rx_irq) + free_irq(mcbsp->rx_irq, (void *)mcbsp); free_irq(mcbsp->tx_irq, (void *)mcbsp); } -- cgit v1.2.3-59-g8ed1b From 752ec2f2d97da34abffa1abff81c96183a895b28 Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Wed, 12 May 2010 12:18:40 -0500 Subject: ARM: McBSP: Add support for omap4 in McBSP driver McBSP module in OMAP4 needs to be able to set its tx/rx threshold and enable the transmitter/receiver when starting an audio stream. Signed-off-by: Jorge Eduardo Candelaria Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Acked-by: Tony Lindgren Signed-off-by: Liam Girdwood --- arch/arm/plat-omap/mcbsp.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 8bbbb93e2128..4820cabadce4 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -488,7 +488,7 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) { struct omap_mcbsp *mcbsp; - if (!cpu_is_omap34xx()) + if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) return; if (!omap_mcbsp_check_valid_id(id)) { @@ -510,7 +510,7 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) { struct omap_mcbsp *mcbsp; - if (!cpu_is_omap34xx()) + if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) return; if (!omap_mcbsp_check_valid_id(id)) { @@ -641,7 +641,7 @@ static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) * Enable wakup behavior, smart idle and all wakeups * REVISIT: some wakeups may be unnecessary */ - if (cpu_is_omap34xx()) { + if (cpu_is_omap34xx() || cpu_is_omap44xx()) { u16 syscon; syscon = MCBSP_READ(mcbsp, SYSCON); @@ -664,7 +664,7 @@ static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) /* * Disable wakup behavior, smart idle and all wakeups */ - if (cpu_is_omap34xx()) { + if (cpu_is_omap34xx() || cpu_is_omap44xx()) { u16 syscon; syscon = MCBSP_READ(mcbsp, SYSCON); @@ -913,7 +913,7 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx) MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7)); } - if (cpu_is_omap2430() || cpu_is_omap34xx()) { + if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { /* Release the transmitter and receiver */ w = MCBSP_READ_CACHE(mcbsp, XCCR); w &= ~(tx ? XDISABLE : 0); @@ -943,7 +943,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx) /* Reset transmitter */ tx &= 1; - if (cpu_is_omap2430() || cpu_is_omap34xx()) { + if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { w = MCBSP_READ_CACHE(mcbsp, XCCR); w |= (tx ? XDISABLE : 0); MCBSP_WRITE(mcbsp, XCCR, w); @@ -953,7 +953,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx) /* Reset receiver */ rx &= 1; - if (cpu_is_omap2430() || cpu_is_omap34xx()) { + if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { w = MCBSP_READ_CACHE(mcbsp, RCCR); w |= (rx ? RDISABLE : 0); MCBSP_WRITE(mcbsp, RCCR, w); -- cgit v1.2.3-59-g8ed1b From 1ff3d7d79204612ebe2e611d2592f8898908ca00 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Fri, 14 May 2010 23:08:15 +0400 Subject: x86, perf: P4 PMU - fix counters management logic Jaswinder reported this #GP: | | Message from syslogd@ht at May 14 09:39:32 ... | kernel:[ 314.908612] EIP: [] | x86_perf_event_set_period+0x19d/0x1b2 SS:ESP 0068:edac3d70 | Ming has narrowed it down to a comparision issue between arguments with different sizes and signs. As result event index reached a wrong value which in turn led to a GP fault. At the same time it was found that p4_next_cntr has broken logic and should return the counter index only if it was not yet borrowed for another event. Reported-by: Jaswinder Singh Rajput Reported-by: Lin Ming Bisected-by: Lin Ming Tested-by: Jaswinder Singh Rajput Signed-off-by: Cyrill Gorcunov CC: Peter Zijlstra CC: Frederic Weisbecker LKML-Reference: <20100514190815.GG13509@lenovo> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_p4.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index cb875b1e2e87..424fc8de68e4 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -18,7 +18,7 @@ struct p4_event_bind { unsigned int opcode; /* Event code and ESCR selector */ unsigned int escr_msr[2]; /* ESCR MSR for this event */ - unsigned char cntr[2][P4_CNTR_LIMIT]; /* counter index (offset), -1 on abscence */ + char cntr[2][P4_CNTR_LIMIT]; /* counter index (offset), -1 on abscence */ }; struct p4_cache_event_bind { @@ -747,11 +747,11 @@ static int p4_get_escr_idx(unsigned int addr) static int p4_next_cntr(int thread, unsigned long *used_mask, struct p4_event_bind *bind) { - int i = 0, j; + int i, j; for (i = 0; i < P4_CNTR_LIMIT; i++) { - j = bind->cntr[thread][i++]; - if (j == -1 || !test_bit(j, used_mask)) + j = bind->cntr[thread][i]; + if (j != -1 && !test_bit(j, used_mask)) return j; } -- cgit v1.2.3-59-g8ed1b From 4d736b5e1cffb716bfbad669ce6aedf454779373 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sun, 4 Apr 2010 23:25:52 +0900 Subject: arm: use asm-generic/scatterlist.h Signed-off-by: FUJITA Tomonori Signed-off-by: Russell King --- arch/arm/include/asm/scatterlist.h | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/scatterlist.h b/arch/arm/include/asm/scatterlist.h index ca0a37d03400..bcda59f39941 100644 --- a/arch/arm/include/asm/scatterlist.h +++ b/arch/arm/include/asm/scatterlist.h @@ -4,24 +4,8 @@ #include #include -struct scatterlist { -#ifdef CONFIG_DEBUG_SG - unsigned long sg_magic; -#endif - unsigned long page_link; - unsigned int offset; /* buffer offset */ - dma_addr_t dma_address; /* dma address */ - unsigned int length; /* length */ -}; +#include -/* - * These macros should be used after a pci_map_sg call has been done - * to get bus addresses of each of the SG entries and their lengths. - * You should only work with the number of sg entries pci_map_sg - * returns, or alternatively stop on the first sg_dma_len(sg) which - * is 0. - */ -#define sg_dma_address(sg) ((sg)->dma_address) -#define sg_dma_len(sg) ((sg)->length) +#undef ARCH_HAS_SG_CHAIN #endif /* _ASMARM_SCATTERLIST_H */ -- cgit v1.2.3-59-g8ed1b From b7072c63c1b0611042ba6ecf0152a33c7b806e67 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sun, 2 May 2010 12:40:35 +0300 Subject: ARM: convert /proc/cpu/aligment to seq_file Convert code away from ->read_proc/->write_proc interfaces. Switch to proc_create()/proc_create_data() which makes addition of proc entries reliable wrt NULL ->proc_fops, NULL ->data and so on. Problem with ->read_proc et al is described here commit 786d7e1612f0b0adb6046f19b906609e4fe8b1ba "Fix rmmod/read/write races in /proc entries" This patch is part of an effort to remove the old simple procfs PAGE_SIZE buffer interface. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Russell King --- arch/arm/mm/alignment.c | 53 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index edddd66faac6..28b7c2776198 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -94,36 +95,29 @@ static const char *usermode_action[] = { "signal+warn" }; -static int -proc_alignment_read(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int alignment_proc_show(struct seq_file *m, void *v) { - char *p = page; - int len; - - p += sprintf(p, "User:\t\t%lu\n", ai_user); - p += sprintf(p, "System:\t\t%lu\n", ai_sys); - p += sprintf(p, "Skipped:\t%lu\n", ai_skipped); - p += sprintf(p, "Half:\t\t%lu\n", ai_half); - p += sprintf(p, "Word:\t\t%lu\n", ai_word); + seq_printf(m, "User:\t\t%lu\n", ai_user); + seq_printf(m, "System:\t\t%lu\n", ai_sys); + seq_printf(m, "Skipped:\t%lu\n", ai_skipped); + seq_printf(m, "Half:\t\t%lu\n", ai_half); + seq_printf(m, "Word:\t\t%lu\n", ai_word); if (cpu_architecture() >= CPU_ARCH_ARMv5TE) - p += sprintf(p, "DWord:\t\t%lu\n", ai_dword); - p += sprintf(p, "Multi:\t\t%lu\n", ai_multi); - p += sprintf(p, "User faults:\t%i (%s)\n", ai_usermode, + seq_printf(m, "DWord:\t\t%lu\n", ai_dword); + seq_printf(m, "Multi:\t\t%lu\n", ai_multi); + seq_printf(m, "User faults:\t%i (%s)\n", ai_usermode, usermode_action[ai_usermode]); - len = (p - page) - off; - if (len < 0) - len = 0; - - *eof = (len <= count) ? 1 : 0; - *start = page + off; + return 0; +} - return len; +static int alignment_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, alignment_proc_show, NULL); } -static int proc_alignment_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static ssize_t alignment_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { char mode; @@ -136,6 +130,13 @@ static int proc_alignment_write(struct file *file, const char __user *buffer, return count; } +static const struct file_operations alignment_proc_fops = { + .open = alignment_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = alignment_proc_write, +}; #endif /* CONFIG_PROC_FS */ union offset_union { @@ -901,12 +902,10 @@ static int __init alignment_init(void) #ifdef CONFIG_PROC_FS struct proc_dir_entry *res; - res = create_proc_entry("cpu/alignment", S_IWUSR | S_IRUGO, NULL); + res = proc_create("cpu/alignment", S_IWUSR | S_IRUGO, NULL, + &alignment_proc_fops); if (!res) return -ENOMEM; - - res->read_proc = proc_alignment_read; - res->write_proc = proc_alignment_write; #endif /* -- cgit v1.2.3-59-g8ed1b From 6262c92f51ffb074800d5a340ee16bc06758e037 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 25 Mar 2010 17:06:19 +0000 Subject: ARM: Remove useless linux/bootmem.h includes These files include linux/bootmem.h without using anything from this file; remove the unnecessary include. Acked-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/mach-clps711x/mm.c | 1 - arch/arm/mach-ixp4xx/common.c | 1 - arch/arm/mach-omap1/board-htcherald.c | 1 - arch/arm/mach-omap2/omap_hwmod.c | 1 - 4 files changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c index a7b4591205a3..986592176767 100644 --- a/arch/arm/mach-clps711x/mm.c +++ b/arch/arm/mach-clps711x/mm.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 71728d36d501..0bce09799d18 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c index e36639f66150..8e313b4b99a9 100644 --- a/arch/arm/mach-omap1/board-htcherald.c +++ b/arch/arm/mach-omap1/board-htcherald.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index c6649472ce0d..aa3e20915d72 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3-59-g8ed1b From ceb683d3bc36f213aeef0c5d79e6fbb1e16bd459 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 25 Mar 2010 18:47:20 +0000 Subject: ARM: Ensure meminfo is sorted prior to sanity_check_meminfo Acked-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/mm/init.c | 10 ---------- arch/arm/mm/mmu.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 7829cb5425f5..8bbb9a972e71 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -387,21 +386,12 @@ static void arm_memory_present(struct meminfo *mi, int node) } #endif -static int __init meminfo_cmp(const void *_a, const void *_b) -{ - const struct membank *a = _a, *b = _b; - long cmp = bank_pfn_start(a) - bank_pfn_start(b); - return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; -} - void __init bootmem_init(void) { struct meminfo *mi = &meminfo; unsigned long min, max_low, max_high; int node, initrd_node; - sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL); - /* * Locate which node contains the ramdisk image, if any. */ diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9d4da6ac28eb..91547196915c 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -1013,6 +1014,13 @@ static void __init kmap_init(void) #endif } +static int __init meminfo_cmp(const void *_a, const void *_b) +{ + const struct membank *a = _a, *b = _b; + long cmp = bank_pfn_start(a) - bank_pfn_start(b); + return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; +} + /* * paging_init() sets up the page tables, initialises the zone memory * maps, and sets up the zero page, bad page and bad page tables. @@ -1021,6 +1029,8 @@ void __init paging_init(struct machine_desc *mdesc) { void *zero_page; + sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL); + build_mem_type_table(); sanity_check_meminfo(); prepare_page_table(); -- cgit v1.2.3-59-g8ed1b From a2227120eead4ea7d2ea04d8ce0947f1dd23dedf Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 25 Mar 2010 18:56:05 +0000 Subject: ARM: Move memory mapping into mmu.c Acked-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/mm/init.c | 24 ------------------------ arch/arm/mm/mm.h | 3 --- arch/arm/mm/mmu.c | 29 ++++++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 8bbb9a972e71..105d1d4f420b 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -225,20 +225,6 @@ static int __init check_initrd(struct meminfo *mi) return initrd_node; } -static inline void map_memory_bank(struct membank *bank) -{ -#ifdef CONFIG_MMU - struct map_desc map; - - map.pfn = bank_pfn_start(bank); - map.virtual = __phys_to_virt(bank_phys_start(bank)); - map.length = bank_phys_size(bank); - map.type = MT_MEMORY; - - create_mapping(&map); -#endif -} - static void __init bootmem_init_node(int node, struct meminfo *mi, unsigned long start_pfn, unsigned long end_pfn) { @@ -247,16 +233,6 @@ static void __init bootmem_init_node(int node, struct meminfo *mi, pg_data_t *pgdat; int i; - /* - * Map the memory banks for this node. - */ - for_each_nodebank(i, mi, node) { - struct membank *bank = &mi->bank[i]; - - if (!bank->highmem) - map_memory_bank(bank); - } - /* * Allocate the bootmem bitmap page. */ diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index a888363398f8..815d08eecbb0 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -28,10 +28,7 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page #endif -struct map_desc; -struct meminfo; struct pglist_data; -void __init create_mapping(struct map_desc *md); void __init bootmem_init(void); void reserve_node_zero(struct pglist_data *pgdat); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 91547196915c..69852003675f 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -600,7 +600,7 @@ static void __init create_36bit_mapping(struct map_desc *md, * offsets, and we take full advantage of sections and * supersections. */ -void __init create_mapping(struct map_desc *md) +static void __init create_mapping(struct map_desc *md) { unsigned long phys, addr, length, end; const struct mem_type *type; @@ -1014,6 +1014,32 @@ static void __init kmap_init(void) #endif } +static inline void map_memory_bank(struct membank *bank) +{ + struct map_desc map; + + map.pfn = bank_pfn_start(bank); + map.virtual = __phys_to_virt(bank_phys_start(bank)); + map.length = bank_phys_size(bank); + map.type = MT_MEMORY; + + create_mapping(&map); +} + +static void __init map_lowmem(void) +{ + struct meminfo *mi = &meminfo; + int i; + + /* Map all the lowmem memory banks. */ + for (i = 0; i < mi->nr_banks; i++) { + struct membank *bank = &mi->bank[i]; + + if (!bank->highmem) + map_memory_bank(bank); + } +} + static int __init meminfo_cmp(const void *_a, const void *_b) { const struct membank *a = _a, *b = _b; @@ -1034,6 +1060,7 @@ void __init paging_init(struct machine_desc *mdesc) build_mem_type_table(); sanity_check_meminfo(); prepare_page_table(); + map_lowmem(); bootmem_init(); devicemaps_init(mdesc); kmap_init(); -- cgit v1.2.3-59-g8ed1b From 64039be8226b9f6c80c704d94ac9891eee4a274c Mon Sep 17 00:00:00 2001 From: Jason McMullan Date: Wed, 5 May 2010 18:59:37 +0100 Subject: ARM: 6094/1: Extend cache-l2x0 to support the 16-way PL310 The L310 cache controller's interface is almost identical to the L210. One major difference is that the PL310 can have up to 16 ways. This change uses the cache's part ID and the Associativity bits in the AUX_CTRL register to determine the number of ways. Also, this version prints out the CACHE_ID and AUX_CTRL registers. Acked-by: Will Deacon Acked-by: Acked-by: Catalin Marinas Signed-off-by: Jason S. McMullan Signed-off-by: Russell King --- arch/arm/include/asm/hardware/cache-l2x0.h | 3 +++ arch/arm/mm/cache-l2x0.c | 39 ++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index cdb9022716fd..6bcba48800fe 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -21,6 +21,9 @@ #define __ASM_ARM_HARDWARE_L2X0_H #define L2X0_CACHE_ID 0x000 +#define L2X0_CACHE_ID_PART_MASK (0xf << 6) +#define L2X0_CACHE_ID_PART_L210 (1 << 6) +#define L2X0_CACHE_ID_PART_L310 (3 << 6) #define L2X0_CACHE_TYPE 0x004 #define L2X0_CTRL 0x100 #define L2X0_AUX_CTRL 0x104 diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 07334632d3e2..78f0fc8595e2 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -27,6 +27,7 @@ static void __iomem *l2x0_base; static DEFINE_SPINLOCK(l2x0_lock); +static uint32_t l2x0_way_mask; /* Bitmask of active ways */ static inline void cache_wait(void __iomem *reg, unsigned long mask) { @@ -99,8 +100,8 @@ static inline void l2x0_inv_all(void) /* invalidate all ways */ spin_lock_irqsave(&l2x0_lock, flags); - writel(0xff, l2x0_base + L2X0_INV_WAY); - cache_wait(l2x0_base + L2X0_INV_WAY, 0xff); + writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); + cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); cache_sync(); spin_unlock_irqrestore(&l2x0_lock, flags); } @@ -199,9 +200,37 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) { __u32 aux; + __u32 cache_id; + int ways; + const char *type; l2x0_base = base; + cache_id = readl(l2x0_base + L2X0_CACHE_ID); + aux = readl(l2x0_base + L2X0_AUX_CTRL); + + /* Determine the number of ways */ + switch (cache_id & L2X0_CACHE_ID_PART_MASK) { + case L2X0_CACHE_ID_PART_L310: + if (aux & (1 << 16)) + ways = 16; + else + ways = 8; + type = "L310"; + break; + case L2X0_CACHE_ID_PART_L210: + ways = (aux >> 13) & 0xf; + type = "L210"; + break; + default: + /* Assume unknown chips have 8 ways */ + ways = 8; + type = "L2x0 series"; + break; + } + + l2x0_way_mask = (1 << ways) - 1; + /* * Check if l2x0 controller is already enabled. * If you are booting from non-secure mode @@ -210,8 +239,6 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) if (!(readl(l2x0_base + L2X0_CTRL) & 1)) { /* l2x0 controller is disabled */ - - aux = readl(l2x0_base + L2X0_AUX_CTRL); aux &= aux_mask; aux |= aux_val; writel(aux, l2x0_base + L2X0_AUX_CTRL); @@ -226,5 +253,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) outer_cache.clean_range = l2x0_clean_range; outer_cache.flush_range = l2x0_flush_range; - printk(KERN_INFO "L2X0 cache controller enabled\n"); + printk(KERN_INFO "%s cache controller enabled\n", type); + printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n", + ways, cache_id, aux); } -- cgit v1.2.3-59-g8ed1b From 75070612c49c0bb976bb9221d051b20316ad1bc7 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 14 May 2010 15:18:54 +0100 Subject: ARM: 6132/1: PL330: Add common core driver PL330 is a configurable DMA controller PrimeCell device. The register map of the device is well defined. The configuration of a particular implementation can be read from the six configuration registers CR0-4,Dn. This patch implements a driver for the specification:- http://infocenter.arm.com/help/topic/com.arm.doc.ddi0424a/DDI0424A_dmac_pl330_r0p0_trm.pdf The exported interface should be sufficient to implement a driver for any DMA API. Signed-off-by: Jassi Brar Signed-off-by: Russell King --- arch/arm/common/Kconfig | 3 + arch/arm/common/Makefile | 1 + arch/arm/common/pl330.c | 1966 +++++++++++++++++++++++++++++++++ arch/arm/include/asm/hardware/pl330.h | 217 ++++ 4 files changed, 2187 insertions(+) create mode 100644 arch/arm/common/pl330.c create mode 100644 arch/arm/include/asm/hardware/pl330.h (limited to 'arch') diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index b64bb78d784c..cf9059091884 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -18,6 +18,9 @@ config ICST525 config ICST307 bool +config PL330 + bool + config SA1111 bool select DMABOUNCE if !ARCH_PXA diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 76be7ff2a7ca..df20c2650206 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_ARM_GIC) += gic.o obj-$(CONFIG_ARM_VIC) += vic.o obj-$(CONFIG_ICST525) += icst525.o obj-$(CONFIG_ICST307) += icst307.o +obj-$(CONFIG_PL330) += pl330.o obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c new file mode 100644 index 000000000000..5ebbab6242a7 --- /dev/null +++ b/arch/arm/common/pl330.c @@ -0,0 +1,1966 @@ +/* linux/arch/arm/common/pl330.c + * + * Copyright (C) 2010 Samsung Electronics Co Ltd. + * Jaswinder Singh + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Register and Bit field Definitions */ +#define DS 0x0 +#define DS_ST_STOP 0x0 +#define DS_ST_EXEC 0x1 +#define DS_ST_CMISS 0x2 +#define DS_ST_UPDTPC 0x3 +#define DS_ST_WFE 0x4 +#define DS_ST_ATBRR 0x5 +#define DS_ST_QBUSY 0x6 +#define DS_ST_WFP 0x7 +#define DS_ST_KILL 0x8 +#define DS_ST_CMPLT 0x9 +#define DS_ST_FLTCMP 0xe +#define DS_ST_FAULT 0xf + +#define DPC 0x4 +#define INTEN 0x20 +#define ES 0x24 +#define INTSTATUS 0x28 +#define INTCLR 0x2c +#define FSM 0x30 +#define FSC 0x34 +#define FTM 0x38 + +#define _FTC 0x40 +#define FTC(n) (_FTC + (n)*0x4) + +#define _CS 0x100 +#define CS(n) (_CS + (n)*0x8) +#define CS_CNS (1 << 21) + +#define _CPC 0x104 +#define CPC(n) (_CPC + (n)*0x8) + +#define _SA 0x400 +#define SA(n) (_SA + (n)*0x20) + +#define _DA 0x404 +#define DA(n) (_DA + (n)*0x20) + +#define _CC 0x408 +#define CC(n) (_CC + (n)*0x20) + +#define CC_SRCINC (1 << 0) +#define CC_DSTINC (1 << 14) +#define CC_SRCPRI (1 << 8) +#define CC_DSTPRI (1 << 22) +#define CC_SRCNS (1 << 9) +#define CC_DSTNS (1 << 23) +#define CC_SRCIA (1 << 10) +#define CC_DSTIA (1 << 24) +#define CC_SRCBRSTLEN_SHFT 4 +#define CC_DSTBRSTLEN_SHFT 18 +#define CC_SRCBRSTSIZE_SHFT 1 +#define CC_DSTBRSTSIZE_SHFT 15 +#define CC_SRCCCTRL_SHFT 11 +#define CC_SRCCCTRL_MASK 0x7 +#define CC_DSTCCTRL_SHFT 25 +#define CC_DRCCCTRL_MASK 0x7 +#define CC_SWAP_SHFT 28 + +#define _LC0 0x40c +#define LC0(n) (_LC0 + (n)*0x20) + +#define _LC1 0x410 +#define LC1(n) (_LC1 + (n)*0x20) + +#define DBGSTATUS 0xd00 +#define DBG_BUSY (1 << 0) + +#define DBGCMD 0xd04 +#define DBGINST0 0xd08 +#define DBGINST1 0xd0c + +#define CR0 0xe00 +#define CR1 0xe04 +#define CR2 0xe08 +#define CR3 0xe0c +#define CR4 0xe10 +#define CRD 0xe14 + +#define PERIPH_ID 0xfe0 +#define PCELL_ID 0xff0 + +#define CR0_PERIPH_REQ_SET (1 << 0) +#define CR0_BOOT_EN_SET (1 << 1) +#define CR0_BOOT_MAN_NS (1 << 2) +#define CR0_NUM_CHANS_SHIFT 4 +#define CR0_NUM_CHANS_MASK 0x7 +#define CR0_NUM_PERIPH_SHIFT 12 +#define CR0_NUM_PERIPH_MASK 0x1f +#define CR0_NUM_EVENTS_SHIFT 17 +#define CR0_NUM_EVENTS_MASK 0x1f + +#define CR1_ICACHE_LEN_SHIFT 0 +#define CR1_ICACHE_LEN_MASK 0x7 +#define CR1_NUM_ICACHELINES_SHIFT 4 +#define CR1_NUM_ICACHELINES_MASK 0xf + +#define CRD_DATA_WIDTH_SHIFT 0 +#define CRD_DATA_WIDTH_MASK 0x7 +#define CRD_WR_CAP_SHIFT 4 +#define CRD_WR_CAP_MASK 0x7 +#define CRD_WR_Q_DEP_SHIFT 8 +#define CRD_WR_Q_DEP_MASK 0xf +#define CRD_RD_CAP_SHIFT 12 +#define CRD_RD_CAP_MASK 0x7 +#define CRD_RD_Q_DEP_SHIFT 16 +#define CRD_RD_Q_DEP_MASK 0xf +#define CRD_DATA_BUFF_SHIFT 20 +#define CRD_DATA_BUFF_MASK 0x3ff + +#define PART 0x330 +#define DESIGNER 0x41 +#define REVISION 0x0 +#define INTEG_CFG 0x0 +#define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12) \ + | (REVISION << 20) | (INTEG_CFG << 24)) + +#define PCELL_ID_VAL 0xb105f00d + +#define PL330_STATE_STOPPED (1 << 0) +#define PL330_STATE_EXECUTING (1 << 1) +#define PL330_STATE_WFE (1 << 2) +#define PL330_STATE_FAULTING (1 << 3) +#define PL330_STATE_COMPLETING (1 << 4) +#define PL330_STATE_WFP (1 << 5) +#define PL330_STATE_KILLING (1 << 6) +#define PL330_STATE_FAULT_COMPLETING (1 << 7) +#define PL330_STATE_CACHEMISS (1 << 8) +#define PL330_STATE_UPDTPC (1 << 9) +#define PL330_STATE_ATBARRIER (1 << 10) +#define PL330_STATE_QUEUEBUSY (1 << 11) +#define PL330_STATE_INVALID (1 << 15) + +#define PL330_STABLE_STATES (PL330_STATE_STOPPED | PL330_STATE_EXECUTING \ + | PL330_STATE_WFE | PL330_STATE_FAULTING) + +#define CMD_DMAADDH 0x54 +#define CMD_DMAEND 0x00 +#define CMD_DMAFLUSHP 0x35 +#define CMD_DMAGO 0xa0 +#define CMD_DMALD 0x04 +#define CMD_DMALDP 0x25 +#define CMD_DMALP 0x20 +#define CMD_DMALPEND 0x28 +#define CMD_DMAKILL 0x01 +#define CMD_DMAMOV 0xbc +#define CMD_DMANOP 0x18 +#define CMD_DMARMB 0x12 +#define CMD_DMASEV 0x34 +#define CMD_DMAST 0x08 +#define CMD_DMASTP 0x29 +#define CMD_DMASTZ 0x0c +#define CMD_DMAWFE 0x36 +#define CMD_DMAWFP 0x30 +#define CMD_DMAWMB 0x13 + +#define SZ_DMAADDH 3 +#define SZ_DMAEND 1 +#define SZ_DMAFLUSHP 2 +#define SZ_DMALD 1 +#define SZ_DMALDP 2 +#define SZ_DMALP 2 +#define SZ_DMALPEND 2 +#define SZ_DMAKILL 1 +#define SZ_DMAMOV 6 +#define SZ_DMANOP 1 +#define SZ_DMARMB 1 +#define SZ_DMASEV 2 +#define SZ_DMAST 1 +#define SZ_DMASTP 2 +#define SZ_DMASTZ 1 +#define SZ_DMAWFE 2 +#define SZ_DMAWFP 2 +#define SZ_DMAWMB 1 +#define SZ_DMAGO 6 + +#define BRST_LEN(ccr) ((((ccr) >> CC_SRCBRSTLEN_SHFT) & 0xf) + 1) +#define BRST_SIZE(ccr) (1 << (((ccr) >> CC_SRCBRSTSIZE_SHFT) & 0x7)) + +#define BYTE_TO_BURST(b, ccr) ((b) / BRST_SIZE(ccr) / BRST_LEN(ccr)) +#define BURST_TO_BYTE(c, ccr) ((c) * BRST_SIZE(ccr) * BRST_LEN(ccr)) + +/* + * With 256 bytes, we can do more than 2.5MB and 5MB xfers per req + * at 1byte/burst for P<->M and M<->M respectively. + * For typical scenario, at 1word/burst, 10MB and 20MB xfers per req + * should be enough for P<->M and M<->M respectively. + */ +#define MCODE_BUFF_PER_REQ 256 + +/* + * Mark a _pl330_req as free. + * We do it by writing DMAEND as the first instruction + * because no valid request is going to have DMAEND as + * its first instruction to execute. + */ +#define MARK_FREE(req) do { \ + _emit_END(0, (req)->mc_cpu); \ + (req)->mc_len = 0; \ + } while (0) + +/* If the _pl330_req is available to the client */ +#define IS_FREE(req) (*((u8 *)((req)->mc_cpu)) == CMD_DMAEND) + +/* Use this _only_ to wait on transient states */ +#define UNTIL(t, s) while (!(_state(t) & (s))) cpu_relax(); + +#ifdef PL330_DEBUG_MCGEN +static unsigned cmd_line; +#define PL330_DBGCMD_DUMP(off, x...) do { \ + printk("%x:", cmd_line); \ + printk(x); \ + cmd_line += off; \ + } while (0) +#define PL330_DBGMC_START(addr) (cmd_line = addr) +#else +#define PL330_DBGCMD_DUMP(off, x...) do {} while (0) +#define PL330_DBGMC_START(addr) do {} while (0) +#endif + +struct _xfer_spec { + u32 ccr; + struct pl330_req *r; + struct pl330_xfer *x; +}; + +enum dmamov_dst { + SAR = 0, + CCR, + DAR, +}; + +enum pl330_dst { + SRC = 0, + DST, +}; + +enum pl330_cond { + SINGLE, + BURST, + ALWAYS, +}; + +struct _pl330_req { + u32 mc_bus; + void *mc_cpu; + /* Number of bytes taken to setup MC for the req */ + u32 mc_len; + struct pl330_req *r; + /* Hook to attach to DMAC's list of reqs with due callback */ + struct list_head rqd; +}; + +/* ToBeDone for tasklet */ +struct _pl330_tbd { + bool reset_dmac; + bool reset_mngr; + u8 reset_chan; +}; + +/* A DMAC Thread */ +struct pl330_thread { + u8 id; + int ev; + /* If the channel is not yet acquired by any client */ + bool free; + /* Parent DMAC */ + struct pl330_dmac *dmac; + /* Only two at a time */ + struct _pl330_req req[2]; + /* Index of the last submitted request */ + unsigned lstenq; +}; + +enum pl330_dmac_state { + UNINIT, + INIT, + DYING, +}; + +/* A DMAC */ +struct pl330_dmac { + spinlock_t lock; + /* Holds list of reqs with due callbacks */ + struct list_head req_done; + /* Pointer to platform specific stuff */ + struct pl330_info *pinfo; + /* Maximum possible events/irqs */ + int events[32]; + /* BUS address of MicroCode buffer */ + u32 mcode_bus; + /* CPU address of MicroCode buffer */ + void *mcode_cpu; + /* List of all Channel threads */ + struct pl330_thread *channels; + /* Pointer to the MANAGER thread */ + struct pl330_thread *manager; + /* To handle bad news in interrupt */ + struct tasklet_struct tasks; + struct _pl330_tbd dmac_tbd; + /* State of DMAC operation */ + enum pl330_dmac_state state; +}; + +static inline void _callback(struct pl330_req *r, enum pl330_op_err err) +{ + if (r && r->xfer_cb) + r->xfer_cb(r->token, err); +} + +static inline bool _queue_empty(struct pl330_thread *thrd) +{ + return (IS_FREE(&thrd->req[0]) && IS_FREE(&thrd->req[1])) + ? true : false; +} + +static inline bool _queue_full(struct pl330_thread *thrd) +{ + return (IS_FREE(&thrd->req[0]) || IS_FREE(&thrd->req[1])) + ? false : true; +} + +static inline bool is_manager(struct pl330_thread *thrd) +{ + struct pl330_dmac *pl330 = thrd->dmac; + + /* MANAGER is indexed at the end */ + if (thrd->id == pl330->pinfo->pcfg.num_chan) + return true; + else + return false; +} + +/* If manager of the thread is in Non-Secure mode */ +static inline bool _manager_ns(struct pl330_thread *thrd) +{ + struct pl330_dmac *pl330 = thrd->dmac; + + return (pl330->pinfo->pcfg.mode & DMAC_MODE_NS) ? true : false; +} + +static inline u32 get_id(struct pl330_info *pi, u32 off) +{ + void __iomem *regs = pi->base; + u32 id = 0; + + id |= (readb(regs + off + 0x0) << 0); + id |= (readb(regs + off + 0x4) << 8); + id |= (readb(regs + off + 0x8) << 16); + id |= (readb(regs + off + 0xc) << 24); + + return id; +} + +static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[], + enum pl330_dst da, u16 val) +{ + if (dry_run) + return SZ_DMAADDH; + + buf[0] = CMD_DMAADDH; + buf[0] |= (da << 1); + *((u16 *)&buf[1]) = val; + + PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n", + da == 1 ? "DA" : "SA", val); + + return SZ_DMAADDH; +} + +static inline u32 _emit_END(unsigned dry_run, u8 buf[]) +{ + if (dry_run) + return SZ_DMAEND; + + buf[0] = CMD_DMAEND; + + PL330_DBGCMD_DUMP(SZ_DMAEND, "\tDMAEND\n"); + + return SZ_DMAEND; +} + +static inline u32 _emit_FLUSHP(unsigned dry_run, u8 buf[], u8 peri) +{ + if (dry_run) + return SZ_DMAFLUSHP; + + buf[0] = CMD_DMAFLUSHP; + + peri &= 0x1f; + peri <<= 3; + buf[1] = peri; + + PL330_DBGCMD_DUMP(SZ_DMAFLUSHP, "\tDMAFLUSHP %u\n", peri >> 3); + + return SZ_DMAFLUSHP; +} + +static inline u32 _emit_LD(unsigned dry_run, u8 buf[], enum pl330_cond cond) +{ + if (dry_run) + return SZ_DMALD; + + buf[0] = CMD_DMALD; + + if (cond == SINGLE) + buf[0] |= (0 << 1) | (1 << 0); + else if (cond == BURST) + buf[0] |= (1 << 1) | (1 << 0); + + PL330_DBGCMD_DUMP(SZ_DMALD, "\tDMALD%c\n", + cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A')); + + return SZ_DMALD; +} + +static inline u32 _emit_LDP(unsigned dry_run, u8 buf[], + enum pl330_cond cond, u8 peri) +{ + if (dry_run) + return SZ_DMALDP; + + buf[0] = CMD_DMALDP; + + if (cond == BURST) + buf[0] |= (1 << 1); + + peri &= 0x1f; + peri <<= 3; + buf[1] = peri; + + PL330_DBGCMD_DUMP(SZ_DMALDP, "\tDMALDP%c %u\n", + cond == SINGLE ? 'S' : 'B', peri >> 3); + + return SZ_DMALDP; +} + +static inline u32 _emit_LP(unsigned dry_run, u8 buf[], + unsigned loop, u8 cnt) +{ + if (dry_run) + return SZ_DMALP; + + buf[0] = CMD_DMALP; + + if (loop) + buf[0] |= (1 << 1); + + cnt--; /* DMAC increments by 1 internally */ + buf[1] = cnt; + + PL330_DBGCMD_DUMP(SZ_DMALP, "\tDMALP_%c %u\n", loop ? '1' : '0', cnt); + + return SZ_DMALP; +} + +struct _arg_LPEND { + enum pl330_cond cond; + bool forever; + unsigned loop; + u8 bjump; +}; + +static inline u32 _emit_LPEND(unsigned dry_run, u8 buf[], + const struct _arg_LPEND *arg) +{ + enum pl330_cond cond = arg->cond; + bool forever = arg->forever; + unsigned loop = arg->loop; + u8 bjump = arg->bjump; + + if (dry_run) + return SZ_DMALPEND; + + buf[0] = CMD_DMALPEND; + + if (loop) + buf[0] |= (1 << 2); + + if (!forever) + buf[0] |= (1 << 4); + + if (cond == SINGLE) + buf[0] |= (0 << 1) | (1 << 0); + else if (cond == BURST) + buf[0] |= (1 << 1) | (1 << 0); + + buf[1] = bjump; + + PL330_DBGCMD_DUMP(SZ_DMALPEND, "\tDMALP%s%c_%c bjmpto_%x\n", + forever ? "FE" : "END", + cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'), + loop ? '1' : '0', + bjump); + + return SZ_DMALPEND; +} + +static inline u32 _emit_KILL(unsigned dry_run, u8 buf[]) +{ + if (dry_run) + return SZ_DMAKILL; + + buf[0] = CMD_DMAKILL; + + return SZ_DMAKILL; +} + +static inline u32 _emit_MOV(unsigned dry_run, u8 buf[], + enum dmamov_dst dst, u32 val) +{ + if (dry_run) + return SZ_DMAMOV; + + buf[0] = CMD_DMAMOV; + buf[1] = dst; + *((u32 *)&buf[2]) = val; + + PL330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n", + dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val); + + return SZ_DMAMOV; +} + +static inline u32 _emit_NOP(unsigned dry_run, u8 buf[]) +{ + if (dry_run) + return SZ_DMANOP; + + buf[0] = CMD_DMANOP; + + PL330_DBGCMD_DUMP(SZ_DMANOP, "\tDMANOP\n"); + + return SZ_DMANOP; +} + +static inline u32 _emit_RMB(unsigned dry_run, u8 buf[]) +{ + if (dry_run) + return SZ_DMARMB; + + buf[0] = CMD_DMARMB; + + PL330_DBGCMD_DUMP(SZ_DMARMB, "\tDMARMB\n"); + + return SZ_DMARMB; +} + +static inline u32 _emit_SEV(unsigned dry_run, u8 buf[], u8 ev) +{ + if (dry_run) + return SZ_DMASEV; + + buf[0] = CMD_DMASEV; + + ev &= 0x1f; + ev <<= 3; + buf[1] = ev; + + PL330_DBGCMD_DUMP(SZ_DMASEV, "\tDMASEV %u\n", ev >> 3); + + return SZ_DMASEV; +} + +static inline u32 _emit_ST(unsigned dry_run, u8 buf[], enum pl330_cond cond) +{ + if (dry_run) + return SZ_DMAST; + + buf[0] = CMD_DMAST; + + if (cond == SINGLE) + buf[0] |= (0 << 1) | (1 << 0); + else if (cond == BURST) + buf[0] |= (1 << 1) | (1 << 0); + + PL330_DBGCMD_DUMP(SZ_DMAST, "\tDMAST%c\n", + cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A')); + + return SZ_DMAST; +} + +static inline u32 _emit_STP(unsigned dry_run, u8 buf[], + enum pl330_cond cond, u8 peri) +{ + if (dry_run) + return SZ_DMASTP; + + buf[0] = CMD_DMASTP; + + if (cond == BURST) + buf[0] |= (1 << 1); + + peri &= 0x1f; + peri <<= 3; + buf[1] = peri; + + PL330_DBGCMD_DUMP(SZ_DMASTP, "\tDMASTP%c %u\n", + cond == SINGLE ? 'S' : 'B', peri >> 3); + + return SZ_DMASTP; +} + +static inline u32 _emit_STZ(unsigned dry_run, u8 buf[]) +{ + if (dry_run) + return SZ_DMASTZ; + + buf[0] = CMD_DMASTZ; + + PL330_DBGCMD_DUMP(SZ_DMASTZ, "\tDMASTZ\n"); + + return SZ_DMASTZ; +} + +static inline u32 _emit_WFE(unsigned dry_run, u8 buf[], u8 ev, + unsigned invalidate) +{ + if (dry_run) + return SZ_DMAWFE; + + buf[0] = CMD_DMAWFE; + + ev &= 0x1f; + ev <<= 3; + buf[1] = ev; + + if (invalidate) + buf[1] |= (1 << 1); + + PL330_DBGCMD_DUMP(SZ_DMAWFE, "\tDMAWFE %u%s\n", + ev >> 3, invalidate ? ", I" : ""); + + return SZ_DMAWFE; +} + +static inline u32 _emit_WFP(unsigned dry_run, u8 buf[], + enum pl330_cond cond, u8 peri) +{ + if (dry_run) + return SZ_DMAWFP; + + buf[0] = CMD_DMAWFP; + + if (cond == SINGLE) + buf[0] |= (0 << 1) | (0 << 0); + else if (cond == BURST) + buf[0] |= (1 << 1) | (0 << 0); + else + buf[0] |= (0 << 1) | (1 << 0); + + peri &= 0x1f; + peri <<= 3; + buf[1] = peri; + + PL330_DBGCMD_DUMP(SZ_DMAWFP, "\tDMAWFP%c %u\n", + cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'P'), peri >> 3); + + return SZ_DMAWFP; +} + +static inline u32 _emit_WMB(unsigned dry_run, u8 buf[]) +{ + if (dry_run) + return SZ_DMAWMB; + + buf[0] = CMD_DMAWMB; + + PL330_DBGCMD_DUMP(SZ_DMAWMB, "\tDMAWMB\n"); + + return SZ_DMAWMB; +} + +struct _arg_GO { + u8 chan; + u32 addr; + unsigned ns; +}; + +static inline u32 _emit_GO(unsigned dry_run, u8 buf[], + const struct _arg_GO *arg) +{ + u8 chan = arg->chan; + u32 addr = arg->addr; + unsigned ns = arg->ns; + + if (dry_run) + return SZ_DMAGO; + + buf[0] = CMD_DMAGO; + buf[0] |= (ns << 1); + + buf[1] = chan & 0x7; + + *((u32 *)&buf[2]) = addr; + + return SZ_DMAGO; +} + +#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) + +/* Returns Time-Out */ +static bool _until_dmac_idle(struct pl330_thread *thrd) +{ + void __iomem *regs = thrd->dmac->pinfo->base; + unsigned long loops = msecs_to_loops(5); + + do { + /* Until Manager is Idle */ + if (!(readl(regs + DBGSTATUS) & DBG_BUSY)) + break; + + cpu_relax(); + } while (--loops); + + if (!loops) + return true; + + return false; +} + +static inline void _execute_DBGINSN(struct pl330_thread *thrd, + u8 insn[], bool as_manager) +{ + void __iomem *regs = thrd->dmac->pinfo->base; + u32 val; + + val = (insn[0] << 16) | (insn[1] << 24); + if (!as_manager) { + val |= (1 << 0); + val |= (thrd->id << 8); /* Channel Number */ + } + writel(val, regs + DBGINST0); + + val = *((u32 *)&insn[2]); + writel(val, regs + DBGINST1); + + /* If timed out due to halted state-machine */ + if (_until_dmac_idle(thrd)) { + dev_err(thrd->dmac->pinfo->dev, "DMAC halted!\n"); + return; + } + + /* Get going */ + writel(0, regs + DBGCMD); +} + +static inline u32 _state(struct pl330_thread *thrd) +{ + void __iomem *regs = thrd->dmac->pinfo->base; + u32 val; + + if (is_manager(thrd)) + val = readl(regs + DS) & 0xf; + else + val = readl(regs + CS(thrd->id)) & 0xf; + + switch (val) { + case DS_ST_STOP: + return PL330_STATE_STOPPED; + case DS_ST_EXEC: + return PL330_STATE_EXECUTING; + case DS_ST_CMISS: + return PL330_STATE_CACHEMISS; + case DS_ST_UPDTPC: + return PL330_STATE_UPDTPC; + case DS_ST_WFE: + return PL330_STATE_WFE; + case DS_ST_FAULT: + return PL330_STATE_FAULTING; + case DS_ST_ATBRR: + if (is_manager(thrd)) + return PL330_STATE_INVALID; + else + return PL330_STATE_ATBARRIER; + case DS_ST_QBUSY: + if (is_manager(thrd)) + return PL330_STATE_INVALID; + else + return PL330_STATE_QUEUEBUSY; + case DS_ST_WFP: + if (is_manager(thrd)) + return PL330_STATE_INVALID; + else + return PL330_STATE_WFP; + case DS_ST_KILL: + if (is_manager(thrd)) + return PL330_STATE_INVALID; + else + return PL330_STATE_KILLING; + case DS_ST_CMPLT: + if (is_manager(thrd)) + return PL330_STATE_INVALID; + else + return PL330_STATE_COMPLETING; + case DS_ST_FLTCMP: + if (is_manager(thrd)) + return PL330_STATE_INVALID; + else + return PL330_STATE_FAULT_COMPLETING; + default: + return PL330_STATE_INVALID; + } +} + +/* If the request 'req' of thread 'thrd' is currently active */ +static inline bool _req_active(struct pl330_thread *thrd, + struct _pl330_req *req) +{ + void __iomem *regs = thrd->dmac->pinfo->base; + u32 buf = req->mc_bus, pc = readl(regs + CPC(thrd->id)); + + if (IS_FREE(req)) + return false; + + return (pc >= buf && pc <= buf + req->mc_len) ? true : false; +} + +/* Returns 0 if the thread is inactive, ID of active req + 1 otherwise */ +static inline unsigned _thrd_active(struct pl330_thread *thrd) +{ + if (_req_active(thrd, &thrd->req[0])) + return 1; /* First req active */ + + if (_req_active(thrd, &thrd->req[1])) + return 2; /* Second req active */ + + return 0; +} + +static void _stop(struct pl330_thread *thrd) +{ + void __iomem *regs = thrd->dmac->pinfo->base; + u8 insn[6] = {0, 0, 0, 0, 0, 0}; + + if (_state(thrd) == PL330_STATE_FAULT_COMPLETING) + UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING); + + /* Return if nothing needs to be done */ + if (_state(thrd) == PL330_STATE_COMPLETING + || _state(thrd) == PL330_STATE_KILLING + || _state(thrd) == PL330_STATE_STOPPED) + return; + + _emit_KILL(0, insn); + + /* Stop generating interrupts for SEV */ + writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN); + + _execute_DBGINSN(thrd, insn, is_manager(thrd)); +} + +/* Start doing req 'idx' of thread 'thrd' */ +static bool _trigger(struct pl330_thread *thrd) +{ + void __iomem *regs = thrd->dmac->pinfo->base; + struct _pl330_req *req; + struct pl330_req *r; + struct _arg_GO go; + unsigned ns; + u8 insn[6] = {0, 0, 0, 0, 0, 0}; + + /* Return if already ACTIVE */ + if (_state(thrd) != PL330_STATE_STOPPED) + return true; + + if (!IS_FREE(&thrd->req[1 - thrd->lstenq])) + req = &thrd->req[1 - thrd->lstenq]; + else if (!IS_FREE(&thrd->req[thrd->lstenq])) + req = &thrd->req[thrd->lstenq]; + else + req = NULL; + + /* Return if no request */ + if (!req || !req->r) + return true; + + r = req->r; + + if (r->cfg) + ns = r->cfg->nonsecure ? 1 : 0; + else if (readl(regs + CS(thrd->id)) & CS_CNS) + ns = 1; + else + ns = 0; + + /* See 'Abort Sources' point-4 at Page 2-25 */ + if (_manager_ns(thrd) && !ns) + dev_info(thrd->dmac->pinfo->dev, "%s:%d Recipe for ABORT!\n", + __func__, __LINE__); + + go.chan = thrd->id; + go.addr = req->mc_bus; + go.ns = ns; + _emit_GO(0, insn, &go); + + /* Set to generate interrupts for SEV */ + writel(readl(regs + INTEN) | (1 << thrd->ev), regs + INTEN); + + /* Only manager can execute GO */ + _execute_DBGINSN(thrd, insn, true); + + return true; +} + +static bool _start(struct pl330_thread *thrd) +{ + switch (_state(thrd)) { + case PL330_STATE_FAULT_COMPLETING: + UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING); + + if (_state(thrd) == PL330_STATE_KILLING) + UNTIL(thrd, PL330_STATE_STOPPED) + + case PL330_STATE_FAULTING: + _stop(thrd); + + case PL330_STATE_KILLING: + case PL330_STATE_COMPLETING: + UNTIL(thrd, PL330_STATE_STOPPED) + + case PL330_STATE_STOPPED: + return _trigger(thrd); + + case PL330_STATE_WFP: + case PL330_STATE_QUEUEBUSY: + case PL330_STATE_ATBARRIER: + case PL330_STATE_UPDTPC: + case PL330_STATE_CACHEMISS: + case PL330_STATE_EXECUTING: + return true; + + case PL330_STATE_WFE: /* For RESUME, nothing yet */ + default: + return false; + } +} + +static inline int _ldst_memtomem(unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs, int cyc) +{ + int off = 0; + + while (cyc--) { + off += _emit_LD(dry_run, &buf[off], ALWAYS); + off += _emit_RMB(dry_run, &buf[off]); + off += _emit_ST(dry_run, &buf[off], ALWAYS); + off += _emit_WMB(dry_run, &buf[off]); + } + + return off; +} + +static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs, int cyc) +{ + int off = 0; + + while (cyc--) { + off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri); + off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->r->peri); + off += _emit_ST(dry_run, &buf[off], ALWAYS); + off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri); + } + + return off; +} + +static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs, int cyc) +{ + int off = 0; + + while (cyc--) { + off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri); + off += _emit_LD(dry_run, &buf[off], ALWAYS); + off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->r->peri); + off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri); + } + + return off; +} + +static int _bursts(unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs, int cyc) +{ + int off = 0; + + switch (pxs->r->rqtype) { + case MEMTODEV: + off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc); + break; + case DEVTOMEM: + off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc); + break; + case MEMTOMEM: + off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc); + break; + default: + off += 0x40000000; /* Scare off the Client */ + break; + } + + return off; +} + +/* Returns bytes consumed and updates bursts */ +static inline int _loop(unsigned dry_run, u8 buf[], + unsigned long *bursts, const struct _xfer_spec *pxs) +{ + int cyc, cycmax, szlp, szlpend, szbrst, off; + unsigned lcnt0, lcnt1, ljmp0, ljmp1; + struct _arg_LPEND lpend; + + /* Max iterations possibile in DMALP is 256 */ + if (*bursts >= 256*256) { + lcnt1 = 256; + lcnt0 = 256; + cyc = *bursts / lcnt1 / lcnt0; + } else if (*bursts > 256) { + lcnt1 = 256; + lcnt0 = *bursts / lcnt1; + cyc = 1; + } else { + lcnt1 = *bursts; + lcnt0 = 0; + cyc = 1; + } + + szlp = _emit_LP(1, buf, 0, 0); + szbrst = _bursts(1, buf, pxs, 1); + + lpend.cond = ALWAYS; + lpend.forever = false; + lpend.loop = 0; + lpend.bjump = 0; + szlpend = _emit_LPEND(1, buf, &lpend); + + if (lcnt0) { + szlp *= 2; + szlpend *= 2; + } + + /* + * Max bursts that we can unroll due to limit on the + * size of backward jump that can be encoded in DMALPEND + * which is 8-bits and hence 255 + */ + cycmax = (255 - (szlp + szlpend)) / szbrst; + + cyc = (cycmax < cyc) ? cycmax : cyc; + + off = 0; + + if (lcnt0) { + off += _emit_LP(dry_run, &buf[off], 0, lcnt0); + ljmp0 = off; + } + + off += _emit_LP(dry_run, &buf[off], 1, lcnt1); + ljmp1 = off; + + off += _bursts(dry_run, &buf[off], pxs, cyc); + + lpend.cond = ALWAYS; + lpend.forever = false; + lpend.loop = 1; + lpend.bjump = off - ljmp1; + off += _emit_LPEND(dry_run, &buf[off], &lpend); + + if (lcnt0) { + lpend.cond = ALWAYS; + lpend.forever = false; + lpend.loop = 0; + lpend.bjump = off - ljmp0; + off += _emit_LPEND(dry_run, &buf[off], &lpend); + } + + *bursts = lcnt1 * cyc; + if (lcnt0) + *bursts *= lcnt0; + + return off; +} + +static inline int _setup_loops(unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs) +{ + struct pl330_xfer *x = pxs->x; + u32 ccr = pxs->ccr; + unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr); + int off = 0; + + while (bursts) { + c = bursts; + off += _loop(dry_run, &buf[off], &c, pxs); + bursts -= c; + } + + return off; +} + +static inline int _setup_xfer(unsigned dry_run, u8 buf[], + const struct _xfer_spec *pxs) +{ + struct pl330_xfer *x = pxs->x; + int off = 0; + + /* DMAMOV SAR, x->src_addr */ + off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr); + /* DMAMOV DAR, x->dst_addr */ + off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); + + /* Setup Loop(s) */ + off += _setup_loops(dry_run, &buf[off], pxs); + + return off; +} + +/* + * A req is a sequence of one or more xfer units. + * Returns the number of bytes taken to setup the MC for the req. + */ +static int _setup_req(unsigned dry_run, struct pl330_thread *thrd, + unsigned index, struct _xfer_spec *pxs) +{ + struct _pl330_req *req = &thrd->req[index]; + struct pl330_xfer *x; + u8 *buf = req->mc_cpu; + int off = 0; + + PL330_DBGMC_START(req->mc_bus); + + /* DMAMOV CCR, ccr */ + off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr); + + x = pxs->r->x; + do { + /* Error if xfer length is not aligned at burst size */ + if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) + return -EINVAL; + + pxs->x = x; + off += _setup_xfer(dry_run, &buf[off], pxs); + + x = x->next; + } while (x); + + /* DMASEV peripheral/event */ + off += _emit_SEV(dry_run, &buf[off], thrd->ev); + /* DMAEND */ + off += _emit_END(dry_run, &buf[off]); + + return off; +} + +static inline u32 _prepare_ccr(const struct pl330_reqcfg *rqc) +{ + u32 ccr = 0; + + if (rqc->src_inc) + ccr |= CC_SRCINC; + + if (rqc->dst_inc) + ccr |= CC_DSTINC; + + /* We set same protection levels for Src and DST for now */ + if (rqc->privileged) + ccr |= CC_SRCPRI | CC_DSTPRI; + if (rqc->nonsecure) + ccr |= CC_SRCNS | CC_DSTNS; + if (rqc->insnaccess) + ccr |= CC_SRCIA | CC_DSTIA; + + ccr |= (((rqc->brst_len - 1) & 0xf) << CC_SRCBRSTLEN_SHFT); + ccr |= (((rqc->brst_len - 1) & 0xf) << CC_DSTBRSTLEN_SHFT); + + ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT); + ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT); + + ccr |= (rqc->dcctl << CC_SRCCCTRL_SHFT); + ccr |= (rqc->scctl << CC_DSTCCTRL_SHFT); + + ccr |= (rqc->swap << CC_SWAP_SHFT); + + return ccr; +} + +static inline bool _is_valid(u32 ccr) +{ + enum pl330_dstcachectrl dcctl; + enum pl330_srccachectrl scctl; + + dcctl = (ccr >> CC_DSTCCTRL_SHFT) & CC_DRCCCTRL_MASK; + scctl = (ccr >> CC_SRCCCTRL_SHFT) & CC_SRCCCTRL_MASK; + + if (dcctl == DINVALID1 || dcctl == DINVALID2 + || scctl == SINVALID1 || scctl == SINVALID2) + return false; + else + return true; +} + +/* + * Submit a list of xfers after which the client wants notification. + * Client is not notified after each xfer unit, just once after all + * xfer units are done or some error occurs. + */ +int pl330_submit_req(void *ch_id, struct pl330_req *r) +{ + struct pl330_thread *thrd = ch_id; + struct pl330_dmac *pl330; + struct pl330_info *pi; + struct _xfer_spec xs; + unsigned long flags; + void __iomem *regs; + unsigned idx; + u32 ccr; + int ret = 0; + + /* No Req or Unacquired Channel or DMAC */ + if (!r || !thrd || thrd->free) + return -EINVAL; + + pl330 = thrd->dmac; + pi = pl330->pinfo; + regs = pi->base; + + if (pl330->state == DYING + || pl330->dmac_tbd.reset_chan & (1 << thrd->id)) { + dev_info(thrd->dmac->pinfo->dev, "%s:%d\n", + __func__, __LINE__); + return -EAGAIN; + } + + /* If request for non-existing peripheral */ + if (r->rqtype != MEMTOMEM && r->peri >= pi->pcfg.num_peri) { + dev_info(thrd->dmac->pinfo->dev, + "%s:%d Invalid peripheral(%u)!\n", + __func__, __LINE__, r->peri); + return -EINVAL; + } + + spin_lock_irqsave(&pl330->lock, flags); + + if (_queue_full(thrd)) { + ret = -EAGAIN; + goto xfer_exit; + } + + /* Prefer Secure Channel */ + if (!_manager_ns(thrd)) + r->cfg->nonsecure = 0; + else + r->cfg->nonsecure = 1; + + /* Use last settings, if not provided */ + if (r->cfg) + ccr = _prepare_ccr(r->cfg); + else + ccr = readl(regs + CC(thrd->id)); + + /* If this req doesn't have valid xfer settings */ + if (!_is_valid(ccr)) { + ret = -EINVAL; + dev_info(thrd->dmac->pinfo->dev, "%s:%d Invalid CCR(%x)!\n", + __func__, __LINE__, ccr); + goto xfer_exit; + } + + idx = IS_FREE(&thrd->req[0]) ? 0 : 1; + + xs.ccr = ccr; + xs.r = r; + + /* First dry run to check if req is acceptable */ + ret = _setup_req(1, thrd, idx, &xs); + if (ret < 0) + goto xfer_exit; + + if (ret > pi->mcbufsz / 2) { + dev_info(thrd->dmac->pinfo->dev, + "%s:%d Trying increasing mcbufsz\n", + __func__, __LINE__); + ret = -ENOMEM; + goto xfer_exit; + } + + /* Hook the request */ + thrd->lstenq = idx; + thrd->req[idx].mc_len = _setup_req(0, thrd, idx, &xs); + thrd->req[idx].r = r; + + ret = 0; + +xfer_exit: + spin_unlock_irqrestore(&pl330->lock, flags); + + return ret; +} +EXPORT_SYMBOL(pl330_submit_req); + +static void pl330_dotask(unsigned long data) +{ + struct pl330_dmac *pl330 = (struct pl330_dmac *) data; + struct pl330_info *pi = pl330->pinfo; + unsigned long flags; + int i; + + spin_lock_irqsave(&pl330->lock, flags); + + /* The DMAC itself gone nuts */ + if (pl330->dmac_tbd.reset_dmac) { + pl330->state = DYING; + /* Reset the manager too */ + pl330->dmac_tbd.reset_mngr = true; + /* Clear the reset flag */ + pl330->dmac_tbd.reset_dmac = false; + } + + if (pl330->dmac_tbd.reset_mngr) { + _stop(pl330->manager); + /* Reset all channels */ + pl330->dmac_tbd.reset_chan = (1 << pi->pcfg.num_chan) - 1; + /* Clear the reset flag */ + pl330->dmac_tbd.reset_mngr = false; + } + + for (i = 0; i < pi->pcfg.num_chan; i++) { + + if (pl330->dmac_tbd.reset_chan & (1 << i)) { + struct pl330_thread *thrd = &pl330->channels[i]; + void __iomem *regs = pi->base; + enum pl330_op_err err; + + _stop(thrd); + + if (readl(regs + FSC) & (1 << thrd->id)) + err = PL330_ERR_FAIL; + else + err = PL330_ERR_ABORT; + + spin_unlock_irqrestore(&pl330->lock, flags); + + _callback(thrd->req[1 - thrd->lstenq].r, err); + _callback(thrd->req[thrd->lstenq].r, err); + + spin_lock_irqsave(&pl330->lock, flags); + + thrd->req[0].r = NULL; + thrd->req[1].r = NULL; + MARK_FREE(&thrd->req[0]); + MARK_FREE(&thrd->req[1]); + + /* Clear the reset flag */ + pl330->dmac_tbd.reset_chan &= ~(1 << i); + } + } + + spin_unlock_irqrestore(&pl330->lock, flags); + + return; +} + +/* Returns 1 if state was updated, 0 otherwise */ +int pl330_update(const struct pl330_info *pi) +{ + struct _pl330_req *rqdone; + struct pl330_dmac *pl330; + unsigned long flags; + void __iomem *regs; + u32 val; + int id, ev, ret = 0; + + if (!pi || !pi->pl330_data) + return 0; + + regs = pi->base; + pl330 = pi->pl330_data; + + spin_lock_irqsave(&pl330->lock, flags); + + val = readl(regs + FSM) & 0x1; + if (val) + pl330->dmac_tbd.reset_mngr = true; + else + pl330->dmac_tbd.reset_mngr = false; + + val = readl(regs + FSC) & ((1 << pi->pcfg.num_chan) - 1); + pl330->dmac_tbd.reset_chan |= val; + if (val) { + int i = 0; + while (i < pi->pcfg.num_chan) { + if (val & (1 << i)) { + dev_info(pi->dev, + "Reset Channel-%d\t CS-%x FTC-%x\n", + i, readl(regs + CS(i)), + readl(regs + FTC(i))); + _stop(&pl330->channels[i]); + } + i++; + } + } + + /* Check which event happened i.e, thread notified */ + val = readl(regs + ES); + if (pi->pcfg.num_events < 32 + && val & ~((1 << pi->pcfg.num_events) - 1)) { + pl330->dmac_tbd.reset_dmac = true; + dev_err(pi->dev, "%s:%d Unexpected!\n", __func__, __LINE__); + ret = 1; + goto updt_exit; + } + + for (ev = 0; ev < pi->pcfg.num_events; ev++) { + if (val & (1 << ev)) { /* Event occured */ + struct pl330_thread *thrd; + u32 inten = readl(regs + INTEN); + int active; + + /* Clear the event */ + if (inten & (1 << ev)) + writel(1 << ev, regs + INTCLR); + + ret = 1; + + id = pl330->events[ev]; + + thrd = &pl330->channels[id]; + + active = _thrd_active(thrd); + if (!active) /* Aborted */ + continue; + + active -= 1; + + rqdone = &thrd->req[active]; + MARK_FREE(rqdone); + + /* Get going again ASAP */ + _start(thrd); + + /* For now, just make a list of callbacks to be done */ + list_add_tail(&rqdone->rqd, &pl330->req_done); + } + } + + /* Now that we are in no hurry, do the callbacks */ + while (!list_empty(&pl330->req_done)) { + rqdone = container_of(pl330->req_done.next, + struct _pl330_req, rqd); + + list_del_init(&rqdone->rqd); + + spin_unlock_irqrestore(&pl330->lock, flags); + _callback(rqdone->r, PL330_ERR_NONE); + spin_lock_irqsave(&pl330->lock, flags); + } + +updt_exit: + spin_unlock_irqrestore(&pl330->lock, flags); + + if (pl330->dmac_tbd.reset_dmac + || pl330->dmac_tbd.reset_mngr + || pl330->dmac_tbd.reset_chan) { + ret = 1; + tasklet_schedule(&pl330->tasks); + } + + return ret; +} +EXPORT_SYMBOL(pl330_update); + +int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op) +{ + struct pl330_thread *thrd = ch_id; + struct pl330_dmac *pl330; + unsigned long flags; + int ret = 0, active; + + if (!thrd || thrd->free || thrd->dmac->state == DYING) + return -EINVAL; + + pl330 = thrd->dmac; + + spin_lock_irqsave(&pl330->lock, flags); + + switch (op) { + case PL330_OP_FLUSH: + /* Make sure the channel is stopped */ + _stop(thrd); + + thrd->req[0].r = NULL; + thrd->req[1].r = NULL; + MARK_FREE(&thrd->req[0]); + MARK_FREE(&thrd->req[1]); + break; + + case PL330_OP_ABORT: + active = _thrd_active(thrd); + + /* Make sure the channel is stopped */ + _stop(thrd); + + /* ABORT is only for the active req */ + if (!active) + break; + + active--; + + thrd->req[active].r = NULL; + MARK_FREE(&thrd->req[active]); + + /* Start the next */ + case PL330_OP_START: + if (!_start(thrd)) + ret = -EIO; + break; + + default: + ret = -EINVAL; + } + + spin_unlock_irqrestore(&pl330->lock, flags); + return ret; +} +EXPORT_SYMBOL(pl330_chan_ctrl); + +int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus) +{ + struct pl330_thread *thrd = ch_id; + struct pl330_dmac *pl330; + struct pl330_info *pi; + void __iomem *regs; + int active; + u32 val; + + if (!pstatus || !thrd || thrd->free) + return -EINVAL; + + pl330 = thrd->dmac; + pi = pl330->pinfo; + regs = pi->base; + + /* The client should remove the DMAC and add again */ + if (pl330->state == DYING) + pstatus->dmac_halted = true; + else + pstatus->dmac_halted = false; + + val = readl(regs + FSC); + if (val & (1 << thrd->id)) + pstatus->faulting = true; + else + pstatus->faulting = false; + + active = _thrd_active(thrd); + + if (!active) { + /* Indicate that the thread is not running */ + pstatus->top_req = NULL; + pstatus->wait_req = NULL; + } else { + active--; + pstatus->top_req = thrd->req[active].r; + pstatus->wait_req = !IS_FREE(&thrd->req[1 - active]) + ? thrd->req[1 - active].r : NULL; + } + + pstatus->src_addr = readl(regs + SA(thrd->id)); + pstatus->dst_addr = readl(regs + DA(thrd->id)); + + return 0; +} +EXPORT_SYMBOL(pl330_chan_status); + +/* Reserve an event */ +static inline int _alloc_event(struct pl330_thread *thrd) +{ + struct pl330_dmac *pl330 = thrd->dmac; + struct pl330_info *pi = pl330->pinfo; + int ev; + + for (ev = 0; ev < pi->pcfg.num_events; ev++) + if (pl330->events[ev] == -1) { + pl330->events[ev] = thrd->id; + return ev; + } + + return -1; +} + +/* Upon success, returns IdentityToken for the + * allocated channel, NULL otherwise. + */ +void *pl330_request_channel(const struct pl330_info *pi) +{ + struct pl330_thread *thrd = NULL; + struct pl330_dmac *pl330; + unsigned long flags; + int chans, i; + + if (!pi || !pi->pl330_data) + return NULL; + + pl330 = pi->pl330_data; + + if (pl330->state == DYING) + return NULL; + + chans = pi->pcfg.num_chan; + + spin_lock_irqsave(&pl330->lock, flags); + + for (i = 0; i < chans; i++) { + thrd = &pl330->channels[i]; + if (thrd->free) { + thrd->ev = _alloc_event(thrd); + if (thrd->ev >= 0) { + thrd->free = false; + thrd->lstenq = 1; + thrd->req[0].r = NULL; + MARK_FREE(&thrd->req[0]); + thrd->req[1].r = NULL; + MARK_FREE(&thrd->req[1]); + break; + } + } + thrd = NULL; + } + + spin_unlock_irqrestore(&pl330->lock, flags); + + return thrd; +} +EXPORT_SYMBOL(pl330_request_channel); + +/* Release an event */ +static inline void _free_event(struct pl330_thread *thrd, int ev) +{ + struct pl330_dmac *pl330 = thrd->dmac; + struct pl330_info *pi = pl330->pinfo; + + /* If the event is valid and was held by the thread */ + if (ev >= 0 && ev < pi->pcfg.num_events + && pl330->events[ev] == thrd->id) + pl330->events[ev] = -1; +} + +void pl330_release_channel(void *ch_id) +{ + struct pl330_thread *thrd = ch_id; + struct pl330_dmac *pl330; + unsigned long flags; + + if (!thrd || thrd->free) + return; + + _stop(thrd); + + _callback(thrd->req[1 - thrd->lstenq].r, PL330_ERR_ABORT); + _callback(thrd->req[thrd->lstenq].r, PL330_ERR_ABORT); + + pl330 = thrd->dmac; + + spin_lock_irqsave(&pl330->lock, flags); + _free_event(thrd, thrd->ev); + thrd->free = true; + spin_unlock_irqrestore(&pl330->lock, flags); +} +EXPORT_SYMBOL(pl330_release_channel); + +/* Initialize the structure for PL330 configuration, that can be used + * by the client driver the make best use of the DMAC + */ +static void read_dmac_config(struct pl330_info *pi) +{ + void __iomem *regs = pi->base; + u32 val; + + val = readl(regs + CRD) >> CRD_DATA_WIDTH_SHIFT; + val &= CRD_DATA_WIDTH_MASK; + pi->pcfg.data_bus_width = 8 * (1 << val); + + val = readl(regs + CRD) >> CRD_DATA_BUFF_SHIFT; + val &= CRD_DATA_BUFF_MASK; + pi->pcfg.data_buf_dep = val + 1; + + val = readl(regs + CR0) >> CR0_NUM_CHANS_SHIFT; + val &= CR0_NUM_CHANS_MASK; + val += 1; + pi->pcfg.num_chan = val; + + val = readl(regs + CR0); + if (val & CR0_PERIPH_REQ_SET) { + val = (val >> CR0_NUM_PERIPH_SHIFT) & CR0_NUM_PERIPH_MASK; + val += 1; + pi->pcfg.num_peri = val; + pi->pcfg.peri_ns = readl(regs + CR4); + } else { + pi->pcfg.num_peri = 0; + } + + val = readl(regs + CR0); + if (val & CR0_BOOT_MAN_NS) + pi->pcfg.mode |= DMAC_MODE_NS; + else + pi->pcfg.mode &= ~DMAC_MODE_NS; + + val = readl(regs + CR0) >> CR0_NUM_EVENTS_SHIFT; + val &= CR0_NUM_EVENTS_MASK; + val += 1; + pi->pcfg.num_events = val; + + pi->pcfg.irq_ns = readl(regs + CR3); + + pi->pcfg.periph_id = get_id(pi, PERIPH_ID); + pi->pcfg.pcell_id = get_id(pi, PCELL_ID); +} + +static inline void _reset_thread(struct pl330_thread *thrd) +{ + struct pl330_dmac *pl330 = thrd->dmac; + struct pl330_info *pi = pl330->pinfo; + + thrd->req[0].mc_cpu = pl330->mcode_cpu + + (thrd->id * pi->mcbufsz); + thrd->req[0].mc_bus = pl330->mcode_bus + + (thrd->id * pi->mcbufsz); + thrd->req[0].r = NULL; + MARK_FREE(&thrd->req[0]); + + thrd->req[1].mc_cpu = thrd->req[0].mc_cpu + + pi->mcbufsz / 2; + thrd->req[1].mc_bus = thrd->req[0].mc_bus + + pi->mcbufsz / 2; + thrd->req[1].r = NULL; + MARK_FREE(&thrd->req[1]); +} + +static int dmac_alloc_threads(struct pl330_dmac *pl330) +{ + struct pl330_info *pi = pl330->pinfo; + int chans = pi->pcfg.num_chan; + struct pl330_thread *thrd; + int i; + + /* Allocate 1 Manager and 'chans' Channel threads */ + pl330->channels = kzalloc((1 + chans) * sizeof(*thrd), + GFP_KERNEL); + if (!pl330->channels) + return -ENOMEM; + + /* Init Channel threads */ + for (i = 0; i < chans; i++) { + thrd = &pl330->channels[i]; + thrd->id = i; + thrd->dmac = pl330; + _reset_thread(thrd); + thrd->free = true; + } + + /* MANAGER is indexed at the end */ + thrd = &pl330->channels[chans]; + thrd->id = chans; + thrd->dmac = pl330; + thrd->free = false; + pl330->manager = thrd; + + return 0; +} + +static int dmac_alloc_resources(struct pl330_dmac *pl330) +{ + struct pl330_info *pi = pl330->pinfo; + int chans = pi->pcfg.num_chan; + int ret; + + /* + * Alloc MicroCode buffer for 'chans' Channel threads. + * A channel's buffer offset is (Channel_Id * MCODE_BUFF_PERCHAN) + */ + pl330->mcode_cpu = dma_alloc_coherent(pi->dev, + chans * pi->mcbufsz, + &pl330->mcode_bus, GFP_KERNEL); + if (!pl330->mcode_cpu) { + dev_err(pi->dev, "%s:%d Can't allocate memory!\n", + __func__, __LINE__); + return -ENOMEM; + } + + ret = dmac_alloc_threads(pl330); + if (ret) { + dev_err(pi->dev, "%s:%d Can't to create channels for DMAC!\n", + __func__, __LINE__); + dma_free_coherent(pi->dev, + chans * pi->mcbufsz, + pl330->mcode_cpu, pl330->mcode_bus); + return ret; + } + + return 0; +} + +int pl330_add(struct pl330_info *pi) +{ + struct pl330_dmac *pl330; + void __iomem *regs; + int i, ret; + + if (!pi || !pi->dev) + return -EINVAL; + + /* If already added */ + if (pi->pl330_data) + return -EINVAL; + + /* + * If the SoC can perform reset on the DMAC, then do it + * before reading its configuration. + */ + if (pi->dmac_reset) + pi->dmac_reset(pi); + + regs = pi->base; + + /* Check if we can handle this DMAC */ + if (get_id(pi, PERIPH_ID) != PERIPH_ID_VAL + || get_id(pi, PCELL_ID) != PCELL_ID_VAL) { + dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n", + readl(regs + PERIPH_ID), readl(regs + PCELL_ID)); + return -EINVAL; + } + + /* Read the configuration of the DMAC */ + read_dmac_config(pi); + + if (pi->pcfg.num_events == 0) { + dev_err(pi->dev, "%s:%d Can't work without events!\n", + __func__, __LINE__); + return -EINVAL; + } + + pl330 = kzalloc(sizeof(*pl330), GFP_KERNEL); + if (!pl330) { + dev_err(pi->dev, "%s:%d Can't allocate memory!\n", + __func__, __LINE__); + return -ENOMEM; + } + + /* Assign the info structure and private data */ + pl330->pinfo = pi; + pi->pl330_data = pl330; + + spin_lock_init(&pl330->lock); + + INIT_LIST_HEAD(&pl330->req_done); + + /* Use default MC buffer size if not provided */ + if (!pi->mcbufsz) + pi->mcbufsz = MCODE_BUFF_PER_REQ * 2; + + /* Mark all events as free */ + for (i = 0; i < pi->pcfg.num_events; i++) + pl330->events[i] = -1; + + /* Allocate resources needed by the DMAC */ + ret = dmac_alloc_resources(pl330); + if (ret) { + dev_err(pi->dev, "Unable to create channels for DMAC\n"); + kfree(pl330); + return ret; + } + + tasklet_init(&pl330->tasks, pl330_dotask, (unsigned long) pl330); + + pl330->state = INIT; + + return 0; +} +EXPORT_SYMBOL(pl330_add); + +static int dmac_free_threads(struct pl330_dmac *pl330) +{ + struct pl330_info *pi = pl330->pinfo; + int chans = pi->pcfg.num_chan; + struct pl330_thread *thrd; + int i; + + /* Release Channel threads */ + for (i = 0; i < chans; i++) { + thrd = &pl330->channels[i]; + pl330_release_channel((void *)thrd); + } + + /* Free memory */ + kfree(pl330->channels); + + return 0; +} + +static void dmac_free_resources(struct pl330_dmac *pl330) +{ + struct pl330_info *pi = pl330->pinfo; + int chans = pi->pcfg.num_chan; + + dmac_free_threads(pl330); + + dma_free_coherent(pi->dev, chans * pi->mcbufsz, + pl330->mcode_cpu, pl330->mcode_bus); +} + +void pl330_del(struct pl330_info *pi) +{ + struct pl330_dmac *pl330; + + if (!pi || !pi->pl330_data) + return; + + pl330 = pi->pl330_data; + + pl330->state = UNINIT; + + tasklet_kill(&pl330->tasks); + + /* Free DMAC resources */ + dmac_free_resources(pl330); + + kfree(pl330); + pi->pl330_data = NULL; +} +EXPORT_SYMBOL(pl330_del); diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h new file mode 100644 index 000000000000..575fa8186ca0 --- /dev/null +++ b/arch/arm/include/asm/hardware/pl330.h @@ -0,0 +1,217 @@ +/* linux/include/asm/hardware/pl330.h + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PL330_CORE_H +#define __PL330_CORE_H + +#define PL330_MAX_CHAN 8 +#define PL330_MAX_IRQS 32 +#define PL330_MAX_PERI 32 + +enum pl330_srccachectrl { + SCCTRL0 = 0, /* Noncacheable and nonbufferable */ + SCCTRL1, /* Bufferable only */ + SCCTRL2, /* Cacheable, but do not allocate */ + SCCTRL3, /* Cacheable and bufferable, but do not allocate */ + SINVALID1, + SINVALID2, + SCCTRL6, /* Cacheable write-through, allocate on reads only */ + SCCTRL7, /* Cacheable write-back, allocate on reads only */ +}; + +enum pl330_dstcachectrl { + DCCTRL0 = 0, /* Noncacheable and nonbufferable */ + DCCTRL1, /* Bufferable only */ + DCCTRL2, /* Cacheable, but do not allocate */ + DCCTRL3, /* Cacheable and bufferable, but do not allocate */ + DINVALID1 = 8, + DINVALID2, + DCCTRL6, /* Cacheable write-through, allocate on writes only */ + DCCTRL7, /* Cacheable write-back, allocate on writes only */ +}; + +/* Populated by the PL330 core driver for DMA API driver's info */ +struct pl330_config { + u32 periph_id; + u32 pcell_id; +#define DMAC_MODE_NS (1 << 0) + unsigned int mode; + unsigned int data_bus_width:10; /* In number of bits */ + unsigned int data_buf_dep:10; + unsigned int num_chan:4; + unsigned int num_peri:6; + u32 peri_ns; + unsigned int num_events:6; + u32 irq_ns; +}; + +/* Handle to the DMAC provided to the PL330 core */ +struct pl330_info { + /* Owning device */ + struct device *dev; + /* Size of MicroCode buffers for each channel. */ + unsigned mcbufsz; + /* ioremap'ed address of PL330 registers. */ + void __iomem *base; + /* Client can freely use it. */ + void *client_data; + /* PL330 core data, Client must not touch it. */ + void *pl330_data; + /* Populated by the PL330 core driver during pl330_add */ + struct pl330_config pcfg; + /* + * If the DMAC has some reset mechanism, then the + * client may want to provide pointer to the method. + */ + void (*dmac_reset)(struct pl330_info *pi); +}; + +enum pl330_byteswap { + SWAP_NO = 0, + SWAP_2, + SWAP_4, + SWAP_8, + SWAP_16, +}; + +/** + * Request Configuration. + * The PL330 core does not modify this and uses the last + * working configuration if the request doesn't provide any. + * + * The Client may want to provide this info only for the + * first request and a request with new settings. + */ +struct pl330_reqcfg { + /* Address Incrementing */ + unsigned dst_inc:1; + unsigned src_inc:1; + + /* + * For now, the SRC & DST protection levels + * and burst size/length are assumed same. + */ + bool nonsecure; + bool privileged; + bool insnaccess; + unsigned brst_len:5; + unsigned brst_size:3; /* in power of 2 */ + + enum pl330_dstcachectrl dcctl; + enum pl330_srccachectrl scctl; + enum pl330_byteswap swap; +}; + +/* + * One cycle of DMAC operation. + * There may be more than one xfer in a request. + */ +struct pl330_xfer { + u32 src_addr; + u32 dst_addr; + /* Size to xfer */ + u32 bytes; + /* + * Pointer to next xfer in the list. + * The last xfer in the req must point to NULL. + */ + struct pl330_xfer *next; +}; + +/* The xfer callbacks are made with one of these arguments. */ +enum pl330_op_err { + /* The all xfers in the request were success. */ + PL330_ERR_NONE, + /* If req aborted due to global error. */ + PL330_ERR_ABORT, + /* If req failed due to problem with Channel. */ + PL330_ERR_FAIL, +}; + +enum pl330_reqtype { + MEMTOMEM, + MEMTODEV, + DEVTOMEM, + DEVTODEV, +}; + +/* A request defining Scatter-Gather List ending with NULL xfer. */ +struct pl330_req { + enum pl330_reqtype rqtype; + /* Index of peripheral for the xfer. */ + unsigned peri:5; + /* Unique token for this xfer, set by the client. */ + void *token; + /* Callback to be called after xfer. */ + void (*xfer_cb)(void *token, enum pl330_op_err err); + /* If NULL, req will be done at last set parameters. */ + struct pl330_reqcfg *cfg; + /* Pointer to first xfer in the request. */ + struct pl330_xfer *x; +}; + +/* + * To know the status of the channel and DMAC, the client + * provides a pointer to this structure. The PL330 core + * fills it with current information. + */ +struct pl330_chanstatus { + /* + * If the DMAC engine halted due to some error, + * the client should remove-add DMAC. + */ + bool dmac_halted; + /* + * If channel is halted due to some error, + * the client should ABORT/FLUSH and START the channel. + */ + bool faulting; + /* Location of last load */ + u32 src_addr; + /* Location of last store */ + u32 dst_addr; + /* + * Pointer to the currently active req, NULL if channel is + * inactive, even though the requests may be present. + */ + struct pl330_req *top_req; + /* Pointer to req waiting second in the queue if any. */ + struct pl330_req *wait_req; +}; + +enum pl330_chan_op { + /* Start the channel */ + PL330_OP_START, + /* Abort the active xfer */ + PL330_OP_ABORT, + /* Stop xfer and flush queue */ + PL330_OP_FLUSH, +}; + +extern int pl330_add(struct pl330_info *); +extern void pl330_del(struct pl330_info *pi); +extern int pl330_update(const struct pl330_info *pi); +extern void pl330_release_channel(void *ch_id); +extern void *pl330_request_channel(const struct pl330_info *pi); +extern int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus); +extern int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op); +extern int pl330_submit_req(void *ch_id, struct pl330_req *r); + +#endif /* __PL330_CORE_H */ -- cgit v1.2.3-59-g8ed1b From 8e2a43f5f5e1255879064924917fb1a6e5be7cb3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 15 May 2010 10:18:05 +0100 Subject: ARM: rename mach_cpu_disable() to platform_cpu_disable() Consistently name all SMP platform related functions. Signed-off-by: Russell King --- arch/arm/include/asm/smp.h | 2 +- arch/arm/kernel/smp.c | 2 +- arch/arm/mach-realview/hotplug.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index e0d763be1846..3d05190797cb 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -82,7 +82,7 @@ struct secondary_data { extern struct secondary_data secondary_data; extern int __cpu_disable(void); -extern int mach_cpu_disable(unsigned int cpu); +extern int platform_cpu_disable(unsigned int cpu); extern void __cpu_die(unsigned int cpu); extern void cpu_die(void); diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 577543f3857f..7a3cc0266934 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -162,7 +162,7 @@ int __cpu_disable(void) struct task_struct *p; int ret; - ret = mach_cpu_disable(cpu); + ret = platform_cpu_disable(cpu); if (ret) return ret; diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c index be048e3e8799..f95521a5e5ce 100644 --- a/arch/arm/mach-realview/hotplug.c +++ b/arch/arm/mach-realview/hotplug.c @@ -131,7 +131,7 @@ void platform_cpu_die(unsigned int cpu) cpu_leave_lowpower(); } -int mach_cpu_disable(unsigned int cpu) +int platform_cpu_disable(unsigned int cpu) { /* * we don't allow CPU 0 to be shutdown (it is still too special -- cgit v1.2.3-59-g8ed1b From 49aea0fd95495538230e19f58e217fb06ffdbfeb Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 15 May 2010 10:40:21 +0100 Subject: ARM: nwfpe: allow debugging output to be configured at runtime Enabling CONFIG_USER_DEBUG allows NWFPE to complain about every FP exception, which with some programs can cause the kernel message log to fill with NWFPE debug, swamping out other messages. This change allows NWFPE debugging to be configured at run time. Signed-off-by: Russell King --- arch/arm/nwfpe/fpmodule.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c index 4c0ab50f399a..cb7658e8acc5 100644 --- a/arch/arm/nwfpe/fpmodule.c +++ b/arch/arm/nwfpe/fpmodule.c @@ -24,6 +24,7 @@ #include "fpa11.h" #include +#include /* XXX */ #include @@ -134,13 +135,17 @@ a SIGFPE exception if necessary. If not the relevant bits in the cumulative exceptions flag byte are set and we return. */ +#ifdef CONFIG_DEBUG_USER +/* By default, ignore inexact errors as there are far too many of them to log */ +static int debug = ~BIT_IXC; +#endif + void float_raise(signed char flags) { register unsigned int fpsr, cumulativeTraps; #ifdef CONFIG_DEBUG_USER - /* Ignore inexact errors as there are far too many of them to log */ - if (flags & ~BIT_IXC) + if (flags & debug) printk(KERN_DEBUG "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n", current->comm, current->pid, flags, @@ -179,3 +184,7 @@ module_exit(fpe_exit); MODULE_AUTHOR("Scott Bambrough "); MODULE_DESCRIPTION("NWFPE floating point emulator (" NWFPE_BITS " precision)"); MODULE_LICENSE("GPL"); + +#ifdef CONFIG_DEBUG_USER +module_param(debug, int, 0644); +#endif -- cgit v1.2.3-59-g8ed1b From 8c0b742ca7a7d21de0ddc87eda6ef0b282e4de18 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Sat, 15 May 2010 09:57:06 +0100 Subject: ARM: 6134/1: Handle instruction cache maintenance fault properly Between "clean D line..." and "invalidate I line" operations in v7_coherent_user_range(), the memory page may get swapped out. And the fault on "invalidate I line" could not be properly handled causing the oops. In ARMv6 "external abort on linefetch" replaced by "instruction cache maintenance fault". Let's handle it as translation fault. It fixes the issue. I'm not sure if it's reasonable to check arch version in run-time. Let's do it in compile time for now. Reviewed-by: Catalin Marinas Signed-off-by: Siarhei Siamashka Signed-off-by: Kirill A. Shutemov Signed-off-by: Russell King --- arch/arm/mm/fault.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 9d40c341e07e..92f5801f99c1 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -463,7 +463,12 @@ static struct fsr_info { { do_bad, SIGILL, BUS_ADRALN, "alignment exception" }, { do_bad, SIGKILL, 0, "terminal exception" }, { do_bad, SIGILL, BUS_ADRALN, "alignment exception" }, +/* Do we need runtime check ? */ +#if __LINUX_ARM_ARCH__ < 6 { do_bad, SIGBUS, 0, "external abort on linefetch" }, +#else + { do_translation_fault, SIGSEGV, SEGV_MAPERR, "I-cache maintenance fault" }, +#endif { do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" }, { do_bad, SIGBUS, 0, "external abort on linefetch" }, { do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" }, -- cgit v1.2.3-59-g8ed1b From 59cda520881a1caf4332d6b03634c96fba361591 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:01 +0900 Subject: ARM: S5PV210: Rearrange the system clock definitions The system clock definitions are currently defined below the peripheral clock definitions in the V210 clock code. For the V210 clock updates that follow this patch, it is required that the system clock definitions such as the mout_apll and mout_mpll be defined prior to the device clock definitions. This patch re-arranges the system clock defintions for the clock updates that follow this patch. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 54 +++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index ccccae262351..a620cd8d347c 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -31,6 +31,33 @@ #include #include +static struct clksrc_clk clk_mout_apll = { + .clk = { + .name = "mout_apll", + .id = -1, + }, + .sources = &clk_src_apll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 }, +}; + +static struct clksrc_clk clk_mout_epll = { + .clk = { + .name = "mout_epll", + .id = -1, + }, + .sources = &clk_src_epll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 }, +}; + +static struct clksrc_clk clk_mout_mpll = { + .clk = { + .name = "mout_mpll", + .id = -1, + }, + .sources = &clk_src_mpll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 }, +}; + static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable); @@ -272,33 +299,6 @@ static struct clk init_clocks[] = { }, }; -static struct clksrc_clk clk_mout_apll = { - .clk = { - .name = "mout_apll", - .id = -1, - }, - .sources = &clk_src_apll, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 }, -}; - -static struct clksrc_clk clk_mout_epll = { - .clk = { - .name = "mout_epll", - .id = -1, - }, - .sources = &clk_src_epll, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 }, -}; - -static struct clksrc_clk clk_mout_mpll = { - .clk = { - .name = "mout_mpll", - .id = -1, - }, - .sources = &clk_src_mpll, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 }, -}; - static struct clk *clkset_uart_list[] = { [6] = &clk_mout_mpll.clk, [7] = &clk_mout_epll.clk, -- cgit v1.2.3-59-g8ed1b From eb1ef1ed06a168cf548419ba6e99f34c8169cffe Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:12 +0900 Subject: ARM: S5PV210: Register apll/mpll/epll clksrc_clk clocks This patch modifies the following. 1. Registers the mout_apll clksrc_clk clock. 2. The mout_mpll and mout_epll clocks were registered as 'struct clk' types and then their parents were setup using the s3c_set_clksrc function. This patch reduces the two steps into one by registering the mout_mpll and mout_epll clocks using the s3c_register_clksrc function. 3. As per point 2 above, the init_parents array is no longer required. So the mout clocks are now put together in a new array named 'sysclks'. The sysclks array will list the system level clocks and more clocks will be added to it in the subsequent patches. 4. The clks array is left empty because of the movement of mpll and epll clocks into the sysclks array. It is not deleted since subsequent patches will add clocks into this array. Signed-off-by: Thomas Abraham samsung.com> Signed-off-by: Kukjin Kim samsung.com> Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index a620cd8d347c..25b73a38d6d5 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -324,7 +324,7 @@ static struct clksrc_clk clksrcs[] = { }; /* Clock initialisation code */ -static struct clksrc_clk *init_parents[] = { +static struct clksrc_clk *sysclks[] = { &clk_mout_apll, &clk_mout_epll, &clk_mout_mpll, @@ -411,16 +411,11 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) clk_h166.rate = hclk166; clk_h200.rate = hclk200; - for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) - s3c_set_clksrc(init_parents[ptr], true); - for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_set_clksrc(&clksrcs[ptr], true); } static struct clk *clks[] __initdata = { - &clk_mout_epll.clk, - &clk_mout_mpll.clk, }; void __init s5pv210_register_clocks(void) @@ -433,6 +428,9 @@ void __init s5pv210_register_clocks(void) if (ret > 0) printk(KERN_ERR "Failed to register %u clocks\n", ret); + for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) + s3c_register_clksrc(sysclks[ptr], 1); + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); -- cgit v1.2.3-59-g8ed1b From c62ec6a9aaabd5d0512e9d091d82940efefa4fa6 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:28 +0900 Subject: ARM: S5PV210: Rearrange assignment of clock for fout apll/mpll/epll clocks The assignment of clock rates for fout apll/mpll/epll is moved further up in the s5pv210_setup_clocks function because the subsequent patches require the clock rate of fout clocks to be setup. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 25b73a38d6d5..d782fed0c76e 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -369,6 +369,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500); + clk_fout_apll.rate = apll; + clk_fout_mpll.rate = mpll; + clk_fout_epll.rate = epll; + printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld", apll, mpll, epll); @@ -398,10 +402,6 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n", armclk, hclk200, hclk166, hclk133, pclk100, pclk83, pclk66); - clk_fout_apll.rate = apll; - clk_fout_mpll.rate = mpll; - clk_fout_epll.rate = epll; - clk_f.rate = armclk; clk_h.rate = hclk133; clk_p.rate = pclk66; -- cgit v1.2.3-59-g8ed1b From 374e0bf5f9e3b6055a943a838605e411b50c2838 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:31 +0900 Subject: ARM: S5PV210: Add armclk of clksrc_clk clock type This patch modifies the following. 1. Adds arm clock 'clk_armclk' of type clksrc_clk clock type. 2. Adds arm clock to the list of system clocks 'sysclks' for registering it along with other system clocks. 3. Modifies the armclk clock rate calculation procedure to be based on the new clk_armclk clock. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index d782fed0c76e..f57fa1ee6ff0 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -58,6 +58,26 @@ static struct clksrc_clk clk_mout_mpll = { .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 }, }; +static struct clk *clkset_armclk_list[] = { + [0] = &clk_mout_apll.clk, + [1] = &clk_mout_mpll.clk, +}; + +static struct clksrc_sources clkset_armclk = { + .sources = clkset_armclk_list, + .nr_sources = ARRAY_SIZE(clkset_armclk_list), +}; + +static struct clksrc_clk clk_armclk = { + .clk = { + .name = "armclk", + .id = -1, + }, + .sources = &clkset_armclk, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 }, +}; + static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable); @@ -328,6 +348,7 @@ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, &clk_mout_epll, &clk_mout_mpll, + &clk_armclk, }; #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) @@ -376,7 +397,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld", apll, mpll, epll); - armclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_APLL); + armclk = clk_get_rate(&clk_armclk.clk); if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX200_MASK) hclk200 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200); else -- cgit v1.2.3-59-g8ed1b From af76a201c63fd7566bab8892f3b8c82e66a264d0 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:34 +0900 Subject: ARM: S5PV210: Remove usage of clk_h200 clock and add clk_hclk_msys clock The clk_h200 represents the HCLK for the MSYS domain. This clock is of type 'struct clk' but on V210, it is more suitable to be of type 'struct clksrc_clk' (since it is a divided version of the armclk). The replacement clock is renamed as clk_hclk_msys to indicate that it represents the HCLK for MSYS domain. This patch modifies the following. 1. Removes the usage of the clk_h200 clock. 2. Adds the new clock 'clk_hclk_msys'. 3. Adds clk_hclk_msys to the list of sysclks to be registered. 4. Modifies the hclk_msys clock rate calculation procedure to be based on the new clk_hclk_msys clock. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index f57fa1ee6ff0..d5acd261795c 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -78,6 +78,15 @@ static struct clksrc_clk clk_armclk = { .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 }, }; +static struct clksrc_clk clk_hclk_msys = { + .clk = { + .name = "hclk_msys", + .id = -1, + .parent = &clk_armclk.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 }, +}; + static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable); @@ -98,11 +107,6 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable) return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); } -static struct clk clk_h200 = { - .name = "hclk200", - .id = -1, -}; - static struct clk clk_h100 = { .name = "hclk100", .id = -1, @@ -134,7 +138,6 @@ static struct clk clk_p66 = { }; static struct clk *sys_clks[] = { - &clk_h200, &clk_h100, &clk_h166, &clk_h133, @@ -349,6 +352,7 @@ static struct clksrc_clk *sysclks[] = { &clk_mout_epll, &clk_mout_mpll, &clk_armclk, + &clk_hclk_msys, }; #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) @@ -358,7 +362,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) struct clk *xtal_clk; unsigned long xtal; unsigned long armclk; - unsigned long hclk200; + unsigned long hclk_msys; unsigned long hclk166; unsigned long hclk133; unsigned long pclk100; @@ -398,10 +402,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) apll, mpll, epll); armclk = clk_get_rate(&clk_armclk.clk); - if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX200_MASK) - hclk200 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200); - else - hclk200 = armclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200); + hclk_msys = clk_get_rate(&clk_hclk_msys.clk); if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX166_MASK) { hclk166 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M); @@ -415,13 +416,13 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) } else hclk133 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133); - pclk100 = hclk200 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100); + pclk100 = hclk_msys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100); pclk83 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83); pclk66 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66); printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld, \ HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n", - armclk, hclk200, hclk166, hclk133, pclk100, pclk83, pclk66); + armclk, hclk_msys, hclk166, hclk133, pclk100, pclk83, pclk66); clk_f.rate = armclk; clk_h.rate = hclk133; @@ -430,7 +431,6 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) clk_p83.rate = pclk83; clk_h133.rate = hclk133; clk_h166.rate = hclk166; - clk_h200.rate = hclk200; for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_set_clksrc(&clksrcs[ptr], true); -- cgit v1.2.3-59-g8ed1b From 0fe967a1ca8845ac227d3cab51e3520ddb310932 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:37 +0900 Subject: ARM: S5PV210: Remove usage of clk_h166 and add clk_hclk_dsys clock The clk_h166 clock, which is the HCLK clock for DSYS domain, is of type 'struct clk' whereas on S5PV210, this clock is suitable to be of type clksrc_clk clock (since it has a choice of clock source and a pre-divider). So this patch replaces the 'struct clk' type clock to 'struct clksrc_clk' type clock for the HCLK DSYS clock. This patch modifies the following. 1. Remove definitions and usage of 'clk_h166' clock. 2. Adds 'clk_sclk_a2m' clock which is one of possible parent clock sources for the DSYS HCLK clock. 3. Adds 'clk_hclk_dsys' clock which is of type 'struct clksrc_clk'. 4. Replace all usage of clk_h166 with clk_hclk_dsys clock. 5. Adds clk_sclk_a2m and clk_hclk_dsys into list of clocks to be registered. 6. Removes the clock rate calculation of hclk166 and replaces it with code that derives the HCLK DSYS clock rate from the clk_hclk_dsys clock. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 55 +++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index d5acd261795c..ecffafea7f83 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -87,6 +87,35 @@ static struct clksrc_clk clk_hclk_msys = { .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 }, }; +static struct clksrc_clk clk_sclk_a2m = { + .clk = { + .name = "sclk_a2m", + .id = -1, + .parent = &clk_mout_apll.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 }, +}; + +static struct clk *clkset_hclk_sys_list[] = { + [0] = &clk_mout_mpll.clk, + [1] = &clk_sclk_a2m.clk, +}; + +static struct clksrc_sources clkset_hclk_sys = { + .sources = clkset_hclk_sys_list, + .nr_sources = ARRAY_SIZE(clkset_hclk_sys_list), +}; + +static struct clksrc_clk clk_hclk_dsys = { + .clk = { + .name = "hclk_dsys", + .id = -1, + }, + .sources = &clkset_hclk_sys, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 }, +}; + static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable); @@ -112,11 +141,6 @@ static struct clk clk_h100 = { .id = -1, }; -static struct clk clk_h166 = { - .name = "hclk166", - .id = -1, -}; - static struct clk clk_h133 = { .name = "hclk133", .id = -1, @@ -139,7 +163,6 @@ static struct clk clk_p66 = { static struct clk *sys_clks[] = { &clk_h100, - &clk_h166, &clk_h133, &clk_p100, &clk_p83, @@ -150,7 +173,7 @@ static struct clk init_clocks_disable[] = { { .name = "rot", .id = -1, - .parent = &clk_h166, + .parent = &clk_hclk_dsys.clk, .enable = s5pv210_clk_ip0_ctrl, .ctrlbit = (1<<29), }, { @@ -168,7 +191,7 @@ static struct clk init_clocks_disable[] = { }, { .name = "lcd", .id = -1, - .parent = &clk_h166, + .parent = &clk_hclk_dsys.clk, .enable = s5pv210_clk_ip1_ctrl, .ctrlbit = (1<<0), }, { @@ -353,6 +376,8 @@ static struct clksrc_clk *sysclks[] = { &clk_mout_mpll, &clk_armclk, &clk_hclk_msys, + &clk_sclk_a2m, + &clk_hclk_dsys, }; #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) @@ -363,7 +388,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) unsigned long xtal; unsigned long armclk; unsigned long hclk_msys; - unsigned long hclk166; + unsigned long hclk_dsys; unsigned long hclk133; unsigned long pclk100; unsigned long pclk83; @@ -403,12 +428,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) armclk = clk_get_rate(&clk_armclk.clk); hclk_msys = clk_get_rate(&clk_hclk_msys.clk); - - if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX166_MASK) { - hclk166 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M); - hclk166 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166); - } else - hclk166 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166); + hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk); if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX133_MASK) { hclk133 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M); @@ -417,12 +437,12 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) hclk133 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133); pclk100 = hclk_msys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100); - pclk83 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83); + pclk83 = hclk_dsys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83); pclk66 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66); printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld, \ HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n", - armclk, hclk_msys, hclk166, hclk133, pclk100, pclk83, pclk66); + armclk, hclk_msys, hclk_dsys, hclk133, pclk100, pclk83, pclk66); clk_f.rate = armclk; clk_h.rate = hclk133; @@ -430,7 +450,6 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) clk_p66.rate = pclk66; clk_p83.rate = pclk83; clk_h133.rate = hclk133; - clk_h166.rate = hclk166; for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_set_clksrc(&clksrcs[ptr], true); -- cgit v1.2.3-59-g8ed1b From acfa245fc7777bc1935c70a8951ff699952921c5 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:40 +0900 Subject: ARM: S5PV210: Remove usage of clk_h133 and add clk_hclk_psys clock The clk_h133 clock, which is the HCLK clock for PSYS domain, is of type 'struct clk' whereas on S5PV210, this clock is suitable to be of type clksrc_clk clock (since it has a choice of clock source and a pre-divider). So this patch replaces the 'struct clk' type clock to 'struct clksrc_clk' type clock for the HCLK PSYS clock. This patch modifies the following. 1. Remove definitions and usage of 'clk_h133' clock. 2. Adds 'clk_hclk_psys' clock which is of type 'struct clksrc_clk'. 3. Replace all usage of clk_h133 with clk_hclk_psys clock. 4. Adds clk_hclk_psys into list of clocks to be registered. 5. Removes the clock rate calculation of hclk133 and replaces it with code that derives the HCLK PSYS clock rate from the clk_hclk_psys clock. 6. Modify printing of the system clock rates. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index ecffafea7f83..7ed1d4e8ae0e 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -116,6 +116,16 @@ static struct clksrc_clk clk_hclk_dsys = { .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 }, }; +static struct clksrc_clk clk_hclk_psys = { + .clk = { + .name = "hclk_psys", + .id = -1, + }, + .sources = &clkset_hclk_sys, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 }, +}; + static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable); @@ -141,11 +151,6 @@ static struct clk clk_h100 = { .id = -1, }; -static struct clk clk_h133 = { - .name = "hclk133", - .id = -1, -}; - static struct clk clk_p100 = { .name = "pclk100", .id = -1, @@ -163,7 +168,6 @@ static struct clk clk_p66 = { static struct clk *sys_clks[] = { &clk_h100, - &clk_h133, &clk_p100, &clk_p83, &clk_p66 @@ -179,13 +183,13 @@ static struct clk init_clocks_disable[] = { }, { .name = "otg", .id = -1, - .parent = &clk_h133, + .parent = &clk_hclk_psys.clk, .enable = s5pv210_clk_ip1_ctrl, .ctrlbit = (1<<16), }, { .name = "usb-host", .id = -1, - .parent = &clk_h133, + .parent = &clk_hclk_psys.clk, .enable = s5pv210_clk_ip1_ctrl, .ctrlbit = (1<<17), }, { @@ -197,31 +201,31 @@ static struct clk init_clocks_disable[] = { }, { .name = "cfcon", .id = 0, - .parent = &clk_h133, + .parent = &clk_hclk_psys.clk, .enable = s5pv210_clk_ip1_ctrl, .ctrlbit = (1<<25), }, { .name = "hsmmc", .id = 0, - .parent = &clk_h133, + .parent = &clk_hclk_psys.clk, .enable = s5pv210_clk_ip2_ctrl, .ctrlbit = (1<<16), }, { .name = "hsmmc", .id = 1, - .parent = &clk_h133, + .parent = &clk_hclk_psys.clk, .enable = s5pv210_clk_ip2_ctrl, .ctrlbit = (1<<17), }, { .name = "hsmmc", .id = 2, - .parent = &clk_h133, + .parent = &clk_hclk_psys.clk, .enable = s5pv210_clk_ip2_ctrl, .ctrlbit = (1<<18), }, { .name = "hsmmc", .id = 3, - .parent = &clk_h133, + .parent = &clk_hclk_psys.clk, .enable = s5pv210_clk_ip2_ctrl, .ctrlbit = (1<<19), }, { @@ -378,6 +382,7 @@ static struct clksrc_clk *sysclks[] = { &clk_hclk_msys, &clk_sclk_a2m, &clk_hclk_dsys, + &clk_hclk_psys, }; #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) @@ -389,7 +394,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) unsigned long armclk; unsigned long hclk_msys; unsigned long hclk_dsys; - unsigned long hclk133; + unsigned long hclk_psys; unsigned long pclk100; unsigned long pclk83; unsigned long pclk66; @@ -429,27 +434,22 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) armclk = clk_get_rate(&clk_armclk.clk); hclk_msys = clk_get_rate(&clk_hclk_msys.clk); hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk); - - if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX133_MASK) { - hclk133 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M); - hclk133 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133); - } else - hclk133 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133); + hclk_psys = clk_get_rate(&clk_hclk_psys.clk); pclk100 = hclk_msys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100); pclk83 = hclk_dsys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83); - pclk66 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66); + pclk66 = hclk_psys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66); - printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld, \ - HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n", - armclk, hclk_msys, hclk_dsys, hclk133, pclk100, pclk83, pclk66); + printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n" + "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n", + armclk, hclk_msys, hclk_dsys, hclk_psys, + pclk100, pclk83, pclk66); clk_f.rate = armclk; - clk_h.rate = hclk133; + clk_h.rate = hclk_psys; clk_p.rate = pclk66; clk_p66.rate = pclk66; clk_p83.rate = pclk83; - clk_h133.rate = hclk133; for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_set_clksrc(&clksrcs[ptr], true); -- cgit v1.2.3-59-g8ed1b From 6ed91a202b3843d2fec51f00c31e65313ca00906 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:42 +0900 Subject: ARM: S5PV210: Remove usage of clk_p100 and add clk_pclk_msys clock The clk_p100 clock, which is the PCLK clock for MSYS domain, is of type 'struct clk' whereas on S5PV210, this clock is suitable to be of type clksrc_clk clock (since it has a choice of clock source and a pre-divider). So this patch replaces the 'struct clk' type clock to 'struct clksrc_clk' type clock for the PCLK MSYS clock. This patch modifies the following. 1. Remove definitions and usage of 'clk_p100' clock. 2. Adds 'clk_pclk_msys' clock which is of type 'struct clksrc_clk'. 3. Replace all usage of clk_p100 with clk_pclk_msys clock. 4. Adds clk_pclk_msys into list of clocks to be registered. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 7ed1d4e8ae0e..4791642f3e6e 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -87,6 +87,15 @@ static struct clksrc_clk clk_hclk_msys = { .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 }, }; +static struct clksrc_clk clk_pclk_msys = { + .clk = { + .name = "pclk_msys", + .id = -1, + .parent = &clk_hclk_msys.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 }, +}; + static struct clksrc_clk clk_sclk_a2m = { .clk = { .name = "sclk_a2m", @@ -151,11 +160,6 @@ static struct clk clk_h100 = { .id = -1, }; -static struct clk clk_p100 = { - .name = "pclk100", - .id = -1, -}; - static struct clk clk_p83 = { .name = "pclk83", .id = -1, @@ -168,7 +172,6 @@ static struct clk clk_p66 = { static struct clk *sys_clks[] = { &clk_h100, - &clk_p100, &clk_p83, &clk_p66 }; @@ -383,6 +386,7 @@ static struct clksrc_clk *sysclks[] = { &clk_sclk_a2m, &clk_hclk_dsys, &clk_hclk_psys, + &clk_pclk_msys, }; #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) @@ -395,7 +399,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) unsigned long hclk_msys; unsigned long hclk_dsys; unsigned long hclk_psys; - unsigned long pclk100; + unsigned long pclk_msys; unsigned long pclk83; unsigned long pclk66; unsigned long apll; @@ -435,15 +439,14 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) hclk_msys = clk_get_rate(&clk_hclk_msys.clk); hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk); hclk_psys = clk_get_rate(&clk_hclk_psys.clk); - - pclk100 = hclk_msys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100); + pclk_msys = clk_get_rate(&clk_pclk_msys.clk); pclk83 = hclk_dsys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83); pclk66 = hclk_psys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66); printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n" "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n", armclk, hclk_msys, hclk_dsys, hclk_psys, - pclk100, pclk83, pclk66); + pclk_msys, pclk83, pclk66); clk_f.rate = armclk; clk_h.rate = hclk_psys; -- cgit v1.2.3-59-g8ed1b From 664f5b2065da188821fe5aa998c6351e8c042d98 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:44 +0900 Subject: ARM: S5PV210: Fix clk_get_rate issue with the clk_h100 clock The clk_h100 clock represents the IMEM clock for the MSYS domain. This clock rate of this clock is always half of the hclk_msys clock. There is an issue when getting the clock rate of the clk_h100 clock (clock get_rate hclk_h100 always returns clock rate that is equal to the hclk_msys clock rate). This patch modifies the following. 1. Moves the definition of the clk_h100 clock into the 'init_clocks' list with the appropriate parent, ctrlbit, enable and ops fields. 2. The name of the clock is changed from 'clk_h100' to 'hclk_imem' to represent more clearly that is represents the IMEM clock in the MSYS domain. 3. The function to get the clock rate of the hclk_imem clock is added. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 4791642f3e6e..527c9c4262f1 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -155,11 +155,6 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable) return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); } -static struct clk clk_h100 = { - .name = "hclk100", - .id = -1, -}; - static struct clk clk_p83 = { .name = "pclk83", .id = -1, @@ -171,11 +166,19 @@ static struct clk clk_p66 = { }; static struct clk *sys_clks[] = { - &clk_h100, &clk_p83, &clk_p66 }; +static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk) +{ + return clk_get_rate(clk->parent) / 2; +} + +static struct clk_ops clk_hclk_imem_ops = { + .get_rate = s5pv210_clk_imem_get_rate, +}; + static struct clk init_clocks_disable[] = { { .name = "rot", @@ -326,6 +329,13 @@ static struct clk init_clocks_disable[] = { static struct clk init_clocks[] = { { + .name = "hclk_imem", + .id = -1, + .parent = &clk_hclk_msys.clk, + .ctrlbit = (1 << 5), + .enable = s5pv210_clk_ip0_ctrl, + .ops = &clk_hclk_imem_ops, + }, { .name = "uart", .id = 0, .parent = &clk_p66, -- cgit v1.2.3-59-g8ed1b From 58772cd34479ca50e90eea25288d2021dd2e6ff6 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:48 +0900 Subject: ARM: S5PV210: Remove usage of clk_p83 and add clk_pclk_dsys clock\ The clk_p83 clock, which is the PCLK clock for DSYS domain, is of type 'struct clk' whereas on S5PV210, this clock is suitable to be of type clksrc_clk clock (since it has a clock divider). So this patch replaces the 'struct clk' type clock to 'struct clksrc_clk' type clock for the PCLK DSYS clock. This patch modifies the following. 1. Remove definitions and usage of 'clk_p83' clock. 2. Adds 'clk_pclk_dsys' clock which is of type 'struct clksrc_clk'. 3. Replace all usage of clk_p83 with clk_pclk_dsys clock. 4. Adds clk_pclk_dsys into list of clocks to be registered. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 527c9c4262f1..b46d9ec69eb8 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -125,6 +125,15 @@ static struct clksrc_clk clk_hclk_dsys = { .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 }, }; +static struct clksrc_clk clk_pclk_dsys = { + .clk = { + .name = "pclk_dsys", + .id = -1, + .parent = &clk_hclk_dsys.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 }, +}; + static struct clksrc_clk clk_hclk_psys = { .clk = { .name = "hclk_psys", @@ -155,18 +164,12 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable) return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); } -static struct clk clk_p83 = { - .name = "pclk83", - .id = -1, -}; - static struct clk clk_p66 = { .name = "pclk66", .id = -1, }; static struct clk *sys_clks[] = { - &clk_p83, &clk_p66 }; @@ -397,6 +400,7 @@ static struct clksrc_clk *sysclks[] = { &clk_hclk_dsys, &clk_hclk_psys, &clk_pclk_msys, + &clk_pclk_dsys, }; #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) @@ -410,7 +414,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) unsigned long hclk_dsys; unsigned long hclk_psys; unsigned long pclk_msys; - unsigned long pclk83; + unsigned long pclk_dsys; unsigned long pclk66; unsigned long apll; unsigned long mpll; @@ -450,19 +454,18 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk); hclk_psys = clk_get_rate(&clk_hclk_psys.clk); pclk_msys = clk_get_rate(&clk_pclk_msys.clk); - pclk83 = hclk_dsys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83); + pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk); pclk66 = hclk_psys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66); printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n" "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n", armclk, hclk_msys, hclk_dsys, hclk_psys, - pclk_msys, pclk83, pclk66); + pclk_msys, pclk_dsys, pclk66); clk_f.rate = armclk; clk_h.rate = hclk_psys; clk_p.rate = pclk66; clk_p66.rate = pclk66; - clk_p83.rate = pclk83; for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_set_clksrc(&clksrcs[ptr], true); -- cgit v1.2.3-59-g8ed1b From f44cf78b6b475116a4d3c98576f8697dd4ca7e79 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:50 +0900 Subject: ARM: S5PV210: Remove usage of clk_p66 and add clk_pclk_psys clock The clk_p83 clock, which is the PCLK clock for PSYS domain, is of type 'struct clk' whereas on S5PV210, this clock is suitable to be of type clksrc_clk clock (since it has a clock divider). So this patch replaces the 'struct clk' type clock to 'struct clksrc_clk' type clock for the PCLK PSYS clock. This patch modifies the following. 1. Removes definitions and usage of 'clk_p66' clock. 2. Adds 'clk_pclk_psys' clock which is of type 'struct clksrc_clk'. 3. Replaces all usage of clk_p66 with clk_pclk_psys clock. 4. Adds clk_pclk_psys into list of clocks to be registered. 5. Removes the sys_clks array since it is no longer required. Also the registration of clocks in sys_clks is also removed. 6. Remove the 'GET_DIV' as it is no longer required. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 66 ++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index b46d9ec69eb8..315955da0d06 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -144,6 +144,15 @@ static struct clksrc_clk clk_hclk_psys = { .reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 }, }; +static struct clksrc_clk clk_pclk_psys = { + .clk = { + .name = "pclk_psys", + .id = -1, + .parent = &clk_hclk_psys.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 }, +}; + static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable); @@ -164,15 +173,6 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable) return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); } -static struct clk clk_p66 = { - .name = "pclk66", - .id = -1, -}; - -static struct clk *sys_clks[] = { - &clk_p66 -}; - static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk) { return clk_get_rate(clk->parent) / 2; @@ -240,73 +240,73 @@ static struct clk init_clocks_disable[] = { }, { .name = "systimer", .id = -1, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<16), }, { .name = "watchdog", .id = -1, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<22), }, { .name = "rtc", .id = -1, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<15), }, { .name = "i2c", .id = 0, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<7), }, { .name = "i2c", .id = 1, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<8), }, { .name = "i2c", .id = 2, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<9), }, { .name = "spi", .id = 0, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<12), }, { .name = "spi", .id = 1, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<13), }, { .name = "spi", .id = 2, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<14), }, { .name = "timers", .id = -1, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<23), }, { .name = "adc", .id = -1, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<24), }, { .name = "keypad", .id = -1, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<21), }, { @@ -341,25 +341,25 @@ static struct clk init_clocks[] = { }, { .name = "uart", .id = 0, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<7), }, { .name = "uart", .id = 1, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<8), }, { .name = "uart", .id = 2, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<9), }, { .name = "uart", .id = 3, - .parent = &clk_p66, + .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<10), }, @@ -401,10 +401,9 @@ static struct clksrc_clk *sysclks[] = { &clk_hclk_psys, &clk_pclk_msys, &clk_pclk_dsys, + &clk_pclk_psys, }; -#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) - void __init_or_cpufreq s5pv210_setup_clocks(void) { struct clk *xtal_clk; @@ -415,7 +414,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) unsigned long hclk_psys; unsigned long pclk_msys; unsigned long pclk_dsys; - unsigned long pclk66; + unsigned long pclk_psys; unsigned long apll; unsigned long mpll; unsigned long epll; @@ -455,17 +454,16 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) hclk_psys = clk_get_rate(&clk_hclk_psys.clk); pclk_msys = clk_get_rate(&clk_pclk_msys.clk); pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk); - pclk66 = hclk_psys / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66); + pclk_psys = clk_get_rate(&clk_pclk_psys.clk); printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n" "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n", armclk, hclk_msys, hclk_dsys, hclk_psys, - pclk_msys, pclk_dsys, pclk66); + pclk_msys, pclk_dsys, pclk_psys); clk_f.rate = armclk; clk_h.rate = hclk_psys; - clk_p.rate = pclk66; - clk_p66.rate = pclk66; + clk_p.rate = pclk_psys; for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) s3c_set_clksrc(&clksrcs[ptr], true); @@ -490,10 +488,6 @@ void __init s5pv210_register_clocks(void) s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); - ret = s3c24xx_register_clocks(sys_clks, ARRAY_SIZE(sys_clks)); - if (ret > 0) - printk(KERN_ERR "Failed to register system clocks\n"); - clkp = init_clocks_disable; for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { ret = s3c24xx_register_clock(clkp); -- cgit v1.2.3-59-g8ed1b From f445dbd5af7863dd7dce4685e39980419d4144eb Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:52 +0900 Subject: ARM: S5PV210: Add support for VPLL This patch adds the following. 1. Adds 'clk_sclk_hdmi27m' clock to represent the HDMI 27MHz clock. 2. Adds 'clk_vpllsrc; clock of type clksrc_clk to represent the input clock for VPLL. 3. Adds 'clk_sclk_vpll' clock of type clksrc_clk to represent the output of the MUX_VPLL mux. 4. Add clk_sclk_hdmi27m, clk_vpllsrc and clk_sclk_vpll to the list of clocks to be registered. 5. Adds boot time print of 'clk_sclk_vpll' clock rate. 6. Adds 'clk_fout_vpll' clock to plat-s5p such that it is reusable on other s5p platforms. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 63 +++++++++++++++++++++++++++++- arch/arm/plat-s5p/clock.c | 8 ++++ arch/arm/plat-s5p/include/plat/s5p-clock.h | 1 + 3 files changed, 70 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 315955da0d06..c86bff525dbe 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -173,6 +173,57 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable) return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); } +static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable); +} + +static struct clk clk_sclk_hdmi27m = { + .name = "sclk_hdmi27m", + .id = -1, + .rate = 27000000, +}; + +static struct clk *clkset_vpllsrc_list[] = { + [0] = &clk_fin_vpll, + [1] = &clk_sclk_hdmi27m, +}; + +static struct clksrc_sources clkset_vpllsrc = { + .sources = clkset_vpllsrc_list, + .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list), +}; + +static struct clksrc_clk clk_vpllsrc = { + .clk = { + .name = "vpll_src", + .id = -1, + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 7), + }, + .sources = &clkset_vpllsrc, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 }, +}; + +static struct clk *clkset_sclk_vpll_list[] = { + [0] = &clk_vpllsrc.clk, + [1] = &clk_fout_vpll, +}; + +static struct clksrc_sources clkset_sclk_vpll = { + .sources = clkset_sclk_vpll_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list), +}; + +static struct clksrc_clk clk_sclk_vpll = { + .clk = { + .name = "sclk_vpll", + .id = -1, + }, + .sources = &clkset_sclk_vpll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 }, +}; + static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk) { return clk_get_rate(clk->parent) / 2; @@ -402,12 +453,15 @@ static struct clksrc_clk *sysclks[] = { &clk_pclk_msys, &clk_pclk_dsys, &clk_pclk_psys, + &clk_vpllsrc, + &clk_sclk_vpll, }; void __init_or_cpufreq s5pv210_setup_clocks(void) { struct clk *xtal_clk; unsigned long xtal; + unsigned long vpllsrc; unsigned long armclk; unsigned long hclk_msys; unsigned long hclk_dsys; @@ -418,6 +472,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) unsigned long apll; unsigned long mpll; unsigned long epll; + unsigned long vpll; unsigned int ptr; u32 clkdiv0, clkdiv1; @@ -440,13 +495,16 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500); + vpllsrc = clk_get_rate(&clk_vpllsrc.clk); + vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502); clk_fout_apll.rate = apll; clk_fout_mpll.rate = mpll; clk_fout_epll.rate = epll; + clk_fout_vpll.rate = vpll; - printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld", - apll, mpll, epll); + printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld", + apll, mpll, epll, vpll); armclk = clk_get_rate(&clk_armclk.clk); hclk_msys = clk_get_rate(&clk_hclk_msys.clk); @@ -470,6 +528,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) } static struct clk *clks[] __initdata = { + &clk_sclk_hdmi27m, }; void __init s5pv210_register_clocks(void) diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index aa96e335073b..4ca0759fa228 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c @@ -69,6 +69,13 @@ struct clk clk_fout_epll = { .ctrlbit = (1 << 31), }; +/* VPLL clock output */ +struct clk clk_fout_vpll = { + .name = "fout_vpll", + .id = -1, + .ctrlbit = (1 << 31), +}; + /* ARM clock */ struct clk clk_arm = { .name = "armclk", @@ -133,6 +140,7 @@ static struct clk *s5p_clks[] __initdata = { &clk_fout_apll, &clk_fout_mpll, &clk_fout_epll, + &clk_fout_vpll, &clk_arm, &clk_vpll, }; diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h index 56fb8b414d41..5ae8866b7989 100644 --- a/arch/arm/plat-s5p/include/plat/s5p-clock.h +++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h @@ -27,6 +27,7 @@ extern struct clk clk_48m; extern struct clk clk_fout_apll; extern struct clk clk_fout_mpll; extern struct clk clk_fout_epll; +extern struct clk clk_fout_vpll; extern struct clk clk_arm; extern struct clk clk_vpll; -- cgit v1.2.3-59-g8ed1b From 2cf4c2e6301f19e08b7090c024b312f6e2c0f230 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:55 +0900 Subject: ARM: S5PV210: Add new system clocks This patch adds the following system clocks. 1. clk_sclk_hdmiphy 2. clk_sclk_usbphy0 3. clk_sclk_usbphy1 4. sclk_dmc (dram memory controller clock) 5. sclk_onenand Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 56 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index c86bff525dbe..2c7be15b5895 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -184,6 +184,21 @@ static struct clk clk_sclk_hdmi27m = { .rate = 27000000, }; +static struct clk clk_sclk_hdmiphy = { + .name = "sclk_hdmiphy", + .id = -1, +}; + +static struct clk clk_sclk_usbphy0 = { + .name = "sclk_usbphy0", + .id = -1, +}; + +static struct clk clk_sclk_usbphy1 = { + .name = "sclk_usbphy1", + .id = -1, +}; + static struct clk *clkset_vpllsrc_list[] = { [0] = &clk_fin_vpll, [1] = &clk_sclk_hdmi27m, @@ -426,8 +441,46 @@ static struct clksrc_sources clkset_uart = { .nr_sources = ARRAY_SIZE(clkset_uart_list), }; +static struct clk *clkset_group1_list[] = { + [0] = &clk_sclk_a2m.clk, + [1] = &clk_mout_mpll.clk, + [2] = &clk_mout_epll.clk, + [3] = &clk_sclk_vpll.clk, +}; + +static struct clksrc_sources clkset_group1 = { + .sources = clkset_group1_list, + .nr_sources = ARRAY_SIZE(clkset_group1_list), +}; + +static struct clk *clkset_sclk_onenand_list[] = { + [0] = &clk_hclk_psys.clk, + [1] = &clk_hclk_dsys.clk, +}; + +static struct clksrc_sources clkset_sclk_onenand = { + .sources = clkset_sclk_onenand_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_onenand_list), +}; + static struct clksrc_clk clksrcs[] = { { + .clk = { + .name = "sclk_dmc", + .id = -1, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 }, + }, { + .clk = { + .name = "sclk_onenand", + .id = -1, + }, + .sources = &clkset_sclk_onenand, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 }, + .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 }, + }, { .clk = { .name = "uclk1", .id = -1, @@ -529,6 +582,9 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) static struct clk *clks[] __initdata = { &clk_sclk_hdmi27m, + &clk_sclk_hdmiphy, + &clk_sclk_usbphy0, + &clk_sclk_usbphy1, }; void __init s5pv210_register_clocks(void) -- cgit v1.2.3-59-g8ed1b From 9e20614bb9403102033b60ce7d8fceb5becdb71c Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:38:57 +0900 Subject: ARM: S5PV210: Add sclk_dac, sclk_mixer and sclk_hdmi clocks Add sclk_dac, sclk_mixer and sclk_hdmi clocks. These clocks are of type 'struct clksrc_clk' and so have a corresponding clock list. These clocks are also added to the list of clocks to be registered at boot time. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 75 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 2c7be15b5895..c03e2880518a 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -463,6 +463,67 @@ static struct clksrc_sources clkset_sclk_onenand = { .nr_sources = ARRAY_SIZE(clkset_sclk_onenand_list), }; +static struct clk *clkset_sclk_dac_list[] = { + [0] = &clk_sclk_vpll.clk, + [1] = &clk_sclk_hdmiphy, +}; + +static struct clksrc_sources clkset_sclk_dac = { + .sources = clkset_sclk_dac_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_dac_list), +}; + +static struct clksrc_clk clk_sclk_dac = { + .clk = { + .name = "sclk_dac", + .id = -1, + .ctrlbit = (1 << 10), + .enable = s5pv210_clk_ip1_ctrl, + }, + .sources = &clkset_sclk_dac, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 }, +}; + +static struct clksrc_clk clk_sclk_pixel = { + .clk = { + .name = "sclk_pixel", + .id = -1, + .parent = &clk_sclk_vpll.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4}, +}; + +static struct clk *clkset_sclk_hdmi_list[] = { + [0] = &clk_sclk_pixel.clk, + [1] = &clk_sclk_hdmiphy, +}; + +static struct clksrc_sources clkset_sclk_hdmi = { + .sources = clkset_sclk_hdmi_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_hdmi_list), +}; + +static struct clksrc_clk clk_sclk_hdmi = { + .clk = { + .name = "sclk_hdmi", + .id = -1, + .enable = s5pv210_clk_ip1_ctrl, + .ctrlbit = (1 << 11), + }, + .sources = &clkset_sclk_hdmi, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 }, +}; + +static struct clk *clkset_sclk_mixer_list[] = { + [0] = &clk_sclk_dac.clk, + [1] = &clk_sclk_hdmi.clk, +}; + +static struct clksrc_sources clkset_sclk_mixer = { + .sources = clkset_sclk_mixer_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list), +}; + static struct clksrc_clk clksrcs[] = { { .clk = { @@ -490,7 +551,16 @@ static struct clksrc_clk clksrcs[] = { .sources = &clkset_uart, .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 }, .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, - } + }, { + .clk = { + .name = "sclk_mixer", + .id = -1, + .enable = s5pv210_clk_ip1_ctrl, + .ctrlbit = (1 << 9), + }, + .sources = &clkset_sclk_mixer, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 }, + }, }; /* Clock initialisation code */ @@ -508,6 +578,9 @@ static struct clksrc_clk *sysclks[] = { &clk_pclk_psys, &clk_vpllsrc, &clk_sclk_vpll, + &clk_sclk_dac, + &clk_sclk_pixel, + &clk_sclk_hdmi, }; void __init_or_cpufreq s5pv210_setup_clocks(void) -- cgit v1.2.3-59-g8ed1b From 4583487c43358070ef1bd43dd1cbaf2dd42e4db7 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:39:00 +0900 Subject: ARM: S5PV210: Add sclk_audio and sclk_spdif clocks. Add the sclk_audio(0/1/2) clocks and sclk_spdif clock of type 'struct clksrc_clk' clock. Also, add clk_pcmcdclk(0/1/2) clocks of type 'struct clk' clock. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 125 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index c03e2880518a..015471040f56 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -199,6 +199,21 @@ static struct clk clk_sclk_usbphy1 = { .id = -1, }; +static struct clk clk_pcmcdclk0 = { + .name = "pcmcdclk", + .id = -1, +}; + +static struct clk clk_pcmcdclk1 = { + .name = "pcmcdclk", + .id = -1, +}; + +static struct clk clk_pcmcdclk2 = { + .name = "pcmcdclk", + .id = -1, +}; + static struct clk *clkset_vpllsrc_list[] = { [0] = &clk_fin_vpll, [1] = &clk_sclk_hdmi27m, @@ -524,6 +539,104 @@ static struct clksrc_sources clkset_sclk_mixer = { .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list), }; +static struct clk *clkset_sclk_audio0_list[] = { + [0] = &clk_ext_xtal_mux, + [1] = &clk_pcmcdclk0, + [2] = &clk_sclk_hdmi27m, + [3] = &clk_sclk_usbphy0, + [4] = &clk_sclk_usbphy1, + [5] = &clk_sclk_hdmiphy, + [6] = &clk_mout_mpll.clk, + [7] = &clk_mout_epll.clk, + [8] = &clk_sclk_vpll.clk, +}; + +static struct clksrc_sources clkset_sclk_audio0 = { + .sources = clkset_sclk_audio0_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list), +}; + +static struct clksrc_clk clk_sclk_audio0 = { + .clk = { + .name = "sclk_audio", + .id = 0, + .enable = s5pv210_clk_ip3_ctrl, + .ctrlbit = (1 << 4), + }, + .sources = &clkset_sclk_audio0, + .reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 }, +}; + +static struct clk *clkset_sclk_audio1_list[] = { + [0] = &clk_ext_xtal_mux, + [1] = &clk_pcmcdclk1, + [2] = &clk_sclk_hdmi27m, + [3] = &clk_sclk_usbphy0, + [4] = &clk_sclk_usbphy1, + [5] = &clk_sclk_hdmiphy, + [6] = &clk_mout_mpll.clk, + [7] = &clk_mout_epll.clk, + [8] = &clk_sclk_vpll.clk, +}; + +static struct clksrc_sources clkset_sclk_audio1 = { + .sources = clkset_sclk_audio1_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_audio1_list), +}; + +static struct clksrc_clk clk_sclk_audio1 = { + .clk = { + .name = "sclk_audio", + .id = 1, + .enable = s5pv210_clk_ip3_ctrl, + .ctrlbit = (1 << 5), + }, + .sources = &clkset_sclk_audio1, + .reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 }, +}; + +static struct clk *clkset_sclk_audio2_list[] = { + [0] = &clk_ext_xtal_mux, + [1] = &clk_pcmcdclk0, + [2] = &clk_sclk_hdmi27m, + [3] = &clk_sclk_usbphy0, + [4] = &clk_sclk_usbphy1, + [5] = &clk_sclk_hdmiphy, + [6] = &clk_mout_mpll.clk, + [7] = &clk_mout_epll.clk, + [8] = &clk_sclk_vpll.clk, +}; + +static struct clksrc_sources clkset_sclk_audio2 = { + .sources = clkset_sclk_audio2_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_audio2_list), +}; + +static struct clksrc_clk clk_sclk_audio2 = { + .clk = { + .name = "sclk_audio", + .id = 2, + .enable = s5pv210_clk_ip3_ctrl, + .ctrlbit = (1 << 6), + }, + .sources = &clkset_sclk_audio2, + .reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 }, +}; + +static struct clk *clkset_sclk_spdif_list[] = { + [0] = &clk_sclk_audio0.clk, + [1] = &clk_sclk_audio1.clk, + [2] = &clk_sclk_audio2.clk, +}; + +static struct clksrc_sources clkset_sclk_spdif = { + .sources = clkset_sclk_spdif_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list), +}; + static struct clksrc_clk clksrcs[] = { { .clk = { @@ -560,6 +673,15 @@ static struct clksrc_clk clksrcs[] = { }, .sources = &clkset_sclk_mixer, .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 }, + }, { + .clk = { + .name = "sclk_spdif", + .id = -1, + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 27), + }, + .sources = &clkset_sclk_spdif, + .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 }, }, }; @@ -658,6 +780,9 @@ static struct clk *clks[] __initdata = { &clk_sclk_hdmiphy, &clk_sclk_usbphy0, &clk_sclk_usbphy1, + &clk_pcmcdclk0, + &clk_pcmcdclk1, + &clk_pcmcdclk2, }; void __init s5pv210_register_clocks(void) -- cgit v1.2.3-59-g8ed1b From f64cacc3194f49c7371e2ce61c22de62b8652dc7 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 May 2010 09:39:03 +0900 Subject: ARM: S5PV210: Add sclk clocks of type 'struct clksrc_clk' clock Add sclk clocks of type 'struct clksrc_clk' clock. The 'group2' of clock clock sources is also added. This patch also changes the the 'id' member value of the uclk1 clock for instance instance 0 since there are 4 instances of the uclk1 clock. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/clock.c | 230 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 229 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 015471040f56..154bca4abc09 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -173,6 +173,11 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable) return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); } +static int s5pv210_clk_ip4_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_IP4, clk, enable); +} + static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable); @@ -637,6 +642,23 @@ static struct clksrc_sources clkset_sclk_spdif = { .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list), }; +static struct clk *clkset_group2_list[] = { + [0] = &clk_ext_xtal_mux, + [1] = &clk_xusbxti, + [2] = &clk_sclk_hdmi27m, + [3] = &clk_sclk_usbphy0, + [4] = &clk_sclk_usbphy1, + [5] = &clk_sclk_hdmiphy, + [6] = &clk_mout_mpll.clk, + [7] = &clk_mout_epll.clk, + [8] = &clk_sclk_vpll.clk, +}; + +static struct clksrc_sources clkset_group2 = { + .sources = clkset_group2_list, + .nr_sources = ARRAY_SIZE(clkset_group2_list), +}; + static struct clksrc_clk clksrcs[] = { { .clk = { @@ -657,13 +679,43 @@ static struct clksrc_clk clksrcs[] = { }, { .clk = { .name = "uclk1", - .id = -1, + .id = 0, .ctrlbit = (1<<17), .enable = s5pv210_clk_ip3_ctrl, }, .sources = &clkset_uart, .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 }, .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "uclk1", + .id = 1, + .enable = s5pv210_clk_ip3_ctrl, + .ctrlbit = (1 << 18), + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "uclk1", + .id = 2, + .enable = s5pv210_clk_ip3_ctrl, + .ctrlbit = (1 << 19), + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 }, + }, { + .clk = { + .name = "uclk1", + .id = 3, + .enable = s5pv210_clk_ip3_ctrl, + .ctrlbit = (1 << 20), + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 }, }, { .clk = { .name = "sclk_mixer", @@ -682,6 +734,182 @@ static struct clksrc_clk clksrcs[] = { }, .sources = &clkset_sclk_spdif, .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 }, + }, { + .clk = { + .name = "sclk_fimc", + .id = 0, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 24), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .id = 1, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 25), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .id = 2, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 26), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "sclk_cam", + .id = 0, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "sclk_cam", + .id = 1, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimd", + .id = -1, + .enable = s5pv210_clk_ip1_ctrl, + .ctrlbit = (1 << 0), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "sclk_mmc", + .id = 0, + .enable = s5pv210_clk_ip2_ctrl, + .ctrlbit = (1 << 16), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_mmc", + .id = 1, + .enable = s5pv210_clk_ip2_ctrl, + .ctrlbit = (1 << 17), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_mmc", + .id = 2, + .enable = s5pv210_clk_ip2_ctrl, + .ctrlbit = (1 << 18), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "sclk_mmc", + .id = 3, + .enable = s5pv210_clk_ip2_ctrl, + .ctrlbit = (1 << 19), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "sclk_mfc", + .id = -1, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 16), + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_g2d", + .id = -1, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 12), + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "sclk_g3d", + .id = -1, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 8), + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_csis", + .id = -1, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 31), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 0, + .enable = s5pv210_clk_ip3_ctrl, + .ctrlbit = (1 << 12), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 1, + .enable = s5pv210_clk_ip3_ctrl, + .ctrlbit = (1 << 13), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_pwi", + .id = -1, + .enable = &s5pv210_clk_ip4_ctrl, + .ctrlbit = (1 << 2), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 }, + }, { + .clk = { + .name = "sclk_pwm", + .id = -1, + .enable = s5pv210_clk_ip3_ctrl, + .ctrlbit = (1 << 23), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 }, }, }; -- cgit v1.2.3-59-g8ed1b From 1114b68468fa2359e15c75f415793b9dd0e5d837 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 27 Apr 2010 16:24:22 +0200 Subject: sn_hwperf: Kill BKL usage This driver always gave up the BKL in its ioctl function, so just convert it to unlocked_ioctl and remove the BKL here. Signed-off-by: Arnd Bergmann Signed-off-by: Frederic Weisbecker --- arch/ia64/sn/kernel/sn2/sn_hwperf.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 55ac3c4e11d2..d68fe0f40a06 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -682,8 +681,7 @@ static int sn_hwperf_map_err(int hwperf_err) /* * ioctl for "sn_hwperf" misc device */ -static int -sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, unsigned long arg) +static long sn_hwperf_ioctl(struct file *fp, u32 op, unsigned long arg) { struct sn_hwperf_ioctl_args a; struct cpuinfo_ia64 *cdata; @@ -699,8 +697,6 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, unsigned long arg) int i; int j; - unlock_kernel(); - /* only user requests are allowed here */ if ((op & SN_HWPERF_OP_MASK) < 10) { r = -EINVAL; @@ -859,12 +855,11 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, unsigned long arg) error: vfree(p); - lock_kernel(); return r; } static const struct file_operations sn_hwperf_fops = { - .ioctl = sn_hwperf_ioctl, + .unlocked_ioctl = sn_hwperf_ioctl, }; static struct miscdevice sn_hwperf_dev = { -- cgit v1.2.3-59-g8ed1b From d5f1d54cbc1b2f320ac054b2df519dec22a27779 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 27 Apr 2010 16:24:23 +0200 Subject: um/mmapper: Remove BKL usage An empty function does not need the BKL, so just remove it. Signed-off-by: Arnd Bergmann Signed-off-by: Frederic Weisbecker --- arch/um/drivers/mmapper_kern.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index d22f9e5c0eac..7158393b6793 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -46,8 +46,7 @@ static ssize_t mmapper_write(struct file *file, const char __user *buf, return count; } -static int mmapper_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long mmapper_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return -ENOIOCTLCMD; } @@ -90,7 +89,7 @@ static const struct file_operations mmapper_fops = { .owner = THIS_MODULE, .read = mmapper_read, .write = mmapper_write, - .ioctl = mmapper_ioctl, + .unlocked_ioctl = mmapper_ioctl, .mmap = mmapper_mmap, .open = mmapper_open, .release = mmapper_release, -- cgit v1.2.3-59-g8ed1b From d6c89d9aca0933d90ab926bf448b32f24a163792 Mon Sep 17 00:00:00 2001 From: John Kacur Date: Fri, 7 May 2010 17:34:28 +0200 Subject: uml: Convert to unlocked_ioctls to remove implicit BKL Convert hostaudio_ioctl and hostmixer_ioctl_mixdev to unlocked_ioctl without pushdown. There is nothing to protect inside, the synchronization is made from the host already. Signed-off-by: John Kacur Cc: Arnd Bergmann Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Jeff Dike Signed-off-by: Frederic Weisbecker --- arch/um/drivers/hostaudio_kern.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index 368219cc2366..ae42695c3597 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -136,7 +136,7 @@ static unsigned int hostaudio_poll(struct file *file, return mask; } -static int hostaudio_ioctl(struct inode *inode, struct file *file, +static long hostaudio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct hostaudio_state *state = file->private_data; @@ -223,7 +223,7 @@ static int hostaudio_release(struct inode *inode, struct file *file) /* /dev/mixer file operations */ -static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, +static long hostmixer_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg) { struct hostmixer_state *state = file->private_data; @@ -289,7 +289,7 @@ static const struct file_operations hostaudio_fops = { .read = hostaudio_read, .write = hostaudio_write, .poll = hostaudio_poll, - .ioctl = hostaudio_ioctl, + .unlocked_ioctl = hostaudio_ioctl, .mmap = NULL, .open = hostaudio_open, .release = hostaudio_release, @@ -298,7 +298,7 @@ static const struct file_operations hostaudio_fops = { static const struct file_operations hostmixer_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .ioctl = hostmixer_ioctl_mixdev, + .unlocked_ioctl = hostmixer_ioctl_mixdev, .open = hostmixer_open_mixdev, .release = hostmixer_release, }; -- cgit v1.2.3-59-g8ed1b From e4af4268a34d8cd28c46a03161fc017cbd2db887 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Fri, 14 May 2010 14:41:14 -0700 Subject: x86, mrst, pci: return 0 for non-present pci bars Moorestown PCI code has special handling of devices with fixed BARs. In case of BAR sizing writes, we need to update the fake PCI MMCFG space with real size decode value. When a BAR is not present, we need to return 0 instead of ~0. ~0 will be treated as device error per bugzilla 12006. Signed-off-by: Jacob Pan LKML-Reference: <1273873281-17489-2-git-send-email-jacob.jun.pan@linux.intel.com> Acked-by: Jesse Barnes Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/pci/mrst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c index 8bf2fcb88d04..d5c7aefe56ff 100644 --- a/arch/x86/pci/mrst.c +++ b/arch/x86/pci/mrst.c @@ -109,7 +109,7 @@ static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn, decode++; decode = ~(decode - 1); } else { - decode = ~0; + decode = 0; } /* -- cgit v1.2.3-59-g8ed1b From fea24e28c663e62663097f0ed3b8ff1f9a87f15e Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Fri, 14 May 2010 14:41:20 -0700 Subject: x86, mrst: add nop functions to x86_init mpparse functions Moorestown does not have BIOS provided MP tables, we can save some time by avoiding scaning of these tables. e.g. [ 0.000000] Scan SMP from c0000000 for 1024 bytes. [ 0.000000] Scan SMP from c009fc00 for 1024 bytes. [ 0.000000] Scan SMP from c00f0000 for 65536 bytes. [ 0.000000] Scan SMP from c00bfff0 for 1024 bytes. Searching EBDA with the base at 0x40E will also result in random pointer deferencing within 1MB. This can be a problem in Lincroft if the pointer hits VGA area and VGA mode is not enabled. Signed-off-by: Jacob Pan LKML-Reference: <1273873281-17489-8-git-send-email-jacob.jun.pan@linux.intel.com> Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/kernel/mrst.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/mrst.c b/arch/x86/kernel/mrst.c index 0aad8670858e..e796448f0eb5 100644 --- a/arch/x86/kernel/mrst.c +++ b/arch/x86/kernel/mrst.c @@ -237,4 +237,9 @@ void __init x86_mrst_early_setup(void) x86_init.pci.fixup_irqs = x86_init_noop; legacy_pic = &null_legacy_pic; + + /* Avoid searching for BIOS MP tables */ + x86_init.mpparse.find_smp_config = x86_init_noop; + x86_init.mpparse.get_smp_config = x86_init_uint_noop; + } -- cgit v1.2.3-59-g8ed1b From 14894b9b8317d9a337bba55998fdef1c9b2dc63d Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 17 May 2010 10:35:29 +0900 Subject: S3C: DMA: Change argument of s3c2410_dma_devconfig All other functions have the channel argument of type 'unsigned int' the s3c2410_dma_devconfig also accept the same value as argument but treat it as type 'int'. Remove this anomaly by make it 'unsigned int'. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/dma.c | 2 +- arch/arm/plat-s3c24xx/dma.c | 2 +- arch/arm/plat-samsung/include/plat/dma.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 33ccf7bf766a..5567e037b0d1 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -414,7 +414,7 @@ err_buff: EXPORT_SYMBOL(s3c2410_dma_enqueue); -int s3c2410_dma_devconfig(int channel, +int s3c2410_dma_devconfig(unsigned int channel, enum s3c2410_dmasrc source, unsigned long devaddr) { diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 93827b3d4e84..6ad274e7593d 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -1104,7 +1104,7 @@ EXPORT_SYMBOL(s3c2410_dma_config); * devaddr: physical address of the source */ -int s3c2410_dma_devconfig(int channel, +int s3c2410_dma_devconfig(unsigned int channel, enum s3c2410_dmasrc source, unsigned long devaddr) { diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h index 7584d751ed51..2e8f8c6560d7 100644 --- a/arch/arm/plat-samsung/include/plat/dma.h +++ b/arch/arm/plat-samsung/include/plat/dma.h @@ -110,8 +110,8 @@ extern int s3c2410_dma_config(unsigned int channel, int xferunit); * configure the device we're talking to */ -extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source, - unsigned long devaddr); +extern int s3c2410_dma_devconfig(unsigned int channel, + enum s3c2410_dmasrc source, unsigned long devaddr); /* s3c2410_dma_getposition * -- cgit v1.2.3-59-g8ed1b From 94038a99119c171aea27608f81c7ba359de98c4e Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 17 May 2010 10:00:00 +0200 Subject: [S390] More cleanup for struct _lowcore Remove cpu_id from lowcore and replace addr_t with __u64. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/lowcore.h | 48 ++++++++++++++++++++--------------------- arch/s390/kernel/asm-offsets.c | 1 - arch/s390/kernel/head.S | 4 ++-- arch/s390/kernel/processor.c | 37 ++++++++++++++++++++----------- arch/s390/kernel/setup.c | 20 +++-------------- drivers/s390/cio/css.c | 7 ++++-- 6 files changed, 57 insertions(+), 60 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 05527c040b7a..f7e78c79b8b1 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -126,16 +126,15 @@ struct _lowcore { __u32 user_exec_asce; /* 0x02ac */ /* SMP info area */ - struct cpuid cpu_id; /* 0x02b0 */ - __u32 cpu_nr; /* 0x02b8 */ - __u32 softirq_pending; /* 0x02bc */ - __u32 percpu_offset; /* 0x02c0 */ - __u32 ext_call_fast; /* 0x02c4 */ - __u64 int_clock; /* 0x02c8 */ - __u64 clock_comparator; /* 0x02d0 */ - __u32 machine_flags; /* 0x02d8 */ - __u32 ftrace_func; /* 0x02dc */ - __u8 pad_0x02e0[0x0300-0x02e0]; /* 0x02e0 */ + __u32 cpu_nr; /* 0x02b0 */ + __u32 softirq_pending; /* 0x02b4 */ + __u32 percpu_offset; /* 0x02b8 */ + __u32 ext_call_fast; /* 0x02bc */ + __u64 int_clock; /* 0x02c0 */ + __u64 clock_comparator; /* 0x02c8 */ + __u32 machine_flags; /* 0x02d0 */ + __u32 ftrace_func; /* 0x02d4 */ + __u8 pad_0x02d8[0x0300-0x02d8]; /* 0x02d8 */ /* Interrupt response block */ __u8 irb[64]; /* 0x0300 */ @@ -189,14 +188,14 @@ struct _lowcore { __u32 data_exc_code; /* 0x0090 */ __u16 mon_class_num; /* 0x0094 */ __u16 per_perc_atmid; /* 0x0096 */ - addr_t per_address; /* 0x0098 */ + __u64 per_address; /* 0x0098 */ __u8 exc_access_id; /* 0x00a0 */ __u8 per_access_id; /* 0x00a1 */ __u8 op_access_id; /* 0x00a2 */ __u8 ar_access_id; /* 0x00a3 */ __u8 pad_0x00a4[0x00a8-0x00a4]; /* 0x00a4 */ - addr_t trans_exc_code; /* 0x00a8 */ - addr_t monitor_code; /* 0x00b0 */ + __u64 trans_exc_code; /* 0x00a8 */ + __u64 monitor_code; /* 0x00b0 */ __u16 subchannel_id; /* 0x00b8 */ __u16 subchannel_nr; /* 0x00ba */ __u32 io_int_parm; /* 0x00bc */ @@ -207,7 +206,7 @@ struct _lowcore { __u32 mcck_interruption_code[2]; /* 0x00e8 */ __u8 pad_0x00f0[0x00f4-0x00f0]; /* 0x00f0 */ __u32 external_damage_code; /* 0x00f4 */ - addr_t failing_storage_address; /* 0x00f8 */ + __u64 failing_storage_address; /* 0x00f8 */ __u8 pad_0x0100[0x0110-0x0100]; /* 0x0100 */ __u64 breaking_event_addr; /* 0x0110 */ __u8 pad_0x0118[0x0120-0x0118]; /* 0x0118 */ @@ -255,17 +254,16 @@ struct _lowcore { __u64 user_exec_asce; /* 0x0318 */ /* SMP info area */ - struct cpuid cpu_id; /* 0x0320 */ - __u32 cpu_nr; /* 0x0328 */ - __u32 softirq_pending; /* 0x032c */ - __u64 percpu_offset; /* 0x0330 */ - __u64 ext_call_fast; /* 0x0338 */ - __u64 int_clock; /* 0x0340 */ - __u64 clock_comparator; /* 0x0348 */ - __u64 vdso_per_cpu_data; /* 0x0350 */ - __u64 machine_flags; /* 0x0358 */ - __u64 ftrace_func; /* 0x0360 */ - __u8 pad_0x0368[0x0380-0x0368]; /* 0x0368 */ + __u32 cpu_nr; /* 0x0320 */ + __u32 softirq_pending; /* 0x0324 */ + __u64 percpu_offset; /* 0x0328 */ + __u64 ext_call_fast; /* 0x0330 */ + __u64 int_clock; /* 0x0338 */ + __u64 clock_comparator; /* 0x0340 */ + __u64 vdso_per_cpu_data; /* 0x0348 */ + __u64 machine_flags; /* 0x0350 */ + __u64 ftrace_func; /* 0x0358 */ + __u8 pad_0x0368[0x0380-0x0360]; /* 0x0360 */ /* Interrupt response block. */ __u8 irb[64]; /* 0x0380 */ diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index a09408952ed0..32b1ede69858 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -126,7 +126,6 @@ int main(void) DEFINE(__LC_KERNEL_ASCE, offsetof(struct _lowcore, kernel_asce)); DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce)); DEFINE(__LC_USER_EXEC_ASCE, offsetof(struct _lowcore, user_exec_asce)); - DEFINE(__LC_CPUID, offsetof(struct _lowcore, cpu_id)); DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock)); DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func)); diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index 9d1f76702d47..51838ad42d56 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -328,8 +328,8 @@ iplstart: # # reset files in VM reader # - stidp __LC_CPUID # store cpuid - tm __LC_CPUID,0xff # running VM ? + stidp __LC_SAVE_AREA # store cpuid + tm __LC_SAVE_AREA,0xff # running VM ? bno .Lnoreset la %r2,.Lreset lhi %r3,26 diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 0729f36c2fe3..ecb2d02b02e4 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -18,24 +18,42 @@ #include #include +static DEFINE_PER_CPU(struct cpuid, cpu_id); + +/* + * cpu_init - initializes state that is per-CPU. + */ +void __cpuinit cpu_init(void) +{ + struct cpuid *id = &per_cpu(cpu_id, smp_processor_id()); + + get_cpu_id(id); + atomic_inc(&init_mm.mm_count); + current->active_mm = &init_mm; + BUG_ON(current->mm); + enter_lazy_tlb(&init_mm, current); +} + +/* + * print_cpu_info - print basic information about a cpu + */ void __cpuinit print_cpu_info(void) { + struct cpuid *id = &per_cpu(cpu_id, smp_processor_id()); + pr_info("Processor %d started, address %d, identification %06X\n", - S390_lowcore.cpu_nr, S390_lowcore.cpu_addr, - S390_lowcore.cpu_id.ident); + S390_lowcore.cpu_nr, S390_lowcore.cpu_addr, id->ident); } /* * show_cpuinfo - Get information on one CPU for use by procfs. */ - static int show_cpuinfo(struct seq_file *m, void *v) { static const char *hwcap_str[10] = { "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", "highgprs" }; - struct _lowcore *lc; unsigned long n = (unsigned long) v - 1; int i; @@ -55,19 +73,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) } if (cpu_online(n)) { -#ifdef CONFIG_SMP - lc = (smp_processor_id() == n) ? - &S390_lowcore : lowcore_ptr[n]; -#else - lc = &S390_lowcore; -#endif + struct cpuid *id = &per_cpu(cpu_id, n); seq_printf(m, "processor %li: " "version = %02X, " "identification = %06X, " "machine = %04X\n", - n, lc->cpu_id.version, - lc->cpu_id.ident, - lc->cpu_id.machine); + n, id->version, id->ident, id->machine); } preempt_enable(); return 0; diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 91625f759ccd..6309276516b9 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -112,22 +112,6 @@ static struct resource data_resource = { .flags = IORESOURCE_BUSY | IORESOURCE_MEM, }; -/* - * cpu_init() initializes state that is per-CPU. - */ -void __cpuinit cpu_init(void) -{ - /* - * Store processor id in lowcore (used e.g. in timer_interrupt) - */ - get_cpu_id(&S390_lowcore.cpu_id); - - atomic_inc(&init_mm.mm_count); - current->active_mm = &init_mm; - BUG_ON(current->mm); - enter_lazy_tlb(&init_mm, current); -} - /* * condev= and conmode= setup parameter. */ @@ -695,6 +679,7 @@ static void __init setup_hwcaps(void) static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 }; unsigned long long facility_list_extended; unsigned int facility_list; + struct cpuid cpu_id; int i; facility_list = stfl(); @@ -756,7 +741,8 @@ static void __init setup_hwcaps(void) */ elf_hwcap |= HWCAP_S390_HIGH_GPRS; - switch (S390_lowcore.cpu_id.machine) { + get_cpu_id(&cpu_id); + switch (cpu_id.machine) { case 0x9672: #if !defined(CONFIG_64BIT) default: /* Use "g5" as default for 31 bit kernels. */ diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 511649115bd7..da6df0483289 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -648,6 +648,8 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow) static void __init css_generate_pgid(struct channel_subsystem *css, u32 tod_high) { + struct cpuid cpu_id; + if (css_general_characteristics.mcss) { css->global_pgid.pgid_high.ext_cssid.version = 0x80; css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid; @@ -658,8 +660,9 @@ css_generate_pgid(struct channel_subsystem *css, u32 tod_high) css->global_pgid.pgid_high.cpu_addr = 0; #endif } - css->global_pgid.cpu_id = S390_lowcore.cpu_id.ident; - css->global_pgid.cpu_model = S390_lowcore.cpu_id.machine; + get_cpu_id(&cpu_id); + css->global_pgid.cpu_id = cpu_id.ident; + css->global_pgid.cpu_model = cpu_id.machine; css->global_pgid.tod_high = tod_high; } -- cgit v1.2.3-59-g8ed1b From 43d399d2ab7e96cb8d952d0ba4e9131587b7c8b9 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 17 May 2010 10:00:01 +0200 Subject: [S390] cleanup sysc_work and io_work code Cleanup the #ifdef mess at io_work in entry[64].S and streamline the TIF work code of the system call and io exit path. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/entry.S | 75 ++++++++++++------------------- arch/s390/kernel/entry64.S | 108 +++++++++++++++------------------------------ 2 files changed, 64 insertions(+), 119 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 6af7045280a8..ffebfb64b913 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -301,31 +301,29 @@ sysc_restore_trace_psw: #endif # -# recheck if there is more work to do -# -sysc_work_loop: - tm __TI_flags+3(%r9),_TIF_WORK_SVC - bz BASED(sysc_restore) # there is no work to do -# -# One of the work bits is on. Find out which one. +# There is work to do, but first we need to check if we return to userspace. # sysc_work: tm SP_PSW+1(%r15),0x01 # returning to user ? bno BASED(sysc_restore) + +# +# One of the work bits is on. Find out which one. +# +sysc_work_loop: tm __TI_flags+3(%r9),_TIF_MCCK_PENDING bo BASED(sysc_mcck_pending) tm __TI_flags+3(%r9),_TIF_NEED_RESCHED bo BASED(sysc_reschedule) tm __TI_flags+3(%r9),_TIF_SIGPENDING - bnz BASED(sysc_sigpending) + bo BASED(sysc_sigpending) tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME - bnz BASED(sysc_notify_resume) + bo BASED(sysc_notify_resume) tm __TI_flags+3(%r9),_TIF_RESTART_SVC bo BASED(sysc_restart) tm __TI_flags+3(%r9),_TIF_SINGLE_STEP bo BASED(sysc_singlestep) - b BASED(sysc_restore) -sysc_work_done: + b BASED(sysc_return) # beware of critical section cleanup # # _TIF_NEED_RESCHED is set, call schedule @@ -386,7 +384,7 @@ sysc_singlestep: mvi SP_SVCNR+1(%r15),0xff la %r2,SP_PTREGS(%r15) # address of register-save area l %r1,BASED(.Lhandle_per) # load adr. of per handler - la %r14,BASED(sysc_return) # load adr. of system return + la %r14,BASED(sysc_work_loop) # load adr. of system return br %r1 # branch to do_single_step # @@ -636,30 +634,36 @@ io_restore_trace_psw: #endif # -# switch to kernel stack, then check the TIF bits +# There is work todo, find out in which context we have been interrupted: +# 1) if we return to user space we can do all _TIF_WORK_INT work +# 2) if we return to kernel code and preemptive scheduling is enabled check +# the preemption counter and if it is zero call preempt_schedule_irq +# Before any work can be done, a switch to the kernel stack is required. # io_work: tm SP_PSW+1(%r15),0x01 # returning to user ? -#ifndef CONFIG_PREEMPT - bno BASED(io_restore) # no-> skip resched & signal -#else - bnz BASED(io_work_user) # no -> check for preemptive scheduling + bo BASED(io_work_user) # yes -> do resched & signal +#ifdef CONFIG_PREEMPT # check for preemptive scheduling icm %r0,15,__TI_precount(%r9) bnz BASED(io_restore) # preemption disabled + # switch to kernel stack l %r1,SP_R15(%r15) s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain lr %r15,%r1 io_resume_loop: - tm __TI_flags+3(%r9),_TIF_NEED_RESCHED - bno BASED(io_restore) l %r1,BASED(.Lpreempt_schedule_irq) la %r14,BASED(io_resume_loop) - br %r1 # call schedule + tm __TI_flags+3(%r9),_TIF_NEED_RESCHED + bor %r1 # call preempt_schedule_irq #endif + b BASED(io_restore) +# +# Need to do work before returning to userspace, switch to kernel stack +# io_work_user: l %r1,__LC_KERNEL_STACK s %r1,BASED(.Lc_spsize) @@ -668,7 +672,7 @@ io_work_user: lr %r15,%r1 # # One of the work bits is on. Find out which one. -# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED +# Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED # and _TIF_MCCK_PENDING # io_work_loop: @@ -677,11 +681,10 @@ io_work_loop: tm __TI_flags+3(%r9),_TIF_NEED_RESCHED bo BASED(io_reschedule) tm __TI_flags+3(%r9),_TIF_SIGPENDING - bnz BASED(io_sigpending) + bo BASED(io_sigpending) tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME - bnz BASED(io_notify_resume) - b BASED(io_restore) -io_work_done: + bo BASED(io_notify_resume) + b BASED(io_return) # beware of critical section cleanup # # _TIF_MCCK_PENDING is set, call handler @@ -701,8 +704,6 @@ io_reschedule: basr %r14,%r1 # call scheduler stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts TRACE_IRQS_OFF - tm __TI_flags+3(%r9),_TIF_WORK_INT - bz BASED(io_restore) # there is no work to do b BASED(io_work_loop) # @@ -921,14 +922,10 @@ cleanup_table_sysc_return: .long sysc_return + 0x80000000, sysc_leave + 0x80000000 cleanup_table_sysc_leave: .long sysc_leave + 0x80000000, sysc_done + 0x80000000 -cleanup_table_sysc_work_loop: - .long sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000 cleanup_table_io_return: .long io_return + 0x80000000, io_leave + 0x80000000 cleanup_table_io_leave: .long io_leave + 0x80000000, io_done + 0x80000000 -cleanup_table_io_work_loop: - .long io_work_loop + 0x80000000, io_work_done + 0x80000000 cleanup_critical: clc 4(4,%r12),BASED(cleanup_table_system_call) @@ -945,11 +942,6 @@ cleanup_critical: bl BASED(0f) clc 4(4,%r12),BASED(cleanup_table_sysc_leave+4) bl BASED(cleanup_sysc_leave) -0: - clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop) - bl BASED(0f) - clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) - bl BASED(cleanup_sysc_return) 0: clc 4(4,%r12),BASED(cleanup_table_io_return) bl BASED(0f) @@ -960,11 +952,6 @@ cleanup_critical: bl BASED(0f) clc 4(4,%r12),BASED(cleanup_table_io_leave+4) bl BASED(cleanup_io_leave) -0: - clc 4(4,%r12),BASED(cleanup_table_io_work_loop) - bl BASED(0f) - clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4) - bl BASED(cleanup_io_work_loop) 0: br %r14 @@ -1043,12 +1030,6 @@ cleanup_io_return: la %r12,__LC_RETURN_PSW br %r14 -cleanup_io_work_loop: - mvc __LC_RETURN_PSW(4),0(%r12) - mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop) - la %r12,__LC_RETURN_PSW - br %r14 - cleanup_io_leave: clc 4(4,%r12),BASED(cleanup_io_leave_insn) be BASED(2f) diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 52106d53271c..ca02b10a2c32 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -291,38 +291,36 @@ sysc_restore_trace_psw: #endif # -# recheck if there is more work to do -# -sysc_work_loop: - tm __TI_flags+7(%r9),_TIF_WORK_SVC - jz sysc_restore # there is no work to do -# -# One of the work bits is on. Find out which one. +# There is work to do, but first we need to check if we return to userspace. # sysc_work: tm SP_PSW+1(%r15),0x01 # returning to user ? jno sysc_restore + +# +# One of the work bits is on. Find out which one. +# +sysc_work_loop: tm __TI_flags+7(%r9),_TIF_MCCK_PENDING jo sysc_mcck_pending tm __TI_flags+7(%r9),_TIF_NEED_RESCHED jo sysc_reschedule tm __TI_flags+7(%r9),_TIF_SIGPENDING - jnz sysc_sigpending + jo sysc_sigpending tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME - jnz sysc_notify_resume + jo sysc_notify_resume tm __TI_flags+7(%r9),_TIF_RESTART_SVC jo sysc_restart tm __TI_flags+7(%r9),_TIF_SINGLE_STEP jo sysc_singlestep - j sysc_restore -sysc_work_done: + j sysc_return # beware of critical section cleanup # # _TIF_NEED_RESCHED is set, call schedule # sysc_reschedule: larl %r14,sysc_work_loop - jg schedule # return point is sysc_return + jg schedule # return point is sysc_work_loop # # _TIF_MCCK_PENDING is set, call handler @@ -369,7 +367,7 @@ sysc_singlestep: ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number la %r2,SP_PTREGS(%r15) # address of register-save area - larl %r14,sysc_return # load adr. of system return + larl %r14,sysc_work_loop # load adr. of system return jg do_single_step # branch to do_sigtrap # @@ -605,37 +603,27 @@ io_restore_trace_psw: #endif # -# There is work todo, we need to check if we return to userspace, then -# check, if we are in SIE, if yes leave it +# There is work todo, find out in which context we have been interrupted: +# 1) if we return to user space we can do all _TIF_WORK_INT work +# 2) if we return to kernel code and kvm is enabled check if we need to +# modify the psw to leave SIE +# 3) if we return to kernel code and preemptive scheduling is enabled check +# the preemption counter and if it is zero call preempt_schedule_irq +# Before any work can be done, a switch to the kernel stack is required. # io_work: tm SP_PSW+1(%r15),0x01 # returning to user ? -#ifndef CONFIG_PREEMPT -#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) - jnz io_work_user # yes -> no need to check for SIE - la %r1, BASED(sie_opcode) # we return to kernel here - lg %r2, SP_PSW+8(%r15) - clc 0(2,%r1), 0(%r2) # is current instruction = SIE? - jne io_restore # no-> return to kernel - lg %r1, SP_PSW+8(%r15) # yes-> add 4 bytes to leave SIE - aghi %r1, 4 - stg %r1, SP_PSW+8(%r15) - j io_restore # return to kernel -#else - jno io_restore # no-> skip resched & signal -#endif -#else - jnz io_work_user # yes -> do resched & signal + jo io_work_user # yes -> do resched & signal #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) - la %r1, BASED(sie_opcode) - lg %r2, SP_PSW+8(%r15) - clc 0(2,%r1), 0(%r2) # is current instruction = SIE? + lg %r2,SP_PSW+8(%r15) # check if current instruction is SIE + lh %r1,0(%r2) + chi %r1,-19948 # signed 16 bit compare with 0xb214 jne 0f # no -> leave PSW alone - lg %r1, SP_PSW+8(%r15) # yes-> add 4 bytes to leave SIE - aghi %r1, 4 - stg %r1, SP_PSW+8(%r15) + aghi %r2,4 # yes-> add 4 bytes to leave SIE + stg %r2,SP_PSW+8(%r15) 0: #endif +#ifdef CONFIG_PREEMPT # check for preemptive scheduling icm %r0,15,__TI_precount(%r9) jnz io_restore # preemption is disabled @@ -646,21 +634,25 @@ io_work: xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain lgr %r15,%r1 io_resume_loop: - tm __TI_flags+7(%r9),_TIF_NEED_RESCHED - jno io_restore larl %r14,io_resume_loop - jg preempt_schedule_irq + tm __TI_flags+7(%r12),_TIF_NEED_RESCHED + jgo preempt_schedule_irq #endif + j io_restore +# +# Need to do work before returning to userspace, switch to kernel stack +# io_work_user: lg %r1,__LC_KERNEL_STACK aghi %r1,-SP_SIZE mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain lgr %r15,%r1 + # # One of the work bits is on. Find out which one. -# Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGPENDING, _TIF_NEED_RESCHED +# Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED # and _TIF_MCCK_PENDING # io_work_loop: @@ -669,16 +661,10 @@ io_work_loop: tm __TI_flags+7(%r9),_TIF_NEED_RESCHED jo io_reschedule tm __TI_flags+7(%r9),_TIF_SIGPENDING - jnz io_sigpending + jo io_sigpending tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME - jnz io_notify_resume - j io_restore -io_work_done: - -#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) -sie_opcode: - .long 0xb2140000 -#endif + jo io_notify_resume + j io_return # beware of critical section cleanup # # _TIF_MCCK_PENDING is set, call handler @@ -696,8 +682,6 @@ io_reschedule: brasl %r14,schedule # call scheduler stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts TRACE_IRQS_OFF - tm __TI_flags+7(%r9),_TIF_WORK_INT - jz io_restore # there is no work to do j io_work_loop # @@ -903,14 +887,10 @@ cleanup_table_sysc_return: .quad sysc_return, sysc_leave cleanup_table_sysc_leave: .quad sysc_leave, sysc_done -cleanup_table_sysc_work_loop: - .quad sysc_work_loop, sysc_work_done cleanup_table_io_return: .quad io_return, io_leave cleanup_table_io_leave: .quad io_leave, io_done -cleanup_table_io_work_loop: - .quad io_work_loop, io_work_done cleanup_critical: clc 8(8,%r12),BASED(cleanup_table_system_call) @@ -927,11 +907,6 @@ cleanup_critical: jl 0f clc 8(8,%r12),BASED(cleanup_table_sysc_leave+8) jl cleanup_sysc_leave -0: - clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop) - jl 0f - clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) - jl cleanup_sysc_return 0: clc 8(8,%r12),BASED(cleanup_table_io_return) jl 0f @@ -942,11 +917,6 @@ cleanup_critical: jl 0f clc 8(8,%r12),BASED(cleanup_table_io_leave+8) jl cleanup_io_leave -0: - clc 8(8,%r12),BASED(cleanup_table_io_work_loop) - jl 0f - clc 8(8,%r12),BASED(cleanup_table_io_work_loop+8) - jl cleanup_io_work_loop 0: br %r14 @@ -1025,12 +995,6 @@ cleanup_io_return: la %r12,__LC_RETURN_PSW br %r14 -cleanup_io_work_loop: - mvc __LC_RETURN_PSW(8),0(%r12) - mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop) - la %r12,__LC_RETURN_PSW - br %r14 - cleanup_io_leave: clc 8(8,%r12),BASED(cleanup_io_leave_insn) je 3f -- cgit v1.2.3-59-g8ed1b From 6a2df3a87276cdc08fd87070d09ea18d1fb9d622 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 17 May 2010 10:00:02 +0200 Subject: [S390] improve irq tracing code in entry[64].S The system call path in entry[64].S is run with interrupts enabled. Remove the irq tracing check from the system call exit code. If a program check interrupted a context enabled for interrupts do a call to trace_irq_off_caller in the program check handler before branching to the system call exit code. Restructure the system call and io interrupt return code to avoid avoid the lpsw[e] to disable machine checks. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/system.h | 5 - arch/s390/kernel/entry.S | 205 ++++++++++++++++++----------------------- arch/s390/kernel/entry64.S | 197 ++++++++++++++++++--------------------- arch/s390/kernel/setup.c | 4 - 4 files changed, 183 insertions(+), 228 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 1741c1556a4e..cef66210c846 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h @@ -459,11 +459,6 @@ extern void (*_machine_power_off)(void); #define arch_align_stack(x) (x) -#ifdef CONFIG_TRACE_IRQFLAGS -extern psw_t sysc_restore_trace_psw; -extern psw_t io_restore_trace_psw; -#endif - static inline int tprot(unsigned long addr) { int rc = -EFAULT; diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index ffebfb64b913..07d849995dac 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -73,21 +73,24 @@ STACK_SIZE = 1 << STACK_SHIFT basr %r14,%r1 .endm - .macro TRACE_IRQS_CHECK - basr %r2,%r0 + .macro TRACE_IRQS_CHECK_ON tm SP_PSW(%r15),0x03 # irqs enabled? - jz 0f - l %r1,BASED(.Ltrace_irq_on_caller) - basr %r14,%r1 - j 1f -0: l %r1,BASED(.Ltrace_irq_off_caller) - basr %r14,%r1 -1: + bz BASED(0f) + TRACE_IRQS_ON +0: + .endm + + .macro TRACE_IRQS_CHECK_OFF + tm SP_PSW(%r15),0x03 # irqs enabled? + bz BASED(0f) + TRACE_IRQS_OFF +0: .endm #else #define TRACE_IRQS_ON #define TRACE_IRQS_OFF -#define TRACE_IRQS_CHECK +#define TRACE_IRQS_CHECK_ON +#define TRACE_IRQS_CHECK_OFF #endif #ifdef CONFIG_LOCKDEP @@ -273,33 +276,14 @@ sysc_do_restart: st %r2,SP_R2(%r15) # store return value (change R2 on stack) sysc_return: + LOCKDEP_SYS_EXIT +sysc_tif: tm __TI_flags+3(%r9),_TIF_WORK_SVC bnz BASED(sysc_work) # there is work to do (signals etc.) sysc_restore: -#ifdef CONFIG_TRACE_IRQFLAGS - la %r1,BASED(sysc_restore_trace_psw_addr) - l %r1,0(%r1) - lpsw 0(%r1) -sysc_restore_trace: - TRACE_IRQS_CHECK - LOCKDEP_SYS_EXIT -#endif -sysc_leave: RESTORE_ALL __LC_RETURN_PSW,1 sysc_done: -#ifdef CONFIG_TRACE_IRQFLAGS -sysc_restore_trace_psw_addr: - .long sysc_restore_trace_psw - - .section .data,"aw",@progbits - .align 8 - .globl sysc_restore_trace_psw -sysc_restore_trace_psw: - .long 0, sysc_restore_trace + 0x80000000 - .previous -#endif - # # There is work to do, but first we need to check if we return to userspace. # @@ -310,7 +294,7 @@ sysc_work: # # One of the work bits is on. Find out which one. # -sysc_work_loop: +sysc_work_tif: tm __TI_flags+3(%r9),_TIF_MCCK_PENDING bo BASED(sysc_mcck_pending) tm __TI_flags+3(%r9),_TIF_NEED_RESCHED @@ -330,7 +314,7 @@ sysc_work_loop: # sysc_reschedule: l %r1,BASED(.Lschedule) - la %r14,BASED(sysc_work_loop) + la %r14,BASED(sysc_return) br %r1 # call scheduler # @@ -338,7 +322,7 @@ sysc_reschedule: # sysc_mcck_pending: l %r1,BASED(.Ls390_handle_mcck) - la %r14,BASED(sysc_work_loop) + la %r14,BASED(sysc_return) br %r1 # TIF bit will be cleared by handler # @@ -353,7 +337,7 @@ sysc_sigpending: bo BASED(sysc_restart) tm __TI_flags+3(%r9),_TIF_SINGLE_STEP bo BASED(sysc_singlestep) - b BASED(sysc_work_loop) + b BASED(sysc_return) # # _TIF_NOTIFY_RESUME is set, call do_notify_resume @@ -361,7 +345,7 @@ sysc_sigpending: sysc_notify_resume: la %r2,SP_PTREGS(%r15) # load pt_regs l %r1,BASED(.Ldo_notify_resume) - la %r14,BASED(sysc_work_loop) + la %r14,BASED(sysc_return) br %r1 # call do_notify_resume @@ -384,7 +368,7 @@ sysc_singlestep: mvi SP_SVCNR+1(%r15),0xff la %r2,SP_PTREGS(%r15) # address of register-save area l %r1,BASED(.Lhandle_per) # load adr. of per handler - la %r14,BASED(sysc_work_loop) # load adr. of system return + la %r14,BASED(sysc_return) # load adr. of system return br %r1 # branch to do_single_step # @@ -456,11 +440,13 @@ kernel_execve: br %r14 # execve succeeded. 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts + TRACE_IRQS_OFF l %r15,__LC_KERNEL_STACK # load ksp s %r15,BASED(.Lc_spsize) # make room for registers & psw l %r9,__LC_THREAD_INFO mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) + TRACE_IRQS_ON stosm __SF_EMPTY(%r15),0x03 # reenable interrupts l %r1,BASED(.Lexecve_tail) basr %r14,%r1 @@ -497,8 +483,8 @@ pgm_check_handler: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER pgm_no_vtime: + TRACE_IRQS_CHECK_OFF l %r9,__LC_THREAD_INFO # load pointer to thread_info struct - TRACE_IRQS_OFF l %r3,__LC_PGM_ILC # load program interruption code la %r8,0x7f nr %r8,%r3 @@ -507,8 +493,10 @@ pgm_do_call: sll %r8,2 l %r7,0(%r8,%r7) # load address of handler routine la %r2,SP_PTREGS(%r15) # address of register-save area - la %r14,BASED(sysc_return) - br %r7 # branch to interrupt-handler + basr %r14,%r7 # branch to interrupt-handler +pgm_exit: + TRACE_IRQS_CHECK_ON + b BASED(sysc_return) # # handle per exception @@ -535,19 +523,19 @@ pgm_per_std: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER pgm_no_vtime2: + TRACE_IRQS_CHECK_OFF l %r9,__LC_THREAD_INFO # load pointer to thread_info struct - TRACE_IRQS_OFF l %r1,__TI_task(%r9) + tm SP_PSW+1(%r15),0x01 # kernel per event ? + bz BASED(kernel_per) mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP - tm SP_PSW+1(%r15),0x01 # kernel per event ? - bz BASED(kernel_per) l %r3,__LC_PGM_ILC # load program interruption code la %r8,0x7f nr %r8,%r3 # clear per-event-bit and ilc - be BASED(sysc_return) # only per or per+check ? + be BASED(pgm_exit) # only per or per+check ? b BASED(pgm_do_call) # @@ -568,8 +556,8 @@ pgm_svcper: mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP TRACE_IRQS_ON - lm %r2,%r6,SP_R2(%r15) # load svc arguments stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + lm %r2,%r6,SP_R2(%r15) # load svc arguments b BASED(sysc_do_svc) # @@ -580,8 +568,8 @@ kernel_per: mvi SP_SVCNR+1(%r15),0xff la %r2,SP_PTREGS(%r15) # address of register-save area l %r1,BASED(.Lhandle_per) # load adr. of per handler - la %r14,BASED(sysc_restore)# load adr. of system return - br %r1 # branch to do_single_step + basr %r14,%r1 # branch to do_single_step + b BASED(pgm_exit) /* * IO interrupt handler routine @@ -600,39 +588,21 @@ io_int_handler: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER io_no_vtime: - l %r9,__LC_THREAD_INFO # load pointer to thread_info struct TRACE_IRQS_OFF + l %r9,__LC_THREAD_INFO # load pointer to thread_info struct l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ la %r2,SP_PTREGS(%r15) # address of register-save area basr %r14,%r1 # branch to standard irq handler io_return: + LOCKDEP_SYS_EXIT + TRACE_IRQS_ON +io_tif: tm __TI_flags+3(%r9),_TIF_WORK_INT bnz BASED(io_work) # there is work to do (signals etc.) io_restore: -#ifdef CONFIG_TRACE_IRQFLAGS - la %r1,BASED(io_restore_trace_psw_addr) - l %r1,0(%r1) - lpsw 0(%r1) -io_restore_trace: - TRACE_IRQS_CHECK - LOCKDEP_SYS_EXIT -#endif -io_leave: RESTORE_ALL __LC_RETURN_PSW,0 io_done: -#ifdef CONFIG_TRACE_IRQFLAGS -io_restore_trace_psw_addr: - .long io_restore_trace_psw - - .section .data,"aw",@progbits - .align 8 - .globl io_restore_trace_psw -io_restore_trace_psw: - .long 0, io_restore_trace + 0x80000000 - .previous -#endif - # # There is work todo, find out in which context we have been interrupted: # 1) if we return to user space we can do all _TIF_WORK_INT work @@ -647,19 +617,23 @@ io_work: # check for preemptive scheduling icm %r0,15,__TI_precount(%r9) bnz BASED(io_restore) # preemption disabled + tm __TI_flags+3(%r9),_TIF_NEED_RESCHED + bno BASED(io_restore) # switch to kernel stack l %r1,SP_R15(%r15) s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain lr %r15,%r1 -io_resume_loop: + # TRACE_IRQS_ON already done at io_return, call + # TRACE_IRQS_OFF to keep things symmetrical + TRACE_IRQS_OFF l %r1,BASED(.Lpreempt_schedule_irq) - la %r14,BASED(io_resume_loop) - tm __TI_flags+3(%r9),_TIF_NEED_RESCHED - bor %r1 # call preempt_schedule_irq -#endif + basr %r14,%r1 # call preempt_schedule_irq + b BASED(io_return) +#else b BASED(io_restore) +#endif # # Need to do work before returning to userspace, switch to kernel stack @@ -670,12 +644,13 @@ io_work_user: mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain lr %r15,%r1 + # # One of the work bits is on. Find out which one. # Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED # and _TIF_MCCK_PENDING # -io_work_loop: +io_work_tif: tm __TI_flags+3(%r9),_TIF_MCCK_PENDING bo BASED(io_mcck_pending) tm __TI_flags+3(%r9),_TIF_NEED_RESCHED @@ -690,47 +665,49 @@ io_work_loop: # _TIF_MCCK_PENDING is set, call handler # io_mcck_pending: + # TRACE_IRQS_ON already done at io_return l %r1,BASED(.Ls390_handle_mcck) basr %r14,%r1 # TIF bit will be cleared by handler - b BASED(io_work_loop) + TRACE_IRQS_OFF + b BASED(io_return) # # _TIF_NEED_RESCHED is set, call schedule # io_reschedule: - TRACE_IRQS_ON + # TRACE_IRQS_ON already done at io_return l %r1,BASED(.Lschedule) stosm __SF_EMPTY(%r15),0x03 # reenable interrupts basr %r14,%r1 # call scheduler stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts TRACE_IRQS_OFF - b BASED(io_work_loop) + b BASED(io_return) # # _TIF_SIGPENDING is set, call do_signal # io_sigpending: - TRACE_IRQS_ON + # TRACE_IRQS_ON already done at io_return stosm __SF_EMPTY(%r15),0x03 # reenable interrupts la %r2,SP_PTREGS(%r15) # load pt_regs l %r1,BASED(.Ldo_signal) basr %r14,%r1 # call do_signal stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts TRACE_IRQS_OFF - b BASED(io_work_loop) + b BASED(io_return) # # _TIF_SIGPENDING is set, call do_signal # io_notify_resume: - TRACE_IRQS_ON + # TRACE_IRQS_ON already done at io_return stosm __SF_EMPTY(%r15),0x03 # reenable interrupts la %r2,SP_PTREGS(%r15) # load pt_regs l %r1,BASED(.Ldo_notify_resume) basr %r14,%r1 # call do_signal stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts TRACE_IRQS_OFF - b BASED(io_work_loop) + b BASED(io_return) /* * External interrupt handler routine @@ -918,14 +895,14 @@ stack_overflow: cleanup_table_system_call: .long system_call + 0x80000000, sysc_do_svc + 0x80000000 -cleanup_table_sysc_return: - .long sysc_return + 0x80000000, sysc_leave + 0x80000000 -cleanup_table_sysc_leave: - .long sysc_leave + 0x80000000, sysc_done + 0x80000000 -cleanup_table_io_return: - .long io_return + 0x80000000, io_leave + 0x80000000 -cleanup_table_io_leave: - .long io_leave + 0x80000000, io_done + 0x80000000 +cleanup_table_sysc_tif: + .long sysc_tif + 0x80000000, sysc_restore + 0x80000000 +cleanup_table_sysc_restore: + .long sysc_restore + 0x80000000, sysc_done + 0x80000000 +cleanup_table_io_tif: + .long io_tif + 0x80000000, io_restore + 0x80000000 +cleanup_table_io_restore: + .long io_restore + 0x80000000, io_done + 0x80000000 cleanup_critical: clc 4(4,%r12),BASED(cleanup_table_system_call) @@ -933,25 +910,25 @@ cleanup_critical: clc 4(4,%r12),BASED(cleanup_table_system_call+4) bl BASED(cleanup_system_call) 0: - clc 4(4,%r12),BASED(cleanup_table_sysc_return) + clc 4(4,%r12),BASED(cleanup_table_sysc_tif) bl BASED(0f) - clc 4(4,%r12),BASED(cleanup_table_sysc_return+4) - bl BASED(cleanup_sysc_return) + clc 4(4,%r12),BASED(cleanup_table_sysc_tif+4) + bl BASED(cleanup_sysc_tif) 0: - clc 4(4,%r12),BASED(cleanup_table_sysc_leave) + clc 4(4,%r12),BASED(cleanup_table_sysc_restore) bl BASED(0f) - clc 4(4,%r12),BASED(cleanup_table_sysc_leave+4) - bl BASED(cleanup_sysc_leave) + clc 4(4,%r12),BASED(cleanup_table_sysc_restore+4) + bl BASED(cleanup_sysc_restore) 0: - clc 4(4,%r12),BASED(cleanup_table_io_return) + clc 4(4,%r12),BASED(cleanup_table_io_tif) bl BASED(0f) - clc 4(4,%r12),BASED(cleanup_table_io_return+4) - bl BASED(cleanup_io_return) + clc 4(4,%r12),BASED(cleanup_table_io_tif+4) + bl BASED(cleanup_io_tif) 0: - clc 4(4,%r12),BASED(cleanup_table_io_leave) + clc 4(4,%r12),BASED(cleanup_table_io_restore) bl BASED(0f) - clc 4(4,%r12),BASED(cleanup_table_io_leave+4) - bl BASED(cleanup_io_leave) + clc 4(4,%r12),BASED(cleanup_table_io_restore+4) + bl BASED(cleanup_io_restore) 0: br %r14 @@ -998,17 +975,17 @@ cleanup_system_call_insn: .long sysc_stime + 0x80000000 .long sysc_update + 0x80000000 -cleanup_sysc_return: +cleanup_sysc_tif: mvc __LC_RETURN_PSW(4),0(%r12) - mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_return) + mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif) la %r12,__LC_RETURN_PSW br %r14 -cleanup_sysc_leave: - clc 4(4,%r12),BASED(cleanup_sysc_leave_insn) +cleanup_sysc_restore: + clc 4(4,%r12),BASED(cleanup_sysc_restore_insn) be BASED(2f) mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER - clc 4(4,%r12),BASED(cleanup_sysc_leave_insn+4) + clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4) be BASED(2f) mvc __LC_RETURN_PSW(8),SP_PSW(%r15) c %r12,BASED(.Lmck_old_psw) @@ -1020,21 +997,21 @@ cleanup_sysc_leave: l %r15,SP_R15(%r15) 2: la %r12,__LC_RETURN_PSW br %r14 -cleanup_sysc_leave_insn: +cleanup_sysc_restore_insn: .long sysc_done - 4 + 0x80000000 .long sysc_done - 8 + 0x80000000 -cleanup_io_return: +cleanup_io_tif: mvc __LC_RETURN_PSW(4),0(%r12) - mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return) + mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif) la %r12,__LC_RETURN_PSW br %r14 -cleanup_io_leave: - clc 4(4,%r12),BASED(cleanup_io_leave_insn) +cleanup_io_restore: + clc 4(4,%r12),BASED(cleanup_io_restore_insn) be BASED(2f) mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER - clc 4(4,%r12),BASED(cleanup_io_leave_insn+4) + clc 4(4,%r12),BASED(cleanup_io_restore_insn+4) be BASED(2f) mvc __LC_RETURN_PSW(8),SP_PSW(%r15) c %r12,BASED(.Lmck_old_psw) @@ -1046,7 +1023,7 @@ cleanup_io_leave: l %r15,SP_R15(%r15) 2: la %r12,__LC_RETURN_PSW br %r14 -cleanup_io_leave_insn: +cleanup_io_restore_insn: .long io_done - 4 + 0x80000000 .long io_done - 8 + 0x80000000 diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index ca02b10a2c32..860cea1d1c8a 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -61,28 +61,33 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ #ifdef CONFIG_TRACE_IRQFLAGS .macro TRACE_IRQS_ON - basr %r2,%r0 - brasl %r14,trace_hardirqs_on_caller + basr %r2,%r0 + brasl %r14,trace_hardirqs_on_caller .endm .macro TRACE_IRQS_OFF - basr %r2,%r0 - brasl %r14,trace_hardirqs_off_caller + basr %r2,%r0 + brasl %r14,trace_hardirqs_off_caller .endm - .macro TRACE_IRQS_CHECK - basr %r2,%r0 + .macro TRACE_IRQS_CHECK_ON tm SP_PSW(%r15),0x03 # irqs enabled? jz 0f - brasl %r14,trace_hardirqs_on_caller - j 1f -0: brasl %r14,trace_hardirqs_off_caller -1: + TRACE_IRQS_ON +0: + .endm + + .macro TRACE_IRQS_CHECK_OFF + tm SP_PSW(%r15),0x03 # irqs enabled? + jz 0f + TRACE_IRQS_OFF +0: .endm #else #define TRACE_IRQS_ON #define TRACE_IRQS_OFF -#define TRACE_IRQS_CHECK +#define TRACE_IRQS_CHECK_ON +#define TRACE_IRQS_CHECK_OFF #endif #ifdef CONFIG_LOCKDEP @@ -267,29 +272,14 @@ sysc_noemu: stg %r2,SP_R2(%r15) # store return value (change R2 on stack) sysc_return: + LOCKDEP_SYS_EXIT +sysc_tif: tm __TI_flags+7(%r9),_TIF_WORK_SVC jnz sysc_work # there is work to do (signals etc.) sysc_restore: -#ifdef CONFIG_TRACE_IRQFLAGS - larl %r1,sysc_restore_trace_psw - lpswe 0(%r1) -sysc_restore_trace: - TRACE_IRQS_CHECK - LOCKDEP_SYS_EXIT -#endif -sysc_leave: RESTORE_ALL __LC_RETURN_PSW,1 sysc_done: -#ifdef CONFIG_TRACE_IRQFLAGS - .section .data,"aw",@progbits - .align 8 - .globl sysc_restore_trace_psw -sysc_restore_trace_psw: - .quad 0, sysc_restore_trace - .previous -#endif - # # There is work to do, but first we need to check if we return to userspace. # @@ -300,7 +290,7 @@ sysc_work: # # One of the work bits is on. Find out which one. # -sysc_work_loop: +sysc_work_tif: tm __TI_flags+7(%r9),_TIF_MCCK_PENDING jo sysc_mcck_pending tm __TI_flags+7(%r9),_TIF_NEED_RESCHED @@ -319,14 +309,14 @@ sysc_work_loop: # _TIF_NEED_RESCHED is set, call schedule # sysc_reschedule: - larl %r14,sysc_work_loop - jg schedule # return point is sysc_work_loop + larl %r14,sysc_return + jg schedule # return point is sysc_return # # _TIF_MCCK_PENDING is set, call handler # sysc_mcck_pending: - larl %r14,sysc_work_loop + larl %r14,sysc_return jg s390_handle_mcck # TIF bit will be cleared by handler # @@ -340,14 +330,14 @@ sysc_sigpending: jo sysc_restart tm __TI_flags+7(%r9),_TIF_SINGLE_STEP jo sysc_singlestep - j sysc_work_loop + j sysc_return # # _TIF_NOTIFY_RESUME is set, call do_notify_resume # sysc_notify_resume: la %r2,SP_PTREGS(%r15) # load pt_regs - larl %r14,sysc_work_loop + larl %r14,sysc_return jg do_notify_resume # call do_notify_resume # @@ -367,7 +357,7 @@ sysc_singlestep: ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number la %r2,SP_PTREGS(%r15) # address of register-save area - larl %r14,sysc_work_loop # load adr. of system return + larl %r14,sysc_return # load adr. of system return jg do_single_step # branch to do_sigtrap # @@ -433,12 +423,14 @@ kernel_execve: br %r14 # execve succeeded. 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts +# TRACE_IRQS_OFF lg %r15,__LC_KERNEL_STACK # load ksp aghi %r15,-SP_SIZE # make room for registers & psw lg %r13,__LC_SVC_NEW_PSW+8 lg %r9,__LC_THREAD_INFO mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) +# TRACE_IRQS_ON stosm __SF_EMPTY(%r15),0x03 # reenable interrupts brasl %r14,execve_tail j sysc_return @@ -474,9 +466,9 @@ pgm_check_handler: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER pgm_no_vtime: + TRACE_IRQS_CHECK_OFF lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct mvc SP_ARGS(8,%r15),__LC_LAST_BREAK - TRACE_IRQS_OFF lgf %r3,__LC_PGM_ILC # load program interruption code lghi %r8,0x7f ngr %r8,%r3 @@ -485,8 +477,10 @@ pgm_do_call: larl %r1,pgm_check_table lg %r1,0(%r8,%r1) # load address of handler routine la %r2,SP_PTREGS(%r15) # address of register-save area - larl %r14,sysc_return - br %r1 # branch to interrupt-handler + basr %r14,%r1 # branch to interrupt-handler +pgm_exit: + TRACE_IRQS_CHECK_ON + j sysc_return # # handle per exception @@ -513,8 +507,8 @@ pgm_per_std: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER pgm_no_vtime2: + TRACE_IRQS_CHECK_OFF lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct - TRACE_IRQS_OFF lg %r1,__TI_task(%r9) tm SP_PSW+1(%r15),0x01 # kernel per event ? jz kernel_per @@ -525,7 +519,7 @@ pgm_no_vtime2: lgf %r3,__LC_PGM_ILC # load program interruption code lghi %r8,0x7f ngr %r8,%r3 # clear per-event-bit and ilc - je sysc_return + je pgm_exit j pgm_do_call # @@ -539,14 +533,15 @@ pgm_svcper: mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct + TRACE_IRQS_OFF lg %r8,__TI_task(%r9) mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP TRACE_IRQS_ON - lmg %r2,%r6,SP_R2(%r15) # load svc arguments stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + lmg %r2,%r6,SP_R2(%r15) # load svc arguments j sysc_do_svc # @@ -555,8 +550,8 @@ pgm_svcper: kernel_per: xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number la %r2,SP_PTREGS(%r15) # address of register-save area - larl %r14,sysc_restore # load adr. of system ret, no work - jg do_single_step # branch to do_single_step + brasl %r14,do_single_step + j pgm_exit /* * IO interrupt handler routine @@ -579,29 +574,15 @@ io_no_vtime: la %r2,SP_PTREGS(%r15) # address of register-save area brasl %r14,do_IRQ # call standard irq handler io_return: + LOCKDEP_SYS_EXIT + TRACE_IRQS_ON +io_tif: tm __TI_flags+7(%r9),_TIF_WORK_INT jnz io_work # there is work to do (signals etc.) io_restore: -#ifdef CONFIG_TRACE_IRQFLAGS - larl %r1,io_restore_trace_psw - lpswe 0(%r1) -io_restore_trace: - TRACE_IRQS_CHECK - LOCKDEP_SYS_EXIT -#endif -io_leave: RESTORE_ALL __LC_RETURN_PSW,0 io_done: -#ifdef CONFIG_TRACE_IRQFLAGS - .section .data,"aw",@progbits - .align 8 - .globl io_restore_trace_psw -io_restore_trace_psw: - .quad 0, io_restore_trace - .previous -#endif - # # There is work todo, find out in which context we have been interrupted: # 1) if we return to user space we can do all _TIF_WORK_INT work @@ -627,18 +608,22 @@ io_work: # check for preemptive scheduling icm %r0,15,__TI_precount(%r9) jnz io_restore # preemption is disabled + tm __TI_flags+7(%r12),_TIF_NEED_RESCHED + jno io_restore # switch to kernel stack lg %r1,SP_R15(%r15) aghi %r1,-SP_SIZE mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain lgr %r15,%r1 -io_resume_loop: - larl %r14,io_resume_loop - tm __TI_flags+7(%r12),_TIF_NEED_RESCHED - jgo preempt_schedule_irq -#endif + # TRACE_IRQS_ON already done at io_return, call + # TRACE_IRQS_OFF to keep things symmetrical + TRACE_IRQS_OFF + brasl %r14,preempt_schedule_irq + j io_return +#else j io_restore +#endif # # Need to do work before returning to userspace, switch to kernel stack @@ -655,7 +640,7 @@ io_work_user: # Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED # and _TIF_MCCK_PENDING # -io_work_loop: +io_work_tif: tm __TI_flags+7(%r9),_TIF_MCCK_PENDING jo io_mcck_pending tm __TI_flags+7(%r9),_TIF_NEED_RESCHED @@ -670,43 +655,45 @@ io_work_loop: # _TIF_MCCK_PENDING is set, call handler # io_mcck_pending: + # TRACE_IRQS_ON already done at io_return brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler - j io_work_loop + TRACE_IRQS_OFF + j io_return # # _TIF_NEED_RESCHED is set, call schedule # io_reschedule: - TRACE_IRQS_ON + # TRACE_IRQS_ON already done at io_return stosm __SF_EMPTY(%r15),0x03 # reenable interrupts brasl %r14,schedule # call scheduler stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts TRACE_IRQS_OFF - j io_work_loop + j io_return # # _TIF_SIGPENDING or is set, call do_signal # io_sigpending: - TRACE_IRQS_ON + # TRACE_IRQS_ON already done at io_return stosm __SF_EMPTY(%r15),0x03 # reenable interrupts la %r2,SP_PTREGS(%r15) # load pt_regs brasl %r14,do_signal # call do_signal stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts TRACE_IRQS_OFF - j io_work_loop + j io_return # # _TIF_NOTIFY_RESUME or is set, call do_notify_resume # io_notify_resume: - TRACE_IRQS_ON + # TRACE_IRQS_ON already done at io_return stosm __SF_EMPTY(%r15),0x03 # reenable interrupts la %r2,SP_PTREGS(%r15) # load pt_regs brasl %r14,do_notify_resume # call do_notify_resume stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts TRACE_IRQS_OFF - j io_work_loop + j io_return /* * External interrupt handler routine @@ -883,14 +870,14 @@ stack_overflow: cleanup_table_system_call: .quad system_call, sysc_do_svc -cleanup_table_sysc_return: - .quad sysc_return, sysc_leave -cleanup_table_sysc_leave: - .quad sysc_leave, sysc_done -cleanup_table_io_return: - .quad io_return, io_leave -cleanup_table_io_leave: - .quad io_leave, io_done +cleanup_table_sysc_tif: + .quad sysc_tif, sysc_restore +cleanup_table_sysc_restore: + .quad sysc_restore, sysc_done +cleanup_table_io_tif: + .quad io_tif, io_restore +cleanup_table_io_restore: + .quad io_restore, io_done cleanup_critical: clc 8(8,%r12),BASED(cleanup_table_system_call) @@ -898,25 +885,25 @@ cleanup_critical: clc 8(8,%r12),BASED(cleanup_table_system_call+8) jl cleanup_system_call 0: - clc 8(8,%r12),BASED(cleanup_table_sysc_return) + clc 8(8,%r12),BASED(cleanup_table_sysc_tif) jl 0f - clc 8(8,%r12),BASED(cleanup_table_sysc_return+8) - jl cleanup_sysc_return + clc 8(8,%r12),BASED(cleanup_table_sysc_tif+8) + jl cleanup_sysc_tif 0: - clc 8(8,%r12),BASED(cleanup_table_sysc_leave) + clc 8(8,%r12),BASED(cleanup_table_sysc_restore) jl 0f - clc 8(8,%r12),BASED(cleanup_table_sysc_leave+8) - jl cleanup_sysc_leave + clc 8(8,%r12),BASED(cleanup_table_sysc_restore+8) + jl cleanup_sysc_restore 0: - clc 8(8,%r12),BASED(cleanup_table_io_return) + clc 8(8,%r12),BASED(cleanup_table_io_tif) jl 0f - clc 8(8,%r12),BASED(cleanup_table_io_return+8) - jl cleanup_io_return + clc 8(8,%r12),BASED(cleanup_table_io_tif+8) + jl cleanup_io_tif 0: - clc 8(8,%r12),BASED(cleanup_table_io_leave) + clc 8(8,%r12),BASED(cleanup_table_io_restore) jl 0f - clc 8(8,%r12),BASED(cleanup_table_io_leave+8) - jl cleanup_io_leave + clc 8(8,%r12),BASED(cleanup_table_io_restore+8) + jl cleanup_io_restore 0: br %r14 @@ -963,16 +950,16 @@ cleanup_system_call_insn: .quad sysc_stime .quad sysc_update -cleanup_sysc_return: +cleanup_sysc_tif: mvc __LC_RETURN_PSW(8),0(%r12) - mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_return) + mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_tif) la %r12,__LC_RETURN_PSW br %r14 -cleanup_sysc_leave: - clc 8(8,%r12),BASED(cleanup_sysc_leave_insn) +cleanup_sysc_restore: + clc 8(8,%r12),BASED(cleanup_sysc_restore_insn) je 3f - clc 8(8,%r12),BASED(cleanup_sysc_leave_insn+8) + clc 8(8,%r12),BASED(cleanup_sysc_restore_insn+8) jhe 0f mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) @@ -985,20 +972,20 @@ cleanup_sysc_leave: lg %r15,SP_R15(%r15) 3: la %r12,__LC_RETURN_PSW br %r14 -cleanup_sysc_leave_insn: +cleanup_sysc_restore_insn: .quad sysc_done - 4 .quad sysc_done - 16 -cleanup_io_return: +cleanup_io_tif: mvc __LC_RETURN_PSW(8),0(%r12) - mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return) + mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_tif) la %r12,__LC_RETURN_PSW br %r14 -cleanup_io_leave: - clc 8(8,%r12),BASED(cleanup_io_leave_insn) +cleanup_io_restore: + clc 8(8,%r12),BASED(cleanup_io_restore_insn) je 3f - clc 8(8,%r12),BASED(cleanup_io_leave_insn+8) + clc 8(8,%r12),BASED(cleanup_io_restore_insn+8) jhe 0f mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) @@ -1011,7 +998,7 @@ cleanup_io_leave: lg %r15,SP_R15(%r15) 3: la %r12,__LC_RETURN_PSW br %r14 -cleanup_io_leave_insn: +cleanup_io_restore_insn: .quad io_done - 4 .quad io_done - 16 diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 6309276516b9..598752499c3e 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -369,10 +369,6 @@ static void setup_addressing_mode(void) pr_info("Address spaces switched, " "mvcos not available\n"); } -#ifdef CONFIG_TRACE_IRQFLAGS - sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; - io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK; -#endif } static void __init -- cgit v1.2.3-59-g8ed1b From 6377981faf1a4425b0531e577736ef03df97c8f6 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 17 May 2010 10:00:03 +0200 Subject: [S390] idle time accounting vs. machine checks A machine check can interrupt the i/o and external interrupt handler anytime. If the machine check occurs while the interrupt handler is waking up from idle vtime_start_cpu can get executed a second time and the int_clock / async_enter_timer values in the lowcore get clobbered. This can confuse the cpu time accounting. To fix this problem two changes are needed. First the machine check handler has to use its own copies of int_clock and async_enter_timer, named mcck_clock and mcck_enter_timer. Second the nested execution of vtime_start_cpu has to be prevented. This is done in s390_idle_check by checking the wait bit in the program status word. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/cputime.h | 9 ++-- arch/s390/include/asm/lowcore.h | 98 +++++++++++++++++++++-------------------- arch/s390/kernel/asm-offsets.c | 2 + arch/s390/kernel/entry.S | 54 +++++++++++------------ arch/s390/kernel/entry64.S | 54 +++++++++++------------ arch/s390/kernel/nmi.c | 3 +- arch/s390/kernel/s390_ext.c | 3 +- arch/s390/kernel/vtime.c | 15 ++++--- drivers/s390/cio/cio.c | 3 +- 9 files changed, 125 insertions(+), 116 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index 258ba88b7b50..8b1a52a137c5 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h @@ -188,15 +188,16 @@ struct s390_idle_data { DECLARE_PER_CPU(struct s390_idle_data, s390_idle); -void vtime_start_cpu(void); +void vtime_start_cpu(__u64 int_clock, __u64 enter_timer); cputime64_t s390_get_idle_time(int cpu); #define arch_idle_time(cpu) s390_get_idle_time(cpu) -static inline void s390_idle_check(void) +static inline void s390_idle_check(struct pt_regs *regs, __u64 int_clock, + __u64 enter_timer) { - if ((&__get_cpu_var(s390_idle))->idle_enter != 0ULL) - vtime_start_cpu(); + if (regs->psw.mask & PSW_MASK_WAIT) + vtime_start_cpu(int_clock, enter_timer); } static inline int s390_nohz_delay(int cpu) diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index f7e78c79b8b1..2c02d46c3588 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -104,37 +104,39 @@ struct _lowcore { /* CPU time accounting values */ __u64 sync_enter_timer; /* 0x0250 */ __u64 async_enter_timer; /* 0x0258 */ - __u64 exit_timer; /* 0x0260 */ - __u64 user_timer; /* 0x0268 */ - __u64 system_timer; /* 0x0270 */ - __u64 steal_timer; /* 0x0278 */ - __u64 last_update_timer; /* 0x0280 */ - __u64 last_update_clock; /* 0x0288 */ + __u64 mcck_enter_timer; /* 0x0260 */ + __u64 exit_timer; /* 0x0268 */ + __u64 user_timer; /* 0x0270 */ + __u64 system_timer; /* 0x0278 */ + __u64 steal_timer; /* 0x0280 */ + __u64 last_update_timer; /* 0x0288 */ + __u64 last_update_clock; /* 0x0290 */ /* Current process. */ - __u32 current_task; /* 0x0290 */ - __u32 thread_info; /* 0x0294 */ - __u32 kernel_stack; /* 0x0298 */ + __u32 current_task; /* 0x0298 */ + __u32 thread_info; /* 0x029c */ + __u32 kernel_stack; /* 0x02a0 */ /* Interrupt and panic stack. */ - __u32 async_stack; /* 0x029c */ - __u32 panic_stack; /* 0x02a0 */ + __u32 async_stack; /* 0x02a4 */ + __u32 panic_stack; /* 0x02a8 */ /* Address space pointer. */ - __u32 kernel_asce; /* 0x02a4 */ - __u32 user_asce; /* 0x02a8 */ - __u32 user_exec_asce; /* 0x02ac */ + __u32 kernel_asce; /* 0x02ac */ + __u32 user_asce; /* 0x02b0 */ + __u32 user_exec_asce; /* 0x02b4 */ /* SMP info area */ - __u32 cpu_nr; /* 0x02b0 */ - __u32 softirq_pending; /* 0x02b4 */ - __u32 percpu_offset; /* 0x02b8 */ - __u32 ext_call_fast; /* 0x02bc */ - __u64 int_clock; /* 0x02c0 */ - __u64 clock_comparator; /* 0x02c8 */ - __u32 machine_flags; /* 0x02d0 */ - __u32 ftrace_func; /* 0x02d4 */ - __u8 pad_0x02d8[0x0300-0x02d8]; /* 0x02d8 */ + __u32 cpu_nr; /* 0x02b8 */ + __u32 softirq_pending; /* 0x02bc */ + __u32 percpu_offset; /* 0x02c0 */ + __u32 ext_call_fast; /* 0x02c4 */ + __u64 int_clock; /* 0x02c8 */ + __u64 mcck_clock; /* 0x02d0 */ + __u64 clock_comparator; /* 0x02d8 */ + __u32 machine_flags; /* 0x02e0 */ + __u32 ftrace_func; /* 0x02e4 */ + __u8 pad_0x02e8[0x0300-0x02e8]; /* 0x02e8 */ /* Interrupt response block */ __u8 irb[64]; /* 0x0300 */ @@ -232,38 +234,40 @@ struct _lowcore { /* CPU accounting and timing values. */ __u64 sync_enter_timer; /* 0x02a0 */ __u64 async_enter_timer; /* 0x02a8 */ - __u64 exit_timer; /* 0x02b0 */ - __u64 user_timer; /* 0x02b8 */ - __u64 system_timer; /* 0x02c0 */ - __u64 steal_timer; /* 0x02c8 */ - __u64 last_update_timer; /* 0x02d0 */ - __u64 last_update_clock; /* 0x02d8 */ + __u64 mcck_enter_timer; /* 0x02b0 */ + __u64 exit_timer; /* 0x02b8 */ + __u64 user_timer; /* 0x02c0 */ + __u64 system_timer; /* 0x02c8 */ + __u64 steal_timer; /* 0x02d0 */ + __u64 last_update_timer; /* 0x02d8 */ + __u64 last_update_clock; /* 0x02e0 */ /* Current process. */ - __u64 current_task; /* 0x02e0 */ - __u64 thread_info; /* 0x02e8 */ - __u64 kernel_stack; /* 0x02f0 */ + __u64 current_task; /* 0x02e8 */ + __u64 thread_info; /* 0x02f0 */ + __u64 kernel_stack; /* 0x02f8 */ /* Interrupt and panic stack. */ - __u64 async_stack; /* 0x02f8 */ - __u64 panic_stack; /* 0x0300 */ + __u64 async_stack; /* 0x0300 */ + __u64 panic_stack; /* 0x0308 */ /* Address space pointer. */ - __u64 kernel_asce; /* 0x0308 */ - __u64 user_asce; /* 0x0310 */ - __u64 user_exec_asce; /* 0x0318 */ + __u64 kernel_asce; /* 0x0310 */ + __u64 user_asce; /* 0x0318 */ + __u64 user_exec_asce; /* 0x0320 */ /* SMP info area */ - __u32 cpu_nr; /* 0x0320 */ - __u32 softirq_pending; /* 0x0324 */ - __u64 percpu_offset; /* 0x0328 */ - __u64 ext_call_fast; /* 0x0330 */ - __u64 int_clock; /* 0x0338 */ - __u64 clock_comparator; /* 0x0340 */ - __u64 vdso_per_cpu_data; /* 0x0348 */ - __u64 machine_flags; /* 0x0350 */ - __u64 ftrace_func; /* 0x0358 */ - __u8 pad_0x0368[0x0380-0x0360]; /* 0x0360 */ + __u32 cpu_nr; /* 0x0328 */ + __u32 softirq_pending; /* 0x032c */ + __u64 percpu_offset; /* 0x0330 */ + __u64 ext_call_fast; /* 0x0338 */ + __u64 int_clock; /* 0x0340 */ + __u64 mcck_clock; /* 0x0348 */ + __u64 clock_comparator; /* 0x0350 */ + __u64 vdso_per_cpu_data; /* 0x0358 */ + __u64 machine_flags; /* 0x0360 */ + __u64 ftrace_func; /* 0x0368 */ + __u8 pad_0x0370[0x0380-0x0370]; /* 0x0370 */ /* Interrupt response block. */ __u8 irb[64]; /* 0x0380 */ diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 32b1ede69858..816d81f479c0 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -112,6 +112,7 @@ int main(void) DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw)); DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer)); DEFINE(__LC_ASYNC_ENTER_TIMER, offsetof(struct _lowcore, async_enter_timer)); + DEFINE(__LC_MCCK_ENTER_TIMER, offsetof(struct _lowcore, mcck_enter_timer)); DEFINE(__LC_EXIT_TIMER, offsetof(struct _lowcore, exit_timer)); DEFINE(__LC_USER_TIMER, offsetof(struct _lowcore, user_timer)); DEFINE(__LC_SYSTEM_TIMER, offsetof(struct _lowcore, system_timer)); @@ -127,6 +128,7 @@ int main(void) DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce)); DEFINE(__LC_USER_EXEC_ASCE, offsetof(struct _lowcore, user_exec_asce)); DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock)); + DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func)); DEFINE(__LC_IRB, offsetof(struct _lowcore, irb)); diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 07d849995dac..0e2b16241dfa 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -742,15 +742,14 @@ __critical_end: .globl mcck_int_handler mcck_int_handler: - stck __LC_INT_CLOCK + stck __LC_MCCK_CLOCK spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+32 la %r12,__LC_MCK_OLD_PSW tm __LC_MCCK_CODE,0x80 # system damage? bo BASED(mcck_int_main) # yes -> rest of mcck code invalid - mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA + mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? bo BASED(1f) la %r14,__LC_SYNC_ENTER_TIMER @@ -764,7 +763,7 @@ mcck_int_handler: bl BASED(0f) la %r14,__LC_LAST_UPDATE_TIMER 0: spt 0(%r14) - mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) + mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 1: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? bno BASED(mcck_int_main) # no -> skip cleanup critical tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit @@ -786,9 +785,9 @@ mcck_int_main: bno BASED(mcck_no_vtime) # no -> skip cleanup critical tm SP_PSW+1(%r15),0x01 # interrupting from user ? bz BASED(mcck_no_vtime) - UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER + UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER - mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER + mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER mcck_no_vtime: l %r9,__LC_THREAD_INFO # load pointer to thread_info struct la %r2,SP_PTREGS(%r15) # load pt_regs @@ -811,7 +810,6 @@ mcck_no_vtime: mcck_return: mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? bno BASED(0f) lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 @@ -934,15 +932,16 @@ cleanup_critical: cleanup_system_call: mvc __LC_RETURN_PSW(8),0(%r12) - c %r12,BASED(.Lmck_old_psw) - be BASED(0f) - la %r12,__LC_SAVE_AREA+16 - b BASED(1f) -0: la %r12,__LC_SAVE_AREA+32 -1: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4) bh BASED(0f) + mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER + c %r12,BASED(.Lmck_old_psw) + be BASED(0f) mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER +0: c %r12,BASED(.Lmck_old_psw) + la %r12,__LC_SAVE_AREA+32 + be BASED(0f) + la %r12,__LC_SAVE_AREA+16 0: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8) bhe BASED(cleanup_vtime) clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn) @@ -984,16 +983,19 @@ cleanup_sysc_tif: cleanup_sysc_restore: clc 4(4,%r12),BASED(cleanup_sysc_restore_insn) be BASED(2f) + mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER + c %r12,BASED(.Lmck_old_psw) + be BASED(0f) mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER - clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4) +0: clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4) be BASED(2f) mvc __LC_RETURN_PSW(8),SP_PSW(%r15) c %r12,BASED(.Lmck_old_psw) - bne BASED(0f) - mvc __LC_SAVE_AREA+32(16),SP_R12(%r15) - b BASED(1f) -0: mvc __LC_SAVE_AREA+16(16),SP_R12(%r15) -1: lm %r0,%r11,SP_R0(%r15) + la %r12,__LC_SAVE_AREA+32 + be BASED(1f) + la %r12,__LC_SAVE_AREA+16 +1: mvc 0(16,%r12),SP_R12(%r15) + lm %r0,%r11,SP_R0(%r15) l %r15,SP_R15(%r15) 2: la %r12,__LC_RETURN_PSW br %r14 @@ -1009,19 +1011,15 @@ cleanup_io_tif: cleanup_io_restore: clc 4(4,%r12),BASED(cleanup_io_restore_insn) - be BASED(2f) - mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER + be BASED(1f) + mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER clc 4(4,%r12),BASED(cleanup_io_restore_insn+4) - be BASED(2f) + be BASED(1f) mvc __LC_RETURN_PSW(8),SP_PSW(%r15) - c %r12,BASED(.Lmck_old_psw) - bne BASED(0f) mvc __LC_SAVE_AREA+32(16),SP_R12(%r15) - b BASED(1f) -0: mvc __LC_SAVE_AREA+16(16),SP_R12(%r15) -1: lm %r0,%r11,SP_R0(%r15) + lm %r0,%r11,SP_R0(%r15) l %r15,SP_R15(%r15) -2: la %r12,__LC_RETURN_PSW +1: la %r12,__LC_RETURN_PSW br %r14 cleanup_io_restore_insn: .long io_done - 4 + 0x80000000 diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 860cea1d1c8a..6536f5ca46f5 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -725,7 +725,7 @@ __critical_end: */ .globl mcck_int_handler mcck_int_handler: - stck __LC_INT_CLOCK + stck __LC_MCCK_CLOCK la %r1,4095 # revalidate r1 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs @@ -734,8 +734,7 @@ mcck_int_handler: tm __LC_MCCK_CODE,0x80 # system damage? jo mcck_int_main # yes -> rest of mcck code invalid la %r14,4095 - mvc __LC_SAVE_AREA+104(8),__LC_ASYNC_ENTER_TIMER - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) + mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? jo 1f la %r14,__LC_SYNC_ENTER_TIMER @@ -749,7 +748,7 @@ mcck_int_handler: jl 0f la %r14,__LC_LAST_UPDATE_TIMER 0: spt 0(%r14) - mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) + mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 1: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? jno mcck_int_main # no -> skip cleanup critical tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit @@ -770,9 +769,9 @@ mcck_int_main: jno mcck_no_vtime # no -> no timer update tm SP_PSW+1(%r15),0x01 # interrupting from user ? jz mcck_no_vtime - UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER + UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER - mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER + mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER mcck_no_vtime: lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct la %r2,SP_PTREGS(%r15) # load pt_regs @@ -794,7 +793,6 @@ mcck_return: mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+104 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? jno 0f stpt __LC_EXIT_TIMER @@ -909,15 +907,16 @@ cleanup_critical: cleanup_system_call: mvc __LC_RETURN_PSW(16),0(%r12) - cghi %r12,__LC_MCK_OLD_PSW - je 0f - la %r12,__LC_SAVE_AREA+32 - j 1f -0: la %r12,__LC_SAVE_AREA+64 -1: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8) jh 0f + mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER + cghi %r12,__LC_MCK_OLD_PSW + je 0f mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER +0: cghi %r12,__LC_MCK_OLD_PSW + la %r12,__LC_SAVE_AREA+64 + je 0f + la %r12,__LC_SAVE_AREA+32 0: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+16) jhe cleanup_vtime clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn) @@ -958,19 +957,22 @@ cleanup_sysc_tif: cleanup_sysc_restore: clc 8(8,%r12),BASED(cleanup_sysc_restore_insn) - je 3f + je 2f clc 8(8,%r12),BASED(cleanup_sysc_restore_insn+8) jhe 0f + mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER + cghi %r12,__LC_MCK_OLD_PSW + je 0f mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) cghi %r12,__LC_MCK_OLD_PSW - jne 1f - mvc __LC_SAVE_AREA+64(32),SP_R12(%r15) - j 2f -1: mvc __LC_SAVE_AREA+32(32),SP_R12(%r15) -2: lmg %r0,%r11,SP_R0(%r15) + la %r12,__LC_SAVE_AREA+64 + je 1f + la %r12,__LC_SAVE_AREA+32 +1: mvc 0(32,%r12),SP_R12(%r15) + lmg %r0,%r11,SP_R0(%r15) lg %r15,SP_R15(%r15) -3: la %r12,__LC_RETURN_PSW +2: la %r12,__LC_RETURN_PSW br %r14 cleanup_sysc_restore_insn: .quad sysc_done - 4 @@ -984,19 +986,15 @@ cleanup_io_tif: cleanup_io_restore: clc 8(8,%r12),BASED(cleanup_io_restore_insn) - je 3f + je 1f clc 8(8,%r12),BASED(cleanup_io_restore_insn+8) jhe 0f - mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER + mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) - cghi %r12,__LC_MCK_OLD_PSW - jne 1f mvc __LC_SAVE_AREA+64(32),SP_R12(%r15) - j 2f -1: mvc __LC_SAVE_AREA+32(32),SP_R12(%r15) -2: lmg %r0,%r11,SP_R0(%r15) + lmg %r0,%r11,SP_R0(%r15) lg %r15,SP_R15(%r15) -3: la %r12,__LC_RETURN_PSW +1: la %r12,__LC_RETURN_PSW br %r14 cleanup_io_restore_insn: .quad io_done - 4 diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c index 015e27da40eb..ac151399ef34 100644 --- a/arch/s390/kernel/nmi.c +++ b/arch/s390/kernel/nmi.c @@ -255,7 +255,8 @@ void notrace s390_do_machine_check(struct pt_regs *regs) int umode; nmi_enter(); - s390_idle_check(); + s390_idle_check(regs, S390_lowcore.mcck_clock, + S390_lowcore.mcck_enter_timer); mci = (struct mci *) &S390_lowcore.mcck_interruption_code; mcck = &__get_cpu_var(cpu_mcck); diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c index 59618bcd99b7..9ce641b5291f 100644 --- a/arch/s390/kernel/s390_ext.c +++ b/arch/s390/kernel/s390_ext.c @@ -120,7 +120,8 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned short code) struct pt_regs *old_regs; old_regs = set_irq_regs(regs); - s390_idle_check(); + s390_idle_check(regs, S390_lowcore.int_clock, + S390_lowcore.async_enter_timer); irq_enter(); if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) /* Serve timer interrupts first. */ diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index b59a812a010e..3479f1b0d4e0 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -121,32 +121,35 @@ void account_system_vtime(struct task_struct *tsk) } EXPORT_SYMBOL_GPL(account_system_vtime); -void vtime_start_cpu(void) +void vtime_start_cpu(__u64 int_clock, __u64 enter_timer) { struct s390_idle_data *idle = &__get_cpu_var(s390_idle); struct vtimer_queue *vq = &__get_cpu_var(virt_cpu_timer); __u64 idle_time, expires; + if (idle->idle_enter == 0ULL) + return; + /* Account time spent with enabled wait psw loaded as idle time. */ - idle_time = S390_lowcore.int_clock - idle->idle_enter; + idle_time = int_clock - idle->idle_enter; account_idle_time(idle_time); S390_lowcore.steal_timer += idle->idle_enter - S390_lowcore.last_update_clock; - S390_lowcore.last_update_clock = S390_lowcore.int_clock; + S390_lowcore.last_update_clock = int_clock; /* Account system time spent going idle. */ S390_lowcore.system_timer += S390_lowcore.last_update_timer - vq->idle; - S390_lowcore.last_update_timer = S390_lowcore.async_enter_timer; + S390_lowcore.last_update_timer = enter_timer; /* Restart vtime CPU timer */ if (vq->do_spt) { /* Program old expire value but first save progress. */ - expires = vq->idle - S390_lowcore.async_enter_timer; + expires = vq->idle - enter_timer; expires += get_vtimer(); set_vtimer(expires); } else { /* Don't account the CPU timer delta while the cpu was idle. */ - vq->elapsed -= vq->idle - S390_lowcore.async_enter_timer; + vq->elapsed -= vq->idle - enter_timer; } idle->sequence++; diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 5feea1a371e1..f4e6cf3aceb8 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -616,7 +616,8 @@ void __irq_entry do_IRQ(struct pt_regs *regs) struct pt_regs *old_regs; old_regs = set_irq_regs(regs); - s390_idle_check(); + s390_idle_check(regs, S390_lowcore.int_clock, + S390_lowcore.async_enter_timer); irq_enter(); __get_cpu_var(s390_idle).nohz_delay = 1; if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) -- cgit v1.2.3-59-g8ed1b From cd3b70f5d4d82f85d1e1d6e822f38ae098cf7c72 Mon Sep 17 00:00:00 2001 From: Carsten Otte Date: Mon, 17 May 2010 10:00:04 +0200 Subject: [S390] virtualization aware cpu measurement Use the SPP instruction to set a tag on entry to / exit of the virtual machine context. This allows the cpu measurement facility to distinguish the samples from the host and the different guests. Signed-off-by: Carsten Otte --- arch/s390/include/asm/lowcore.h | 3 +- arch/s390/include/asm/setup.h | 5 ++- arch/s390/kernel/asm-offsets.c | 2 ++ arch/s390/kernel/early.c | 4 +++ arch/s390/kernel/entry64.S | 26 ++++++++------ arch/s390/kernel/setup.c | 3 +- arch/s390/kvm/Kconfig | 11 ++++++ arch/s390/kvm/sie64a.S | 77 ++++++++++++++++++++++++++++++++++------- 8 files changed, 105 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 2c02d46c3588..0f97ef2d92ac 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -267,7 +267,8 @@ struct _lowcore { __u64 vdso_per_cpu_data; /* 0x0358 */ __u64 machine_flags; /* 0x0360 */ __u64 ftrace_func; /* 0x0368 */ - __u8 pad_0x0370[0x0380-0x0370]; /* 0x0370 */ + __u64 sie_hook; /* 0x0370 */ + __u64 cmf_hpp; /* 0x0378 */ /* Interrupt response block. */ __u8 irb[64]; /* 0x0380 */ diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 9ab6bd3a65d1..25e831d58e1e 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -2,7 +2,7 @@ * include/asm-s390/setup.h * * S390 version - * Copyright IBM Corp. 1999,2006 + * Copyright IBM Corp. 1999,2010 */ #ifndef _ASM_S390_SETUP_H @@ -72,6 +72,7 @@ extern unsigned int user_mode; #define MACHINE_FLAG_HPAGE (1UL << 10) #define MACHINE_FLAG_PFMF (1UL << 11) #define MACHINE_FLAG_LPAR (1UL << 12) +#define MACHINE_FLAG_SPP (1UL << 13) #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) @@ -88,6 +89,7 @@ extern unsigned int user_mode; #define MACHINE_HAS_MVCOS (0) #define MACHINE_HAS_HPAGE (0) #define MACHINE_HAS_PFMF (0) +#define MACHINE_HAS_SPP (0) #else /* __s390x__ */ #define MACHINE_HAS_IEEE (1) #define MACHINE_HAS_CSP (1) @@ -97,6 +99,7 @@ extern unsigned int user_mode; #define MACHINE_HAS_MVCOS (S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS) #define MACHINE_HAS_HPAGE (S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE) #define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) +#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP) #endif /* __s390x__ */ #define ZFCPDUMP_HSA_SIZE (32UL<<20) diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 816d81f479c0..44a4336d9a33 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -131,6 +131,8 @@ int main(void) DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func)); + DEFINE(__LC_SIE_HOOK, offsetof(struct _lowcore, sie_hook)); + DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp)); DEFINE(__LC_IRB, offsetof(struct _lowcore, irb)); DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area)); DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area)); diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 2d92c2cf92d7..c00856ad4e5a 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -356,6 +356,7 @@ static __init void detect_machine_facilities(void) { #ifdef CONFIG_64BIT unsigned int facilities; + unsigned long long facility_bits; facilities = stfl(); if (facilities & (1 << 28)) @@ -364,6 +365,9 @@ static __init void detect_machine_facilities(void) S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; if (facilities & (1 << 4)) S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; + if ((stfle(&facility_bits, 1) > 0) && + (facility_bits & (1ULL << (63 - 40)))) + S390_lowcore.machine_flags |= MACHINE_FLAG_SPP; #endif } diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 6536f5ca46f5..829b759ba1e1 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -2,7 +2,7 @@ * arch/s390/kernel/entry64.S * S390 low-level entry points. * - * Copyright (C) IBM Corp. 1999,2006 + * Copyright (C) IBM Corp. 1999,2010 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), * Hartmut Penner (hp@de.ibm.com), * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), @@ -59,6 +59,16 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ #define BASED(name) name-system_call(%r13) + .macro HANDLE_SIE_INTERCEPT +#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) + lg %r3,__LC_SIE_HOOK + ltgr %r3,%r3 + jz 0f + basr %r14,%r3 + 0: +#endif + .endm + #ifdef CONFIG_TRACE_IRQFLAGS .macro TRACE_IRQS_ON basr %r2,%r0 @@ -466,6 +476,7 @@ pgm_check_handler: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER pgm_no_vtime: + HANDLE_SIE_INTERCEPT TRACE_IRQS_CHECK_OFF lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct mvc SP_ARGS(8,%r15),__LC_LAST_BREAK @@ -507,6 +518,7 @@ pgm_per_std: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER pgm_no_vtime2: + HANDLE_SIE_INTERCEPT TRACE_IRQS_CHECK_OFF lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct lg %r1,__TI_task(%r9) @@ -570,6 +582,7 @@ io_int_handler: mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER io_no_vtime: lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct + HANDLE_SIE_INTERCEPT TRACE_IRQS_OFF la %r2,SP_PTREGS(%r15) # address of register-save area brasl %r14,do_IRQ # call standard irq handler @@ -595,15 +608,6 @@ io_done: io_work: tm SP_PSW+1(%r15),0x01 # returning to user ? jo io_work_user # yes -> do resched & signal -#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) - lg %r2,SP_PSW+8(%r15) # check if current instruction is SIE - lh %r1,0(%r2) - chi %r1,-19948 # signed 16 bit compare with 0xb214 - jne 0f # no -> leave PSW alone - aghi %r2,4 # yes-> add 4 bytes to leave SIE - stg %r2,SP_PSW+8(%r15) -0: -#endif #ifdef CONFIG_PREEMPT # check for preemptive scheduling icm %r0,15,__TI_precount(%r9) @@ -712,6 +716,7 @@ ext_int_handler: mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER ext_no_vtime: lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct + HANDLE_SIE_INTERCEPT TRACE_IRQS_OFF la %r2,SP_PTREGS(%r15) # address of register-save area llgh %r3,__LC_EXT_INT_CODE # get interruption code @@ -786,6 +791,7 @@ mcck_no_vtime: stosm __SF_EMPTY(%r15),0x04 # turn dat on tm __TI_flags+7(%r9),_TIF_MCCK_PENDING jno mcck_return + HANDLE_SIE_INTERCEPT TRACE_IRQS_OFF brasl %r14,s390_handle_mcck TRACE_IRQS_ON diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 598752499c3e..7d893248d265 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -2,7 +2,7 @@ * arch/s390/kernel/setup.c * * S390 version - * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright (C) IBM Corp. 1999,2010 * Author(s): Hartmut Penner (hp@de.ibm.com), * Martin Schwidefsky (schwidefsky@de.ibm.com) * @@ -401,6 +401,7 @@ setup_lowcore(void) lc->io_new_psw.mask = psw_kernel_bits; lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; lc->clock_comparator = -1ULL; + lc->cmf_hpp = -1ULL; lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; lc->async_stack = (unsigned long) __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index a7251580891c..2f4b687cc7fa 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig @@ -33,6 +33,17 @@ config KVM If unsure, say N. +config KVM_AWARE_CMF + depends on KVM + bool "KVM aware sampling" + ---help--- + This option enhances the sampling data from the CPU Measurement + Facility with additional information, that allows to distinguish + guest(s) and host when using the kernel based virtual machine + functionality. + + If unsure, say N. + # OK, it's a little counter-intuitive to do this, but it puts it neatly under # the virtualization menu. source drivers/vhost/Kconfig diff --git a/arch/s390/kvm/sie64a.S b/arch/s390/kvm/sie64a.S index 934fd6a885f6..31646bd0e469 100644 --- a/arch/s390/kvm/sie64a.S +++ b/arch/s390/kvm/sie64a.S @@ -1,20 +1,60 @@ /* * sie64a.S - low level sie call * - * Copyright IBM Corp. 2008 + * Copyright IBM Corp. 2008,2010 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License (version 2 only) * as published by the Free Software Foundation. * * Author(s): Heiko Carstens + * Christian Ehrhardt */ #include #include +#include +#include +#include +#include + +_TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) + +/* + * offsets into stackframe + * SP_ = offsets into stack sie64 is called with + * SPI_ = offsets into irq stack + */ +SP_GREGS = __SF_EMPTY +SP_HOOK = __SF_EMPTY+8 +SP_GPP = __SF_EMPTY+16 +SPI_PSW = STACK_FRAME_OVERHEAD + __PT_PSW + -SP_R5 = 5 * 8 # offset into stackframe -SP_R6 = 6 * 8 + .macro SPP newpp +#ifdef CONFIG_KVM_AWARE_CMF + tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP + jz 0f + .insn s,0xb2800000,\newpp + 0: +#endif + .endm + +sie_irq_handler: + SPP __LC_CMF_HPP # set host id + larl %r2,sie_inst + clg %r2,SPI_PSW+8(0,%r15) # intercepted sie + jne 1f + xc __LC_SIE_HOOK(8),__LC_SIE_HOOK + lg %r2,__LC_THREAD_INFO # pointer thread_info struct + tm __TI_flags+7(%r2),_TIF_EXIT_SIE + jz 0f + larl %r2,sie_exit # work pending, leave sie + stg %r2,__LC_RETURN_PSW+8 + br %r14 +0: larl %r2,sie_reenter # re-enter with guest id + stg %r2,__LC_RETURN_PSW+8 +1: br %r14 /* * sie64a calling convention: @@ -23,23 +63,34 @@ SP_R6 = 6 * 8 */ .globl sie64a sie64a: - lgr %r5,%r3 - stmg %r5,%r14,SP_R5(%r15) # save register on entry - lgr %r14,%r2 # pointer to sie control block - lmg %r0,%r13,0(%r3) # load guest gprs 0-13 + stg %r3,SP_GREGS(%r15) # save guest register save area + stmg %r6,%r14,__SF_GPRS(%r15) # save registers on entry + lgr %r14,%r2 # pointer to sie control block + larl %r5,sie_irq_handler + stg %r2,SP_GPP(%r15) + stg %r5,SP_HOOK(%r15) # save hook target + lmg %r0,%r13,0(%r3) # load guest gprs 0-13 +sie_reenter: + mvc __LC_SIE_HOOK(8),SP_HOOK(%r15) + SPP SP_GPP(%r15) # set guest id sie_inst: sie 0(%r14) - lg %r14,SP_R5(%r15) - stmg %r0,%r13,0(%r14) # save guest gprs 0-13 + xc __LC_SIE_HOOK(8),__LC_SIE_HOOK + SPP __LC_CMF_HPP # set host id +sie_exit: + lg %r14,SP_GREGS(%r15) + stmg %r0,%r13,0(%r14) # save guest gprs 0-13 lghi %r2,0 - lmg %r6,%r14,SP_R6(%r15) + lmg %r6,%r14,__SF_GPRS(%r15) br %r14 sie_err: - lg %r14,SP_R5(%r15) - stmg %r0,%r13,0(%r14) # save guest gprs 0-13 + xc __LC_SIE_HOOK(8),__LC_SIE_HOOK + SPP __LC_CMF_HPP # set host id + lg %r14,SP_GREGS(%r15) + stmg %r0,%r13,0(%r14) # save guest gprs 0-13 lghi %r2,-EFAULT - lmg %r6,%r14,SP_R6(%r15) + lmg %r6,%r14,__SF_GPRS(%r15) br %r14 .section __ex_table,"a" -- cgit v1.2.3-59-g8ed1b From 86f2552bbd0e17b19bb5e9881042533eaea553c7 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 17 May 2010 10:00:05 +0200 Subject: [S390] add breaking event address for user space Copy the last breaking event address from the lowcore to a new field in the thread_struct on each system entry. Add a new ptrace request PTRACE_GET_LAST_BREAK and a new utrace regset REGSET_LAST_BREAK to query the last breaking event. This is useful for debugging wild branches in user space code. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/ptrace.h | 3 +- arch/s390/include/asm/thread_info.h | 1 + arch/s390/kernel/asm-offsets.c | 1 + arch/s390/kernel/entry.S | 4 +- arch/s390/kernel/entry64.S | 270 +++++++++++++++++++----------------- arch/s390/kernel/ptrace.c | 68 +++++++++ arch/s390/kernel/signal.c | 2 + include/linux/elf.h | 1 + 8 files changed, 223 insertions(+), 127 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index fef9b33cdd59..e2c218dc68a6 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -328,8 +328,8 @@ struct pt_regs psw_t psw; unsigned long gprs[NUM_GPRS]; unsigned long orig_gpr2; - unsigned short svcnr; unsigned short ilc; + unsigned short svcnr; }; #endif @@ -436,6 +436,7 @@ typedef struct #define PTRACE_PEEKDATA_AREA 0x5003 #define PTRACE_POKETEXT_AREA 0x5004 #define PTRACE_POKEDATA_AREA 0x5005 +#define PTRACE_GET_LAST_BREAK 0x5006 /* * PT_PROT definition is loosely based on hppa bsd definition in diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 34f0873d6525..be3d3f91d86c 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -50,6 +50,7 @@ struct thread_info { struct restart_block restart_block; __u64 user_timer; __u64 system_timer; + unsigned long last_break; /* last breaking-event-address. */ }; /* diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 44a4336d9a33..d9b490a2716e 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -39,6 +39,7 @@ int main(void) DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count)); DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer)); DEFINE(__TI_system_timer, offsetof(struct thread_info, system_timer)); + DEFINE(__TI_last_break, offsetof(struct thread_info, last_break)); BLANK(); DEFINE(__PT_ARGS, offsetof(struct pt_regs, args)); DEFINE(__PT_PSW, offsetof(struct pt_regs, psw)); diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 0e2b16241dfa..d5e3e6007447 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -180,9 +180,9 @@ STACK_SIZE = 1 << STACK_SHIFT s %r15,BASED(.Lc_spsize) # make room for registers & psw mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 - icm %r12,3,__LC_SVC_ILC + icm %r12,12,__LC_SVC_ILC stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack - st %r12,SP_SVCNR(%r15) + st %r12,SP_ILC(%r15) mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack la %r12,0 st %r12,__SF_BACKCHAIN(%r15) # clear back chain diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 829b759ba1e1..178d92536d90 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -126,31 +126,35 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ * R15 - kernel stack pointer */ - .macro SAVE_ALL_BASE savearea - stmg %r12,%r15,\savearea - larl %r13,system_call - .endm - .macro SAVE_ALL_SVC psworg,savearea - la %r12,\psworg + stmg %r11,%r15,\savearea lg %r15,__LC_KERNEL_STACK # problem state -> load ksp + aghi %r15,-SP_SIZE # make room for registers & psw + lg %r11,__LC_LAST_BREAK .endm - .macro SAVE_ALL_SYNC psworg,savearea - la %r12,\psworg + .macro SAVE_ALL_PGM psworg,savearea + stmg %r11,%r15,\savearea tm \psworg+1,0x01 # test problem state bit - jz 2f # skip stack setup save - lg %r15,__LC_KERNEL_STACK # problem state -> load ksp #ifdef CONFIG_CHECK_STACK - j 3f -2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD - jz stack_overflow -3: + jnz 1f + tml %r15,STACK_SIZE - CONFIG_STACK_GUARD + jnz 2f + la %r12,\psworg + j stack_overflow +#else + jz 2f #endif -2: +1: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp +2: aghi %r15,-SP_SIZE # make room for registers & psw + larl %r13,system_call + lg %r11,__LC_LAST_BREAK .endm .macro SAVE_ALL_ASYNC psworg,savearea + stmg %r11,%r15,\savearea + larl %r13,system_call + lg %r11,__LC_LAST_BREAK la %r12,\psworg tm \psworg+1,0x01 # test problem state bit jnz 1f # from user -> load kernel stack @@ -164,27 +168,23 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ 0: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ? slgr %r14,%r15 srag %r14,%r14,STACK_SHIFT - jz 2f -1: lg %r15,__LC_ASYNC_STACK # load async stack #ifdef CONFIG_CHECK_STACK - j 3f -2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD - jz stack_overflow -3: + jnz 1f + tml %r15,STACK_SIZE - CONFIG_STACK_GUARD + jnz 2f + j stack_overflow +#else + jz 2f #endif -2: +1: lg %r15,__LC_ASYNC_STACK # load async stack +2: aghi %r15,-SP_SIZE # make room for registers & psw .endm - .macro CREATE_STACK_FRAME psworg,savearea - aghi %r15,-SP_SIZE # make room for registers & psw - mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack + .macro CREATE_STACK_FRAME savearea + xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 - icm %r12,3,__LC_SVC_ILC - stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack - st %r12,SP_SVCNR(%r15) - mvc SP_R12(32,%r15),\savearea # move %r12-%r15 to stack - la %r12,0 - stg %r12,__SF_BACKCHAIN(%r15) + mvc SP_R11(40,%r15),\savearea # move %r11-%r15 to stack + stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack .endm .macro RESTORE_ALL psworg,sync @@ -200,6 +200,13 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ lpswe \psworg # back to caller .endm + .macro LAST_BREAK + srag %r10,%r11,23 + jz 0f + stg %r11,__TI_last_break(%r12) +0: + .endm + /* * Scheduler resume function, called by switch_to * gpr2 = (task_struct *) prev @@ -245,37 +252,38 @@ __critical_start: system_call: stpt __LC_SYNC_ENTER_TIMER sysc_saveall: - SAVE_ALL_BASE __LC_SAVE_AREA SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA - llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore + CREATE_STACK_FRAME __LC_SAVE_AREA + mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW + mvc SP_ILC(4,%r15),__LC_SVC_ILC + stg %r7,SP_ARGS(%r15) + lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct sysc_vtime: UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER sysc_stime: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER sysc_update: mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER + LAST_BREAK sysc_do_svc: - lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct - ltgr %r7,%r7 # test for svc 0 + llgh %r7,SP_SVCNR(%r15) + slag %r7,%r7,2 # shift and test for svc 0 jnz sysc_nr_ok # svc 0: system call number in %r1 - cl %r1,BASED(.Lnr_syscalls) + llgfr %r1,%r1 # clear high word in r1 + cghi %r1,NR_syscalls jnl sysc_nr_ok - lgfr %r7,%r1 # clear high word in r1 + sth %r1,SP_SVCNR(%r15) + slag %r7,%r1,2 # shift and test for svc 0 sysc_nr_ok: - mvc SP_ARGS(8,%r15),SP_R7(%r15) -sysc_do_restart: - sth %r7,SP_SVCNR(%r15) - sllg %r7,%r7,2 # svc number * 4 larl %r10,sys_call_table #ifdef CONFIG_COMPAT - tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ? + tm __TI_flags+5(%r12),(_TIF_31BIT>>16) # running in 31 bit mode ? jno sysc_noemu larl %r10,sys_call_table_emu # use 31 bit emulation system calls sysc_noemu: #endif - tm __TI_flags+6(%r9),_TIF_SYSCALL + tm __TI_flags+6(%r12),_TIF_SYSCALL lgf %r8,0(%r7,%r10) # load address of system call routine jnz sysc_tracesys basr %r14,%r8 # call sys_xxxx @@ -284,7 +292,7 @@ sysc_noemu: sysc_return: LOCKDEP_SYS_EXIT sysc_tif: - tm __TI_flags+7(%r9),_TIF_WORK_SVC + tm __TI_flags+7(%r12),_TIF_WORK_SVC jnz sysc_work # there is work to do (signals etc.) sysc_restore: RESTORE_ALL __LC_RETURN_PSW,1 @@ -301,17 +309,17 @@ sysc_work: # One of the work bits is on. Find out which one. # sysc_work_tif: - tm __TI_flags+7(%r9),_TIF_MCCK_PENDING + tm __TI_flags+7(%r12),_TIF_MCCK_PENDING jo sysc_mcck_pending - tm __TI_flags+7(%r9),_TIF_NEED_RESCHED + tm __TI_flags+7(%r12),_TIF_NEED_RESCHED jo sysc_reschedule - tm __TI_flags+7(%r9),_TIF_SIGPENDING + tm __TI_flags+7(%r12),_TIF_SIGPENDING jo sysc_sigpending - tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME + tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME jo sysc_notify_resume - tm __TI_flags+7(%r9),_TIF_RESTART_SVC + tm __TI_flags+7(%r12),_TIF_RESTART_SVC jo sysc_restart - tm __TI_flags+7(%r9),_TIF_SINGLE_STEP + tm __TI_flags+7(%r12),_TIF_SINGLE_STEP jo sysc_singlestep j sysc_return # beware of critical section cleanup @@ -333,12 +341,12 @@ sysc_mcck_pending: # _TIF_SIGPENDING is set, call do_signal # sysc_sigpending: - ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP + ni __TI_flags+7(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP la %r2,SP_PTREGS(%r15) # load pt_regs brasl %r14,do_signal # call do_signal - tm __TI_flags+7(%r9),_TIF_RESTART_SVC + tm __TI_flags+7(%r12),_TIF_RESTART_SVC jo sysc_restart - tm __TI_flags+7(%r9),_TIF_SINGLE_STEP + tm __TI_flags+7(%r12),_TIF_SINGLE_STEP jo sysc_singlestep j sysc_return @@ -354,17 +362,19 @@ sysc_notify_resume: # _TIF_RESTART_SVC is set, set up registers and restart svc # sysc_restart: - ni __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC + ni __TI_flags+7(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC lg %r7,SP_R2(%r15) # load new svc number mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument lmg %r2,%r6,SP_R2(%r15) # load svc arguments - j sysc_do_restart # restart svc + sth %r7,SP_SVCNR(%r15) + slag %r7,%r7,2 + j sysc_nr_ok # restart svc # # _TIF_SINGLE_STEP is set, call do_single_step # sysc_singlestep: - ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP + ni __TI_flags+7(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number la %r2,SP_PTREGS(%r15) # address of register-save area larl %r14,sysc_return # load adr. of system return @@ -377,8 +387,8 @@ sysc_singlestep: sysc_tracesys: la %r2,SP_PTREGS(%r15) # load pt_regs la %r3,0 - srl %r7,2 - stg %r7,SP_R2(%r15) + llgh %r0,SP_SVCNR(%r15) + stg %r0,SP_R2(%r15) brasl %r14,do_syscall_trace_enter lghi %r0,NR_syscalls clgr %r0,%r2 @@ -391,7 +401,7 @@ sysc_tracego: basr %r14,%r8 # call sys_xxx stg %r2,SP_R2(%r15) # store return value sysc_tracenogo: - tm __TI_flags+6(%r9),_TIF_SYSCALL + tm __TI_flags+6(%r12),_TIF_SYSCALL jz sysc_return la %r2,SP_PTREGS(%r15) # load pt_regs larl %r14,sysc_return # return point is sysc_return @@ -403,7 +413,7 @@ sysc_tracenogo: .globl ret_from_fork ret_from_fork: lg %r13,__LC_SVC_NEW_PSW+8 - lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct + lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? jo 0f stg %r15,SP_R15(%r15) # store stack pointer for new kthread @@ -437,8 +447,8 @@ kernel_execve: lg %r15,__LC_KERNEL_STACK # load ksp aghi %r15,-SP_SIZE # make room for registers & psw lg %r13,__LC_SVC_NEW_PSW+8 - lg %r9,__LC_THREAD_INFO mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs + lg %r12,__LC_THREAD_INFO xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # TRACE_IRQS_ON stosm __SF_EMPTY(%r15),0x03 # reenable interrupts @@ -465,21 +475,23 @@ pgm_check_handler: * for LPSW?). */ stpt __LC_SYNC_ENTER_TIMER - SAVE_ALL_BASE __LC_SAVE_AREA tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception jnz pgm_per # got per exception -> special case - SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA + SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA + CREATE_STACK_FRAME __LC_SAVE_AREA + xc SP_ILC(4,%r15),SP_ILC(%r15) + mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW + lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # interrupting from user ? jz pgm_no_vtime UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER + LAST_BREAK pgm_no_vtime: HANDLE_SIE_INTERCEPT TRACE_IRQS_CHECK_OFF - lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct - mvc SP_ARGS(8,%r15),__LC_LAST_BREAK + stg %r11,SP_ARGS(%r15) lgf %r3,__LC_PGM_ILC # load program interruption code lghi %r8,0x7f ngr %r8,%r3 @@ -503,31 +515,32 @@ pgm_per: clc __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW je pgm_svcper # no interesting special case, ignore PER event - lmg %r12,%r15,__LC_SAVE_AREA lpswe __LC_PGM_OLD_PSW # # Normal per exception # pgm_per_std: - SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA + SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA + CREATE_STACK_FRAME __LC_SAVE_AREA + mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW + lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # interrupting from user ? jz pgm_no_vtime2 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER + LAST_BREAK pgm_no_vtime2: HANDLE_SIE_INTERCEPT TRACE_IRQS_CHECK_OFF - lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct - lg %r1,__TI_task(%r9) + lg %r1,__TI_task(%r12) tm SP_PSW+1(%r15),0x01 # kernel per event ? jz kernel_per mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID - oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP + oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP lgf %r3,__LC_PGM_ILC # load program interruption code lghi %r8,0x7f ngr %r8,%r3 # clear per-event-bit and ilc @@ -538,19 +551,21 @@ pgm_no_vtime2: # it was a single stepped SVC that is causing all the trouble # pgm_svcper: - SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA + SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA + CREATE_STACK_FRAME __LC_SAVE_AREA + mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW + mvc SP_ILC(4,%r15),__LC_SVC_ILC + lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER - llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore - lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct + LAST_BREAK TRACE_IRQS_OFF - lg %r8,__TI_task(%r9) + lg %r8,__TI_task(%r12) mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID - oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP + oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP TRACE_IRQS_ON stosm __SF_EMPTY(%r15),0x03 # reenable interrupts lmg %r2,%r6,SP_R2(%r15) # load svc arguments @@ -572,16 +587,17 @@ kernel_per: io_int_handler: stck __LC_INT_CLOCK stpt __LC_ASYNC_ENTER_TIMER - SAVE_ALL_BASE __LC_SAVE_AREA+32 - SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 - CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 + SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+40 + CREATE_STACK_FRAME __LC_SAVE_AREA+40 + mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack + lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # interrupting from user ? jz io_no_vtime UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER + LAST_BREAK io_no_vtime: - lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct HANDLE_SIE_INTERCEPT TRACE_IRQS_OFF la %r2,SP_PTREGS(%r15) # address of register-save area @@ -590,7 +606,7 @@ io_return: LOCKDEP_SYS_EXIT TRACE_IRQS_ON io_tif: - tm __TI_flags+7(%r9),_TIF_WORK_INT + tm __TI_flags+7(%r12),_TIF_WORK_INT jnz io_work # there is work to do (signals etc.) io_restore: RESTORE_ALL __LC_RETURN_PSW,0 @@ -610,7 +626,7 @@ io_work: jo io_work_user # yes -> do resched & signal #ifdef CONFIG_PREEMPT # check for preemptive scheduling - icm %r0,15,__TI_precount(%r9) + icm %r0,15,__TI_precount(%r12) jnz io_restore # preemption is disabled tm __TI_flags+7(%r12),_TIF_NEED_RESCHED jno io_restore @@ -645,13 +661,13 @@ io_work_user: # and _TIF_MCCK_PENDING # io_work_tif: - tm __TI_flags+7(%r9),_TIF_MCCK_PENDING + tm __TI_flags+7(%r12),_TIF_MCCK_PENDING jo io_mcck_pending - tm __TI_flags+7(%r9),_TIF_NEED_RESCHED + tm __TI_flags+7(%r12),_TIF_NEED_RESCHED jo io_reschedule - tm __TI_flags+7(%r9),_TIF_SIGPENDING + tm __TI_flags+7(%r12),_TIF_SIGPENDING jo io_sigpending - tm __TI_flags+7(%r9),_TIF_NOTIFY_RESUME + tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME jo io_notify_resume j io_return # beware of critical section cleanup @@ -706,16 +722,17 @@ io_notify_resume: ext_int_handler: stck __LC_INT_CLOCK stpt __LC_ASYNC_ENTER_TIMER - SAVE_ALL_BASE __LC_SAVE_AREA+32 - SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 - CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 + SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+40 + CREATE_STACK_FRAME __LC_SAVE_AREA+40 + mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack + lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # interrupting from user ? jz ext_no_vtime UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER + LAST_BREAK ext_no_vtime: - lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct HANDLE_SIE_INTERCEPT TRACE_IRQS_OFF la %r2,SP_PTREGS(%r15) # address of register-save area @@ -734,7 +751,9 @@ mcck_int_handler: la %r1,4095 # revalidate r1 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs - SAVE_ALL_BASE __LC_SAVE_AREA+64 + stmg %r11,%r15,__LC_SAVE_AREA+80 + larl %r13,system_call + lg %r11,__LC_LAST_BREAK la %r12,__LC_MCK_OLD_PSW tm __LC_MCCK_CODE,0x80 # system damage? jo mcck_int_main # yes -> rest of mcck code invalid @@ -769,7 +788,10 @@ mcck_int_main: srag %r14,%r14,PAGE_SHIFT jz 0f lg %r15,__LC_PANIC_STACK # load panic stack -0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64 +0: aghi %r15,-SP_SIZE # make room for registers & psw + CREATE_STACK_FRAME __LC_SAVE_AREA+80 + mvc SP_PSW(16,%r15),0(%r12) + lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? jno mcck_no_vtime # no -> no timer update tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -777,8 +799,8 @@ mcck_int_main: UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER + LAST_BREAK mcck_no_vtime: - lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct la %r2,SP_PTREGS(%r15) # load pt_regs brasl %r14,s390_do_machine_check tm SP_PSW+1(%r15),0x01 # returning to user ? @@ -789,7 +811,7 @@ mcck_no_vtime: xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain lgr %r15,%r1 stosm __SF_EMPTY(%r15),0x04 # turn dat on - tm __TI_flags+7(%r9),_TIF_MCCK_PENDING + tm __TI_flags+7(%r12),_TIF_MCCK_PENDING jno mcck_return HANDLE_SIE_INTERCEPT TRACE_IRQS_OFF @@ -803,6 +825,7 @@ mcck_return: jno 0f stpt __LC_EXIT_TIMER 0: lpswe __LC_RETURN_MCCK_PSW # back to caller +mcck_done: /* * Restart interruption handler, kick starter for additional CPUs @@ -858,14 +881,14 @@ stack_overflow: lg %r15,__LC_PANIC_STACK # change to panic stack aghi %r15,-SP_SIZE mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack - stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack + stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack la %r1,__LC_SAVE_AREA chi %r12,__LC_SVC_OLD_PSW je 0f chi %r12,__LC_PGM_OLD_PSW je 0f - la %r1,__LC_SAVE_AREA+32 -0: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack + la %r1,__LC_SAVE_AREA+40 +0: mvc SP_R11(40,%r15),0(%r1) # move %r11-%r15 to stack mvc SP_ARGS(8,%r15),__LC_LAST_BREAK xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain la %r2,SP_PTREGS(%r15) # load pt_regs @@ -920,21 +943,23 @@ cleanup_system_call: je 0f mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 0: cghi %r12,__LC_MCK_OLD_PSW - la %r12,__LC_SAVE_AREA+64 + la %r12,__LC_SAVE_AREA+80 je 0f - la %r12,__LC_SAVE_AREA+32 + la %r12,__LC_SAVE_AREA+40 0: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+16) jhe cleanup_vtime clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn) jh 0f - mvc __LC_SAVE_AREA(32),0(%r12) -0: stg %r13,8(%r12) - stg %r12,__LC_SAVE_AREA+96 # argh - SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA - lg %r12,__LC_SAVE_AREA+96 # argh - stg %r15,24(%r12) - llgh %r7,__LC_SVC_INT_CODE + mvc __LC_SAVE_AREA(40),0(%r12) +0: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp + aghi %r15,-SP_SIZE # make room for registers & psw + stg %r15,32(%r12) + stg %r11,0(%r12) + CREATE_STACK_FRAME __LC_SAVE_AREA + mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW + mvc SP_ILC(4,%r15),__LC_SVC_ILC + stg %r7,SP_ARGS(%r15) + mvc 8(8,%r12),__LC_THREAD_INFO cleanup_vtime: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) jhe cleanup_stime @@ -945,7 +970,11 @@ cleanup_stime: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER cleanup_update: mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER - mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) + srag %r12,%r11,23 + lg %r12,__LC_THREAD_INFO + jz 0f + stg %r11,__TI_last_break(%r12) +0: mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) la %r12,__LC_RETURN_PSW br %r14 cleanup_system_call_insn: @@ -972,11 +1001,11 @@ cleanup_sysc_restore: mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) cghi %r12,__LC_MCK_OLD_PSW - la %r12,__LC_SAVE_AREA+64 + la %r12,__LC_SAVE_AREA+80 je 1f - la %r12,__LC_SAVE_AREA+32 -1: mvc 0(32,%r12),SP_R12(%r15) - lmg %r0,%r11,SP_R0(%r15) + la %r12,__LC_SAVE_AREA+40 +1: mvc 0(40,%r12),SP_R11(%r15) + lmg %r0,%r10,SP_R0(%r15) lg %r15,SP_R15(%r15) 2: la %r12,__LC_RETURN_PSW br %r14 @@ -997,8 +1026,8 @@ cleanup_io_restore: jhe 0f mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 0: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) - mvc __LC_SAVE_AREA+64(32),SP_R12(%r15) - lmg %r0,%r11,SP_R0(%r15) + mvc __LC_SAVE_AREA+80(40),SP_R11(%r15) + lmg %r0,%r10,SP_R0(%r15) lg %r15,SP_R15(%r15) 1: la %r12,__LC_RETURN_PSW br %r14 @@ -1010,13 +1039,6 @@ cleanup_io_restore_insn: * Integer constants */ .align 4 -.Lconst: -.Lnr_syscalls: .long NR_syscalls -.L0x0130: .short 0x130 -.L0x0140: .short 0x140 -.L0x0150: .short 0x150 -.L0x0160: .short 0x160 -.L0x0170: .short 0x170 .Lcritical_start: .quad __critical_start .Lcritical_end: diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 9f654da4cecc..83339d33c4b1 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -57,6 +57,7 @@ enum s390_regset { REGSET_GENERAL, REGSET_FP, + REGSET_LAST_BREAK, REGSET_GENERAL_EXTENDED, }; @@ -381,6 +382,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) copied += sizeof(unsigned long); } return 0; + case PTRACE_GET_LAST_BREAK: + put_user(task_thread_info(child)->last_break, + (unsigned long __user *) data); + return 0; default: /* Removing high order bit from addr (only for 31 bit). */ addr &= PSW_ADDR_INSN; @@ -633,6 +638,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, copied += sizeof(unsigned int); } return 0; + case PTRACE_GET_LAST_BREAK: + put_user(task_thread_info(child)->last_break, + (unsigned int __user *) data); + return 0; } return compat_ptrace_request(child, request, addr, data); } @@ -797,6 +806,28 @@ static int s390_fpregs_set(struct task_struct *target, return rc; } +#ifdef CONFIG_64BIT + +static int s390_last_break_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + if (count > 0) { + if (kbuf) { + unsigned long *k = kbuf; + *k = task_thread_info(target)->last_break; + } else { + unsigned long __user *u = ubuf; + if (__put_user(task_thread_info(target)->last_break, u)) + return -EFAULT; + } + } + return 0; +} + +#endif + static const struct user_regset s390_regsets[] = { [REGSET_GENERAL] = { .core_note_type = NT_PRSTATUS, @@ -814,6 +845,15 @@ static const struct user_regset s390_regsets[] = { .get = s390_fpregs_get, .set = s390_fpregs_set, }, +#ifdef CONFIG_64BIT + [REGSET_LAST_BREAK] = { + .core_note_type = NT_S390_LAST_BREAK, + .n = 1, + .size = sizeof(long), + .align = sizeof(long), + .get = s390_last_break_get, + }, +#endif }; static const struct user_regset_view user_s390_view = { @@ -948,6 +988,27 @@ static int s390_compat_regs_high_set(struct task_struct *target, return rc; } +static int s390_compat_last_break_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + compat_ulong_t last_break; + + if (count > 0) { + last_break = task_thread_info(target)->last_break; + if (kbuf) { + unsigned long *k = kbuf; + *k = last_break; + } else { + unsigned long __user *u = ubuf; + if (__put_user(last_break, u)) + return -EFAULT; + } + } + return 0; +} + static const struct user_regset s390_compat_regsets[] = { [REGSET_GENERAL] = { .core_note_type = NT_PRSTATUS, @@ -965,6 +1026,13 @@ static const struct user_regset s390_compat_regsets[] = { .get = s390_fpregs_get, .set = s390_fpregs_set, }, + [REGSET_LAST_BREAK] = { + .core_note_type = NT_S390_LAST_BREAK, + .n = 1, + .size = sizeof(long), + .align = sizeof(long), + .get = s390_compat_last_break_get, + }, [REGSET_GENERAL_EXTENDED] = { .core_note_type = NT_S390_HIGH_GPRS, .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t), diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 6289945562b0..ee7ac8b11782 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -313,6 +313,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, To avoid breaking binary compatibility, they are passed as args. */ regs->gprs[4] = current->thread.trap_no; regs->gprs[5] = current->thread.prot_addr; + regs->gprs[6] = task_thread_info(current)->last_break; /* Place signal number on stack to allow backtrace from handler. */ if (__put_user(regs->gprs[2], (int __user *) &frame->signo)) @@ -376,6 +377,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->gprs[2] = map_signal(sig); regs->gprs[3] = (unsigned long) &frame->info; regs->gprs[4] = (unsigned long) &frame->uc; + regs->gprs[5] = task_thread_info(current)->last_break; return 0; give_sigsegv: diff --git a/include/linux/elf.h b/include/linux/elf.h index 597858418051..4d608014753a 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -394,6 +394,7 @@ typedef struct elf64_shdr { #define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */ #define NT_S390_CTRS 0x304 /* s390 control registers */ #define NT_S390_PREFIX 0x305 /* s390 prefix register */ +#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ /* Note header in a PT_NOTE section */ -- cgit v1.2.3-59-g8ed1b From 58ea91c05346f7c6336e6248b743aa9a8e1c19a9 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 17 May 2010 10:00:07 +0200 Subject: [S390] avoid default_llseek in s390 drivers Use nonseekable_open for a couple of s390 device drivers. This avoids the use of default_llseek function which has a dependency on the BKL. Signed-off-by: Martin Schwidefsky --- arch/s390/hypfs/inode.c | 2 +- arch/s390/kernel/debug.c | 1 + drivers/s390/char/fs3270.c | 1 + drivers/s390/char/zcore.c | 4 ++-- drivers/s390/cio/chsc_sch.c | 1 + drivers/s390/cio/css.c | 1 + drivers/s390/crypto/zcrypt_api.c | 2 +- drivers/s390/scsi/zfcp_cfdc.c | 1 + 8 files changed, 9 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index c53f8ac825ca..95c1aaac06cd 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -145,7 +145,7 @@ static int hypfs_open(struct inode *inode, struct file *filp) } mutex_unlock(&fs_info->lock); } - return 0; + return nonseekable_open(inode, filp); } static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov, diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 0168472b2fdf..98192261491d 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -655,6 +655,7 @@ found: p_info->act_entry_offset = 0; file->private_data = p_info; debug_info_get(debug_info); + nonseekable_open(inode, file); out: mutex_unlock(&debug_mutex); return rc; diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 0eabcca3c92d..857dfcb7b359 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -484,6 +484,7 @@ fs3270_open(struct inode *inode, struct file *filp) raw3270_del_view(&fp->view); goto out; } + nonseekable_open(inode, filp); filp->private_data = fp; out: mutex_unlock(&fs3270_mutex); diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 7217966f7d31..f5ea3384a4b9 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -445,7 +445,7 @@ static int zcore_memmap_open(struct inode *inode, struct file *filp) } kfree(chunk_array); filp->private_data = buf; - return 0; + return nonseekable_open(inode, filp); } static int zcore_memmap_release(struct inode *inode, struct file *filp) @@ -473,7 +473,7 @@ static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf, static int zcore_reipl_open(struct inode *inode, struct file *filp) { - return 0; + return nonseekable_open(inode, filp); } static int zcore_reipl_release(struct inode *inode, struct file *filp) diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 3b6f4adc5094..a83877c664a6 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -803,6 +803,7 @@ static long chsc_ioctl(struct file *filp, unsigned int cmd, static const struct file_operations chsc_fops = { .owner = THIS_MODULE, + .open = nonseekable_open, .unlocked_ioctl = chsc_ioctl, .compat_ioctl = chsc_ioctl, }; diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index da6df0483289..ac94ac751459 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -1065,6 +1065,7 @@ static ssize_t cio_settle_write(struct file *file, const char __user *buf, } static const struct file_operations cio_settle_proc_fops = { + .open = nonseekable_open, .write = cio_settle_write, }; diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 304caf549973..41e0aaefafd5 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -302,7 +302,7 @@ static ssize_t zcrypt_write(struct file *filp, const char __user *buf, static int zcrypt_open(struct inode *inode, struct file *filp) { atomic_inc(&zcrypt_open_count); - return 0; + return nonseekable_open(inode, filp); } /** diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index 25d9e0ae9c57..1a2db0a35737 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c @@ -254,6 +254,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, } static const struct file_operations zfcp_cfdc_fops = { + .open = nonseekable_open, .unlocked_ioctl = zfcp_cfdc_dev_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = zfcp_cfdc_dev_ioctl -- cgit v1.2.3-59-g8ed1b From a78f1c4c1dc4b9dedd17c46dd414f26c7bf1e503 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Mon, 17 May 2010 10:00:08 +0200 Subject: [S390] vdso: remove redundant check for CONFIG_64BIT This is a check for CONFIG_64BIT inside a block that is only active when CONFIG_64BIT is set. So the check is actually useless and potentially irritating. Signed-off-by: Christoph Egger Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/vdso.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 6bc9c197aa91..6b83870507d5 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -102,11 +102,7 @@ static void vdso_init_per_cpu_data(int cpu, struct vdso_per_cpu_data *vpcd) /* * Allocate/free per cpu vdso data. */ -#ifdef CONFIG_64BIT #define SEGMENT_ORDER 2 -#else -#define SEGMENT_ORDER 1 -#endif int vdso_alloc_per_cpu(int cpu, struct _lowcore *lowcore) { -- cgit v1.2.3-59-g8ed1b From f3cb31e495668eae568c584c666631e26c68bdea Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Mon, 17 May 2010 10:00:09 +0200 Subject: [S390] vdso: add missing vdso_install target Add missing vdso_install target to install the unstripped vdso images into $(MODLIB)/vdso/. These files are helpful when containing additional debugging information. Signed-off-by: Hendrik Brueckner Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 0da10746e0e5..30c5f01f93b0 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -116,6 +116,12 @@ image bzImage: vmlinux zfcpdump: $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +vdso_install: +ifeq ($(CONFIG_64BIT),y) + $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@ +endif + $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@ + archclean: $(Q)$(MAKE) $(clean)=$(boot) -- cgit v1.2.3-59-g8ed1b From 10d3858950557cd3cc05f647ede597114c610177 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 17 May 2010 10:00:12 +0200 Subject: [S390] topology: expose core identifier Provide a topology_core_id define which makes sure that the contents of /sys/devices/system/cpu/cpuX/topology/core_id indeed do contain the core id and not always 0. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/topology.h | 2 ++ arch/s390/kernel/topology.c | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index 6e7211abd950..dc8a67297d0f 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h @@ -7,8 +7,10 @@ const struct cpumask *cpu_coregroup_mask(unsigned int cpu); +extern unsigned char cpu_core_id[NR_CPUS]; extern cpumask_t cpu_core_map[NR_CPUS]; +#define topology_core_id(cpu) (cpu_core_id[cpu]) #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) int topology_set_cpu_management(int fc); diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 247b4c2d1e51..bcef00766a64 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -37,7 +37,8 @@ struct tl_cpu { }; struct tl_container { - unsigned char reserved[8]; + unsigned char reserved[7]; + unsigned char id; }; union tl_entry { @@ -58,6 +59,7 @@ struct tl_info { struct core_info { struct core_info *next; + unsigned char id; cpumask_t mask; }; @@ -73,6 +75,7 @@ static DECLARE_WORK(topology_work, topology_work_fn); static DEFINE_SPINLOCK(topology_lock); cpumask_t cpu_core_map[NR_CPUS]; +unsigned char cpu_core_id[NR_CPUS]; static cpumask_t cpu_coregroup_map(unsigned int cpu) { @@ -116,6 +119,7 @@ static void add_cpus_to_core(struct tl_cpu *tl_cpu, struct core_info *core) for_each_present_cpu(lcpu) { if (cpu_logical_map(lcpu) == rcpu) { cpu_set(lcpu, core->mask); + cpu_core_id[lcpu] = core->id; smp_cpu_polarization[lcpu] = tl_cpu->pp; } } @@ -158,6 +162,7 @@ static void tl_to_cores(struct tl_info *info) break; case 1: core = core->next; + core->id = tle->container.id; break; case 0: add_cpus_to_core(&tle->cpu, core); -- cgit v1.2.3-59-g8ed1b From 6ea50968274673ea7b58695efec2eeb55ca2f5dd Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 17 May 2010 10:00:13 +0200 Subject: [S390] user space fault: report fault before calling do_exit Report user space faults before calling do_exit, since do_exit does not return and therefore we will never see the fault message on the console. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 6e7ad63854c0..e605f070610c 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -390,8 +390,8 @@ static void default_trap_handler(struct pt_regs * regs, long interruption_code) { if (regs->psw.mask & PSW_MASK_PSTATE) { local_irq_enable(); - do_exit(SIGSEGV); report_user_fault(interruption_code, regs); + do_exit(SIGSEGV); } else die("Unknown program exception", regs, interruption_code); } -- cgit v1.2.3-59-g8ed1b From cc961d400e06e78c7aa39aeab1f001eb8f76ef90 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Mon, 17 May 2010 10:00:19 +0200 Subject: [S390] qdio: remove API wrappers Remove qdio API wrappers used by qeth and replace them by calling the appropriate functions directly. Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/qdio.h | 2 -- drivers/s390/cio/qdio_main.c | 46 --------------------------------------- drivers/s390/net/qeth_core_main.c | 17 +++++++++++---- 3 files changed, 13 insertions(+), 52 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index 9b04b1102bbc..0eaae6260274 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h @@ -368,14 +368,12 @@ struct qdio_initialize { #define QDIO_FLAG_SYNC_OUTPUT 0x02 #define QDIO_FLAG_PCI_OUT 0x10 -extern int qdio_initialize(struct qdio_initialize *); extern int qdio_allocate(struct qdio_initialize *); extern int qdio_establish(struct qdio_initialize *); extern int qdio_activate(struct ccw_device *); extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags, int q_nr, unsigned int bufnr, unsigned int count); -extern int qdio_cleanup(struct ccw_device*, int); extern int qdio_shutdown(struct ccw_device*, int); extern int qdio_free(struct ccw_device *); extern int qdio_get_ssqd_desc(struct ccw_device *dev, struct qdio_ssqd_desc*); diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index dafb3e5bdad7..00520f9a7a8e 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -1023,30 +1023,6 @@ int qdio_get_ssqd_desc(struct ccw_device *cdev, } EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc); -/** - * qdio_cleanup - shutdown queues and free data structures - * @cdev: associated ccw device - * @how: use halt or clear to shutdown - * - * This function calls qdio_shutdown() for @cdev with method @how. - * and qdio_free(). The qdio_free() return value is ignored since - * !irq_ptr is already checked. - */ -int qdio_cleanup(struct ccw_device *cdev, int how) -{ - struct qdio_irq *irq_ptr = cdev->private->qdio_data; - int rc; - - if (!irq_ptr) - return -ENODEV; - - rc = qdio_shutdown(cdev, how); - - qdio_free(cdev); - return rc; -} -EXPORT_SYMBOL_GPL(qdio_cleanup); - static void qdio_shutdown_queues(struct ccw_device *cdev) { struct qdio_irq *irq_ptr = cdev->private->qdio_data; @@ -1163,28 +1139,6 @@ int qdio_free(struct ccw_device *cdev) } EXPORT_SYMBOL_GPL(qdio_free); -/** - * qdio_initialize - allocate and establish queues for a qdio subchannel - * @init_data: initialization data - * - * This function first allocates queues via qdio_allocate() and on success - * establishes them via qdio_establish(). - */ -int qdio_initialize(struct qdio_initialize *init_data) -{ - int rc; - - rc = qdio_allocate(init_data); - if (rc) - return rc; - - rc = qdio_establish(init_data); - if (rc) - qdio_free(init_data->cdev); - return rc; -} -EXPORT_SYMBOL_GPL(qdio_initialize); - /** * qdio_allocate - allocate qdio queues and associated data * @init_data: initialization data diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3ba738b2e271..28f71349fdec 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1292,13 +1292,14 @@ int qeth_qdio_clear_card(struct qeth_card *card, int use_halt) QETH_QDIO_CLEANING)) { case QETH_QDIO_ESTABLISHED: if (card->info.type == QETH_CARD_TYPE_IQD) - rc = qdio_cleanup(CARD_DDEV(card), + rc = qdio_shutdown(CARD_DDEV(card), QDIO_FLAG_CLEANUP_USING_HALT); else - rc = qdio_cleanup(CARD_DDEV(card), + rc = qdio_shutdown(CARD_DDEV(card), QDIO_FLAG_CLEANUP_USING_CLEAR); if (rc) QETH_DBF_TEXT_(TRACE, 3, "1err%d", rc); + qdio_free(CARD_DDEV(card)); atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED); break; case QETH_QDIO_CLEANING: @@ -3810,10 +3811,18 @@ static int qeth_qdio_establish(struct qeth_card *card) if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED, QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) { - rc = qdio_initialize(&init_data); - if (rc) + rc = qdio_allocate(&init_data); + if (rc) { + atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED); + goto out; + } + rc = qdio_establish(&init_data); + if (rc) { atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED); + qdio_free(CARD_DDEV(card)); + } } +out: kfree(out_sbal_ptrs); kfree(in_sbal_ptrs); kfree(qib_param_field); -- cgit v1.2.3-59-g8ed1b From 57b28f66316d287b9dbf7b28358ca90257230769 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Mon, 17 May 2010 10:00:20 +0200 Subject: [S390] s390_hypfs: Add new attributes In order to access the data of the hypfs diagnose calls from user space also in binary form, this patch adds two new attributes in debugfs: * z/VM: s390_hypfs/d2fc_bin * LPAR: s390_hypfs/d204_bin Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/hypfs/hypfs.h | 4 ++ arch/s390/hypfs/hypfs_diag.c | 123 +++++++++++++++++++++++++++++++++++++++--- arch/s390/hypfs/hypfs_vm.c | 87 +++++++++++++++++++++++++++--- arch/s390/hypfs/inode.c | 40 ++++++++------ arch/s390/include/asm/timex.h | 8 ++- 5 files changed, 230 insertions(+), 32 deletions(-) (limited to 'arch') diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h index aea572009d60..fa487d4cc08b 100644 --- a/arch/s390/hypfs/hypfs.h +++ b/arch/s390/hypfs/hypfs.h @@ -11,6 +11,7 @@ #include #include +#include #define REG_FILE_MODE 0440 #define UPDATE_FILE_MODE 0220 @@ -34,6 +35,9 @@ extern int hypfs_diag_create_files(struct super_block *sb, struct dentry *root); /* VM Hypervisor */ extern int hypfs_vm_init(void); +extern void hypfs_vm_exit(void); extern int hypfs_vm_create_files(struct super_block *sb, struct dentry *root); +/* Directory for debugfs files */ +extern struct dentry *hypfs_dbfs_dir; #endif /* _HYPFS_H_ */ diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 5b1acdba6495..1211bb1d2f24 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "hypfs.h" @@ -22,6 +23,8 @@ #define CPU_NAME_LEN 16 /* type name len of cpus in diag224 name table */ #define TMP_SIZE 64 /* size of temporary buffers */ +#define DBFS_D204_HDR_VERSION 0 + /* diag 204 subcodes */ enum diag204_sc { SUBC_STIB4 = 4, @@ -47,6 +50,8 @@ static void *diag204_buf; /* 4K aligned buffer for diag204 data */ static void *diag204_buf_vmalloc; /* vmalloc pointer for diag204 data */ static int diag204_buf_pages; /* number of pages for diag204 data */ +static struct dentry *dbfs_d204_file; + /* * DIAG 204 data structures and member access functions. * @@ -364,18 +369,21 @@ static void diag204_free_buffer(void) } else { free_pages((unsigned long) diag204_buf, 0); } - diag204_buf_pages = 0; diag204_buf = NULL; } +static void *page_align_ptr(void *ptr) +{ + return (void *) PAGE_ALIGN((unsigned long) ptr); +} + static void *diag204_alloc_vbuf(int pages) { /* The buffer has to be page aligned! */ diag204_buf_vmalloc = vmalloc(PAGE_SIZE * (pages + 1)); if (!diag204_buf_vmalloc) return ERR_PTR(-ENOMEM); - diag204_buf = (void*)((unsigned long)diag204_buf_vmalloc - & ~0xfffUL) + 0x1000; + diag204_buf = page_align_ptr(diag204_buf_vmalloc); diag204_buf_pages = pages; return diag204_buf; } @@ -468,17 +476,26 @@ fail_alloc: return rc; } +static int diag204_do_store(void *buf, int pages) +{ + int rc; + + rc = diag204((unsigned long) diag204_store_sc | + (unsigned long) diag204_info_type, pages, buf); + return rc < 0 ? -ENOSYS : 0; +} + static void *diag204_store(void) { void *buf; - int pages; + int pages, rc; buf = diag204_get_buffer(diag204_info_type, &pages); if (IS_ERR(buf)) goto out; - if (diag204((unsigned long)diag204_store_sc | - (unsigned long)diag204_info_type, pages, buf) < 0) - return ERR_PTR(-ENOSYS); + rc = diag204_do_store(buf, pages); + if (rc) + return ERR_PTR(rc); out: return buf; } @@ -526,6 +543,92 @@ static int diag224_idx2name(int index, char *name) return 0; } +struct dbfs_d204_hdr { + u64 len; /* Length of d204 buffer without header */ + u16 version; /* Version of header */ + u8 sc; /* Used subcode */ + char reserved[53]; +} __attribute__ ((packed)); + +struct dbfs_d204 { + struct dbfs_d204_hdr hdr; /* 64 byte header */ + char buf[]; /* d204 buffer */ +} __attribute__ ((packed)); + +struct dbfs_d204_private { + struct dbfs_d204 *d204; /* Aligned d204 data with header */ + void *base; /* Base pointer (needed for vfree) */ +}; + +static int dbfs_d204_open(struct inode *inode, struct file *file) +{ + struct dbfs_d204_private *data; + struct dbfs_d204 *d204; + int rc, buf_size; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + buf_size = PAGE_SIZE * (diag204_buf_pages + 1) + sizeof(d204->hdr); + data->base = vmalloc(buf_size); + if (!data->base) { + rc = -ENOMEM; + goto fail_kfree_data; + } + memset(data->base, 0, buf_size); + d204 = page_align_ptr(data->base + sizeof(d204->hdr)) + - sizeof(d204->hdr); + rc = diag204_do_store(&d204->buf, diag204_buf_pages); + if (rc) + goto fail_vfree_base; + d204->hdr.version = DBFS_D204_HDR_VERSION; + d204->hdr.len = PAGE_SIZE * diag204_buf_pages; + d204->hdr.sc = diag204_store_sc; + data->d204 = d204; + file->private_data = data; + return nonseekable_open(inode, file); + +fail_vfree_base: + vfree(data->base); +fail_kfree_data: + kfree(data); + return rc; +} + +static int dbfs_d204_release(struct inode *inode, struct file *file) +{ + struct dbfs_d204_private *data = file->private_data; + + vfree(data->base); + kfree(data); + return 0; +} + +static ssize_t dbfs_d204_read(struct file *file, char __user *buf, + size_t size, loff_t *ppos) +{ + struct dbfs_d204_private *data = file->private_data; + + return simple_read_from_buffer(buf, size, ppos, data->d204, + data->d204->hdr.len + + sizeof(data->d204->hdr)); +} + +static const struct file_operations dbfs_d204_ops = { + .open = dbfs_d204_open, + .read = dbfs_d204_read, + .release = dbfs_d204_release, +}; + +static int hypfs_dbfs_init(void) +{ + dbfs_d204_file = debugfs_create_file("diag_204", 0400, hypfs_dbfs_dir, + NULL, &dbfs_d204_ops); + if (IS_ERR(dbfs_d204_file)) + return PTR_ERR(dbfs_d204_file); + return 0; +} + __init int hypfs_diag_init(void) { int rc; @@ -540,11 +643,17 @@ __init int hypfs_diag_init(void) pr_err("The hardware system does not provide all " "functions required by hypfs\n"); } + if (diag204_info_type == INFO_EXT) { + rc = hypfs_dbfs_init(); + if (rc) + diag204_free_buffer(); + } return rc; } void hypfs_diag_exit(void) { + debugfs_remove(dbfs_d204_file); diag224_delete_name_table(); diag204_free_buffer(); } diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c index f0b0d31f0b48..ee5ab1a578e7 100644 --- a/arch/s390/hypfs/hypfs_vm.c +++ b/arch/s390/hypfs/hypfs_vm.c @@ -10,14 +10,18 @@ #include #include #include +#include #include "hypfs.h" #define NAME_LEN 8 +#define DBFS_D2FC_HDR_VERSION 0 static char local_guest[] = " "; static char all_guests[] = "* "; static char *guest_query; +static struct dentry *dbfs_d2fc_file; + struct diag2fc_data { __u32 version; __u32 flags; @@ -76,23 +80,26 @@ static int diag2fc(int size, char* query, void *addr) return -residual_cnt; } -static struct diag2fc_data *diag2fc_store(char *query, int *count) +/* + * Allocate buffer for "query" and store diag 2fc at "offset" + */ +static void *diag2fc_store(char *query, unsigned int *count, int offset) { + void *data; int size; - struct diag2fc_data *data; do { size = diag2fc(0, query, NULL); if (size < 0) return ERR_PTR(-EACCES); - data = vmalloc(size); + data = vmalloc(size + offset); if (!data) return ERR_PTR(-ENOMEM); - if (diag2fc(size, query, data) == 0) + if (diag2fc(size, query, data + offset) == 0) break; vfree(data); } while (1); - *count = (size / sizeof(*data)); + *count = (size / sizeof(struct diag2fc_data)); return data; } @@ -168,9 +175,10 @@ int hypfs_vm_create_files(struct super_block *sb, struct dentry *root) { struct dentry *dir, *file; struct diag2fc_data *data; - int rc, i, count = 0; + unsigned int count = 0; + int rc, i; - data = diag2fc_store(guest_query, &count); + data = diag2fc_store(guest_query, &count, 0); if (IS_ERR(data)) return PTR_ERR(data); @@ -218,8 +226,61 @@ failed: return rc; } +struct dbfs_d2fc_hdr { + u64 len; /* Length of d2fc buffer without header */ + u16 version; /* Version of header */ + char tod_ext[16]; /* TOD clock for d2fc */ + u64 count; /* Number of VM guests in d2fc buffer */ + char reserved[30]; +} __attribute__ ((packed)); + +struct dbfs_d2fc { + struct dbfs_d2fc_hdr hdr; /* 64 byte header */ + char buf[]; /* d2fc buffer */ +} __attribute__ ((packed)); + +static int dbfs_d2fc_open(struct inode *inode, struct file *file) +{ + struct dbfs_d2fc *data; + unsigned int count; + + data = diag2fc_store(guest_query, &count, sizeof(data->hdr)); + if (IS_ERR(data)) + return PTR_ERR(data); + get_clock_ext(data->hdr.tod_ext); + data->hdr.len = count * sizeof(struct diag2fc_data); + data->hdr.version = DBFS_D2FC_HDR_VERSION; + data->hdr.count = count; + memset(&data->hdr.reserved, 0, sizeof(data->hdr.reserved)); + file->private_data = data; + return nonseekable_open(inode, file); +} + +static int dbfs_d2fc_release(struct inode *inode, struct file *file) +{ + diag2fc_free(file->private_data); + return 0; +} + +static ssize_t dbfs_d2fc_read(struct file *file, char __user *buf, + size_t size, loff_t *ppos) +{ + struct dbfs_d2fc *data = file->private_data; + + return simple_read_from_buffer(buf, size, ppos, data, data->hdr.len + + sizeof(struct dbfs_d2fc_hdr)); +} + +static const struct file_operations dbfs_d2fc_ops = { + .open = dbfs_d2fc_open, + .read = dbfs_d2fc_read, + .release = dbfs_d2fc_release, +}; + int hypfs_vm_init(void) { + if (!MACHINE_IS_VM) + return 0; if (diag2fc(0, all_guests, NULL) > 0) guest_query = all_guests; else if (diag2fc(0, local_guest, NULL) > 0) @@ -227,5 +288,17 @@ int hypfs_vm_init(void) else return -EACCES; + dbfs_d2fc_file = debugfs_create_file("diag_2fc", 0400, hypfs_dbfs_dir, + NULL, &dbfs_d2fc_ops); + if (IS_ERR(dbfs_d2fc_file)) + return PTR_ERR(dbfs_d2fc_file); + return 0; } + +void hypfs_vm_exit(void) +{ + if (!MACHINE_IS_VM) + return; + debugfs_remove(dbfs_d2fc_file); +} diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 95c1aaac06cd..6b120f073043 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -46,6 +46,8 @@ static const struct super_operations hypfs_s_ops; /* start of list of all dentries, which have to be deleted on update */ static struct dentry *hypfs_last_dentry; +struct dentry *hypfs_dbfs_dir; + static void hypfs_update_update(struct super_block *sb) { struct hypfs_sb_info *sb_info = sb->s_fs_info; @@ -468,20 +470,22 @@ static int __init hypfs_init(void) { int rc; - if (MACHINE_IS_VM) { - if (hypfs_vm_init()) - /* no diag 2fc, just exit */ - return -ENODATA; - } else { - if (hypfs_diag_init()) { - rc = -ENODATA; - goto fail_diag; - } + hypfs_dbfs_dir = debugfs_create_dir("s390_hypfs", NULL); + if (IS_ERR(hypfs_dbfs_dir)) + return PTR_ERR(hypfs_dbfs_dir); + + if (hypfs_diag_init()) { + rc = -ENODATA; + goto fail_debugfs_remove; + } + if (hypfs_vm_init()) { + rc = -ENODATA; + goto fail_hypfs_diag_exit; } s390_kobj = kobject_create_and_add("s390", hypervisor_kobj); if (!s390_kobj) { rc = -ENOMEM; - goto fail_sysfs; + goto fail_hypfs_vm_exit; } rc = register_filesystem(&hypfs_type); if (rc) @@ -490,18 +494,22 @@ static int __init hypfs_init(void) fail_filesystem: kobject_put(s390_kobj); -fail_sysfs: - if (!MACHINE_IS_VM) - hypfs_diag_exit(); -fail_diag: +fail_hypfs_vm_exit: + hypfs_vm_exit(); +fail_hypfs_diag_exit: + hypfs_diag_exit(); +fail_debugfs_remove: + debugfs_remove(hypfs_dbfs_dir); + pr_err("Initialization of hypfs failed with rc=%i\n", rc); return rc; } static void __exit hypfs_exit(void) { - if (!MACHINE_IS_VM) - hypfs_diag_exit(); + hypfs_diag_exit(); + hypfs_vm_exit(); + debugfs_remove(hypfs_dbfs_dir); unregister_filesystem(&hypfs_type); kobject_put(s390_kobj); } diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index f174bdaa6b59..09d345a701dc 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -61,11 +61,15 @@ static inline unsigned long long get_clock (void) return clk; } +static inline void get_clock_ext(char *clk) +{ + asm volatile("stcke %0" : "=Q" (*clk) : : "cc"); +} + static inline unsigned long long get_clock_xt(void) { unsigned char clk[16]; - - asm volatile("stcke %0" : "=Q" (clk) : : "cc"); + get_clock_ext(clk); return *((unsigned long long *)&clk[1]); } -- cgit v1.2.3-59-g8ed1b From ab3c68ee5fd329ba48094d3417fd60e30ea14a87 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 17 May 2010 10:00:21 +0200 Subject: [S390] debug: enable exception-trace debug facility The exception-trace facility on x86 and other architectures prints traces to dmesg whenever a user space application crashes. s390 has such a feature since ages however it is called userprocess_debug and is enabled differently. This patch makes sure that whenever one of the two procfs files /proc/sys/kernel/userprocess_debug /proc/sys/debug/exception-trace is modified the contents of the second one changes as well. That way we keep backwards compatibilty but also support the same interface like other architectures do. Besides that the output of the traces is improved since it will now also contain the corresponding filename of the vma (when available) where the process caused a fault or trap. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 7 ------- arch/s390/kernel/traps.c | 31 +++++++++++++------------------ arch/s390/mm/fault.c | 32 +++++++++++++++++--------------- kernel/sysctl.c | 5 +++-- 4 files changed, 33 insertions(+), 42 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 0d8cd9bbe101..79d0ca086820 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -444,13 +444,6 @@ config FORCE_MAX_ZONEORDER int default "9" -config PROCESS_DEBUG - bool "Show crashed user process info" - help - Say Y to print all process fault locations to the console. This is - a debugging option; you probably do not want to set it unless you - are an S390 port maintainer. - config PFAULT bool "Pseudo page fault support" help diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index e605f070610c..5d8f0f3d0250 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -46,13 +46,7 @@ pgm_check_handler_t *pgm_check_table[128]; -#ifdef CONFIG_SYSCTL -#ifdef CONFIG_PROCESS_DEBUG -int sysctl_userprocess_debug = 1; -#else -int sysctl_userprocess_debug = 0; -#endif -#endif +int show_unhandled_signals; extern pgm_check_handler_t do_protection_exception; extern pgm_check_handler_t do_dat_exception; @@ -315,18 +309,19 @@ void die(const char * str, struct pt_regs * regs, long err) do_exit(SIGSEGV); } -static void inline -report_user_fault(long interruption_code, struct pt_regs *regs) +static void inline report_user_fault(struct pt_regs *regs, long int_code, + int signr) { -#if defined(CONFIG_SYSCTL) - if (!sysctl_userprocess_debug) + if ((task_pid_nr(current) > 1) && !show_unhandled_signals) return; -#endif -#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG) - printk("User process fault: interruption code 0x%lX\n", - interruption_code); + if (!unhandled_signal(current, signr)) + return; + if (!printk_ratelimit()) + return; + printk("User process fault: interruption code 0x%lX ", int_code); + print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); + printk("\n"); show_regs(regs); -#endif } int is_valid_bugaddr(unsigned long addr) @@ -354,7 +349,7 @@ static void __kprobes inline do_trap(long interruption_code, int signr, tsk->thread.trap_no = interruption_code & 0xffff; force_sig_info(signr, info, tsk); - report_user_fault(interruption_code, regs); + report_user_fault(regs, interruption_code, signr); } else { const struct exception_table_entry *fixup; fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); @@ -390,7 +385,7 @@ static void default_trap_handler(struct pt_regs * regs, long interruption_code) { if (regs->psw.mask & PSW_MASK_PSTATE) { local_irq_enable(); - report_user_fault(interruption_code, regs); + report_user_fault(regs, interruption_code, SIGSEGV); do_exit(SIGSEGV); } else die("Unknown program exception", regs, interruption_code); diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 3040d7c78fe0..2505b2ea0ef1 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -48,10 +48,6 @@ #define __PF_RES_FIELD 0x8000000000000000ULL #endif /* CONFIG_64BIT */ -#ifdef CONFIG_SYSCTL -extern int sysctl_userprocess_debug; -#endif - #define VM_FAULT_BADCONTEXT 0x010000 #define VM_FAULT_BADMAP 0x020000 #define VM_FAULT_BADACCESS 0x040000 @@ -120,6 +116,22 @@ static inline int user_space_fault(unsigned long trans_exc_code) return trans_exc_code != 3; } +static inline void report_user_fault(struct pt_regs *regs, long int_code, + int signr, unsigned long address) +{ + if ((task_pid_nr(current) > 1) && !show_unhandled_signals) + return; + if (!unhandled_signal(current, signr)) + return; + if (!printk_ratelimit()) + return; + printk("User process fault: interruption code 0x%lX ", int_code); + print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); + printk("\n"); + printk("failing address: %lX\n", address); + show_regs(regs); +} + /* * Send SIGSEGV to task. This is an external routine * to keep the stack usage of do_page_fault small. @@ -133,17 +145,7 @@ static noinline void do_sigsegv(struct pt_regs *regs, long int_code, address = trans_exc_code & __FAIL_ADDR_MASK; current->thread.prot_addr = address; current->thread.trap_no = int_code; -#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG) -#if defined(CONFIG_SYSCTL) - if (sysctl_userprocess_debug) -#endif - { - printk("User process fault: interruption code 0x%lX\n", - int_code); - printk("failing address: %lX\n", address); - show_regs(regs); - } -#endif + report_user_fault(regs, int_code, SIGSEGV, address); si.si_signo = SIGSEGV; si.si_code = si_code; si.si_addr = (void __user *) address; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 8686b0f5fc12..90f536d84643 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -621,7 +621,7 @@ static struct ctl_table kern_table[] = { #endif { .procname = "userprocess_debug", - .data = &sysctl_userprocess_debug, + .data = &show_unhandled_signals, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec, @@ -1431,7 +1431,8 @@ static struct ctl_table fs_table[] = { }; static struct ctl_table debug_table[] = { -#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) +#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \ + defined(CONFIG_S390) { .procname = "exception-trace", .data = &show_unhandled_signals, -- cgit v1.2.3-59-g8ed1b From 0fc5c3a54d68d0e6c2f3b346dcc924ba928c4d0e Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 27 Feb 2010 17:51:43 +0100 Subject: KVM: arch/x86/kvm/kvm_timer.h checkpatch cleanup arch/x86/kvm/kvm_timer.h:13: ERROR: code indent should use tabs where possible Signed-off-by: Andrea Gelmini Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/kvm_timer.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/kvm_timer.h b/arch/x86/kvm/kvm_timer.h index 55c7524dda54..64bc6ea78d90 100644 --- a/arch/x86/kvm/kvm_timer.h +++ b/arch/x86/kvm/kvm_timer.h @@ -10,9 +10,7 @@ struct kvm_timer { }; struct kvm_timer_ops { - bool (*is_periodic)(struct kvm_timer *); + bool (*is_periodic)(struct kvm_timer *); }; - enum hrtimer_restart kvm_timer_fn(struct hrtimer *data); - -- cgit v1.2.3-59-g8ed1b From d24778265ac9b2602889a5e99c6e7ba777a236df Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 1 Mar 2010 15:34:34 +0100 Subject: KVM: SVM: Return correct values in nested_svm_exit_handled_msr The nested_svm_exit_handled_msr() returned an bool which is a bug. I worked by accident because the exected integer return values match with the true and false values. This patch changes the return value to int and let the function return the correct values. Signed-off-by: Joerg Roedel Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/svm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 6882be5b9267..07437ca12787 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1552,16 +1552,16 @@ static void nested_svm_unmap(struct page *page) kvm_release_page_dirty(page); } -static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm) +static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) { u32 param = svm->vmcb->control.exit_info_1 & 1; u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; - bool ret = false; u32 t0, t1; + int ret; u8 val; if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) - return false; + return NESTED_EXIT_HOST; switch (msr) { case 0 ... 0x1fff: @@ -1579,12 +1579,12 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm) t0 %= 8; break; default: - ret = true; + ret = NESTED_EXIT_DONE; goto out; } if (!kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + t1, &val, 1)) - ret = val & ((1 << param) << t0); + ret = val & ((1 << param) << t0) ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; out: return ret; -- cgit v1.2.3-59-g8ed1b From 455716fa941ec7a03c04bd54e1b906698171b15c Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 1 Mar 2010 15:34:35 +0100 Subject: KVM: SVM: Move msrpm offset calculation to seperate function The algorithm to find the offset in the msrpm for a given msr is needed at other places too. Move that logic to its own function. Signed-off-by: Joerg Roedel Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/svm.c | 53 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 07437ca12787..429a24435c6d 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -117,6 +117,8 @@ struct vcpu_svm { unsigned long int3_rip; }; +#define MSR_INVALID 0xffffffffU + /* enable NPT for AMD64 and X86 with PAE */ #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) static bool npt_enabled = true; @@ -200,6 +202,27 @@ static u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000}; #define MSRS_RANGE_SIZE 2048 #define MSRS_IN_RANGE (MSRS_RANGE_SIZE * 8 / 2) +static u32 svm_msrpm_offset(u32 msr) +{ + u32 offset; + int i; + + for (i = 0; i < NUM_MSR_MAPS; i++) { + if (msr < msrpm_ranges[i] || + msr >= msrpm_ranges[i] + MSRS_IN_RANGE) + continue; + + offset = (msr - msrpm_ranges[i]) / 4; /* 4 msrs per u8 */ + offset += (i * MSRS_RANGE_SIZE); /* add range offset */ + + /* Now we have the u8 offset - but need the u32 offset */ + return offset / 4; + } + + /* MSR not in any range */ + return MSR_INVALID; +} + #define MAX_INST_SIZE 15 static inline u32 svm_has(u32 feat) @@ -418,23 +441,21 @@ err_1: static void set_msr_interception(u32 *msrpm, unsigned msr, int read, int write) { - int i; + u8 bit_read, bit_write; + unsigned long tmp; + u32 offset; - for (i = 0; i < NUM_MSR_MAPS; i++) { - if (msr >= msrpm_ranges[i] && - msr < msrpm_ranges[i] + MSRS_IN_RANGE) { - u32 msr_offset = (i * MSRS_IN_RANGE + msr - - msrpm_ranges[i]) * 2; - - u32 *base = msrpm + (msr_offset / 32); - u32 msr_shift = msr_offset % 32; - u32 mask = ((write) ? 0 : 2) | ((read) ? 0 : 1); - *base = (*base & ~(0x3 << msr_shift)) | - (mask << msr_shift); - return; - } - } - BUG(); + offset = svm_msrpm_offset(msr); + bit_read = 2 * (msr & 0x0f); + bit_write = 2 * (msr & 0x0f) + 1; + tmp = msrpm[offset]; + + BUG_ON(offset == MSR_INVALID); + + read ? clear_bit(bit_read, &tmp) : set_bit(bit_read, &tmp); + write ? clear_bit(bit_write, &tmp) : set_bit(bit_write, &tmp); + + msrpm[offset] = tmp; } static void svm_vcpu_init_msrpm(u32 *msrpm) -- cgit v1.2.3-59-g8ed1b From ac72a9b733995cb3ef538000f6309b5e724aa469 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 1 Mar 2010 15:34:36 +0100 Subject: KVM: SVM: Introduce direct access msr list This patch introduces a list with all msrs a guest might have direct access to and changes the svm_vcpu_init_msrpm function to use this list. It also adds a check to set_msr_interception which triggers a warning if a developer changes a msr intercept that is not in the list. Signed-off-by: Joerg Roedel Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/svm.c | 56 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 429a24435c6d..a079550d3886 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -119,6 +119,27 @@ struct vcpu_svm { #define MSR_INVALID 0xffffffffU +static struct svm_direct_access_msrs { + u32 index; /* Index of the MSR */ + bool always; /* True if intercept is always on */ +} direct_access_msrs[] = { + { .index = MSR_K6_STAR, .always = true }, + { .index = MSR_IA32_SYSENTER_CS, .always = true }, +#ifdef CONFIG_X86_64 + { .index = MSR_GS_BASE, .always = true }, + { .index = MSR_FS_BASE, .always = true }, + { .index = MSR_KERNEL_GS_BASE, .always = true }, + { .index = MSR_LSTAR, .always = true }, + { .index = MSR_CSTAR, .always = true }, + { .index = MSR_SYSCALL_MASK, .always = true }, +#endif + { .index = MSR_IA32_LASTBRANCHFROMIP, .always = false }, + { .index = MSR_IA32_LASTBRANCHTOIP, .always = false }, + { .index = MSR_IA32_LASTINTFROMIP, .always = false }, + { .index = MSR_IA32_LASTINTTOIP, .always = false }, + { .index = MSR_INVALID, .always = false }, +}; + /* enable NPT for AMD64 and X86 with PAE */ #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) static bool npt_enabled = true; @@ -438,6 +459,17 @@ err_1: } +static bool valid_msr_intercept(u32 index) +{ + int i; + + for (i = 0; direct_access_msrs[i].index != MSR_INVALID; i++) + if (direct_access_msrs[i].index == index) + return true; + + return false; +} + static void set_msr_interception(u32 *msrpm, unsigned msr, int read, int write) { @@ -445,6 +477,12 @@ static void set_msr_interception(u32 *msrpm, unsigned msr, unsigned long tmp; u32 offset; + /* + * If this warning triggers extend the direct_access_msrs list at the + * beginning of the file + */ + WARN_ON(!valid_msr_intercept(msr)); + offset = svm_msrpm_offset(msr); bit_read = 2 * (msr & 0x0f); bit_write = 2 * (msr & 0x0f) + 1; @@ -460,18 +498,16 @@ static void set_msr_interception(u32 *msrpm, unsigned msr, static void svm_vcpu_init_msrpm(u32 *msrpm) { + int i; + memset(msrpm, 0xff, PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER)); -#ifdef CONFIG_X86_64 - set_msr_interception(msrpm, MSR_GS_BASE, 1, 1); - set_msr_interception(msrpm, MSR_FS_BASE, 1, 1); - set_msr_interception(msrpm, MSR_KERNEL_GS_BASE, 1, 1); - set_msr_interception(msrpm, MSR_LSTAR, 1, 1); - set_msr_interception(msrpm, MSR_CSTAR, 1, 1); - set_msr_interception(msrpm, MSR_SYSCALL_MASK, 1, 1); -#endif - set_msr_interception(msrpm, MSR_K6_STAR, 1, 1); - set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1); + for (i = 0; direct_access_msrs[i].index != MSR_INVALID; i++) { + if (!direct_access_msrs[i].always) + continue; + + set_msr_interception(msrpm, direct_access_msrs[i].index, 1, 1); + } } static void svm_enable_lbrv(struct vcpu_svm *svm) -- cgit v1.2.3-59-g8ed1b From 323c3d809b8bd42d6d557c734d4bdfdefa110445 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 1 Mar 2010 15:34:37 +0100 Subject: KVM: SVM: Optimize nested svm msrpm merging This patch optimizes the way the msrpm of the host and the guest are merged. The old code merged the 2 msrpm pages completly. This code needed to touch 24kb of memory for that operation. The optimized variant this patch introduces merges only the parts where the host msrpm may contain zero bits. This reduces the amount of memory which is touched to 48 bytes. Signed-off-by: Joerg Roedel Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/svm.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index a079550d3886..45a287e51e18 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -93,6 +93,9 @@ struct nested_state { }; +#define MSRPM_OFFSETS 16 +static u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; + struct vcpu_svm { struct kvm_vcpu vcpu; struct vmcb *vmcb; @@ -510,6 +513,49 @@ static void svm_vcpu_init_msrpm(u32 *msrpm) } } +static void add_msr_offset(u32 offset) +{ + int i; + + for (i = 0; i < MSRPM_OFFSETS; ++i) { + + /* Offset already in list? */ + if (msrpm_offsets[i] == offset) + return; + + /* Slot used by another offset? */ + if (msrpm_offsets[i] != MSR_INVALID) + continue; + + /* Add offset to list */ + msrpm_offsets[i] = offset; + + return; + } + + /* + * If this BUG triggers the msrpm_offsets table has an overflow. Just + * increase MSRPM_OFFSETS in this case. + */ + BUG(); +} + +static void init_msrpm_offsets(void) +{ + int i; + + memset(msrpm_offsets, 0xff, sizeof(msrpm_offsets)); + + for (i = 0; direct_access_msrs[i].index != MSR_INVALID; i++) { + u32 offset; + + offset = svm_msrpm_offset(direct_access_msrs[i].index); + BUG_ON(offset == MSR_INVALID); + + add_msr_offset(offset); + } +} + static void svm_enable_lbrv(struct vcpu_svm *svm) { u32 *msrpm = svm->msrpm; @@ -548,6 +594,8 @@ static __init int svm_hardware_setup(void) memset(iopm_va, 0xff, PAGE_SIZE * (1 << IOPM_ALLOC_ORDER)); iopm_base = page_to_pfn(iopm_pages) << PAGE_SHIFT; + init_msrpm_offsets(); + if (boot_cpu_has(X86_FEATURE_NX)) kvm_enable_efer_bits(EFER_NX); @@ -811,6 +859,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) svm_vcpu_init_msrpm(svm->msrpm); svm->nested.msrpm = page_address(nested_msrpm_pages); + svm_vcpu_init_msrpm(svm->nested.msrpm); svm->vmcb = page_address(page); clear_page(svm->vmcb); @@ -1888,20 +1937,33 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) { - u32 *nested_msrpm; - struct page *page; + /* + * This function merges the msr permission bitmaps of kvm and the + * nested vmcb. It is omptimized in that it only merges the parts where + * the kvm msr permission bitmap may contain zero bits + */ int i; - nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, &page); - if (!nested_msrpm) - return false; + if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) + return true; - for (i = 0; i < PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++) - svm->nested.msrpm[i] = svm->msrpm[i] | nested_msrpm[i]; + for (i = 0; i < MSRPM_OFFSETS; i++) { + u32 value, p; + u64 offset; - svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm); + if (msrpm_offsets[i] == 0xffffffff) + break; - nested_svm_unmap(page); + offset = svm->nested.vmcb_msrpm + msrpm_offsets[i]; + p = msrpm_offsets[i] / 4; + + if (kvm_read_guest(svm->vcpu.kvm, offset, &value, 4)) + return false; + + svm->nested.msrpm[p] = svm->msrpm[p] | value; + } + + svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm); return true; } -- cgit v1.2.3-59-g8ed1b From 0d6b35378e80c555e20ca3aa3d3cc609b403cbb6 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 1 Mar 2010 15:34:38 +0100 Subject: KVM: SVM: Use svm_msrpm_offset in nested_svm_exit_handled_msr There is a generic function now to calculate msrpm offsets. Use that function in nested_svm_exit_handled_msr() remove the duplicate logic (which had a bug anyway). Signed-off-by: Joerg Roedel Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/svm.c | 47 +++++++++++++++++------------------------------ 1 file changed, 17 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 45a287e51e18..7cb2eb906eca 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1660,40 +1660,27 @@ static void nested_svm_unmap(struct page *page) static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) { - u32 param = svm->vmcb->control.exit_info_1 & 1; - u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; - u32 t0, t1; - int ret; - u8 val; + u32 offset, msr, value; + int write, mask; if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) return NESTED_EXIT_HOST; - switch (msr) { - case 0 ... 0x1fff: - t0 = (msr * 2) % 8; - t1 = msr / 8; - break; - case 0xc0000000 ... 0xc0001fff: - t0 = (8192 + msr - 0xc0000000) * 2; - t1 = (t0 / 8); - t0 %= 8; - break; - case 0xc0010000 ... 0xc0011fff: - t0 = (16384 + msr - 0xc0010000) * 2; - t1 = (t0 / 8); - t0 %= 8; - break; - default: - ret = NESTED_EXIT_DONE; - goto out; - } + msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; + offset = svm_msrpm_offset(msr); + write = svm->vmcb->control.exit_info_1 & 1; + mask = 1 << ((2 * (msr & 0xf)) + write); - if (!kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + t1, &val, 1)) - ret = val & ((1 << param) << t0) ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; + if (offset == MSR_INVALID) + return NESTED_EXIT_DONE; -out: - return ret; + /* Offset is in 32 bit units but need in 8 bit units */ + offset *= 4; + + if (kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + offset, &value, 4)) + return NESTED_EXIT_DONE; + + return (value & mask) ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; } static int nested_svm_exit_special(struct vcpu_svm *svm) @@ -1954,8 +1941,8 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) if (msrpm_offsets[i] == 0xffffffff) break; - offset = svm->nested.vmcb_msrpm + msrpm_offsets[i]; - p = msrpm_offsets[i] / 4; + p = msrpm_offsets[i]; + offset = svm->nested.vmcb_msrpm + (p * 4); if (kvm_read_guest(svm->vcpu.kvm, offset, &value, 4)) return false; -- cgit v1.2.3-59-g8ed1b From ce2ac085ff1500aad157cabd8221b7c38eb751bd Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 1 Mar 2010 15:34:39 +0100 Subject: KVM; SVM: Add correct handling of nested iopm This patch adds the correct handling of the nested io permission bitmap. Old behavior was to not lookup the port in the iopm but only reinject an io intercept to the guest. Signed-off-by: Joerg Roedel Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/svm.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 7cb2eb906eca..ddea391e78cd 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -79,6 +79,7 @@ struct nested_state { /* gpa pointers to the real vectors */ u64 vmcb_msrpm; + u64 vmcb_iopm; /* A VMEXIT is required but not yet emulated */ bool exit_required; @@ -1658,6 +1659,26 @@ static void nested_svm_unmap(struct page *page) kvm_release_page_dirty(page); } +static int nested_svm_intercept_ioio(struct vcpu_svm *svm) +{ + unsigned port; + u8 val, bit; + u64 gpa; + + if (!(svm->nested.intercept & (1ULL << INTERCEPT_IOIO_PROT))) + return NESTED_EXIT_HOST; + + port = svm->vmcb->control.exit_info_1 >> 16; + gpa = svm->nested.vmcb_iopm + (port / 8); + bit = port % 8; + val = 0; + + if (kvm_read_guest(svm->vcpu.kvm, gpa, &val, 1)) + val &= (1 << bit); + + return val ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; +} + static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) { u32 offset, msr, value; @@ -1723,6 +1744,9 @@ static int nested_svm_intercept(struct vcpu_svm *svm) case SVM_EXIT_MSR: vmexit = nested_svm_exit_handled_msr(svm); break; + case SVM_EXIT_IOIO: + vmexit = nested_svm_intercept_ioio(svm); + break; case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: { u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0); if (svm->nested.intercept_cr_read & cr_bits) @@ -2047,6 +2071,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) svm->vmcb->save.cpl = nested_vmcb->save.cpl; svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa; + svm->nested.vmcb_iopm = nested_vmcb->control.iopm_base_pa & ~0x0fffULL; /* cache intercepts */ svm->nested.intercept_cr_read = nested_vmcb->control.intercept_cr_read; -- cgit v1.2.3-59-g8ed1b From f71385383fb86246ab3c69cc17a09ef9883590d8 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 1 Mar 2010 15:34:40 +0100 Subject: KVM: SVM: Ignore lower 12 bit of nested msrpm_pa These bits are ignored by the hardware too. Implement this for nested svm too. Signed-off-by: Joerg Roedel Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index ddea391e78cd..490bec199887 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2070,7 +2070,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) svm->vmcb->save.dr6 = nested_vmcb->save.dr6; svm->vmcb->save.cpl = nested_vmcb->save.cpl; - svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa; + svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa & ~0x0fffULL; svm->nested.vmcb_iopm = nested_vmcb->control.iopm_base_pa & ~0x0fffULL; /* cache intercepts */ -- cgit v1.2.3-59-g8ed1b From 835e6b80478e59820cff127adba3e518ae5a43f5 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Wed, 3 Mar 2010 17:53:05 +0200 Subject: KVM: x86 emulator mark VMMCALL and LMSW as privileged LMSW is present in both group tables. It was marked privileged only in one of them. Intel analog of VMMCALL is already marked privileged. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5b6794adaa2e..2832a8c07c6a 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -362,9 +362,9 @@ static u32 group_table[] = { static u32 group2_table[] = { [Group7*8] = - SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM, + SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM | Priv, SrcNone | ModRM | DstMem | Mov, 0, - SrcMem16 | ModRM | Mov, 0, + SrcMem16 | ModRM | Mov | Priv, 0, [Group9*8] = 0, 0, 0, 0, 0, 0, 0, 0, }; -- cgit v1.2.3-59-g8ed1b From 7b06bf2ffa15e119c7439ed0b024d44f66d7b605 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 9 Mar 2010 14:37:53 +0800 Subject: KVM: s390: Fix possible memory leak of in kvm_arch_vcpu_create() This patch fixed possible memory leak in kvm_arch_vcpu_create() under s390, which would happen when kvm_arch_vcpu_create() fails. Signed-off-by: Wei Yongjun Acked-by: Carsten Otte Cc: stable@kernel.org Signed-off-by: Avi Kivity --- arch/s390/kvm/kvm-s390.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 49292869a5cd..ee7c713686ce 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -341,11 +341,13 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, rc = kvm_vcpu_init(vcpu, kvm, id); if (rc) - goto out_free_cpu; + goto out_free_sie_block; VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu, vcpu->arch.sie_block); return vcpu; +out_free_sie_block: + free_page((unsigned long)(vcpu->arch.sie_block)); out_free_cpu: kfree(vcpu); out_nomem: -- cgit v1.2.3-59-g8ed1b From 06056bfb944a0302a8f22eb45f09123de7fb417b Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 9 Mar 2010 14:13:43 +0800 Subject: KVM: PPC: Do not create debugfs if fail to create vcpu If fail to create the vcpu, we should not create the debugfs for it. Signed-off-by: Wei Yongjun Acked-by: Alexander Graf Cc: stable@kernel.org Signed-off-by: Avi Kivity --- arch/powerpc/kvm/powerpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index ace31ca05245..3f8677e9d8f9 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -194,7 +194,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) { struct kvm_vcpu *vcpu; vcpu = kvmppc_core_vcpu_create(kvm, id); - kvmppc_create_vcpu_debugfs(vcpu, id); + if (!IS_ERR(vcpu)) + kvmppc_create_vcpu_debugfs(vcpu, id); return vcpu; } -- cgit v1.2.3-59-g8ed1b From 2ed152afc7ed61830b848b32936e1541a1a57799 Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Wed, 10 Mar 2010 19:00:43 +0800 Subject: KVM: cleanup kvm trace This patch does: - no need call tracepoint_synchronize_unregister() when kvm module is unloaded since ftrace can handle it - cleanup ftrace's macro Signed-off-by: Xiao Guangrong Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 1 - arch/x86/kvm/mmutrace.h | 7 +++++-- arch/x86/kvm/trace.h | 7 +++++-- arch/x86/kvm/x86.c | 2 +- include/trace/events/kvm.h | 1 - virt/kvm/kvm_main.c | 1 - 6 files changed, 11 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 19a8906bcaa2..3af2dfd8778e 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -148,7 +148,6 @@ module_param(oos_shadow, bool, 0644); #include -#undef TRACE_INCLUDE_FILE #define CREATE_TRACE_POINTS #include "mmutrace.h" diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h index 3e4a5c6ca2a9..1fe956ab7617 100644 --- a/arch/x86/kvm/mmutrace.h +++ b/arch/x86/kvm/mmutrace.h @@ -6,8 +6,6 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM kvmmmu -#define TRACE_INCLUDE_PATH . -#define TRACE_INCLUDE_FILE mmutrace #define KVM_MMU_PAGE_FIELDS \ __field(__u64, gfn) \ @@ -216,5 +214,10 @@ TRACE_EVENT( #endif /* _TRACE_KVMMMU_H */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE mmutrace + /* This part must be outside protection */ #include diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 17b52ccd9774..b75efef79e56 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -5,8 +5,6 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM kvm -#define TRACE_INCLUDE_PATH arch/x86/kvm -#define TRACE_INCLUDE_FILE trace /* * Tracepoint for guest mode entry. @@ -575,5 +573,10 @@ TRACE_EVENT(kvm_skinit, #endif /* _TRACE_KVM_H */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH arch/x86/kvm +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace + /* This part must be outside protection */ #include diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 2b34dc705cfb..74e70d975ffa 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -41,7 +41,7 @@ #include #include #include -#undef TRACE_INCLUDE_FILE + #define CREATE_TRACE_POINTS #include "trace.h" diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index b17d49dfc3ef..6dd3a51ab1cb 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -5,7 +5,6 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM kvm -#define TRACE_INCLUDE_FILE kvm #if defined(__KVM_HAVE_IOAPIC) TRACE_EVENT(kvm_set_irq, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 5bac6eb0f0a9..b152b23cd095 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2279,7 +2279,6 @@ EXPORT_SYMBOL_GPL(kvm_init); void kvm_exit(void) { - tracepoint_synchronize_unregister(); kvm_exit_debug(); misc_deregister(&kvm_dev); kmem_cache_destroy(kvm_vcpu_cache); -- cgit v1.2.3-59-g8ed1b From d4f64b6cad0fc0fb4cec868c6ca6b1325949d08b Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Wed, 10 Mar 2010 23:31:22 +0900 Subject: KVM: remove redundant initialization of page->private The prep_new_page() in page allocator calls set_page_private(page, 0). So we don't need to reinitialize private of page. Signed-off-by: Minchan Kim Cc: Avi Kivity Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 3af2dfd8778e..4455ddbe36f4 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -326,7 +326,6 @@ static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache, page = alloc_page(GFP_KERNEL); if (!page) return -ENOMEM; - set_page_private(page, 0); cache->objects[cache->nobjs++] = page_address(page); } return 0; -- cgit v1.2.3-59-g8ed1b From 5bfd8b5455e69b37af16a2df1edae2c3b567648c Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 11 Mar 2010 10:50:44 +0200 Subject: KVM: Move kvm_exit tracepoint rip reading inside tracepoint Reading rip is expensive on vmx, so move it inside the tracepoint so we only incur the cost if tracing is enabled. Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 2 +- arch/x86/kvm/trace.h | 6 +++--- arch/x86/kvm/vmx.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 490bec199887..abbc3f9d03b2 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2686,7 +2686,7 @@ static int handle_exit(struct kvm_vcpu *vcpu) struct kvm_run *kvm_run = vcpu->run; u32 exit_code = svm->vmcb->control.exit_code; - trace_kvm_exit(exit_code, svm->vmcb->save.rip); + trace_kvm_exit(exit_code, vcpu); if (unlikely(svm->nested.exit_required)) { nested_svm_vmexit(svm); diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index b75efef79e56..d10b359a21f3 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -182,8 +182,8 @@ TRACE_EVENT(kvm_apic, * Tracepoint for kvm guest exit: */ TRACE_EVENT(kvm_exit, - TP_PROTO(unsigned int exit_reason, unsigned long guest_rip), - TP_ARGS(exit_reason, guest_rip), + TP_PROTO(unsigned int exit_reason, struct kvm_vcpu *vcpu), + TP_ARGS(exit_reason, vcpu), TP_STRUCT__entry( __field( unsigned int, exit_reason ) @@ -192,7 +192,7 @@ TRACE_EVENT(kvm_exit, TP_fast_assign( __entry->exit_reason = exit_reason; - __entry->guest_rip = guest_rip; + __entry->guest_rip = kvm_rip_read(vcpu); ), TP_printk("reason %s rip 0x%lx", diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 8e2a24693be9..3dbfc20824b7 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3612,7 +3612,7 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu) u32 exit_reason = vmx->exit_reason; u32 vectoring_info = vmx->idt_vectoring_info; - trace_kvm_exit(exit_reason, kvm_rip_read(vcpu)); + trace_kvm_exit(exit_reason, vcpu); /* If guest state is invalid, start emulating */ if (vmx->emulation_required && emulate_invalid_guest_state) -- cgit v1.2.3-59-g8ed1b From 5c1c85d08da5c257b21b0423b96fa6554aa4cb6f Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 11 Mar 2010 13:01:59 +0200 Subject: KVM: Trace exception injection Often an exception can help point out where things start to go wrong. Signed-off-by: Avi Kivity --- arch/x86/kvm/trace.h | 32 ++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.c | 3 +++ 2 files changed, 35 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index d10b359a21f3..32c912c40bf8 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -219,6 +219,38 @@ TRACE_EVENT(kvm_inj_virq, TP_printk("irq %u", __entry->irq) ); +#define EXS(x) { x##_VECTOR, "#" #x } + +#define kvm_trace_sym_exc \ + EXS(DE), EXS(DB), EXS(BP), EXS(OF), EXS(BR), EXS(UD), EXS(NM), \ + EXS(DF), EXS(TS), EXS(NP), EXS(SS), EXS(GP), EXS(PF), \ + EXS(MF), EXS(MC) + +/* + * Tracepoint for kvm interrupt injection: + */ +TRACE_EVENT(kvm_inj_exception, + TP_PROTO(unsigned exception, bool has_error, unsigned error_code), + TP_ARGS(exception, has_error, error_code), + + TP_STRUCT__entry( + __field( u8, exception ) + __field( u8, has_error ) + __field( u32, error_code ) + ), + + TP_fast_assign( + __entry->exception = exception; + __entry->has_error = has_error; + __entry->error_code = error_code; + ), + + TP_printk("%s (0x%x)", + __print_symbolic(__entry->exception, kvm_trace_sym_exc), + /* FIXME: don't print error_code if not present */ + __entry->has_error ? __entry->error_code : 0) +); + /* * Tracepoint for page fault. */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 74e70d975ffa..a1cf87fe9f3a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4237,6 +4237,9 @@ static void inject_pending_event(struct kvm_vcpu *vcpu) { /* try to reinject previous events if any */ if (vcpu->arch.exception.pending) { + trace_kvm_inj_exception(vcpu->arch.exception.nr, + vcpu->arch.exception.has_error_code, + vcpu->arch.exception.error_code); kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, vcpu->arch.exception.has_error_code, vcpu->arch.exception.error_code); -- cgit v1.2.3-59-g8ed1b From ec68798c8fd0f01cdbd3f3e1a970e76a644cf08e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 5 Mar 2010 12:11:48 +0800 Subject: KVM: x86: Use native_store_idt() instead of kvm_get_idt() This patch use generic linux function native_store_idt() instead of kvm_get_idt(), and also removed the useless function kvm_get_idt(). Signed-off-by: Wei Yongjun Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 5 ----- arch/x86/kvm/vmx.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index ec891a2ce86e..ea1b6c615f9f 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -716,11 +716,6 @@ static inline void kvm_load_ldt(u16 sel) asm("lldt %0" : : "rm"(sel)); } -static inline void kvm_get_idt(struct desc_ptr *table) -{ - asm("sidt %0" : "=m"(*table)); -} - #ifdef CONFIG_X86_64 static inline unsigned long read_msr(unsigned long msr) { diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 3dbfc20824b7..33d88e0a0601 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2452,7 +2452,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */ - kvm_get_idt(&dt); + native_store_idt(&dt); vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */ asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return)); -- cgit v1.2.3-59-g8ed1b From 5c0d0920a270b9f2aa20c1cecb162703da32e766 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 12 Mar 2010 08:45:39 +0800 Subject: KVM: ia64: fix the error code of ioctl KVM_IA64_VCPU_GET_STACK failure The ioctl KVM_IA64_VCPU_GET_STACK does not set the error code if copy_to_user() fail, and 0 will be return, we should use -EFAULT instead of 0 in this case, so this patch fixed it. Signed-off-by: Wei Yongjun Signed-off-by: Marcelo Tosatti --- arch/ia64/kvm/kvm-ia64.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 7f3c0a2e60cd..38d51302f5b3 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1535,8 +1535,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp, goto out; if (copy_to_user(user_stack, stack, - sizeof(struct kvm_ia64_vcpu_stack))) + sizeof(struct kvm_ia64_vcpu_stack))) { + r = -EFAULT; goto out; + } break; } -- cgit v1.2.3-59-g8ed1b From 160d2f6c0c90713aa3bb93dd344fe0d527342e26 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 12 Mar 2010 10:09:45 +0800 Subject: KVM: x86: fix the error of ioctl KVM_IRQ_LINE if no irq chip If no irq chip in kernel, ioctl KVM_IRQ_LINE will return -EFAULT. But I see in other place such as KVM_[GET|SET]IRQCHIP, -ENXIO is return. So this patch used -ENXIO instead of -EFAULT. Signed-off-by: Wei Yongjun Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a1cf87fe9f3a..7a8fe9051ecf 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2836,11 +2836,13 @@ long kvm_arch_vm_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&irq_event, argp, sizeof irq_event)) goto out; + r = -ENXIO; if (irqchip_in_kernel(kvm)) { __s32 status; status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irq_event.irq, irq_event.level); if (ioctl == KVM_IRQ_LINE_STATUS) { + r = -EFAULT; irq_event.status = status; if (copy_to_user(argp, &irq_event, sizeof irq_event)) -- cgit v1.2.3-59-g8ed1b From 600f1ec3761671307935a583c46f17fff0fa9b72 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 12 Mar 2010 10:11:15 +0800 Subject: KVM: ia64: fix the error of ioctl KVM_IRQ_LINE if no irq chip If no irq chip in kernel, ioctl KVM_IRQ_LINE will return -EFAULT. But I see in other place such as KVM_[GET|SET]IRQCHIP, -ENXIO is return. So this patch used -ENXIO instead of -EFAULT. Signed-off-by: Wei Yongjun Signed-off-by: Marcelo Tosatti --- arch/ia64/kvm/kvm-ia64.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 38d51302f5b3..d7bac1f75af0 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -979,11 +979,13 @@ long kvm_arch_vm_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&irq_event, argp, sizeof irq_event)) goto out; + r = -ENXIO; if (irqchip_in_kernel(kvm)) { __s32 status; status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irq_event.irq, irq_event.level); if (ioctl == KVM_IRQ_LINE_STATUS) { + r = -EFAULT; irq_event.status = status; if (copy_to_user(argp, &irq_event, sizeof irq_event)) -- cgit v1.2.3-59-g8ed1b From 72016f3a4221799a0b1fdf443ef6e29db572a9bb Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 15 Mar 2010 13:59:53 +0200 Subject: KVM: MMU: Consolidate two guest pte reads in kvm_mmu_pte_write() kvm_mmu_pte_write() reads guest ptes in two different occasions, both to allow a 32-bit pae guest to update a pte with 4-byte writes. Consolidate these into a single read, which also allows us to consolidate another read from an invlpg speculating a gpte into the shadow page table. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 69 ++++++++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 4455ddbe36f4..91f8b171c825 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2560,36 +2560,11 @@ static bool last_updated_pte_accessed(struct kvm_vcpu *vcpu) } static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, - const u8 *new, int bytes) + u64 gpte) { gfn_t gfn; - int r; - u64 gpte = 0; pfn_t pfn; - if (bytes != 4 && bytes != 8) - return; - - /* - * Assume that the pte write on a page table of the same type - * as the current vcpu paging mode. This is nearly always true - * (might be false while changing modes). Note it is verified later - * by update_pte(). - */ - if (is_pae(vcpu)) { - /* Handle a 32-bit guest writing two halves of a 64-bit gpte */ - if ((bytes == 4) && (gpa % 4 == 0)) { - r = kvm_read_guest(vcpu->kvm, gpa & ~(u64)7, &gpte, 8); - if (r) - return; - memcpy((void *)&gpte + (gpa % 8), new, 4); - } else if ((bytes == 8) && (gpa % 8 == 0)) { - memcpy((void *)&gpte, new, 8); - } - } else { - if ((bytes == 4) && (gpa % 4 == 0)) - memcpy((void *)&gpte, new, 4); - } if (!is_present_gpte(gpte)) return; gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; @@ -2640,7 +2615,34 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, int r; pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes); - mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes); + + switch (bytes) { + case 4: + gentry = *(const u32 *)new; + break; + case 8: + gentry = *(const u64 *)new; + break; + default: + gentry = 0; + break; + } + + /* + * Assume that the pte write on a page table of the same type + * as the current vcpu paging mode. This is nearly always true + * (might be false while changing modes). Note it is verified later + * by update_pte(). + */ + if (is_pae(vcpu) && bytes == 4) { + /* Handle a 32-bit guest writing two halves of a 64-bit gpte */ + gpa &= ~(gpa_t)7; + r = kvm_read_guest(vcpu->kvm, gpa, &gentry, 8); + if (r) + gentry = 0; + } + + mmu_guess_page_from_pte_write(vcpu, gpa, gentry); spin_lock(&vcpu->kvm->mmu_lock); kvm_mmu_access_page(vcpu, gfn); kvm_mmu_free_some_pages(vcpu); @@ -2705,20 +2707,11 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, continue; } spte = &sp->spt[page_offset / sizeof(*spte)]; - if ((gpa & (pte_size - 1)) || (bytes < pte_size)) { - gentry = 0; - r = kvm_read_guest_atomic(vcpu->kvm, - gpa & ~(u64)(pte_size - 1), - &gentry, pte_size); - new = (const void *)&gentry; - if (r < 0) - new = NULL; - } while (npte--) { entry = *spte; mmu_pte_write_zap_pte(vcpu, sp, spte); - if (new) - mmu_pte_write_new_pte(vcpu, sp, spte, new); + if (gentry) + mmu_pte_write_new_pte(vcpu, sp, spte, &gentry); mmu_pte_write_flush_tlb(vcpu, entry, *spte); ++spte; } -- cgit v1.2.3-59-g8ed1b From daea3e73cb4ac971bee97f333ae027861d00fc0b Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 15 Mar 2010 13:59:54 +0200 Subject: KVM: Make locked operations truly atomic Once upon a time, locked operations were emulated while holding the mmu mutex. Since mmu pages were write protected, it was safe to emulate the writes in a non-atomic manner, since there could be no other writer, either in the guest or in the kernel. These days emulation takes place without holding the mmu spinlock, so the write could be preempted by an unshadowing event, which exposes the page to writes by the guest. This may cause corruption of guest page tables. Fix by using an atomic cmpxchg for these operations. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 69 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7a8fe9051ecf..855f3ea9edd1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3291,41 +3291,68 @@ int emulator_write_emulated(unsigned long addr, } EXPORT_SYMBOL_GPL(emulator_write_emulated); +#define CMPXCHG_TYPE(t, ptr, old, new) \ + (cmpxchg((t *)(ptr), *(t *)(old), *(t *)(new)) == *(t *)(old)) + +#ifdef CONFIG_X86_64 +# define CMPXCHG64(ptr, old, new) CMPXCHG_TYPE(u64, ptr, old, new) +#else +# define CMPXCHG64(ptr, old, new) \ + (cmpxchg64((u64 *)(ptr), *(u64 *)(old), *(u *)(new)) == *(u64 *)(old)) +#endif + static int emulator_cmpxchg_emulated(unsigned long addr, const void *old, const void *new, unsigned int bytes, struct kvm_vcpu *vcpu) { - printk_once(KERN_WARNING "kvm: emulating exchange as write\n"); -#ifndef CONFIG_X86_64 - /* guests cmpxchg8b have to be emulated atomically */ - if (bytes == 8) { - gpa_t gpa; - struct page *page; - char *kaddr; - u64 val; + gpa_t gpa; + struct page *page; + char *kaddr; + bool exchanged; - gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, NULL); + /* guests cmpxchg8b have to be emulated atomically */ + if (bytes > 8 || (bytes & (bytes - 1))) + goto emul_write; - if (gpa == UNMAPPED_GVA || - (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) - goto emul_write; + gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, NULL); - if (((gpa + bytes - 1) & PAGE_MASK) != (gpa & PAGE_MASK)) - goto emul_write; + if (gpa == UNMAPPED_GVA || + (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) + goto emul_write; - val = *(u64 *)new; + if (((gpa + bytes - 1) & PAGE_MASK) != (gpa & PAGE_MASK)) + goto emul_write; - page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); + page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); - kaddr = kmap_atomic(page, KM_USER0); - set_64bit((u64 *)(kaddr + offset_in_page(gpa)), val); - kunmap_atomic(kaddr, KM_USER0); - kvm_release_page_dirty(page); + kaddr = kmap_atomic(page, KM_USER0); + kaddr += offset_in_page(gpa); + switch (bytes) { + case 1: + exchanged = CMPXCHG_TYPE(u8, kaddr, old, new); + break; + case 2: + exchanged = CMPXCHG_TYPE(u16, kaddr, old, new); + break; + case 4: + exchanged = CMPXCHG_TYPE(u32, kaddr, old, new); + break; + case 8: + exchanged = CMPXCHG64(kaddr, old, new); + break; + default: + BUG(); } + kunmap_atomic(kaddr, KM_USER0); + kvm_release_page_dirty(page); + + if (!exchanged) + return X86EMUL_CMPXCHG_FAILED; + emul_write: -#endif + printk_once(KERN_WARNING "kvm: emulating exchange as write\n"); return emulator_write_emulated(addr, new, bytes, vcpu); } -- cgit v1.2.3-59-g8ed1b From 4a5f48f666ccc4ffdbc54241d9cab06806ed7922 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 15 Mar 2010 13:59:55 +0200 Subject: KVM: Don't follow an atomic operation by a non-atomic one Currently emulated atomic operations are immediately followed by a non-atomic operation, so that kvm_mmu_pte_write() can be invoked. This updates the mmu but undoes the whole point of doing things atomically. Fix by only performing the atomic operation and the mmu update, and avoiding the non-atomic write. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 855f3ea9edd1..dd4a7ad63aff 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3234,7 +3234,8 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, static int emulator_write_emulated_onepage(unsigned long addr, const void *val, unsigned int bytes, - struct kvm_vcpu *vcpu) + struct kvm_vcpu *vcpu, + bool mmu_only) { gpa_t gpa; u32 error_code; @@ -3250,6 +3251,10 @@ static int emulator_write_emulated_onepage(unsigned long addr, if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) goto mmio; + if (mmu_only) { + kvm_mmu_pte_write(vcpu, gpa, val, bytes, 1); + return X86EMUL_CONTINUE; + } if (emulator_write_phys(vcpu, gpa, val, bytes)) return X86EMUL_CONTINUE; @@ -3270,24 +3275,35 @@ mmio: return X86EMUL_CONTINUE; } -int emulator_write_emulated(unsigned long addr, +int __emulator_write_emulated(unsigned long addr, const void *val, unsigned int bytes, - struct kvm_vcpu *vcpu) + struct kvm_vcpu *vcpu, + bool mmu_only) { /* Crossing a page boundary? */ if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { int rc, now; now = -addr & ~PAGE_MASK; - rc = emulator_write_emulated_onepage(addr, val, now, vcpu); + rc = emulator_write_emulated_onepage(addr, val, now, vcpu, + mmu_only); if (rc != X86EMUL_CONTINUE) return rc; addr += now; val += now; bytes -= now; } - return emulator_write_emulated_onepage(addr, val, bytes, vcpu); + return emulator_write_emulated_onepage(addr, val, bytes, vcpu, + mmu_only); +} + +int emulator_write_emulated(unsigned long addr, + const void *val, + unsigned int bytes, + struct kvm_vcpu *vcpu) +{ + return __emulator_write_emulated(addr, val, bytes, vcpu, false); } EXPORT_SYMBOL_GPL(emulator_write_emulated); @@ -3351,6 +3367,8 @@ static int emulator_cmpxchg_emulated(unsigned long addr, if (!exchanged) return X86EMUL_CMPXCHG_FAILED; + return __emulator_write_emulated(addr, new, bytes, vcpu, true); + emul_write: printk_once(KERN_WARNING "kvm: emulating exchange as write\n"); @@ -4005,7 +4023,7 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu) kvm_x86_ops->patch_hypercall(vcpu, instruction); - return emulator_write_emulated(rip, instruction, 3, vcpu); + return __emulator_write_emulated(rip, instruction, 3, vcpu, false); } static u64 mk_cr_64(u64 curr_cr, u32 new_val) -- cgit v1.2.3-59-g8ed1b From fbc5d139bb92e6822e4c000f97631a072d8babf9 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 15 Mar 2010 13:59:56 +0200 Subject: KVM: MMU: Do not instantiate nontrapping spte on unsync page The update_pte() path currently uses a nontrapping spte when a nonpresent (or nonaccessed) gpte is written. This is fine since at present it is only used on sync pages. However, on an unsync page this will cause an endless fault loop as the guest is under no obligation to invlpg a gpte that transitions from nonpresent to present. Needed for the next patch which reinstates update_pte() on invlpg. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/paging_tmpl.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 81eab9a50e6a..4b37e1acd375 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -258,11 +258,17 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page, pt_element_t gpte; unsigned pte_access; pfn_t pfn; + u64 new_spte; gpte = *(const pt_element_t *)pte; if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) { - if (!is_present_gpte(gpte)) - __set_spte(spte, shadow_notrap_nonpresent_pte); + if (!is_present_gpte(gpte)) { + if (page->unsync) + new_spte = shadow_trap_nonpresent_pte; + else + new_spte = shadow_notrap_nonpresent_pte; + __set_spte(spte, new_spte); + } return; } pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); -- cgit v1.2.3-59-g8ed1b From 08e850c6536db302050c0287649e68e3bbdfe2c7 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 15 Mar 2010 13:59:57 +0200 Subject: KVM: MMU: Reinstate pte prefetch on invlpg Commit fb341f57 removed the pte prefetch on guest invlpg, citing guest races. However, the SDM is adamant that prefetch is allowed: "The processor may create entries in paging-structure caches for translations required for prefetches and for accesses that are a result of speculative execution that would never actually occur in the executed code path." And, in fact, there was a race in the prefetch code: we picked up the pte without the mmu lock held, so an older invlpg could install the pte over a newer invlpg. Reinstate the prefetch logic, but this time note whether another invlpg has executed using a counter. If a race occured, do not install the pte. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/mmu.c | 37 +++++++++++++++++++++++-------------- arch/x86/kvm/paging_tmpl.h | 15 +++++++++++++++ 3 files changed, 39 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index ea1b6c615f9f..28826c82d1e2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -389,6 +389,7 @@ struct kvm_arch { unsigned int n_free_mmu_pages; unsigned int n_requested_mmu_pages; unsigned int n_alloc_mmu_pages; + atomic_t invlpg_counter; struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES]; /* * Hash table of struct kvm_mmu_page. diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 91f8b171c825..064c3efb49dc 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2613,20 +2613,11 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, int flooded = 0; int npte; int r; + int invlpg_counter; pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes); - switch (bytes) { - case 4: - gentry = *(const u32 *)new; - break; - case 8: - gentry = *(const u64 *)new; - break; - default: - gentry = 0; - break; - } + invlpg_counter = atomic_read(&vcpu->kvm->arch.invlpg_counter); /* * Assume that the pte write on a page table of the same type @@ -2634,16 +2625,34 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, * (might be false while changing modes). Note it is verified later * by update_pte(). */ - if (is_pae(vcpu) && bytes == 4) { + if ((is_pae(vcpu) && bytes == 4) || !new) { /* Handle a 32-bit guest writing two halves of a 64-bit gpte */ - gpa &= ~(gpa_t)7; - r = kvm_read_guest(vcpu->kvm, gpa, &gentry, 8); + if (is_pae(vcpu)) { + gpa &= ~(gpa_t)7; + bytes = 8; + } + r = kvm_read_guest(vcpu->kvm, gpa, &gentry, min(bytes, 8)); if (r) gentry = 0; + new = (const u8 *)&gentry; + } + + switch (bytes) { + case 4: + gentry = *(const u32 *)new; + break; + case 8: + gentry = *(const u64 *)new; + break; + default: + gentry = 0; + break; } mmu_guess_page_from_pte_write(vcpu, gpa, gentry); spin_lock(&vcpu->kvm->mmu_lock); + if (atomic_read(&vcpu->kvm->arch.invlpg_counter) != invlpg_counter) + gentry = 0; kvm_mmu_access_page(vcpu, gfn); kvm_mmu_free_some_pages(vcpu); ++vcpu->kvm->stat.mmu_pte_write; diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 4b37e1acd375..067797a72768 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -463,6 +463,7 @@ out_unlock: static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) { struct kvm_shadow_walk_iterator iterator; + gpa_t pte_gpa = -1; int level; u64 *sptep; int need_flush = 0; @@ -476,6 +477,10 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) if (level == PT_PAGE_TABLE_LEVEL || ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) || ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) { + struct kvm_mmu_page *sp = page_header(__pa(sptep)); + + pte_gpa = (sp->gfn << PAGE_SHIFT); + pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t); if (is_shadow_present_pte(*sptep)) { rmap_remove(vcpu->kvm, sptep); @@ -493,7 +498,17 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) if (need_flush) kvm_flush_remote_tlbs(vcpu->kvm); + + atomic_inc(&vcpu->kvm->arch.invlpg_counter); + spin_unlock(&vcpu->kvm->mmu_lock); + + if (pte_gpa == -1) + return; + + if (mmu_topup_memory_caches(vcpu)) + return; + kvm_mmu_pte_write(vcpu, pte_gpa, NULL, sizeof(pt_element_t), 0); } static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access, -- cgit v1.2.3-59-g8ed1b From d6d367d6783e38634377bc66b62bff3ffd717e5f Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Mon, 15 Mar 2010 16:38:28 +0200 Subject: KVM: x86 emulator: Fix DstAcc decoding. Set correct operation length. Add RAX (64bit) handling. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 2832a8c07c6a..0b70a364f0f4 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1194,9 +1194,9 @@ done_prefixes: break; case DstAcc: c->dst.type = OP_REG; - c->dst.bytes = c->op_bytes; + c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.ptr = &c->regs[VCPU_REGS_RAX]; - switch (c->op_bytes) { + switch (c->dst.bytes) { case 1: c->dst.val = *(u8 *)c->dst.ptr; break; @@ -1206,6 +1206,9 @@ done_prefixes: case 4: c->dst.val = *(u32 *)c->dst.ptr; break; + case 8: + c->dst.val = *(u64 *)c->dst.ptr; + break; } c->dst.orig_val = c->dst.val; break; -- cgit v1.2.3-59-g8ed1b From c73e197bc525e67b71578126b679446f5b88b508 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Mon, 15 Mar 2010 16:38:29 +0200 Subject: KVM: x86 emulator: fix RCX access during rep emulation During rep emulation access length to RCX depends on current address mode. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 0b70a364f0f4..4dce80560d26 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1852,7 +1852,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) if (c->rep_prefix && (c->d & String)) { /* All REP prefixes have the same first termination condition */ - if (c->regs[VCPU_REGS_RCX] == 0) { + if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) { kvm_rip_write(ctxt->vcpu, c->eip); goto done; } @@ -1876,7 +1876,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) goto done; } } - c->regs[VCPU_REGS_RCX]--; + register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); c->eip = kvm_rip_read(ctxt->vcpu); } -- cgit v1.2.3-59-g8ed1b From af5b4f7ff7ec76400b89db9538accd9aeb996da4 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Mon, 15 Mar 2010 16:38:30 +0200 Subject: KVM: x86 emulator: check return value against correct define Check return value against correct define instead of open code the value. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 4dce80560d26..670ca8f151d2 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -566,7 +566,7 @@ static u32 group2_table[] = { #define insn_fetch(_type, _size, _eip) \ ({ unsigned long _x; \ rc = do_insn_fetch(ctxt, ops, (_eip), &_x, (_size)); \ - if (rc != 0) \ + if (rc != X86EMUL_CONTINUE) \ goto done; \ (_eip) += (_size); \ (_type)_x; \ -- cgit v1.2.3-59-g8ed1b From 49c6799a2ce3a6a4dd66021dabeb468901c7a700 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Mon, 15 Mar 2010 16:38:31 +0200 Subject: KVM: Remove pointer to rflags from realmode_set_cr parameters. Mov reg, cr instruction doesn't change flags in any meaningful way, so no need to update rflags after instruction execution. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 3 +-- arch/x86/kvm/emulate.c | 3 +-- arch/x86/kvm/x86.c | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 28826c82d1e2..53f520259471 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -587,8 +587,7 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, unsigned long *rflags); unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr); -void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value, - unsigned long *rflags); +void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value); void kvm_enable_efer_bits(u64); int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data); int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 670ca8f151d2..91450b5cd49e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2534,8 +2534,7 @@ twobyte_insn: case 0x22: /* mov reg, cr */ if (c->modrm_mod != 3) goto cannot_emulate; - realmode_set_cr(ctxt->vcpu, - c->modrm_reg, c->modrm_val, &ctxt->eflags); + realmode_set_cr(ctxt->vcpu, c->modrm_reg, c->modrm_val); c->dst.type = OP_NONE; break; case 0x23: /* mov from reg to dr */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index dd4a7ad63aff..35db4f0db4ea 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4080,13 +4080,11 @@ unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) return value; } -void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val, - unsigned long *rflags) +void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val) { switch (cr) { case 0: kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val)); - *rflags = kvm_get_rflags(vcpu); break; case 2: vcpu->arch.cr2 = val; -- cgit v1.2.3-59-g8ed1b From 31299944584fd62df8b0cfa30ad2c56f445b8cf2 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Mon, 15 Mar 2010 17:29:09 +0800 Subject: KVM: VMX: change to use bool return values Make use of bool as return values, and remove some useless bool value converting. Thanks Avi to point this out. Signed-off-by: Gui Jianfeng Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/vmx.c | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 33d88e0a0601..87b3c6843aac 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -234,56 +234,56 @@ static const u32 vmx_msr_index[] = { }; #define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index) -static inline int is_page_fault(u32 intr_info) +static inline bool is_page_fault(u32 intr_info) { return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | INTR_INFO_VALID_MASK)) == (INTR_TYPE_HARD_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK); } -static inline int is_no_device(u32 intr_info) +static inline bool is_no_device(u32 intr_info) { return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | INTR_INFO_VALID_MASK)) == (INTR_TYPE_HARD_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK); } -static inline int is_invalid_opcode(u32 intr_info) +static inline bool is_invalid_opcode(u32 intr_info) { return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | INTR_INFO_VALID_MASK)) == (INTR_TYPE_HARD_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK); } -static inline int is_external_interrupt(u32 intr_info) +static inline bool is_external_interrupt(u32 intr_info) { return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) == (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK); } -static inline int is_machine_check(u32 intr_info) +static inline bool is_machine_check(u32 intr_info) { return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | INTR_INFO_VALID_MASK)) == (INTR_TYPE_HARD_EXCEPTION | MC_VECTOR | INTR_INFO_VALID_MASK); } -static inline int cpu_has_vmx_msr_bitmap(void) +static inline bool cpu_has_vmx_msr_bitmap(void) { return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS; } -static inline int cpu_has_vmx_tpr_shadow(void) +static inline bool cpu_has_vmx_tpr_shadow(void) { return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW; } -static inline int vm_need_tpr_shadow(struct kvm *kvm) +static inline bool vm_need_tpr_shadow(struct kvm *kvm) { return (cpu_has_vmx_tpr_shadow()) && (irqchip_in_kernel(kvm)); } -static inline int cpu_has_secondary_exec_ctrls(void) +static inline bool cpu_has_secondary_exec_ctrls(void) { return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS; @@ -303,80 +303,80 @@ static inline bool cpu_has_vmx_flexpriority(void) static inline bool cpu_has_vmx_ept_execute_only(void) { - return !!(vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT); + return vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT; } static inline bool cpu_has_vmx_eptp_uncacheable(void) { - return !!(vmx_capability.ept & VMX_EPTP_UC_BIT); + return vmx_capability.ept & VMX_EPTP_UC_BIT; } static inline bool cpu_has_vmx_eptp_writeback(void) { - return !!(vmx_capability.ept & VMX_EPTP_WB_BIT); + return vmx_capability.ept & VMX_EPTP_WB_BIT; } static inline bool cpu_has_vmx_ept_2m_page(void) { - return !!(vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT); + return vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT; } static inline bool cpu_has_vmx_ept_1g_page(void) { - return !!(vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT); + return vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT; } -static inline int cpu_has_vmx_invept_individual_addr(void) +static inline bool cpu_has_vmx_invept_individual_addr(void) { - return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT); + return vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT; } -static inline int cpu_has_vmx_invept_context(void) +static inline bool cpu_has_vmx_invept_context(void) { - return !!(vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT); + return vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT; } -static inline int cpu_has_vmx_invept_global(void) +static inline bool cpu_has_vmx_invept_global(void) { - return !!(vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT); + return vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT; } -static inline int cpu_has_vmx_ept(void) +static inline bool cpu_has_vmx_ept(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_EPT; } -static inline int cpu_has_vmx_unrestricted_guest(void) +static inline bool cpu_has_vmx_unrestricted_guest(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_UNRESTRICTED_GUEST; } -static inline int cpu_has_vmx_ple(void) +static inline bool cpu_has_vmx_ple(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_PAUSE_LOOP_EXITING; } -static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm) +static inline bool vm_need_virtualize_apic_accesses(struct kvm *kvm) { return flexpriority_enabled && irqchip_in_kernel(kvm); } -static inline int cpu_has_vmx_vpid(void) +static inline bool cpu_has_vmx_vpid(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_VPID; } -static inline int cpu_has_vmx_rdtscp(void) +static inline bool cpu_has_vmx_rdtscp(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_RDTSCP; } -static inline int cpu_has_virtual_nmis(void) +static inline bool cpu_has_virtual_nmis(void) { return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS; } -- cgit v1.2.3-59-g8ed1b From 52a4661737ecc918633f6b05c611a4af4b5eae5a Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:03 +0200 Subject: KVM: Provide callback to get/set control registers in emulator ops. Use this callback instead of directly call kvm function. Also rename realmode_(set|get)_cr to emulator_(set|get)_cr since function has nothing to do with real mode. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_emulate.h | 3 +- arch/x86/include/asm/kvm_host.h | 2 - arch/x86/kvm/emulate.c | 7 +-- arch/x86/kvm/x86.c | 114 +++++++++++++++++++------------------ 4 files changed, 63 insertions(+), 63 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 2666d7ac3229..0c5caa469eb8 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -108,7 +108,8 @@ struct x86_emulate_ops { const void *new, unsigned int bytes, struct kvm_vcpu *vcpu); - + ulong (*get_cr)(int cr, struct kvm_vcpu *vcpu); + void (*set_cr)(int cr, ulong val, struct kvm_vcpu *vcpu); }; /* Type, address-of, and value of an instruction's operand. */ diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 53f520259471..9d474c7ae261 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -586,8 +586,6 @@ void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, unsigned long *rflags); -unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr); -void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value); void kvm_enable_efer_bits(u64); int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data); int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 91450b5cd49e..5b060e4be0e3 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2483,7 +2483,7 @@ twobyte_insn: break; case 4: /* smsw */ c->dst.bytes = 2; - c->dst.val = realmode_get_cr(ctxt->vcpu, 0); + c->dst.val = ops->get_cr(0, ctxt->vcpu); break; case 6: /* lmsw */ realmode_lmsw(ctxt->vcpu, (u16)c->src.val, @@ -2519,8 +2519,7 @@ twobyte_insn: case 0x20: /* mov cr, reg */ if (c->modrm_mod != 3) goto cannot_emulate; - c->regs[c->modrm_rm] = - realmode_get_cr(ctxt->vcpu, c->modrm_reg); + c->regs[c->modrm_rm] = ops->get_cr(c->modrm_reg, ctxt->vcpu); c->dst.type = OP_NONE; /* no writeback */ break; case 0x21: /* mov from dr to reg */ @@ -2534,7 +2533,7 @@ twobyte_insn: case 0x22: /* mov reg, cr */ if (c->modrm_mod != 3) goto cannot_emulate; - realmode_set_cr(ctxt->vcpu, c->modrm_reg, c->modrm_val); + ops->set_cr(c->modrm_reg, c->modrm_val, ctxt->vcpu); c->dst.type = OP_NONE; break; case 0x23: /* mov from reg to dr */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 35db4f0db4ea..94a29759ab2c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3423,12 +3423,70 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) } EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); +static u64 mk_cr_64(u64 curr_cr, u32 new_val) +{ + return (curr_cr & ~((1ULL << 32) - 1)) | new_val; +} + +static unsigned long emulator_get_cr(int cr, struct kvm_vcpu *vcpu) +{ + unsigned long value; + + switch (cr) { + case 0: + value = kvm_read_cr0(vcpu); + break; + case 2: + value = vcpu->arch.cr2; + break; + case 3: + value = vcpu->arch.cr3; + break; + case 4: + value = kvm_read_cr4(vcpu); + break; + case 8: + value = kvm_get_cr8(vcpu); + break; + default: + vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); + return 0; + } + + return value; +} + +static void emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu) +{ + switch (cr) { + case 0: + kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val)); + break; + case 2: + vcpu->arch.cr2 = val; + break; + case 3: + kvm_set_cr3(vcpu, val); + break; + case 4: + kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val)); + break; + case 8: + kvm_set_cr8(vcpu, val & 0xfUL); + break; + default: + vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); + } +} + static struct x86_emulate_ops emulate_ops = { .read_std = kvm_read_guest_virt_system, .fetch = kvm_fetch_guest_virt, .read_emulated = emulator_read_emulated, .write_emulated = emulator_write_emulated, .cmpxchg_emulated = emulator_cmpxchg_emulated, + .get_cr = emulator_get_cr, + .set_cr = emulator_set_cr, }; static void cache_all_regs(struct kvm_vcpu *vcpu) @@ -4026,11 +4084,6 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu) return __emulator_write_emulated(rip, instruction, 3, vcpu, false); } -static u64 mk_cr_64(u64 curr_cr, u32 new_val) -{ - return (curr_cr & ~((1ULL << 32) - 1)) | new_val; -} - void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) { struct desc_ptr dt = { limit, base }; @@ -4052,57 +4105,6 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, *rflags = kvm_get_rflags(vcpu); } -unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) -{ - unsigned long value; - - switch (cr) { - case 0: - value = kvm_read_cr0(vcpu); - break; - case 2: - value = vcpu->arch.cr2; - break; - case 3: - value = vcpu->arch.cr3; - break; - case 4: - value = kvm_read_cr4(vcpu); - break; - case 8: - value = kvm_get_cr8(vcpu); - break; - default: - vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); - return 0; - } - - return value; -} - -void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val) -{ - switch (cr) { - case 0: - kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val)); - break; - case 2: - vcpu->arch.cr2 = val; - break; - case 3: - kvm_set_cr3(vcpu, val); - break; - case 4: - kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val)); - break; - case 8: - kvm_set_cr8(vcpu, val & 0xfUL); - break; - default: - vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); - } -} - static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i) { struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i]; -- cgit v1.2.3-59-g8ed1b From 93a152be5af3d651ff0ab5459f5e0f9662b22438 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:04 +0200 Subject: KVM: remove realmode_lmsw function. Use (get|set)_cr callback to emulate lmsw inside emulator. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 2 -- arch/x86/kvm/emulate.c | 4 ++-- arch/x86/kvm/x86.c | 7 ------- 3 files changed, 2 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 9d474c7ae261..b99cec1547c6 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -583,8 +583,6 @@ int emulate_instruction(struct kvm_vcpu *vcpu, void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context); void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); -void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, - unsigned long *rflags); void kvm_enable_efer_bits(u64); int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data); diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5b060e4be0e3..5e2fa61e8104 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2486,8 +2486,8 @@ twobyte_insn: c->dst.val = ops->get_cr(0, ctxt->vcpu); break; case 6: /* lmsw */ - realmode_lmsw(ctxt->vcpu, (u16)c->src.val, - &ctxt->eflags); + ops->set_cr(0, (ops->get_cr(0, ctxt->vcpu) & ~0x0ful) | + (c->src.val & 0x0f), ctxt->vcpu); c->dst.type = OP_NONE; break; case 7: /* invlpg*/ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 94a29759ab2c..c382e9721099 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4098,13 +4098,6 @@ void realmode_lidt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) kvm_x86_ops->set_idt(vcpu, &dt); } -void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, - unsigned long *rflags) -{ - kvm_lmsw(vcpu, msw); - *rflags = kvm_get_rflags(vcpu); -} - static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i) { struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i]; -- cgit v1.2.3-59-g8ed1b From 9c5372445c1ad4fcdb4128957ec89334223b8113 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:05 +0200 Subject: KVM: Provide x86_emulate_ctxt callback to get current cpl Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_emulate.h | 1 + arch/x86/kvm/emulate.c | 15 ++++++++------- arch/x86/kvm/x86.c | 6 ++++++ 3 files changed, 15 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 0c5caa469eb8..b048fd21c54e 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -110,6 +110,7 @@ struct x86_emulate_ops { struct kvm_vcpu *vcpu); ulong (*get_cr)(int cr, struct kvm_vcpu *vcpu); void (*set_cr)(int cr, ulong val, struct kvm_vcpu *vcpu); + int (*cpl)(struct kvm_vcpu *vcpu); }; /* Type, address-of, and value of an instruction's operand. */ diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5e2fa61e8104..8bd05571672c 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1257,7 +1257,7 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt, int rc; unsigned long val, change_mask; int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; - int cpl = kvm_x86_ops->get_cpl(ctxt->vcpu); + int cpl = ops->cpl(ctxt->vcpu); rc = emulate_pop(ctxt, ops, &val, len); if (rc != X86EMUL_CONTINUE) @@ -1758,7 +1758,8 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) return X86EMUL_CONTINUE; } -static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) +static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) { int iopl; if (ctxt->mode == X86EMUL_MODE_REAL) @@ -1766,7 +1767,7 @@ static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) if (ctxt->mode == X86EMUL_MODE_VM86) return true; iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; - return kvm_x86_ops->get_cpl(ctxt->vcpu) > iopl; + return ops->cpl(ctxt->vcpu) > iopl; } static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, @@ -1803,7 +1804,7 @@ static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, u16 port, u16 len) { - if (emulator_bad_iopl(ctxt)) + if (emulator_bad_iopl(ctxt, ops)) if (!emulator_io_port_access_allowed(ctxt, ops, port, len)) return false; return true; @@ -1842,7 +1843,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) } /* Privileged instruction can be executed only in CPL=0 */ - if ((c->d & Priv) && kvm_x86_ops->get_cpl(ctxt->vcpu)) { + if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) { kvm_inject_gp(ctxt->vcpu, 0); goto done; } @@ -2378,7 +2379,7 @@ special_insn: c->dst.type = OP_NONE; /* Disable writeback. */ break; case 0xfa: /* cli */ - if (emulator_bad_iopl(ctxt)) + if (emulator_bad_iopl(ctxt, ops)) kvm_inject_gp(ctxt->vcpu, 0); else { ctxt->eflags &= ~X86_EFLAGS_IF; @@ -2386,7 +2387,7 @@ special_insn: } break; case 0xfb: /* sti */ - if (emulator_bad_iopl(ctxt)) + if (emulator_bad_iopl(ctxt, ops)) kvm_inject_gp(ctxt->vcpu, 0); else { toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_STI); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c382e9721099..9cb28a943c9a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3479,6 +3479,11 @@ static void emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu) } } +static int emulator_get_cpl(struct kvm_vcpu *vcpu) +{ + return kvm_x86_ops->get_cpl(vcpu); +} + static struct x86_emulate_ops emulate_ops = { .read_std = kvm_read_guest_virt_system, .fetch = kvm_fetch_guest_virt, @@ -3487,6 +3492,7 @@ static struct x86_emulate_ops emulate_ops = { .cmpxchg_emulated = emulator_cmpxchg_emulated, .get_cr = emulator_get_cr, .set_cr = emulator_set_cr, + .cpl = emulator_get_cpl, }; static void cache_all_regs(struct kvm_vcpu *vcpu) -- cgit v1.2.3-59-g8ed1b From 063db061b9b3472c925f09ae3a0a8359b80c2295 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:06 +0200 Subject: KVM: Provide current eip as part of emulator context. Eliminate the need to call back into KVM to get it from emulator. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_emulate.h | 3 ++- arch/x86/kvm/emulate.c | 12 ++++++------ arch/x86/kvm/x86.c | 1 + 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index b048fd21c54e..07657258af8f 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -141,7 +141,7 @@ struct decode_cache { u8 seg_override; unsigned int d; unsigned long regs[NR_VCPU_REGS]; - unsigned long eip, eip_orig; + unsigned long eip; /* modrm */ u8 modrm; u8 modrm_mod; @@ -160,6 +160,7 @@ struct x86_emulate_ctxt { struct kvm_vcpu *vcpu; unsigned long eflags; + unsigned long eip; /* eip before instruction emulation */ /* Emulated execution mode, represented by an X86EMUL_MODE value. */ int mode; u32 cs_base; diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8bd05571672c..2c27aa466cf4 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -667,7 +667,7 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, int rc; /* x86 instructions are limited to 15 bytes. */ - if (eip + size - ctxt->decode.eip_orig > 15) + if (eip + size - ctxt->eip > 15) return X86EMUL_UNHANDLEABLE; eip += ctxt->cs_base; while (size--) { @@ -927,7 +927,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) /* Shadow copy of register state. Committed on successful emulation. */ memset(c, 0, sizeof(struct decode_cache)); - c->eip = c->eip_orig = kvm_rip_read(ctxt->vcpu); + c->eip = ctxt->eip; ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); @@ -1878,7 +1878,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) } } register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); - c->eip = kvm_rip_read(ctxt->vcpu); + c->eip = ctxt->eip; } if (c->src.type == OP_MEM) { @@ -2447,7 +2447,7 @@ twobyte_insn: goto done; /* Let the processor re-execute the fixed hypercall */ - c->eip = kvm_rip_read(ctxt->vcpu); + c->eip = ctxt->eip; /* Disable writeback. */ c->dst.type = OP_NONE; break; @@ -2551,7 +2551,7 @@ twobyte_insn: | ((u64)c->regs[VCPU_REGS_RDX] << 32); if (kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data)) { kvm_inject_gp(ctxt->vcpu, 0); - c->eip = kvm_rip_read(ctxt->vcpu); + c->eip = ctxt->eip; } rc = X86EMUL_CONTINUE; c->dst.type = OP_NONE; @@ -2560,7 +2560,7 @@ twobyte_insn: /* rdmsr */ if (kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data)) { kvm_inject_gp(ctxt->vcpu, 0); - c->eip = kvm_rip_read(ctxt->vcpu); + c->eip = ctxt->eip; } else { c->regs[VCPU_REGS_RAX] = (u32)msr_data; c->regs[VCPU_REGS_RDX] = msr_data >> 32; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9cb28a943c9a..0ecd37ac9d39 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3531,6 +3531,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, vcpu->arch.emulate_ctxt.vcpu = vcpu; vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu); + vcpu->arch.emulate_ctxt.eip = kvm_rip_read(vcpu); vcpu->arch.emulate_ctxt.mode = (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL : (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM) -- cgit v1.2.3-59-g8ed1b From 5e3ae6c5407ffb23bc4d9871e09d1b222e1b31a4 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:07 +0200 Subject: KVM: x86 emulator: fix mov r/m, sreg emulation. mov r/m, sreg generates #UD ins sreg is incorrect. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 2c27aa466cf4..c3b9334eb248 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2126,12 +2126,11 @@ special_insn: case 0x8c: { /* mov r/m, sreg */ struct kvm_segment segreg; - if (c->modrm_reg <= 5) + if (c->modrm_reg <= VCPU_SREG_GS) kvm_get_segment(ctxt->vcpu, &segreg, c->modrm_reg); else { - printk(KERN_INFO "0x8c: Invalid segreg in modrm byte 0x%02x\n", - c->modrm); - goto cannot_emulate; + kvm_queue_exception(ctxt->vcpu, UD_VECTOR); + goto done; } c->dst.val = segreg.selector; break; -- cgit v1.2.3-59-g8ed1b From 6e1e5ffee8d95f9bce71eaa029cb5247b0f2f673 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:08 +0200 Subject: KVM: x86 emulator: fix 0f 01 /5 emulation It is undefined and should generate #UD. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index c3b9334eb248..7c7debb424df 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2490,6 +2490,9 @@ twobyte_insn: (c->src.val & 0x0f), ctxt->vcpu); c->dst.type = OP_NONE; break; + case 5: /* not defined */ + kvm_queue_exception(ctxt->vcpu, UD_VECTOR); + goto done; case 7: /* invlpg*/ emulate_invlpg(ctxt->vcpu, memop); /* Disable writeback. */ -- cgit v1.2.3-59-g8ed1b From ab8557b2b361c8bb2e2421c791c8f6c4f6ba3d08 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:09 +0200 Subject: KVM: x86 emulator: 0f (20|21|22|23) ignore mod bits. Resent spec says that for 0f (20|21|22|23) the 2 bits in the mod field are ignored. Interestingly enough older spec says that 11 is only valid encoding. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 7c7debb424df..fa4604e03250 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2520,28 +2520,20 @@ twobyte_insn: c->dst.type = OP_NONE; break; case 0x20: /* mov cr, reg */ - if (c->modrm_mod != 3) - goto cannot_emulate; c->regs[c->modrm_rm] = ops->get_cr(c->modrm_reg, ctxt->vcpu); c->dst.type = OP_NONE; /* no writeback */ break; case 0x21: /* mov from dr to reg */ - if (c->modrm_mod != 3) - goto cannot_emulate; if (emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm])) goto cannot_emulate; rc = X86EMUL_CONTINUE; c->dst.type = OP_NONE; /* no writeback */ break; case 0x22: /* mov reg, cr */ - if (c->modrm_mod != 3) - goto cannot_emulate; ops->set_cr(c->modrm_reg, c->modrm_val, ctxt->vcpu); c->dst.type = OP_NONE; break; case 0x23: /* mov from reg to dr */ - if (c->modrm_mod != 3) - goto cannot_emulate; if (emulator_set_dr(ctxt, c->modrm_reg, c->regs[c->modrm_rm])) goto cannot_emulate; rc = X86EMUL_CONTINUE; -- cgit v1.2.3-59-g8ed1b From 6aebfa6ea75f9a02a0339e733090dd40d6f2edfd Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:10 +0200 Subject: KVM: x86 emulator: inject #UD on access to non-existing CR Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index fa4604e03250..836e97ba45da 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2520,6 +2520,13 @@ twobyte_insn: c->dst.type = OP_NONE; break; case 0x20: /* mov cr, reg */ + switch (c->modrm_reg) { + case 1: + case 5 ... 7: + case 9 ... 15: + kvm_queue_exception(ctxt->vcpu, UD_VECTOR); + goto done; + } c->regs[c->modrm_rm] = ops->get_cr(c->modrm_reg, ctxt->vcpu); c->dst.type = OP_NONE; /* no writeback */ break; -- cgit v1.2.3-59-g8ed1b From 1e470be5a10801cb1c5c145f2cd9e0f5ebaf4f2e Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:11 +0200 Subject: KVM: x86 emulator: fix mov dr to inject #UD when needed. If CR4.DE=1 access to registers DR4/DR5 cause #UD. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 836e97ba45da..5afddcfa1a7e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2531,9 +2531,12 @@ twobyte_insn: c->dst.type = OP_NONE; /* no writeback */ break; case 0x21: /* mov from dr to reg */ - if (emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm])) - goto cannot_emulate; - rc = X86EMUL_CONTINUE; + if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) && + (c->modrm_reg == 4 || c->modrm_reg == 5)) { + kvm_queue_exception(ctxt->vcpu, UD_VECTOR); + goto done; + } + emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]); c->dst.type = OP_NONE; /* no writeback */ break; case 0x22: /* mov reg, cr */ @@ -2541,9 +2544,12 @@ twobyte_insn: c->dst.type = OP_NONE; break; case 0x23: /* mov from reg to dr */ - if (emulator_set_dr(ctxt, c->modrm_reg, c->regs[c->modrm_rm])) - goto cannot_emulate; - rc = X86EMUL_CONTINUE; + if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) && + (c->modrm_reg == 4 || c->modrm_reg == 5)) { + kvm_queue_exception(ctxt->vcpu, UD_VECTOR); + goto done; + } + emulator_set_dr(ctxt, c->modrm_reg, c->regs[c->modrm_rm]); c->dst.type = OP_NONE; /* no writeback */ break; case 0x30: -- cgit v1.2.3-59-g8ed1b From 2e901c4cf4b550ad37840870246e835889cf7322 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:12 +0200 Subject: KVM: x86 emulator: fix return values of syscall/sysenter/sysexit emulations Return X86EMUL_PROPAGATE_FAULT is fault was injected. Also inject #UD for those instruction when appropriate. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5afddcfa1a7e..1393bf034243 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1600,8 +1600,11 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt) u64 msr_data; /* syscall is not available in real mode */ - if (ctxt->mode == X86EMUL_MODE_REAL || ctxt->mode == X86EMUL_MODE_VM86) - return X86EMUL_UNHANDLEABLE; + if (ctxt->mode == X86EMUL_MODE_REAL || + ctxt->mode == X86EMUL_MODE_VM86) { + kvm_queue_exception(ctxt->vcpu, UD_VECTOR); + return X86EMUL_PROPAGATE_FAULT; + } setup_syscalls_segments(ctxt, &cs, &ss); @@ -1651,14 +1654,16 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt) /* inject #GP if in real mode */ if (ctxt->mode == X86EMUL_MODE_REAL) { kvm_inject_gp(ctxt->vcpu, 0); - return X86EMUL_UNHANDLEABLE; + return X86EMUL_PROPAGATE_FAULT; } /* XXX sysenter/sysexit have not been tested in 64bit mode. * Therefore, we inject an #UD. */ - if (ctxt->mode == X86EMUL_MODE_PROT64) - return X86EMUL_UNHANDLEABLE; + if (ctxt->mode == X86EMUL_MODE_PROT64) { + kvm_queue_exception(ctxt->vcpu, UD_VECTOR); + return X86EMUL_PROPAGATE_FAULT; + } setup_syscalls_segments(ctxt, &cs, &ss); @@ -1713,7 +1718,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) if (ctxt->mode == X86EMUL_MODE_REAL || ctxt->mode == X86EMUL_MODE_VM86) { kvm_inject_gp(ctxt->vcpu, 0); - return X86EMUL_UNHANDLEABLE; + return X86EMUL_PROPAGATE_FAULT; } setup_syscalls_segments(ctxt, &cs, &ss); -- cgit v1.2.3-59-g8ed1b From fd5253658b403d51fc19e56ecb44c54a3071fded Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:13 +0200 Subject: KVM: x86 emulator: do not call writeback if msr access fails. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 1393bf034243..b89a8f217332 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2563,7 +2563,7 @@ twobyte_insn: | ((u64)c->regs[VCPU_REGS_RDX] << 32); if (kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data)) { kvm_inject_gp(ctxt->vcpu, 0); - c->eip = ctxt->eip; + goto done; } rc = X86EMUL_CONTINUE; c->dst.type = OP_NONE; @@ -2572,7 +2572,7 @@ twobyte_insn: /* rdmsr */ if (kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data)) { kvm_inject_gp(ctxt->vcpu, 0); - c->eip = ctxt->eip; + goto done; } else { c->regs[VCPU_REGS_RAX] = (u32)msr_data; c->regs[VCPU_REGS_RDX] = msr_data >> 32; -- cgit v1.2.3-59-g8ed1b From a41ffb7540cb37426759e688083502d6463421b2 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:14 +0200 Subject: KVM: x86 emulator: If LOCK prefix is used dest arg should be memory. If LOCK prefix is used dest arg should be memory, otherwise instruction should generate #UD. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index b89a8f217332..46a7ee3040a0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1842,7 +1842,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) } /* LOCK prefix is allowed only with some instructions */ - if (c->lock_prefix && !(c->d & Lock)) { + if (c->lock_prefix && (!(c->d & Lock) || c->dst.type != OP_MEM)) { kvm_queue_exception(ctxt->vcpu, UD_VECTOR); goto done; } -- cgit v1.2.3-59-g8ed1b From aca06a83071e4e4c9150751db7ea6a46240734fc Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:15 +0200 Subject: KVM: x86 emulator: cleanup grp3 return value When x86_emulate_insn() does not know how to emulate instruction it exits via cannot_emulate label in all cases except when emulating grp3. Fix that. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 46a7ee3040a0..d696cbd6ff7a 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1397,7 +1397,6 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = &ctxt->decode; - int rc = X86EMUL_CONTINUE; switch (c->modrm_reg) { case 0 ... 1: /* test */ @@ -1410,11 +1409,9 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, emulate_1op("neg", c->dst, ctxt->eflags); break; default: - DPRINTF("Cannot emulate %02x\n", c->b); - rc = X86EMUL_UNHANDLEABLE; - break; + return 0; } - return rc; + return 1; } static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, @@ -2374,9 +2371,8 @@ special_insn: c->dst.type = OP_NONE; /* Disable writeback. */ break; case 0xf6 ... 0xf7: /* Grp3 */ - rc = emulate_grp3(ctxt, ops); - if (rc != X86EMUL_CONTINUE) - goto done; + if (!emulate_grp3(ctxt, ops)) + goto cannot_emulate; break; case 0xf8: /* clc */ ctxt->eflags &= ~EFLG_CF; -- cgit v1.2.3-59-g8ed1b From 2dafc6c234b6064189405f42e1602e9a0abe5a44 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:16 +0200 Subject: KVM: x86 emulator: Provide more callbacks for x86 emulator. Provide get_cached_descriptor(), set_cached_descriptor(), get_segment_selector(), set_segment_selector(), get_gdt(), write_std() callbacks. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_emulate.h | 16 +++++ arch/x86/kvm/x86.c | 130 ++++++++++++++++++++++++++++++++----- 2 files changed, 131 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 07657258af8f..f901467a18b0 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -62,6 +62,15 @@ struct x86_emulate_ops { int (*read_std)(unsigned long addr, void *val, unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error); + /* + * write_std: Write bytes of standard (non-emulated/special) memory. + * Used for descriptor writing. + * @addr: [IN ] Linear address to which to write. + * @val: [OUT] Value write to memory, zero-extended to 'u_long'. + * @bytes: [IN ] Number of bytes to write to memory. + */ + int (*write_std)(unsigned long addr, void *val, + unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error); /* * fetch: Read bytes of standard (non-emulated/special) memory. * Used for instruction fetch. @@ -108,6 +117,13 @@ struct x86_emulate_ops { const void *new, unsigned int bytes, struct kvm_vcpu *vcpu); + bool (*get_cached_descriptor)(struct desc_struct *desc, + int seg, struct kvm_vcpu *vcpu); + void (*set_cached_descriptor)(struct desc_struct *desc, + int seg, struct kvm_vcpu *vcpu); + u16 (*get_segment_selector)(int seg, struct kvm_vcpu *vcpu); + void (*set_segment_selector)(u16 sel, int seg, struct kvm_vcpu *vcpu); + void (*get_gdt)(struct desc_ptr *dt, struct kvm_vcpu *vcpu); ulong (*get_cr)(int cr, struct kvm_vcpu *vcpu); void (*set_cr)(int cr, ulong val, struct kvm_vcpu *vcpu); int (*cpl)(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0ecd37ac9d39..fbee8fbb33b5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3058,6 +3058,18 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v) return kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, addr, len, v); } +static void kvm_set_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg) +{ + kvm_x86_ops->set_segment(vcpu, var, seg); +} + +void kvm_get_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg) +{ + kvm_x86_ops->get_segment(vcpu, var, seg); +} + gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) { u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; @@ -3138,14 +3150,18 @@ static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes, return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error); } -static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes, - struct kvm_vcpu *vcpu, u32 *error) +static int kvm_write_guest_virt_helper(gva_t addr, void *val, + unsigned int bytes, + struct kvm_vcpu *vcpu, u32 access, + u32 *error) { void *data = val; int r = X86EMUL_CONTINUE; + access |= PFERR_WRITE_MASK; + while (bytes) { - gpa_t gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error); + gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr, access, error); unsigned offset = addr & (PAGE_SIZE-1); unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); int ret; @@ -3168,6 +3184,19 @@ out: return r; } +static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes, + struct kvm_vcpu *vcpu, u32 *error) +{ + u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; + return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, access, error); +} + +static int kvm_write_guest_virt_system(gva_t addr, void *val, + unsigned int bytes, + struct kvm_vcpu *vcpu, u32 *error) +{ + return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, 0, error); +} static int emulator_read_emulated(unsigned long addr, void *val, @@ -3484,12 +3513,95 @@ static int emulator_get_cpl(struct kvm_vcpu *vcpu) return kvm_x86_ops->get_cpl(vcpu); } +static void emulator_get_gdt(struct desc_ptr *dt, struct kvm_vcpu *vcpu) +{ + kvm_x86_ops->get_gdt(vcpu, dt); +} + +static bool emulator_get_cached_descriptor(struct desc_struct *desc, int seg, + struct kvm_vcpu *vcpu) +{ + struct kvm_segment var; + + kvm_get_segment(vcpu, &var, seg); + + if (var.unusable) + return false; + + if (var.g) + var.limit >>= 12; + set_desc_limit(desc, var.limit); + set_desc_base(desc, (unsigned long)var.base); + desc->type = var.type; + desc->s = var.s; + desc->dpl = var.dpl; + desc->p = var.present; + desc->avl = var.avl; + desc->l = var.l; + desc->d = var.db; + desc->g = var.g; + + return true; +} + +static void emulator_set_cached_descriptor(struct desc_struct *desc, int seg, + struct kvm_vcpu *vcpu) +{ + struct kvm_segment var; + + /* needed to preserve selector */ + kvm_get_segment(vcpu, &var, seg); + + var.base = get_desc_base(desc); + var.limit = get_desc_limit(desc); + if (desc->g) + var.limit = (var.limit << 12) | 0xfff; + var.type = desc->type; + var.present = desc->p; + var.dpl = desc->dpl; + var.db = desc->d; + var.s = desc->s; + var.l = desc->l; + var.g = desc->g; + var.avl = desc->avl; + var.present = desc->p; + var.unusable = !var.present; + var.padding = 0; + + kvm_set_segment(vcpu, &var, seg); + return; +} + +static u16 emulator_get_segment_selector(int seg, struct kvm_vcpu *vcpu) +{ + struct kvm_segment kvm_seg; + + kvm_get_segment(vcpu, &kvm_seg, seg); + return kvm_seg.selector; +} + +static void emulator_set_segment_selector(u16 sel, int seg, + struct kvm_vcpu *vcpu) +{ + struct kvm_segment kvm_seg; + + kvm_get_segment(vcpu, &kvm_seg, seg); + kvm_seg.selector = sel; + kvm_set_segment(vcpu, &kvm_seg, seg); +} + static struct x86_emulate_ops emulate_ops = { .read_std = kvm_read_guest_virt_system, + .write_std = kvm_write_guest_virt_system, .fetch = kvm_fetch_guest_virt, .read_emulated = emulator_read_emulated, .write_emulated = emulator_write_emulated, .cmpxchg_emulated = emulator_cmpxchg_emulated, + .get_cached_descriptor = emulator_get_cached_descriptor, + .set_cached_descriptor = emulator_set_cached_descriptor, + .get_segment_selector = emulator_get_segment_selector, + .set_segment_selector = emulator_set_segment_selector, + .get_gdt = emulator_get_gdt, .get_cr = emulator_get_cr, .set_cr = emulator_set_cr, .cpl = emulator_get_cpl, @@ -4649,12 +4761,6 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) return 0; } -void kvm_get_segment(struct kvm_vcpu *vcpu, - struct kvm_segment *var, int seg) -{ - kvm_x86_ops->get_segment(vcpu, var, seg); -} - void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) { struct kvm_segment cs; @@ -4726,12 +4832,6 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, return 0; } -static void kvm_set_segment(struct kvm_vcpu *vcpu, - struct kvm_segment *var, int seg) -{ - kvm_x86_ops->set_segment(vcpu, var, seg); -} - static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector, struct kvm_segment *kvm_desct) { -- cgit v1.2.3-59-g8ed1b From 38ba30ba51a003360f177d5b8349439fe44fc55b Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:17 +0200 Subject: KVM: x86 emulator: Emulate task switch in emulator.c Implement emulation of 16/32 bit task switch in emulator.c Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_emulate.h | 5 + arch/x86/kvm/emulate.c | 563 +++++++++++++++++++++++++++++++++++++ 2 files changed, 568 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index f901467a18b0..bd469296f5e5 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -11,6 +11,8 @@ #ifndef _ASM_X86_KVM_X86_EMULATE_H #define _ASM_X86_KVM_X86_EMULATE_H +#include + struct x86_emulate_ctxt; /* @@ -210,5 +212,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops); int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops); +int emulator_task_switch(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 tss_selector, int reason); #endif /* _ASM_X86_KVM_X86_EMULATE_H */ diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d696cbd6ff7a..db4776c6b500 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -33,6 +33,7 @@ #include #include "x86.h" +#include "tss.h" /* * Opcode effective-address decode tables. @@ -1221,6 +1222,198 @@ done: return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; } +static u32 desc_limit_scaled(struct desc_struct *desc) +{ + u32 limit = get_desc_limit(desc); + + return desc->g ? (limit << 12) | 0xfff : limit; +} + +static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 selector, struct desc_ptr *dt) +{ + if (selector & 1 << 2) { + struct desc_struct desc; + memset (dt, 0, sizeof *dt); + if (!ops->get_cached_descriptor(&desc, VCPU_SREG_LDTR, ctxt->vcpu)) + return; + + dt->size = desc_limit_scaled(&desc); /* what if limit > 65535? */ + dt->address = get_desc_base(&desc); + } else + ops->get_gdt(dt, ctxt->vcpu); +} + +/* allowed just for 8 bytes segments */ +static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 selector, struct desc_struct *desc) +{ + struct desc_ptr dt; + u16 index = selector >> 3; + int ret; + u32 err; + ulong addr; + + get_descriptor_table_ptr(ctxt, ops, selector, &dt); + + if (dt.size < index * 8 + 7) { + kvm_inject_gp(ctxt->vcpu, selector & 0xfffc); + return X86EMUL_PROPAGATE_FAULT; + } + addr = dt.address + index * 8; + ret = ops->read_std(addr, desc, sizeof *desc, ctxt->vcpu, &err); + if (ret == X86EMUL_PROPAGATE_FAULT) + kvm_inject_page_fault(ctxt->vcpu, addr, err); + + return ret; +} + +/* allowed just for 8 bytes segments */ +static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 selector, struct desc_struct *desc) +{ + struct desc_ptr dt; + u16 index = selector >> 3; + u32 err; + ulong addr; + int ret; + + get_descriptor_table_ptr(ctxt, ops, selector, &dt); + + if (dt.size < index * 8 + 7) { + kvm_inject_gp(ctxt->vcpu, selector & 0xfffc); + return X86EMUL_PROPAGATE_FAULT; + } + + addr = dt.address + index * 8; + ret = ops->write_std(addr, desc, sizeof *desc, ctxt->vcpu, &err); + if (ret == X86EMUL_PROPAGATE_FAULT) + kvm_inject_page_fault(ctxt->vcpu, addr, err); + + return ret; +} + +static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 selector, int seg) +{ + struct desc_struct seg_desc; + u8 dpl, rpl, cpl; + unsigned err_vec = GP_VECTOR; + u32 err_code = 0; + bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */ + int ret; + + memset(&seg_desc, 0, sizeof seg_desc); + + if ((seg <= VCPU_SREG_GS && ctxt->mode == X86EMUL_MODE_VM86) + || ctxt->mode == X86EMUL_MODE_REAL) { + /* set real mode segment descriptor */ + set_desc_base(&seg_desc, selector << 4); + set_desc_limit(&seg_desc, 0xffff); + seg_desc.type = 3; + seg_desc.p = 1; + seg_desc.s = 1; + goto load; + } + + /* NULL selector is not valid for TR, CS and SS */ + if ((seg == VCPU_SREG_CS || seg == VCPU_SREG_SS || seg == VCPU_SREG_TR) + && null_selector) + goto exception; + + /* TR should be in GDT only */ + if (seg == VCPU_SREG_TR && (selector & (1 << 2))) + goto exception; + + if (null_selector) /* for NULL selector skip all following checks */ + goto load; + + ret = read_segment_descriptor(ctxt, ops, selector, &seg_desc); + if (ret != X86EMUL_CONTINUE) + return ret; + + err_code = selector & 0xfffc; + err_vec = GP_VECTOR; + + /* can't load system descriptor into segment selecor */ + if (seg <= VCPU_SREG_GS && !seg_desc.s) + goto exception; + + if (!seg_desc.p) { + err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR; + goto exception; + } + + rpl = selector & 3; + dpl = seg_desc.dpl; + cpl = ops->cpl(ctxt->vcpu); + + switch (seg) { + case VCPU_SREG_SS: + /* + * segment is not a writable data segment or segment + * selector's RPL != CPL or segment selector's RPL != CPL + */ + if (rpl != cpl || (seg_desc.type & 0xa) != 0x2 || dpl != cpl) + goto exception; + break; + case VCPU_SREG_CS: + if (!(seg_desc.type & 8)) + goto exception; + + if (seg_desc.type & 4) { + /* conforming */ + if (dpl > cpl) + goto exception; + } else { + /* nonconforming */ + if (rpl > cpl || dpl != cpl) + goto exception; + } + /* CS(RPL) <- CPL */ + selector = (selector & 0xfffc) | cpl; + break; + case VCPU_SREG_TR: + if (seg_desc.s || (seg_desc.type != 1 && seg_desc.type != 9)) + goto exception; + break; + case VCPU_SREG_LDTR: + if (seg_desc.s || seg_desc.type != 2) + goto exception; + break; + default: /* DS, ES, FS, or GS */ + /* + * segment is not a data or readable code segment or + * ((segment is a data or nonconforming code segment) + * and (both RPL and CPL > DPL)) + */ + if ((seg_desc.type & 0xa) == 0x8 || + (((seg_desc.type & 0xc) != 0xc) && + (rpl > dpl && cpl > dpl))) + goto exception; + break; + } + + if (seg_desc.s) { + /* mark segment as accessed */ + seg_desc.type |= 1; + ret = write_segment_descriptor(ctxt, ops, selector, &seg_desc); + if (ret != X86EMUL_CONTINUE) + return ret; + } +load: + ops->set_segment_selector(selector, seg, ctxt->vcpu); + ops->set_cached_descriptor(&seg_desc, seg, ctxt->vcpu); + return X86EMUL_CONTINUE; +exception: + kvm_queue_exception_e(ctxt->vcpu, err_vec, err_code); + return X86EMUL_PROPAGATE_FAULT; +} + static inline void emulate_push(struct x86_emulate_ctxt *ctxt) { struct decode_cache *c = &ctxt->decode; @@ -1812,6 +2005,376 @@ static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt, return true; } +static u32 get_cached_descriptor_base(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + int seg) +{ + struct desc_struct desc; + if (ops->get_cached_descriptor(&desc, seg, ctxt->vcpu)) + return get_desc_base(&desc); + else + return ~0; +} + +static void save_state_to_tss16(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + struct tss_segment_16 *tss) +{ + struct decode_cache *c = &ctxt->decode; + + tss->ip = c->eip; + tss->flag = ctxt->eflags; + tss->ax = c->regs[VCPU_REGS_RAX]; + tss->cx = c->regs[VCPU_REGS_RCX]; + tss->dx = c->regs[VCPU_REGS_RDX]; + tss->bx = c->regs[VCPU_REGS_RBX]; + tss->sp = c->regs[VCPU_REGS_RSP]; + tss->bp = c->regs[VCPU_REGS_RBP]; + tss->si = c->regs[VCPU_REGS_RSI]; + tss->di = c->regs[VCPU_REGS_RDI]; + + tss->es = ops->get_segment_selector(VCPU_SREG_ES, ctxt->vcpu); + tss->cs = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu); + tss->ss = ops->get_segment_selector(VCPU_SREG_SS, ctxt->vcpu); + tss->ds = ops->get_segment_selector(VCPU_SREG_DS, ctxt->vcpu); + tss->ldt = ops->get_segment_selector(VCPU_SREG_LDTR, ctxt->vcpu); +} + +static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + struct tss_segment_16 *tss) +{ + struct decode_cache *c = &ctxt->decode; + int ret; + + c->eip = tss->ip; + ctxt->eflags = tss->flag | 2; + c->regs[VCPU_REGS_RAX] = tss->ax; + c->regs[VCPU_REGS_RCX] = tss->cx; + c->regs[VCPU_REGS_RDX] = tss->dx; + c->regs[VCPU_REGS_RBX] = tss->bx; + c->regs[VCPU_REGS_RSP] = tss->sp; + c->regs[VCPU_REGS_RBP] = tss->bp; + c->regs[VCPU_REGS_RSI] = tss->si; + c->regs[VCPU_REGS_RDI] = tss->di; + + /* + * SDM says that segment selectors are loaded before segment + * descriptors + */ + ops->set_segment_selector(tss->ldt, VCPU_SREG_LDTR, ctxt->vcpu); + ops->set_segment_selector(tss->es, VCPU_SREG_ES, ctxt->vcpu); + ops->set_segment_selector(tss->cs, VCPU_SREG_CS, ctxt->vcpu); + ops->set_segment_selector(tss->ss, VCPU_SREG_SS, ctxt->vcpu); + ops->set_segment_selector(tss->ds, VCPU_SREG_DS, ctxt->vcpu); + + /* + * Now load segment descriptors. If fault happenes at this stage + * it is handled in a context of new task + */ + ret = load_segment_descriptor(ctxt, ops, tss->ldt, VCPU_SREG_LDTR); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = load_segment_descriptor(ctxt, ops, tss->es, VCPU_SREG_ES); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = load_segment_descriptor(ctxt, ops, tss->cs, VCPU_SREG_CS); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = load_segment_descriptor(ctxt, ops, tss->ss, VCPU_SREG_SS); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = load_segment_descriptor(ctxt, ops, tss->ds, VCPU_SREG_DS); + if (ret != X86EMUL_CONTINUE) + return ret; + + return X86EMUL_CONTINUE; +} + +static int task_switch_16(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 tss_selector, u16 old_tss_sel, + ulong old_tss_base, struct desc_struct *new_desc) +{ + struct tss_segment_16 tss_seg; + int ret; + u32 err, new_tss_base = get_desc_base(new_desc); + + ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, + &err); + if (ret == X86EMUL_PROPAGATE_FAULT) { + /* FIXME: need to provide precise fault address */ + kvm_inject_page_fault(ctxt->vcpu, old_tss_base, err); + return ret; + } + + save_state_to_tss16(ctxt, ops, &tss_seg); + + ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, + &err); + if (ret == X86EMUL_PROPAGATE_FAULT) { + /* FIXME: need to provide precise fault address */ + kvm_inject_page_fault(ctxt->vcpu, old_tss_base, err); + return ret; + } + + ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, + &err); + if (ret == X86EMUL_PROPAGATE_FAULT) { + /* FIXME: need to provide precise fault address */ + kvm_inject_page_fault(ctxt->vcpu, new_tss_base, err); + return ret; + } + + if (old_tss_sel != 0xffff) { + tss_seg.prev_task_link = old_tss_sel; + + ret = ops->write_std(new_tss_base, + &tss_seg.prev_task_link, + sizeof tss_seg.prev_task_link, + ctxt->vcpu, &err); + if (ret == X86EMUL_PROPAGATE_FAULT) { + /* FIXME: need to provide precise fault address */ + kvm_inject_page_fault(ctxt->vcpu, new_tss_base, err); + return ret; + } + } + + return load_state_from_tss16(ctxt, ops, &tss_seg); +} + +static void save_state_to_tss32(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + struct tss_segment_32 *tss) +{ + struct decode_cache *c = &ctxt->decode; + + tss->cr3 = ops->get_cr(3, ctxt->vcpu); + tss->eip = c->eip; + tss->eflags = ctxt->eflags; + tss->eax = c->regs[VCPU_REGS_RAX]; + tss->ecx = c->regs[VCPU_REGS_RCX]; + tss->edx = c->regs[VCPU_REGS_RDX]; + tss->ebx = c->regs[VCPU_REGS_RBX]; + tss->esp = c->regs[VCPU_REGS_RSP]; + tss->ebp = c->regs[VCPU_REGS_RBP]; + tss->esi = c->regs[VCPU_REGS_RSI]; + tss->edi = c->regs[VCPU_REGS_RDI]; + + tss->es = ops->get_segment_selector(VCPU_SREG_ES, ctxt->vcpu); + tss->cs = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu); + tss->ss = ops->get_segment_selector(VCPU_SREG_SS, ctxt->vcpu); + tss->ds = ops->get_segment_selector(VCPU_SREG_DS, ctxt->vcpu); + tss->fs = ops->get_segment_selector(VCPU_SREG_FS, ctxt->vcpu); + tss->gs = ops->get_segment_selector(VCPU_SREG_GS, ctxt->vcpu); + tss->ldt_selector = ops->get_segment_selector(VCPU_SREG_LDTR, ctxt->vcpu); +} + +static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + struct tss_segment_32 *tss) +{ + struct decode_cache *c = &ctxt->decode; + int ret; + + ops->set_cr(3, tss->cr3, ctxt->vcpu); + c->eip = tss->eip; + ctxt->eflags = tss->eflags | 2; + c->regs[VCPU_REGS_RAX] = tss->eax; + c->regs[VCPU_REGS_RCX] = tss->ecx; + c->regs[VCPU_REGS_RDX] = tss->edx; + c->regs[VCPU_REGS_RBX] = tss->ebx; + c->regs[VCPU_REGS_RSP] = tss->esp; + c->regs[VCPU_REGS_RBP] = tss->ebp; + c->regs[VCPU_REGS_RSI] = tss->esi; + c->regs[VCPU_REGS_RDI] = tss->edi; + + /* + * SDM says that segment selectors are loaded before segment + * descriptors + */ + ops->set_segment_selector(tss->ldt_selector, VCPU_SREG_LDTR, ctxt->vcpu); + ops->set_segment_selector(tss->es, VCPU_SREG_ES, ctxt->vcpu); + ops->set_segment_selector(tss->cs, VCPU_SREG_CS, ctxt->vcpu); + ops->set_segment_selector(tss->ss, VCPU_SREG_SS, ctxt->vcpu); + ops->set_segment_selector(tss->ds, VCPU_SREG_DS, ctxt->vcpu); + ops->set_segment_selector(tss->fs, VCPU_SREG_FS, ctxt->vcpu); + ops->set_segment_selector(tss->gs, VCPU_SREG_GS, ctxt->vcpu); + + /* + * Now load segment descriptors. If fault happenes at this stage + * it is handled in a context of new task + */ + ret = load_segment_descriptor(ctxt, ops, tss->ldt_selector, VCPU_SREG_LDTR); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = load_segment_descriptor(ctxt, ops, tss->es, VCPU_SREG_ES); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = load_segment_descriptor(ctxt, ops, tss->cs, VCPU_SREG_CS); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = load_segment_descriptor(ctxt, ops, tss->ss, VCPU_SREG_SS); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = load_segment_descriptor(ctxt, ops, tss->ds, VCPU_SREG_DS); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = load_segment_descriptor(ctxt, ops, tss->fs, VCPU_SREG_FS); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = load_segment_descriptor(ctxt, ops, tss->gs, VCPU_SREG_GS); + if (ret != X86EMUL_CONTINUE) + return ret; + + return X86EMUL_CONTINUE; +} + +static int task_switch_32(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 tss_selector, u16 old_tss_sel, + ulong old_tss_base, struct desc_struct *new_desc) +{ + struct tss_segment_32 tss_seg; + int ret; + u32 err, new_tss_base = get_desc_base(new_desc); + + ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, + &err); + if (ret == X86EMUL_PROPAGATE_FAULT) { + /* FIXME: need to provide precise fault address */ + kvm_inject_page_fault(ctxt->vcpu, old_tss_base, err); + return ret; + } + + save_state_to_tss32(ctxt, ops, &tss_seg); + + ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, + &err); + if (ret == X86EMUL_PROPAGATE_FAULT) { + /* FIXME: need to provide precise fault address */ + kvm_inject_page_fault(ctxt->vcpu, old_tss_base, err); + return ret; + } + + ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, + &err); + if (ret == X86EMUL_PROPAGATE_FAULT) { + /* FIXME: need to provide precise fault address */ + kvm_inject_page_fault(ctxt->vcpu, new_tss_base, err); + return ret; + } + + if (old_tss_sel != 0xffff) { + tss_seg.prev_task_link = old_tss_sel; + + ret = ops->write_std(new_tss_base, + &tss_seg.prev_task_link, + sizeof tss_seg.prev_task_link, + ctxt->vcpu, &err); + if (ret == X86EMUL_PROPAGATE_FAULT) { + /* FIXME: need to provide precise fault address */ + kvm_inject_page_fault(ctxt->vcpu, new_tss_base, err); + return ret; + } + } + + return load_state_from_tss32(ctxt, ops, &tss_seg); +} + +static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 tss_selector, int reason) +{ + struct desc_struct curr_tss_desc, next_tss_desc; + int ret; + u16 old_tss_sel = ops->get_segment_selector(VCPU_SREG_TR, ctxt->vcpu); + ulong old_tss_base = + get_cached_descriptor_base(ctxt, ops, VCPU_SREG_TR); + + /* FIXME: old_tss_base == ~0 ? */ + + ret = read_segment_descriptor(ctxt, ops, tss_selector, &next_tss_desc); + if (ret != X86EMUL_CONTINUE) + return ret; + ret = read_segment_descriptor(ctxt, ops, old_tss_sel, &curr_tss_desc); + if (ret != X86EMUL_CONTINUE) + return ret; + + /* FIXME: check that next_tss_desc is tss */ + + if (reason != TASK_SWITCH_IRET) { + if ((tss_selector & 3) > next_tss_desc.dpl || + ops->cpl(ctxt->vcpu) > next_tss_desc.dpl) { + kvm_inject_gp(ctxt->vcpu, 0); + return X86EMUL_PROPAGATE_FAULT; + } + } + + if (!next_tss_desc.p || desc_limit_scaled(&next_tss_desc) < 0x67) { + kvm_queue_exception_e(ctxt->vcpu, TS_VECTOR, + tss_selector & 0xfffc); + return X86EMUL_PROPAGATE_FAULT; + } + + if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) { + curr_tss_desc.type &= ~(1 << 1); /* clear busy flag */ + write_segment_descriptor(ctxt, ops, old_tss_sel, + &curr_tss_desc); + } + + if (reason == TASK_SWITCH_IRET) + ctxt->eflags = ctxt->eflags & ~X86_EFLAGS_NT; + + /* set back link to prev task only if NT bit is set in eflags + note that old_tss_sel is not used afetr this point */ + if (reason != TASK_SWITCH_CALL && reason != TASK_SWITCH_GATE) + old_tss_sel = 0xffff; + + if (next_tss_desc.type & 8) + ret = task_switch_32(ctxt, ops, tss_selector, old_tss_sel, + old_tss_base, &next_tss_desc); + else + ret = task_switch_16(ctxt, ops, tss_selector, old_tss_sel, + old_tss_base, &next_tss_desc); + + if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) + ctxt->eflags = ctxt->eflags | X86_EFLAGS_NT; + + if (reason != TASK_SWITCH_IRET) { + next_tss_desc.type |= (1 << 1); /* set busy flag */ + write_segment_descriptor(ctxt, ops, tss_selector, + &next_tss_desc); + } + + ops->set_cr(0, ops->get_cr(0, ctxt->vcpu) | X86_CR0_TS, ctxt->vcpu); + ops->set_cached_descriptor(&next_tss_desc, VCPU_SREG_TR, ctxt->vcpu); + ops->set_segment_selector(tss_selector, VCPU_SREG_TR, ctxt->vcpu); + + return ret; +} + +int emulator_task_switch(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 tss_selector, int reason) +{ + struct decode_cache *c = &ctxt->decode; + int rc; + + memset(c, 0, sizeof(struct decode_cache)); + c->eip = ctxt->eip; + memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); + + rc = emulator_do_task_switch(ctxt, ops, tss_selector, reason); + + if (rc == X86EMUL_CONTINUE) { + memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); + kvm_rip_write(ctxt->vcpu, c->eip); + } + + return rc; +} + int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { -- cgit v1.2.3-59-g8ed1b From 2e873022f511b82a5318c7af179f588f08d68cb9 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:18 +0200 Subject: KVM: x86 emulator: Use load_segment_descriptor() instead of kvm_load_segment_descriptor() Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index db4776c6b500..702bffffd27f 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1508,7 +1508,7 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt, if (rc != X86EMUL_CONTINUE) return rc; - rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, seg); + rc = load_segment_descriptor(ctxt, ops, (u16)selector, seg); return rc; } @@ -1683,7 +1683,7 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); if (rc != X86EMUL_CONTINUE) return rc; - rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, VCPU_SREG_CS); + rc = load_segment_descriptor(ctxt, ops, (u16)cs, VCPU_SREG_CS); return rc; } @@ -2717,7 +2717,7 @@ special_insn: if (c->modrm_reg == VCPU_SREG_SS) toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_MOV_SS); - rc = kvm_load_segment_descriptor(ctxt->vcpu, sel, c->modrm_reg); + rc = load_segment_descriptor(ctxt, ops, sel, c->modrm_reg); c->dst.type = OP_NONE; /* Disable writeback. */ break; @@ -2892,8 +2892,8 @@ special_insn: goto jmp; case 0xea: /* jmp far */ jump_far: - if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, - VCPU_SREG_CS)) + if (load_segment_descriptor(ctxt, ops, c->src2.val, + VCPU_SREG_CS)) goto done; c->eip = c->src.val; -- cgit v1.2.3-59-g8ed1b From ceffb4597253b2420d2f171d8b1cdf2cd3137989 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:19 +0200 Subject: KVM: Use task switch from emulator.c Remove old task switch code from x86.c Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 6 +- arch/x86/kvm/x86.c | 561 ++----------------------------------------------- 2 files changed, 22 insertions(+), 545 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 702bffffd27f..8225ec26efed 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2291,6 +2291,7 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, u16 old_tss_sel = ops->get_segment_selector(VCPU_SREG_TR, ctxt->vcpu); ulong old_tss_base = get_cached_descriptor_base(ctxt, ops, VCPU_SREG_TR); + u32 desc_limit; /* FIXME: old_tss_base == ~0 ? */ @@ -2311,7 +2312,10 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, } } - if (!next_tss_desc.p || desc_limit_scaled(&next_tss_desc) < 0x67) { + desc_limit = desc_limit_scaled(&next_tss_desc); + if (!next_tss_desc.p || + ((desc_limit < 0x67 && (next_tss_desc.type & 8)) || + desc_limit < 0x2b)) { kvm_queue_exception_e(ctxt->vcpu, TS_VECTOR, tss_selector & 0xfffc); return X86EMUL_PROPAGATE_FAULT; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fbee8fbb33b5..f69854c8f339 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4832,557 +4832,30 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, return 0; } -static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector, - struct kvm_segment *kvm_desct) -{ - kvm_desct->base = get_desc_base(seg_desc); - kvm_desct->limit = get_desc_limit(seg_desc); - if (seg_desc->g) { - kvm_desct->limit <<= 12; - kvm_desct->limit |= 0xfff; - } - kvm_desct->selector = selector; - kvm_desct->type = seg_desc->type; - kvm_desct->present = seg_desc->p; - kvm_desct->dpl = seg_desc->dpl; - kvm_desct->db = seg_desc->d; - kvm_desct->s = seg_desc->s; - kvm_desct->l = seg_desc->l; - kvm_desct->g = seg_desc->g; - kvm_desct->avl = seg_desc->avl; - if (!selector) - kvm_desct->unusable = 1; - else - kvm_desct->unusable = 0; - kvm_desct->padding = 0; -} - -static void get_segment_descriptor_dtable(struct kvm_vcpu *vcpu, - u16 selector, - struct desc_ptr *dtable) -{ - if (selector & 1 << 2) { - struct kvm_segment kvm_seg; - - kvm_get_segment(vcpu, &kvm_seg, VCPU_SREG_LDTR); - - if (kvm_seg.unusable) - dtable->size = 0; - else - dtable->size = kvm_seg.limit; - dtable->address = kvm_seg.base; - } - else - kvm_x86_ops->get_gdt(vcpu, dtable); -} - -/* allowed just for 8 bytes segments */ -static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, - struct desc_struct *seg_desc) -{ - struct desc_ptr dtable; - u16 index = selector >> 3; - int ret; - u32 err; - gva_t addr; - - get_segment_descriptor_dtable(vcpu, selector, &dtable); - - if (dtable.size < index * 8 + 7) { - kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); - return X86EMUL_PROPAGATE_FAULT; - } - addr = dtable.base + index * 8; - ret = kvm_read_guest_virt_system(addr, seg_desc, sizeof(*seg_desc), - vcpu, &err); - if (ret == X86EMUL_PROPAGATE_FAULT) - kvm_inject_page_fault(vcpu, addr, err); - - return ret; -} - -/* allowed just for 8 bytes segments */ -static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, - struct desc_struct *seg_desc) -{ - struct desc_ptr dtable; - u16 index = selector >> 3; - - get_segment_descriptor_dtable(vcpu, selector, &dtable); - - if (dtable.size < index * 8 + 7) - return 1; - return kvm_write_guest_virt(dtable.address + index*8, seg_desc, sizeof(*seg_desc), vcpu, NULL); -} - -static gpa_t get_tss_base_addr_write(struct kvm_vcpu *vcpu, - struct desc_struct *seg_desc) -{ - u32 base_addr = get_desc_base(seg_desc); - - return kvm_mmu_gva_to_gpa_write(vcpu, base_addr, NULL); -} - -static gpa_t get_tss_base_addr_read(struct kvm_vcpu *vcpu, - struct desc_struct *seg_desc) -{ - u32 base_addr = get_desc_base(seg_desc); - - return kvm_mmu_gva_to_gpa_read(vcpu, base_addr, NULL); -} - -static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg) -{ - struct kvm_segment kvm_seg; - - kvm_get_segment(vcpu, &kvm_seg, seg); - return kvm_seg.selector; -} - -static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg) -{ - struct kvm_segment segvar = { - .base = selector << 4, - .limit = 0xffff, - .selector = selector, - .type = 3, - .present = 1, - .dpl = 3, - .db = 0, - .s = 1, - .l = 0, - .g = 0, - .avl = 0, - .unusable = 0, - }; - kvm_x86_ops->set_segment(vcpu, &segvar, seg); - return X86EMUL_CONTINUE; -} - -static int is_vm86_segment(struct kvm_vcpu *vcpu, int seg) -{ - return (seg != VCPU_SREG_LDTR) && - (seg != VCPU_SREG_TR) && - (kvm_get_rflags(vcpu) & X86_EFLAGS_VM); -} - -int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg) -{ - struct kvm_segment kvm_seg; - struct desc_struct seg_desc; - u8 dpl, rpl, cpl; - unsigned err_vec = GP_VECTOR; - u32 err_code = 0; - bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */ - int ret; - - if (is_vm86_segment(vcpu, seg) || !is_protmode(vcpu)) - return kvm_load_realmode_segment(vcpu, selector, seg); - - /* NULL selector is not valid for TR, CS and SS */ - if ((seg == VCPU_SREG_CS || seg == VCPU_SREG_SS || seg == VCPU_SREG_TR) - && null_selector) - goto exception; - - /* TR should be in GDT only */ - if (seg == VCPU_SREG_TR && (selector & (1 << 2))) - goto exception; - - ret = load_guest_segment_descriptor(vcpu, selector, &seg_desc); - if (ret) - return ret; - - seg_desct_to_kvm_desct(&seg_desc, selector, &kvm_seg); - - if (null_selector) { /* for NULL selector skip all following checks */ - kvm_seg.unusable = 1; - goto load; - } - - err_code = selector & 0xfffc; - err_vec = GP_VECTOR; - - /* can't load system descriptor into segment selecor */ - if (seg <= VCPU_SREG_GS && !kvm_seg.s) - goto exception; - - if (!kvm_seg.present) { - err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR; - goto exception; - } - - rpl = selector & 3; - dpl = kvm_seg.dpl; - cpl = kvm_x86_ops->get_cpl(vcpu); - - switch (seg) { - case VCPU_SREG_SS: - /* - * segment is not a writable data segment or segment - * selector's RPL != CPL or segment selector's RPL != CPL - */ - if (rpl != cpl || (kvm_seg.type & 0xa) != 0x2 || dpl != cpl) - goto exception; - break; - case VCPU_SREG_CS: - if (!(kvm_seg.type & 8)) - goto exception; - - if (kvm_seg.type & 4) { - /* conforming */ - if (dpl > cpl) - goto exception; - } else { - /* nonconforming */ - if (rpl > cpl || dpl != cpl) - goto exception; - } - /* CS(RPL) <- CPL */ - selector = (selector & 0xfffc) | cpl; - break; - case VCPU_SREG_TR: - if (kvm_seg.s || (kvm_seg.type != 1 && kvm_seg.type != 9)) - goto exception; - break; - case VCPU_SREG_LDTR: - if (kvm_seg.s || kvm_seg.type != 2) - goto exception; - break; - default: /* DS, ES, FS, or GS */ - /* - * segment is not a data or readable code segment or - * ((segment is a data or nonconforming code segment) - * and (both RPL and CPL > DPL)) - */ - if ((kvm_seg.type & 0xa) == 0x8 || - (((kvm_seg.type & 0xc) != 0xc) && (rpl > dpl && cpl > dpl))) - goto exception; - break; - } - - if (!kvm_seg.unusable && kvm_seg.s) { - /* mark segment as accessed */ - kvm_seg.type |= 1; - seg_desc.type |= 1; - save_guest_segment_descriptor(vcpu, selector, &seg_desc); - } -load: - kvm_set_segment(vcpu, &kvm_seg, seg); - return X86EMUL_CONTINUE; -exception: - kvm_queue_exception_e(vcpu, err_vec, err_code); - return X86EMUL_PROPAGATE_FAULT; -} - -static void save_state_to_tss32(struct kvm_vcpu *vcpu, - struct tss_segment_32 *tss) -{ - tss->cr3 = vcpu->arch.cr3; - tss->eip = kvm_rip_read(vcpu); - tss->eflags = kvm_get_rflags(vcpu); - tss->eax = kvm_register_read(vcpu, VCPU_REGS_RAX); - tss->ecx = kvm_register_read(vcpu, VCPU_REGS_RCX); - tss->edx = kvm_register_read(vcpu, VCPU_REGS_RDX); - tss->ebx = kvm_register_read(vcpu, VCPU_REGS_RBX); - tss->esp = kvm_register_read(vcpu, VCPU_REGS_RSP); - tss->ebp = kvm_register_read(vcpu, VCPU_REGS_RBP); - tss->esi = kvm_register_read(vcpu, VCPU_REGS_RSI); - tss->edi = kvm_register_read(vcpu, VCPU_REGS_RDI); - tss->es = get_segment_selector(vcpu, VCPU_SREG_ES); - tss->cs = get_segment_selector(vcpu, VCPU_SREG_CS); - tss->ss = get_segment_selector(vcpu, VCPU_SREG_SS); - tss->ds = get_segment_selector(vcpu, VCPU_SREG_DS); - tss->fs = get_segment_selector(vcpu, VCPU_SREG_FS); - tss->gs = get_segment_selector(vcpu, VCPU_SREG_GS); - tss->ldt_selector = get_segment_selector(vcpu, VCPU_SREG_LDTR); -} - -static void kvm_load_segment_selector(struct kvm_vcpu *vcpu, u16 sel, int seg) -{ - struct kvm_segment kvm_seg; - kvm_get_segment(vcpu, &kvm_seg, seg); - kvm_seg.selector = sel; - kvm_set_segment(vcpu, &kvm_seg, seg); -} - -static int load_state_from_tss32(struct kvm_vcpu *vcpu, - struct tss_segment_32 *tss) -{ - kvm_set_cr3(vcpu, tss->cr3); - - kvm_rip_write(vcpu, tss->eip); - kvm_set_rflags(vcpu, tss->eflags | 2); - - kvm_register_write(vcpu, VCPU_REGS_RAX, tss->eax); - kvm_register_write(vcpu, VCPU_REGS_RCX, tss->ecx); - kvm_register_write(vcpu, VCPU_REGS_RDX, tss->edx); - kvm_register_write(vcpu, VCPU_REGS_RBX, tss->ebx); - kvm_register_write(vcpu, VCPU_REGS_RSP, tss->esp); - kvm_register_write(vcpu, VCPU_REGS_RBP, tss->ebp); - kvm_register_write(vcpu, VCPU_REGS_RSI, tss->esi); - kvm_register_write(vcpu, VCPU_REGS_RDI, tss->edi); - - /* - * SDM says that segment selectors are loaded before segment - * descriptors - */ - kvm_load_segment_selector(vcpu, tss->ldt_selector, VCPU_SREG_LDTR); - kvm_load_segment_selector(vcpu, tss->es, VCPU_SREG_ES); - kvm_load_segment_selector(vcpu, tss->cs, VCPU_SREG_CS); - kvm_load_segment_selector(vcpu, tss->ss, VCPU_SREG_SS); - kvm_load_segment_selector(vcpu, tss->ds, VCPU_SREG_DS); - kvm_load_segment_selector(vcpu, tss->fs, VCPU_SREG_FS); - kvm_load_segment_selector(vcpu, tss->gs, VCPU_SREG_GS); - - /* - * Now load segment descriptors. If fault happenes at this stage - * it is handled in a context of new task - */ - if (kvm_load_segment_descriptor(vcpu, tss->ldt_selector, VCPU_SREG_LDTR)) - return 1; - - if (kvm_load_segment_descriptor(vcpu, tss->es, VCPU_SREG_ES)) - return 1; - - if (kvm_load_segment_descriptor(vcpu, tss->cs, VCPU_SREG_CS)) - return 1; - - if (kvm_load_segment_descriptor(vcpu, tss->ss, VCPU_SREG_SS)) - return 1; - - if (kvm_load_segment_descriptor(vcpu, tss->ds, VCPU_SREG_DS)) - return 1; - - if (kvm_load_segment_descriptor(vcpu, tss->fs, VCPU_SREG_FS)) - return 1; - - if (kvm_load_segment_descriptor(vcpu, tss->gs, VCPU_SREG_GS)) - return 1; - return 0; -} - -static void save_state_to_tss16(struct kvm_vcpu *vcpu, - struct tss_segment_16 *tss) -{ - tss->ip = kvm_rip_read(vcpu); - tss->flag = kvm_get_rflags(vcpu); - tss->ax = kvm_register_read(vcpu, VCPU_REGS_RAX); - tss->cx = kvm_register_read(vcpu, VCPU_REGS_RCX); - tss->dx = kvm_register_read(vcpu, VCPU_REGS_RDX); - tss->bx = kvm_register_read(vcpu, VCPU_REGS_RBX); - tss->sp = kvm_register_read(vcpu, VCPU_REGS_RSP); - tss->bp = kvm_register_read(vcpu, VCPU_REGS_RBP); - tss->si = kvm_register_read(vcpu, VCPU_REGS_RSI); - tss->di = kvm_register_read(vcpu, VCPU_REGS_RDI); - - tss->es = get_segment_selector(vcpu, VCPU_SREG_ES); - tss->cs = get_segment_selector(vcpu, VCPU_SREG_CS); - tss->ss = get_segment_selector(vcpu, VCPU_SREG_SS); - tss->ds = get_segment_selector(vcpu, VCPU_SREG_DS); - tss->ldt = get_segment_selector(vcpu, VCPU_SREG_LDTR); -} - -static int load_state_from_tss16(struct kvm_vcpu *vcpu, - struct tss_segment_16 *tss) -{ - kvm_rip_write(vcpu, tss->ip); - kvm_set_rflags(vcpu, tss->flag | 2); - kvm_register_write(vcpu, VCPU_REGS_RAX, tss->ax); - kvm_register_write(vcpu, VCPU_REGS_RCX, tss->cx); - kvm_register_write(vcpu, VCPU_REGS_RDX, tss->dx); - kvm_register_write(vcpu, VCPU_REGS_RBX, tss->bx); - kvm_register_write(vcpu, VCPU_REGS_RSP, tss->sp); - kvm_register_write(vcpu, VCPU_REGS_RBP, tss->bp); - kvm_register_write(vcpu, VCPU_REGS_RSI, tss->si); - kvm_register_write(vcpu, VCPU_REGS_RDI, tss->di); - - /* - * SDM says that segment selectors are loaded before segment - * descriptors - */ - kvm_load_segment_selector(vcpu, tss->ldt, VCPU_SREG_LDTR); - kvm_load_segment_selector(vcpu, tss->es, VCPU_SREG_ES); - kvm_load_segment_selector(vcpu, tss->cs, VCPU_SREG_CS); - kvm_load_segment_selector(vcpu, tss->ss, VCPU_SREG_SS); - kvm_load_segment_selector(vcpu, tss->ds, VCPU_SREG_DS); - - /* - * Now load segment descriptors. If fault happenes at this stage - * it is handled in a context of new task - */ - if (kvm_load_segment_descriptor(vcpu, tss->ldt, VCPU_SREG_LDTR)) - return 1; - - if (kvm_load_segment_descriptor(vcpu, tss->es, VCPU_SREG_ES)) - return 1; - - if (kvm_load_segment_descriptor(vcpu, tss->cs, VCPU_SREG_CS)) - return 1; - - if (kvm_load_segment_descriptor(vcpu, tss->ss, VCPU_SREG_SS)) - return 1; - - if (kvm_load_segment_descriptor(vcpu, tss->ds, VCPU_SREG_DS)) - return 1; - return 0; -} - -static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector, - u16 old_tss_sel, u32 old_tss_base, - struct desc_struct *nseg_desc) -{ - struct tss_segment_16 tss_segment_16; - int ret = 0; - - if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_16, - sizeof tss_segment_16)) - goto out; - - save_state_to_tss16(vcpu, &tss_segment_16); - - if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_16, - sizeof tss_segment_16)) - goto out; - - if (kvm_read_guest(vcpu->kvm, get_tss_base_addr_read(vcpu, nseg_desc), - &tss_segment_16, sizeof tss_segment_16)) - goto out; - - if (old_tss_sel != 0xffff) { - tss_segment_16.prev_task_link = old_tss_sel; - - if (kvm_write_guest(vcpu->kvm, - get_tss_base_addr_write(vcpu, nseg_desc), - &tss_segment_16.prev_task_link, - sizeof tss_segment_16.prev_task_link)) - goto out; - } - - if (load_state_from_tss16(vcpu, &tss_segment_16)) - goto out; - - ret = 1; -out: - return ret; -} - -static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector, - u16 old_tss_sel, u32 old_tss_base, - struct desc_struct *nseg_desc) -{ - struct tss_segment_32 tss_segment_32; - int ret = 0; - - if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_32, - sizeof tss_segment_32)) - goto out; - - save_state_to_tss32(vcpu, &tss_segment_32); - - if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_32, - sizeof tss_segment_32)) - goto out; - - if (kvm_read_guest(vcpu->kvm, get_tss_base_addr_read(vcpu, nseg_desc), - &tss_segment_32, sizeof tss_segment_32)) - goto out; - - if (old_tss_sel != 0xffff) { - tss_segment_32.prev_task_link = old_tss_sel; - - if (kvm_write_guest(vcpu->kvm, - get_tss_base_addr_write(vcpu, nseg_desc), - &tss_segment_32.prev_task_link, - sizeof tss_segment_32.prev_task_link)) - goto out; - } - - if (load_state_from_tss32(vcpu, &tss_segment_32)) - goto out; - - ret = 1; -out: - return ret; -} - int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) { - struct kvm_segment tr_seg; - struct desc_struct cseg_desc; - struct desc_struct nseg_desc; - int ret = 0; - u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR); - u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR); - u32 desc_limit; - - old_tss_base = kvm_mmu_gva_to_gpa_write(vcpu, old_tss_base, NULL); - - /* FIXME: Handle errors. Failure to read either TSS or their - * descriptors should generate a pagefault. - */ - if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc)) - goto out; - - if (load_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc)) - goto out; - - if (reason != TASK_SWITCH_IRET) { - int cpl; - - cpl = kvm_x86_ops->get_cpl(vcpu); - if ((tss_selector & 3) > nseg_desc.dpl || cpl > nseg_desc.dpl) { - kvm_queue_exception_e(vcpu, GP_VECTOR, 0); - return 1; - } - } - - desc_limit = get_desc_limit(&nseg_desc); - if (!nseg_desc.p || - ((desc_limit < 0x67 && (nseg_desc.type & 8)) || - desc_limit < 0x2b)) { - kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc); - return 1; - } - - if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) { - cseg_desc.type &= ~(1 << 1); //clear the B flag - save_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc); - } - - if (reason == TASK_SWITCH_IRET) { - u32 eflags = kvm_get_rflags(vcpu); - kvm_set_rflags(vcpu, eflags & ~X86_EFLAGS_NT); - } + int cs_db, cs_l, ret; + cache_all_regs(vcpu); - /* set back link to prev task only if NT bit is set in eflags - note that old_tss_sel is not used afetr this point */ - if (reason != TASK_SWITCH_CALL && reason != TASK_SWITCH_GATE) - old_tss_sel = 0xffff; + kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); - if (nseg_desc.type & 8) - ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_sel, - old_tss_base, &nseg_desc); - else - ret = kvm_task_switch_16(vcpu, tss_selector, old_tss_sel, - old_tss_base, &nseg_desc); + vcpu->arch.emulate_ctxt.vcpu = vcpu; + vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu); + vcpu->arch.emulate_ctxt.eip = kvm_rip_read(vcpu); + vcpu->arch.emulate_ctxt.mode = + (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL : + (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM) + ? X86EMUL_MODE_VM86 : cs_l + ? X86EMUL_MODE_PROT64 : cs_db + ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; - if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) { - u32 eflags = kvm_get_rflags(vcpu); - kvm_set_rflags(vcpu, eflags | X86_EFLAGS_NT); - } + ret = emulator_task_switch(&vcpu->arch.emulate_ctxt, &emulate_ops, + tss_selector, reason); - if (reason != TASK_SWITCH_IRET) { - nseg_desc.type |= (1 << 1); - save_guest_segment_descriptor(vcpu, tss_selector, - &nseg_desc); - } + if (ret == X86EMUL_CONTINUE) + kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); - kvm_x86_ops->set_cr0(vcpu, kvm_read_cr0(vcpu) | X86_CR0_TS); - seg_desct_to_kvm_desct(&nseg_desc, tss_selector, &tr_seg); - tr_seg.type = 11; - kvm_set_segment(vcpu, &tr_seg, VCPU_SREG_TR); -out: - return ret; + return (ret != X86EMUL_CONTINUE); } EXPORT_SYMBOL_GPL(kvm_task_switch); -- cgit v1.2.3-59-g8ed1b From 69f55cb11e8d789433d111ac3a0f60be37a1ae01 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:20 +0200 Subject: KVM: x86 emulator: populate OP_MEM operand during decoding. All struct operand fields are initialized during decoding for all operand types except OP_MEM, but there is no reason for that. Move OP_MEM operand initialization into decoding stage for consistency. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 66 ++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 37 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8225ec26efed..0eed6839619f 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1057,6 +1057,10 @@ done_prefixes: if (c->ad_bytes != 8) c->modrm_ea = (u32)c->modrm_ea; + + if (c->rip_relative) + c->modrm_ea += c->eip; + /* * Decode and fetch the source operand: register, memory * or immediate. @@ -1091,6 +1095,8 @@ done_prefixes: break; } c->src.type = OP_MEM; + c->src.ptr = (unsigned long *)c->modrm_ea; + c->src.val = 0; break; case SrcImm: case SrcImmU: @@ -1169,8 +1175,10 @@ done_prefixes: c->src2.val = 1; break; case Src2Mem16: - c->src2.bytes = 2; c->src2.type = OP_MEM; + c->src2.bytes = 2; + c->src2.ptr = (unsigned long *)(c->modrm_ea + c->src.bytes); + c->src2.val = 0; break; } @@ -1192,6 +1200,15 @@ done_prefixes: break; } c->dst.type = OP_MEM; + c->dst.ptr = (unsigned long *)c->modrm_ea; + c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + c->dst.val = 0; + if (c->d & BitOp) { + unsigned long mask = ~(c->dst.bytes * 8 - 1); + + c->dst.ptr = (void *)c->dst.ptr + + (c->src.val & mask) / 8; + } break; case DstAcc: c->dst.type = OP_REG; @@ -1215,9 +1232,6 @@ done_prefixes: break; } - if (c->rip_relative) - c->modrm_ea += c->eip; - done: return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; } @@ -1638,14 +1652,13 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, } static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, - struct x86_emulate_ops *ops, - unsigned long memop) + struct x86_emulate_ops *ops) { struct decode_cache *c = &ctxt->decode; u64 old, new; int rc; - rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu); + rc = ops->read_emulated(c->modrm_ea, &old, 8, ctxt->vcpu); if (rc != X86EMUL_CONTINUE) return rc; @@ -1660,7 +1673,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, new = ((u64)c->regs[VCPU_REGS_RCX] << 32) | (u32) c->regs[VCPU_REGS_RBX]; - rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu); + rc = ops->cmpxchg_emulated(c->modrm_ea, &old, &new, 8, ctxt->vcpu); if (rc != X86EMUL_CONTINUE) return rc; ctxt->eflags |= EFLG_ZF; @@ -2382,7 +2395,6 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt, int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { - unsigned long memop = 0; u64 msr_data; unsigned long saved_eip = 0; struct decode_cache *c = &ctxt->decode; @@ -2417,9 +2429,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) goto done; } - if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs)) - memop = c->modrm_ea; - if (c->rep_prefix && (c->d & String)) { /* All REP prefixes have the same first termination condition */ if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) { @@ -2451,8 +2460,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) } if (c->src.type == OP_MEM) { - c->src.ptr = (unsigned long *)memop; - c->src.val = 0; rc = ops->read_emulated((unsigned long)c->src.ptr, &c->src.val, c->src.bytes, @@ -2463,8 +2470,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) } if (c->src2.type == OP_MEM) { - c->src2.ptr = (unsigned long *)(memop + c->src.bytes); - c->src2.val = 0; rc = ops->read_emulated((unsigned long)c->src2.ptr, &c->src2.val, c->src2.bytes, @@ -2477,25 +2482,12 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) goto special_insn; - if (c->dst.type == OP_MEM) { - c->dst.ptr = (unsigned long *)memop; - c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; - c->dst.val = 0; - if (c->d & BitOp) { - unsigned long mask = ~(c->dst.bytes * 8 - 1); - - c->dst.ptr = (void *)c->dst.ptr + - (c->src.val & mask) / 8; - } - if (!(c->d & Mov)) { - /* optimisation - avoid slow emulated read */ - rc = ops->read_emulated((unsigned long)c->dst.ptr, - &c->dst.val, - c->dst.bytes, - ctxt->vcpu); - if (rc != X86EMUL_CONTINUE) - goto done; - } + if ((c->dst.type == OP_MEM) && !(c->d & Mov)) { + /* optimisation - avoid slow emulated read if Mov */ + rc = ops->read_emulated((unsigned long)c->dst.ptr, &c->dst.val, + c->dst.bytes, ctxt->vcpu); + if (rc != X86EMUL_CONTINUE) + goto done; } c->dst.orig_val = c->dst.val; @@ -3062,7 +3054,7 @@ twobyte_insn: kvm_queue_exception(ctxt->vcpu, UD_VECTOR); goto done; case 7: /* invlpg*/ - emulate_invlpg(ctxt->vcpu, memop); + emulate_invlpg(ctxt->vcpu, c->modrm_ea); /* Disable writeback. */ c->dst.type = OP_NONE; break; @@ -3263,7 +3255,7 @@ twobyte_insn: (u64) c->src.val; break; case 0xc7: /* Grp9 (cmpxchg8b) */ - rc = emulate_grp9(ctxt, ops, memop); + rc = emulate_grp9(ctxt, ops); if (rc != X86EMUL_CONTINUE) goto done; c->dst.type = OP_NONE; -- cgit v1.2.3-59-g8ed1b From a682e35449abc83d260a8219015c7cb4b25ecced Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:21 +0200 Subject: KVM: x86 emulator: add decoding of X,Y parameters from Intel SDM Add decoding of X,Y parameters from Intel SDM which are used by string instruction to specify source and destination. Use this new decoding to implement movs, cmps, stos, lods in a generic way. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 125 +++++++++++++++++-------------------------------- 1 file changed, 44 insertions(+), 81 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 0eed6839619f..3b32270a20db 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -51,6 +51,7 @@ #define DstReg (2<<1) /* Register operand. */ #define DstMem (3<<1) /* Memory operand. */ #define DstAcc (4<<1) /* Destination Accumulator */ +#define DstDI (5<<1) /* Destination is in ES:(E)DI */ #define DstMask (7<<1) /* Source operand type. */ #define SrcNone (0<<4) /* No source operand. */ @@ -64,6 +65,7 @@ #define SrcOne (7<<4) /* Implied '1' */ #define SrcImmUByte (8<<4) /* 8-bit unsigned immediate operand. */ #define SrcImmU (9<<4) /* Immediate operand, unsigned */ +#define SrcSI (0xa<<4) /* Source is in the DS:RSI */ #define SrcMask (0xf<<4) /* Generic ModRM decode. */ #define ModRM (1<<8) @@ -177,12 +179,12 @@ static u32 opcode_table[256] = { /* 0xA0 - 0xA7 */ ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs, ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs, - ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String, - ByteOp | ImplicitOps | String, ImplicitOps | String, + ByteOp | SrcSI | DstDI | Mov | String, SrcSI | DstDI | Mov | String, + ByteOp | SrcSI | DstDI | String, SrcSI | DstDI | String, /* 0xA8 - 0xAF */ - 0, 0, ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String, - ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String, - ByteOp | ImplicitOps | String, ImplicitOps | String, + 0, 0, ByteOp | DstDI | Mov | String, DstDI | Mov | String, + ByteOp | SrcSI | DstAcc | Mov | String, SrcSI | DstAcc | Mov | String, + ByteOp | DstDI | String, DstDI | String, /* 0xB0 - 0xB7 */ ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov, @@ -1145,6 +1147,14 @@ done_prefixes: c->src.bytes = 1; c->src.val = 1; break; + case SrcSI: + c->src.type = OP_MEM; + c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + c->src.ptr = (unsigned long *) + register_address(c, seg_override_base(ctxt, c), + c->regs[VCPU_REGS_RSI]); + c->src.val = 0; + break; } /* @@ -1230,6 +1240,14 @@ done_prefixes: } c->dst.orig_val = c->dst.val; break; + case DstDI: + c->dst.type = OP_MEM; + c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + c->dst.ptr = (unsigned long *) + register_address(c, es_base(ctxt), + c->regs[VCPU_REGS_RDI]); + c->dst.val = 0; + break; } done: @@ -2392,6 +2410,16 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt, return rc; } +static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base, + int reg, unsigned long **ptr) +{ + struct decode_cache *c = &ctxt->decode; + int df = (ctxt->eflags & EFLG_DF) ? -1 : 1; + + register_address_increment(c, &c->regs[reg], df * c->src.bytes); + *ptr = (unsigned long *)register_address(c, base, c->regs[reg]); +} + int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { @@ -2754,89 +2782,16 @@ special_insn: c->dst.val = (unsigned long)c->regs[VCPU_REGS_RAX]; break; case 0xa4 ... 0xa5: /* movs */ - c->dst.type = OP_MEM; - c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; - c->dst.ptr = (unsigned long *)register_address(c, - es_base(ctxt), - c->regs[VCPU_REGS_RDI]); - rc = ops->read_emulated(register_address(c, - seg_override_base(ctxt, c), - c->regs[VCPU_REGS_RSI]), - &c->dst.val, - c->dst.bytes, ctxt->vcpu); - if (rc != X86EMUL_CONTINUE) - goto done; - register_address_increment(c, &c->regs[VCPU_REGS_RSI], - (ctxt->eflags & EFLG_DF) ? -c->dst.bytes - : c->dst.bytes); - register_address_increment(c, &c->regs[VCPU_REGS_RDI], - (ctxt->eflags & EFLG_DF) ? -c->dst.bytes - : c->dst.bytes); - break; + goto mov; case 0xa6 ... 0xa7: /* cmps */ - c->src.type = OP_NONE; /* Disable writeback. */ - c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; - c->src.ptr = (unsigned long *)register_address(c, - seg_override_base(ctxt, c), - c->regs[VCPU_REGS_RSI]); - rc = ops->read_emulated((unsigned long)c->src.ptr, - &c->src.val, - c->src.bytes, - ctxt->vcpu); - if (rc != X86EMUL_CONTINUE) - goto done; - c->dst.type = OP_NONE; /* Disable writeback. */ - c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; - c->dst.ptr = (unsigned long *)register_address(c, - es_base(ctxt), - c->regs[VCPU_REGS_RDI]); - rc = ops->read_emulated((unsigned long)c->dst.ptr, - &c->dst.val, - c->dst.bytes, - ctxt->vcpu); - if (rc != X86EMUL_CONTINUE) - goto done; - DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr); - - emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags); - - register_address_increment(c, &c->regs[VCPU_REGS_RSI], - (ctxt->eflags & EFLG_DF) ? -c->src.bytes - : c->src.bytes); - register_address_increment(c, &c->regs[VCPU_REGS_RDI], - (ctxt->eflags & EFLG_DF) ? -c->dst.bytes - : c->dst.bytes); - - break; + goto cmp; case 0xaa ... 0xab: /* stos */ - c->dst.type = OP_MEM; - c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; - c->dst.ptr = (unsigned long *)register_address(c, - es_base(ctxt), - c->regs[VCPU_REGS_RDI]); c->dst.val = c->regs[VCPU_REGS_RAX]; - register_address_increment(c, &c->regs[VCPU_REGS_RDI], - (ctxt->eflags & EFLG_DF) ? -c->dst.bytes - : c->dst.bytes); break; case 0xac ... 0xad: /* lods */ - c->dst.type = OP_REG; - c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; - c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; - rc = ops->read_emulated(register_address(c, - seg_override_base(ctxt, c), - c->regs[VCPU_REGS_RSI]), - &c->dst.val, - c->dst.bytes, - ctxt->vcpu); - if (rc != X86EMUL_CONTINUE) - goto done; - register_address_increment(c, &c->regs[VCPU_REGS_RSI], - (ctxt->eflags & EFLG_DF) ? -c->dst.bytes - : c->dst.bytes); - break; + goto mov; case 0xae ... 0xaf: /* scas */ DPRINTF("Urk! I don't handle SCAS.\n"); goto cannot_emulate; @@ -2979,6 +2934,14 @@ writeback: if (rc != X86EMUL_CONTINUE) goto done; + if ((c->d & SrcMask) == SrcSI) + string_addr_inc(ctxt, seg_override_base(ctxt, c), VCPU_REGS_RSI, + &c->src.ptr); + + if ((c->d & DstMask) == DstDI) + string_addr_inc(ctxt, es_base(ctxt), VCPU_REGS_RDI, + &c->dst.ptr); + /* Commit shadow register state. */ memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); kvm_rip_write(ctxt->vcpu, c->eip); -- cgit v1.2.3-59-g8ed1b From d9271123a46011af26da680baeb7fdf67b498abf Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:22 +0200 Subject: KVM: x86 emulator: during rep emulation decrement ECX only if emulation succeeded Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 3b32270a20db..594574d8b9e9 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2411,13 +2411,13 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt, } static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base, - int reg, unsigned long **ptr) + int reg, struct operand *op) { struct decode_cache *c = &ctxt->decode; int df = (ctxt->eflags & EFLG_DF) ? -1 : 1; - register_address_increment(c, &c->regs[reg], df * c->src.bytes); - *ptr = (unsigned long *)register_address(c, base, c->regs[reg]); + register_address_increment(c, &c->regs[reg], df * op->bytes); + op->ptr = (unsigned long *)register_address(c, base, c->regs[reg]); } int @@ -2483,7 +2483,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) goto done; } } - register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); c->eip = ctxt->eip; } @@ -2936,11 +2935,13 @@ writeback: if ((c->d & SrcMask) == SrcSI) string_addr_inc(ctxt, seg_override_base(ctxt, c), VCPU_REGS_RSI, - &c->src.ptr); + &c->src); if ((c->d & DstMask) == DstDI) - string_addr_inc(ctxt, es_base(ctxt), VCPU_REGS_RDI, - &c->dst.ptr); + string_addr_inc(ctxt, es_base(ctxt), VCPU_REGS_RDI, &c->dst); + + if (c->rep_prefix && (c->d & String)) + register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); /* Commit shadow register state. */ memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); -- cgit v1.2.3-59-g8ed1b From cf8f70bfe38b326bb80b10f76d6544f571040229 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:23 +0200 Subject: KVM: x86 emulator: fix in/out emulation. in/out emulation is broken now. The breakage is different depending on where IO device resides. If it is in userspace emulator reports emulation failure since it incorrectly interprets kvm_emulate_pio() return value. If IO device is in the kernel emulation of 'in' will do nothing since kvm_emulate_pio() stores result directly into vcpu registers, so emulator will overwrite result of emulation during commit of shadowed register. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_emulate.h | 7 ++ arch/x86/include/asm/kvm_host.h | 3 +- arch/x86/kvm/emulate.c | 50 +++++---- arch/x86/kvm/svm.c | 20 ++-- arch/x86/kvm/vmx.c | 18 ++-- arch/x86/kvm/x86.c | 213 +++++++++++++++++++++++-------------- 6 files changed, 178 insertions(+), 133 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index bd469296f5e5..679245c9a55f 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -119,6 +119,13 @@ struct x86_emulate_ops { const void *new, unsigned int bytes, struct kvm_vcpu *vcpu); + + int (*pio_in_emulated)(int size, unsigned short port, void *val, + unsigned int count, struct kvm_vcpu *vcpu); + + int (*pio_out_emulated)(int size, unsigned short port, const void *val, + unsigned int count, struct kvm_vcpu *vcpu); + bool (*get_cached_descriptor)(struct desc_struct *desc, int seg, struct kvm_vcpu *vcpu); void (*set_cached_descriptor)(struct desc_struct *desc, diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index b99cec1547c6..776d3e202b56 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -590,8 +590,7 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); struct x86_emulate_ctxt; -int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, - int size, unsigned port); +int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port); int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in, int size, unsigned long count, int down, gva_t address, int rep, unsigned port); diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 594574d8b9e9..2d095ce9dc87 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -210,13 +210,13 @@ static u32 opcode_table[256] = { 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0 - 0xE7 */ 0, 0, 0, 0, - ByteOp | SrcImmUByte, SrcImmUByte, - ByteOp | SrcImmUByte, SrcImmUByte, + ByteOp | SrcImmUByte | DstAcc, SrcImmUByte | DstAcc, + ByteOp | SrcImmUByte | DstAcc, SrcImmUByte | DstAcc, /* 0xE8 - 0xEF */ SrcImm | Stack, SrcImm | ImplicitOps, SrcImmU | Src2Imm16 | No64, SrcImmByte | ImplicitOps, - SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, - SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, + SrcNone | ByteOp | DstAcc, SrcNone | DstAcc, + SrcNone | ByteOp | DstAcc, SrcNone | DstAcc, /* 0xF0 - 0xF7 */ 0, 0, 0, 0, ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3, @@ -2426,8 +2426,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) u64 msr_data; unsigned long saved_eip = 0; struct decode_cache *c = &ctxt->decode; - unsigned int port; - int io_dir_in; int rc = X86EMUL_CONTINUE; ctxt->interruptibility = 0; @@ -2823,14 +2821,10 @@ special_insn: break; case 0xe4: /* inb */ case 0xe5: /* in */ - port = c->src.val; - io_dir_in = 1; - goto do_io; + goto do_io_in; case 0xe6: /* outb */ case 0xe7: /* out */ - port = c->src.val; - io_dir_in = 0; - goto do_io; + goto do_io_out; case 0xe8: /* call (near) */ { long int rel = c->src.val; c->src.val = (unsigned long) c->eip; @@ -2855,25 +2849,29 @@ special_insn: break; case 0xec: /* in al,dx */ case 0xed: /* in (e/r)ax,dx */ - port = c->regs[VCPU_REGS_RDX]; - io_dir_in = 1; - goto do_io; + c->src.val = c->regs[VCPU_REGS_RDX]; + do_io_in: + c->dst.bytes = min(c->dst.bytes, 4u); + if (!emulator_io_permited(ctxt, ops, c->src.val, c->dst.bytes)) { + kvm_inject_gp(ctxt->vcpu, 0); + goto done; + } + if (!ops->pio_in_emulated(c->dst.bytes, c->src.val, + &c->dst.val, 1, ctxt->vcpu)) + goto done; /* IO is needed */ + break; case 0xee: /* out al,dx */ case 0xef: /* out (e/r)ax,dx */ - port = c->regs[VCPU_REGS_RDX]; - io_dir_in = 0; - do_io: - if (!emulator_io_permited(ctxt, ops, port, - (c->d & ByteOp) ? 1 : c->op_bytes)) { + c->src.val = c->regs[VCPU_REGS_RDX]; + do_io_out: + c->dst.bytes = min(c->dst.bytes, 4u); + if (!emulator_io_permited(ctxt, ops, c->src.val, c->dst.bytes)) { kvm_inject_gp(ctxt->vcpu, 0); goto done; } - if (kvm_emulate_pio(ctxt->vcpu, io_dir_in, - (c->d & ByteOp) ? 1 : c->op_bytes, - port) != 0) { - c->eip = saved_eip; - goto cannot_emulate; - } + ops->pio_out_emulated(c->dst.bytes, c->src.val, &c->dst.val, 1, + ctxt->vcpu); + c->dst.type = OP_NONE; /* Disable writeback. */ break; case 0xf4: /* hlt */ ctxt->vcpu->arch.halt_request = 1; diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index abbc3f9d03b2..e9f79619e185 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1494,29 +1494,23 @@ static int shutdown_interception(struct vcpu_svm *svm) static int io_interception(struct vcpu_svm *svm) { + struct kvm_vcpu *vcpu = &svm->vcpu; u32 io_info = svm->vmcb->control.exit_info_1; /* address size bug? */ int size, in, string; unsigned port; ++svm->vcpu.stat.io_exits; - - svm->next_rip = svm->vmcb->control.exit_info_2; - string = (io_info & SVM_IOIO_STR_MASK) != 0; - - if (string) { - if (emulate_instruction(&svm->vcpu, - 0, 0, 0) == EMULATE_DO_MMIO) - return 0; - return 1; - } - in = (io_info & SVM_IOIO_TYPE_MASK) != 0; + if (string || in) + return !(emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO); + port = io_info >> 16; size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; - + svm->next_rip = svm->vmcb->control.exit_info_2; skip_emulated_instruction(&svm->vcpu); - return kvm_emulate_pio(&svm->vcpu, in, size, port); + + return kvm_fast_pio_out(vcpu, size, port); } static int nmi_interception(struct vcpu_svm *svm) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 87b3c6843aac..1cceca1c59be 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2985,22 +2985,20 @@ static int handle_io(struct kvm_vcpu *vcpu) int size, in, string; unsigned port; - ++vcpu->stat.io_exits; exit_qualification = vmcs_readl(EXIT_QUALIFICATION); string = (exit_qualification & 16) != 0; + in = (exit_qualification & 8) != 0; - if (string) { - if (emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO) - return 0; - return 1; - } + ++vcpu->stat.io_exits; - size = (exit_qualification & 7) + 1; - in = (exit_qualification & 8) != 0; - port = exit_qualification >> 16; + if (string || in) + return !(emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO); + port = exit_qualification >> 16; + size = (exit_qualification & 7) + 1; skip_emulated_instruction(vcpu); - return kvm_emulate_pio(vcpu, in, size, port); + + return kvm_fast_pio_out(vcpu, size, port); } static void diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f69854c8f339..6624ad13ee99 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3404,6 +3404,86 @@ emul_write: return emulator_write_emulated(addr, new, bytes, vcpu); } +static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) +{ + /* TODO: String I/O for in kernel device */ + int r; + + if (vcpu->arch.pio.in) + r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port, + vcpu->arch.pio.size, pd); + else + r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS, + vcpu->arch.pio.port, vcpu->arch.pio.size, + pd); + return r; +} + + +static int emulator_pio_in_emulated(int size, unsigned short port, void *val, + unsigned int count, struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.pio.cur_count) + goto data_avail; + + trace_kvm_pio(1, port, size, 1); + + vcpu->arch.pio.port = port; + vcpu->arch.pio.in = 1; + vcpu->arch.pio.string = 0; + vcpu->arch.pio.down = 0; + vcpu->arch.pio.rep = 0; + vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count; + vcpu->arch.pio.size = size; + + if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { + data_avail: + memcpy(val, vcpu->arch.pio_data, size * count); + vcpu->arch.pio.cur_count = 0; + return 1; + } + + vcpu->run->exit_reason = KVM_EXIT_IO; + vcpu->run->io.direction = KVM_EXIT_IO_IN; + vcpu->run->io.size = size; + vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; + vcpu->run->io.count = count; + vcpu->run->io.port = port; + + return 0; +} + +static int emulator_pio_out_emulated(int size, unsigned short port, + const void *val, unsigned int count, + struct kvm_vcpu *vcpu) +{ + trace_kvm_pio(0, port, size, 1); + + vcpu->arch.pio.port = port; + vcpu->arch.pio.in = 0; + vcpu->arch.pio.string = 0; + vcpu->arch.pio.down = 0; + vcpu->arch.pio.rep = 0; + vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count; + vcpu->arch.pio.size = size; + + memcpy(vcpu->arch.pio_data, val, size * count); + + if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { + vcpu->arch.pio.cur_count = 0; + return 1; + } + + vcpu->run->exit_reason = KVM_EXIT_IO; + vcpu->run->io.direction = KVM_EXIT_IO_OUT; + vcpu->run->io.size = size; + vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; + vcpu->run->io.count = count; + vcpu->run->io.port = port; + + return 0; +} + static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) { return kvm_x86_ops->get_segment_base(vcpu, seg); @@ -3597,6 +3677,8 @@ static struct x86_emulate_ops emulate_ops = { .read_emulated = emulator_read_emulated, .write_emulated = emulator_write_emulated, .cmpxchg_emulated = emulator_cmpxchg_emulated, + .pio_in_emulated = emulator_pio_in_emulated, + .pio_out_emulated = emulator_pio_out_emulated, .get_cached_descriptor = emulator_get_cached_descriptor, .set_cached_descriptor = emulator_set_cached_descriptor, .get_segment_selector = emulator_get_segment_selector, @@ -3704,6 +3786,12 @@ int emulate_instruction(struct kvm_vcpu *vcpu, if (vcpu->arch.pio.string) return EMULATE_DO_MMIO; + if (vcpu->arch.pio.cur_count && !vcpu->arch.pio.string) { + if (!vcpu->arch.pio.in) + vcpu->arch.pio.cur_count = 0; + return EMULATE_DO_MMIO; + } + if (r || vcpu->mmio_is_write) { run->exit_reason = KVM_EXIT_MMIO; run->mmio.phys_addr = vcpu->mmio_phys_addr; @@ -3760,43 +3848,36 @@ int complete_pio(struct kvm_vcpu *vcpu) int r; unsigned long val; - if (!io->string) { - if (io->in) { - val = kvm_register_read(vcpu, VCPU_REGS_RAX); - memcpy(&val, vcpu->arch.pio_data, io->size); - kvm_register_write(vcpu, VCPU_REGS_RAX, val); - } - } else { - if (io->in) { - r = pio_copy_data(vcpu); - if (r) - goto out; - } + if (io->in) { + r = pio_copy_data(vcpu); + if (r) + goto out; + } - delta = 1; - if (io->rep) { - delta *= io->cur_count; - /* - * The size of the register should really depend on - * current address size. - */ - val = kvm_register_read(vcpu, VCPU_REGS_RCX); - val -= delta; - kvm_register_write(vcpu, VCPU_REGS_RCX, val); - } - if (io->down) - delta = -delta; - delta *= io->size; - if (io->in) { - val = kvm_register_read(vcpu, VCPU_REGS_RDI); - val += delta; - kvm_register_write(vcpu, VCPU_REGS_RDI, val); - } else { - val = kvm_register_read(vcpu, VCPU_REGS_RSI); - val += delta; - kvm_register_write(vcpu, VCPU_REGS_RSI, val); - } + delta = 1; + if (io->rep) { + delta *= io->cur_count; + /* + * The size of the register should really depend on + * current address size. + */ + val = kvm_register_read(vcpu, VCPU_REGS_RCX); + val -= delta; + kvm_register_write(vcpu, VCPU_REGS_RCX, val); + } + if (io->down) + delta = -delta; + delta *= io->size; + if (io->in) { + val = kvm_register_read(vcpu, VCPU_REGS_RDI); + val += delta; + kvm_register_write(vcpu, VCPU_REGS_RDI, val); + } else { + val = kvm_register_read(vcpu, VCPU_REGS_RSI); + val += delta; + kvm_register_write(vcpu, VCPU_REGS_RSI, val); } + out: io->count -= io->cur_count; io->cur_count = 0; @@ -3804,21 +3885,6 @@ out: return 0; } -static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) -{ - /* TODO: String I/O for in kernel device */ - int r; - - if (vcpu->arch.pio.in) - r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port, - vcpu->arch.pio.size, pd); - else - r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS, - vcpu->arch.pio.port, vcpu->arch.pio.size, - pd); - return r; -} - static int pio_string_write(struct kvm_vcpu *vcpu) { struct kvm_pio_request *io = &vcpu->arch.pio; @@ -3836,36 +3902,6 @@ static int pio_string_write(struct kvm_vcpu *vcpu) return r; } -int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, int size, unsigned port) -{ - unsigned long val; - - trace_kvm_pio(!in, port, size, 1); - - vcpu->run->exit_reason = KVM_EXIT_IO; - vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; - vcpu->run->io.size = vcpu->arch.pio.size = size; - vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; - vcpu->run->io.count = vcpu->arch.pio.count = vcpu->arch.pio.cur_count = 1; - vcpu->run->io.port = vcpu->arch.pio.port = port; - vcpu->arch.pio.in = in; - vcpu->arch.pio.string = 0; - vcpu->arch.pio.down = 0; - vcpu->arch.pio.rep = 0; - - if (!vcpu->arch.pio.in) { - val = kvm_register_read(vcpu, VCPU_REGS_RAX); - memcpy(vcpu->arch.pio_data, &val, 4); - } - - if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { - complete_pio(vcpu); - return 1; - } - return 0; -} -EXPORT_SYMBOL_GPL(kvm_emulate_pio); - int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in, int size, unsigned long count, int down, gva_t address, int rep, unsigned port) @@ -3931,6 +3967,16 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in, } EXPORT_SYMBOL_GPL(kvm_emulate_pio_string); +int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port) +{ + unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX); + int ret = emulator_pio_out_emulated(size, port, &val, 1, vcpu); + /* do not return to emulator after return from userspace */ + vcpu->arch.pio.cur_count = 0; + return ret; +} +EXPORT_SYMBOL_GPL(kvm_fast_pio_out); + static void bounce_off(void *info) { /* nothing */ @@ -4661,9 +4707,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (vcpu->arch.pio.cur_count) { vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); - r = complete_pio(vcpu); + if (!vcpu->arch.pio.string) + r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE); + else + r = complete_pio(vcpu); srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); - if (r) + if (r == EMULATE_DO_MMIO) goto out; } if (vcpu->mmio_needed) { -- cgit v1.2.3-59-g8ed1b From 7972995b0c346de76fe260ce0fd6bcc8ffab724a Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:24 +0200 Subject: KVM: x86 emulator: Move string pio emulation into emulator.c Currently emulation is done outside of emulator so things like doing ins/outs to/from mmio are broken it also makes it hard (if not impossible) to implement single stepping in the future. The implementation in this patch is not efficient since it exits to userspace for each IO while previous implementation did 'ins' in batches. Further patch that implements pio in string read ahead address this problem. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 8 -- arch/x86/kvm/emulate.c | 48 +++------- arch/x86/kvm/x86.c | 206 ++++------------------------------------ 3 files changed, 32 insertions(+), 230 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 776d3e202b56..26c629a062db 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -224,14 +224,9 @@ struct kvm_pv_mmu_op_buffer { struct kvm_pio_request { unsigned long count; - int cur_count; - gva_t guest_gva; int in; int port; int size; - int string; - int down; - int rep; }; /* @@ -591,9 +586,6 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); struct x86_emulate_ctxt; int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port); -int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in, - int size, unsigned long count, int down, - gva_t address, int rep, unsigned port); void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); int kvm_emulate_halt(struct kvm_vcpu *vcpu); int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address); diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 2d095ce9dc87..2c66e097d916 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -153,8 +153,8 @@ static u32 opcode_table[256] = { 0, 0, 0, 0, /* 0x68 - 0x6F */ SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0, - SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */ - SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */ + DstDI | ByteOp | Mov | String, DstDI | Mov | String, /* insb, insw/insd */ + SrcSI | ByteOp | ImplicitOps | String, SrcSI | ImplicitOps | String, /* outsb, outsw/outsd */ /* 0x70 - 0x77 */ SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, @@ -2615,47 +2615,29 @@ special_insn: break; case 0x6c: /* insb */ case 0x6d: /* insw/insd */ + c->dst.bytes = min(c->dst.bytes, 4u); if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], - (c->d & ByteOp) ? 1 : c->op_bytes)) { + c->dst.bytes)) { kvm_inject_gp(ctxt->vcpu, 0); goto done; } - if (kvm_emulate_pio_string(ctxt->vcpu, - 1, - (c->d & ByteOp) ? 1 : c->op_bytes, - c->rep_prefix ? - address_mask(c, c->regs[VCPU_REGS_RCX]) : 1, - (ctxt->eflags & EFLG_DF), - register_address(c, es_base(ctxt), - c->regs[VCPU_REGS_RDI]), - c->rep_prefix, - c->regs[VCPU_REGS_RDX]) == 0) { - c->eip = saved_eip; - return -1; - } - return 0; + if (!ops->pio_in_emulated(c->dst.bytes, c->regs[VCPU_REGS_RDX], + &c->dst.val, 1, ctxt->vcpu)) + goto done; /* IO is needed, skip writeback */ + break; case 0x6e: /* outsb */ case 0x6f: /* outsw/outsd */ + c->src.bytes = min(c->src.bytes, 4u); if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], - (c->d & ByteOp) ? 1 : c->op_bytes)) { + c->src.bytes)) { kvm_inject_gp(ctxt->vcpu, 0); goto done; } - if (kvm_emulate_pio_string(ctxt->vcpu, - 0, - (c->d & ByteOp) ? 1 : c->op_bytes, - c->rep_prefix ? - address_mask(c, c->regs[VCPU_REGS_RCX]) : 1, - (ctxt->eflags & EFLG_DF), - register_address(c, - seg_override_base(ctxt, c), - c->regs[VCPU_REGS_RSI]), - c->rep_prefix, - c->regs[VCPU_REGS_RDX]) == 0) { - c->eip = saved_eip; - return -1; - } - return 0; + ops->pio_out_emulated(c->src.bytes, c->regs[VCPU_REGS_RDX], + &c->src.val, 1, ctxt->vcpu); + + c->dst.type = OP_NONE; /* nothing to writeback */ + break; case 0x70 ... 0x7f: /* jcc (short) */ if (test_cc(c->b, ctxt->eflags)) jmp_rel(c, c->src.val); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6624ad13ee99..658e8e8155cb 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3150,18 +3150,17 @@ static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes, return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error); } -static int kvm_write_guest_virt_helper(gva_t addr, void *val, +static int kvm_write_guest_virt_system(gva_t addr, void *val, unsigned int bytes, - struct kvm_vcpu *vcpu, u32 access, + struct kvm_vcpu *vcpu, u32 *error) { void *data = val; int r = X86EMUL_CONTINUE; - access |= PFERR_WRITE_MASK; - while (bytes) { - gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr, access, error); + gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr, + PFERR_WRITE_MASK, error); unsigned offset = addr & (PAGE_SIZE-1); unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); int ret; @@ -3184,20 +3183,6 @@ out: return r; } -static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes, - struct kvm_vcpu *vcpu, u32 *error) -{ - u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; - return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, access, error); -} - -static int kvm_write_guest_virt_system(gva_t addr, void *val, - unsigned int bytes, - struct kvm_vcpu *vcpu, u32 *error) -{ - return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, 0, error); -} - static int emulator_read_emulated(unsigned long addr, void *val, unsigned int bytes, @@ -3423,23 +3408,20 @@ static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) static int emulator_pio_in_emulated(int size, unsigned short port, void *val, unsigned int count, struct kvm_vcpu *vcpu) { - if (vcpu->arch.pio.cur_count) + if (vcpu->arch.pio.count) goto data_avail; trace_kvm_pio(1, port, size, 1); vcpu->arch.pio.port = port; vcpu->arch.pio.in = 1; - vcpu->arch.pio.string = 0; - vcpu->arch.pio.down = 0; - vcpu->arch.pio.rep = 0; - vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count; + vcpu->arch.pio.count = count; vcpu->arch.pio.size = size; if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { data_avail: memcpy(val, vcpu->arch.pio_data, size * count); - vcpu->arch.pio.cur_count = 0; + vcpu->arch.pio.count = 0; return 1; } @@ -3461,16 +3443,13 @@ static int emulator_pio_out_emulated(int size, unsigned short port, vcpu->arch.pio.port = port; vcpu->arch.pio.in = 0; - vcpu->arch.pio.string = 0; - vcpu->arch.pio.down = 0; - vcpu->arch.pio.rep = 0; - vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count; + vcpu->arch.pio.count = count; vcpu->arch.pio.size = size; memcpy(vcpu->arch.pio_data, val, size * count); if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { - vcpu->arch.pio.cur_count = 0; + vcpu->arch.pio.count = 0; return 1; } @@ -3717,7 +3696,6 @@ int emulate_instruction(struct kvm_vcpu *vcpu, cache_all_regs(vcpu); vcpu->mmio_is_write = 0; - vcpu->arch.pio.string = 0; if (!(emulation_type & EMULTYPE_NO_DECODE)) { int cs_db, cs_l; @@ -3783,12 +3761,9 @@ int emulate_instruction(struct kvm_vcpu *vcpu, if (r == 0) kvm_x86_ops->set_interrupt_shadow(vcpu, shadow_mask); - if (vcpu->arch.pio.string) - return EMULATE_DO_MMIO; - - if (vcpu->arch.pio.cur_count && !vcpu->arch.pio.string) { + if (vcpu->arch.pio.count) { if (!vcpu->arch.pio.in) - vcpu->arch.pio.cur_count = 0; + vcpu->arch.pio.count = 0; return EMULATE_DO_MMIO; } @@ -3821,158 +3796,12 @@ int emulate_instruction(struct kvm_vcpu *vcpu, } EXPORT_SYMBOL_GPL(emulate_instruction); -static int pio_copy_data(struct kvm_vcpu *vcpu) -{ - void *p = vcpu->arch.pio_data; - gva_t q = vcpu->arch.pio.guest_gva; - unsigned bytes; - int ret; - u32 error_code; - - bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count; - if (vcpu->arch.pio.in) - ret = kvm_write_guest_virt(q, p, bytes, vcpu, &error_code); - else - ret = kvm_read_guest_virt(q, p, bytes, vcpu, &error_code); - - if (ret == X86EMUL_PROPAGATE_FAULT) - kvm_inject_page_fault(vcpu, q, error_code); - - return ret; -} - -int complete_pio(struct kvm_vcpu *vcpu) -{ - struct kvm_pio_request *io = &vcpu->arch.pio; - long delta; - int r; - unsigned long val; - - if (io->in) { - r = pio_copy_data(vcpu); - if (r) - goto out; - } - - delta = 1; - if (io->rep) { - delta *= io->cur_count; - /* - * The size of the register should really depend on - * current address size. - */ - val = kvm_register_read(vcpu, VCPU_REGS_RCX); - val -= delta; - kvm_register_write(vcpu, VCPU_REGS_RCX, val); - } - if (io->down) - delta = -delta; - delta *= io->size; - if (io->in) { - val = kvm_register_read(vcpu, VCPU_REGS_RDI); - val += delta; - kvm_register_write(vcpu, VCPU_REGS_RDI, val); - } else { - val = kvm_register_read(vcpu, VCPU_REGS_RSI); - val += delta; - kvm_register_write(vcpu, VCPU_REGS_RSI, val); - } - -out: - io->count -= io->cur_count; - io->cur_count = 0; - - return 0; -} - -static int pio_string_write(struct kvm_vcpu *vcpu) -{ - struct kvm_pio_request *io = &vcpu->arch.pio; - void *pd = vcpu->arch.pio_data; - int i, r = 0; - - for (i = 0; i < io->cur_count; i++) { - if (kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS, - io->port, io->size, pd)) { - r = -EOPNOTSUPP; - break; - } - pd += io->size; - } - return r; -} - -int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in, - int size, unsigned long count, int down, - gva_t address, int rep, unsigned port) -{ - unsigned now, in_page; - int ret = 0; - - trace_kvm_pio(!in, port, size, count); - - vcpu->run->exit_reason = KVM_EXIT_IO; - vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; - vcpu->run->io.size = vcpu->arch.pio.size = size; - vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; - vcpu->run->io.count = vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count; - vcpu->run->io.port = vcpu->arch.pio.port = port; - vcpu->arch.pio.in = in; - vcpu->arch.pio.string = 1; - vcpu->arch.pio.down = down; - vcpu->arch.pio.rep = rep; - - if (!count) { - kvm_x86_ops->skip_emulated_instruction(vcpu); - return 1; - } - - if (!down) - in_page = PAGE_SIZE - offset_in_page(address); - else - in_page = offset_in_page(address) + size; - now = min(count, (unsigned long)in_page / size); - if (!now) - now = 1; - if (down) { - /* - * String I/O in reverse. Yuck. Kill the guest, fix later. - */ - pr_unimpl(vcpu, "guest string pio down\n"); - kvm_inject_gp(vcpu, 0); - return 1; - } - vcpu->run->io.count = now; - vcpu->arch.pio.cur_count = now; - - if (vcpu->arch.pio.cur_count == vcpu->arch.pio.count) - kvm_x86_ops->skip_emulated_instruction(vcpu); - - vcpu->arch.pio.guest_gva = address; - - if (!vcpu->arch.pio.in) { - /* string PIO write */ - ret = pio_copy_data(vcpu); - if (ret == X86EMUL_PROPAGATE_FAULT) - return 1; - if (ret == 0 && !pio_string_write(vcpu)) { - complete_pio(vcpu); - if (vcpu->arch.pio.count == 0) - ret = 1; - } - } - /* no string PIO read support yet */ - - return ret; -} -EXPORT_SYMBOL_GPL(kvm_emulate_pio_string); - int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port) { unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX); int ret = emulator_pio_out_emulated(size, port, &val, 1, vcpu); /* do not return to emulator after return from userspace */ - vcpu->arch.pio.cur_count = 0; + vcpu->arch.pio.count = 0; return ret; } EXPORT_SYMBOL_GPL(kvm_fast_pio_out); @@ -4705,15 +4534,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (!irqchip_in_kernel(vcpu->kvm)) kvm_set_cr8(vcpu, kvm_run->cr8); - if (vcpu->arch.pio.cur_count) { + if (vcpu->arch.pio.count) { vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); - if (!vcpu->arch.pio.string) - r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE); - else - r = complete_pio(vcpu); + r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE); srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); - if (r == EMULATE_DO_MMIO) + if (r == EMULATE_DO_MMIO) { + r = 0; goto out; + } } if (vcpu->mmio_needed) { memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); -- cgit v1.2.3-59-g8ed1b From cb404fe0898779ec5fe5e06e90aaddcf40aefad8 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:25 +0200 Subject: KVM: x86 emulator: remove saved_eip c->eip is never written back in case of emulation failure, so no need to set it to old value. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 2c66e097d916..0579d9dd9aac 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2424,7 +2424,6 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { u64 msr_data; - unsigned long saved_eip = 0; struct decode_cache *c = &ctxt->decode; int rc = X86EMUL_CONTINUE; @@ -2436,7 +2435,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) */ memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); - saved_eip = c->eip; if (ctxt->mode == X86EMUL_MODE_PROT64 && (c->d & No64)) { kvm_queue_exception(ctxt->vcpu, UD_VECTOR); @@ -2928,11 +2926,7 @@ writeback: kvm_rip_write(ctxt->vcpu, c->eip); done: - if (rc == X86EMUL_UNHANDLEABLE) { - c->eip = saved_eip; - return -1; - } - return 0; + return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; twobyte_insn: switch (c->b) { @@ -3209,6 +3203,5 @@ twobyte_insn: cannot_emulate: DPRINTF("Cannot emulate %02x\n", c->b); - c->eip = saved_eip; return -1; } -- cgit v1.2.3-59-g8ed1b From 5cd21917da245fbe98bd443de2c7f519b3df6814 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:26 +0200 Subject: KVM: x86 emulator: restart string instruction without going back to a guest. Currently when string instruction is only partially complete we go back to a guest mode, guest tries to reexecute instruction and exits again and at this point emulation continues. Avoid all of this by restarting instruction without going back to a guest mode, but return to a guest mode each 1024 iterations to allow interrupt injection. Pending exception causes immediate guest entry too. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_emulate.h | 1 + arch/x86/kvm/emulate.c | 34 +++++++++++++++++++++++----------- arch/x86/kvm/x86.c | 19 ++++++++++++++++++- 3 files changed, 42 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 679245c9a55f..7fda16f89cc8 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -193,6 +193,7 @@ struct x86_emulate_ctxt { /* interruptibility state, as a result of execution of STI or MOV SS */ int interruptibility; + bool restart; /* restart string instruction after writeback */ /* decode cache */ struct decode_cache decode; }; diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 0579d9dd9aac..6de6ad1610d8 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -927,8 +927,11 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) int mode = ctxt->mode; int def_op_bytes, def_ad_bytes, group; - /* Shadow copy of register state. Committed on successful emulation. */ + /* we cannot decode insn before we complete previous rep insn */ + WARN_ON(ctxt->restart); + + /* Shadow copy of register state. Committed on successful emulation. */ memset(c, 0, sizeof(struct decode_cache)); c->eip = ctxt->eip; ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); @@ -2426,6 +2429,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) u64 msr_data; struct decode_cache *c = &ctxt->decode; int rc = X86EMUL_CONTINUE; + int saved_dst_type = c->dst.type; ctxt->interruptibility = 0; @@ -2454,8 +2458,11 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) } if (c->rep_prefix && (c->d & String)) { + ctxt->restart = true; /* All REP prefixes have the same first termination condition */ if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) { + string_done: + ctxt->restart = false; kvm_rip_write(ctxt->vcpu, c->eip); goto done; } @@ -2467,17 +2474,13 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) * - if REPNE/REPNZ and ZF = 1 then done */ if ((c->b == 0xa6) || (c->b == 0xa7) || - (c->b == 0xae) || (c->b == 0xaf)) { + (c->b == 0xae) || (c->b == 0xaf)) { if ((c->rep_prefix == REPE_PREFIX) && - ((ctxt->eflags & EFLG_ZF) == 0)) { - kvm_rip_write(ctxt->vcpu, c->eip); - goto done; - } + ((ctxt->eflags & EFLG_ZF) == 0)) + goto string_done; if ((c->rep_prefix == REPNE_PREFIX) && - ((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) { - kvm_rip_write(ctxt->vcpu, c->eip); - goto done; - } + ((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) + goto string_done; } c->eip = ctxt->eip; } @@ -2911,6 +2914,12 @@ writeback: if (rc != X86EMUL_CONTINUE) goto done; + /* + * restore dst type in case the decoding will be reused + * (happens for string instruction ) + */ + c->dst.type = saved_dst_type; + if ((c->d & SrcMask) == SrcSI) string_addr_inc(ctxt, seg_override_base(ctxt, c), VCPU_REGS_RSI, &c->src); @@ -2918,8 +2927,11 @@ writeback: if ((c->d & DstMask) == DstDI) string_addr_inc(ctxt, es_base(ctxt), VCPU_REGS_RDI, &c->dst); - if (c->rep_prefix && (c->d & String)) + if (c->rep_prefix && (c->d & String)) { register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); + if (!(c->regs[VCPU_REGS_RCX] & 0x3ff)) + ctxt->restart = false; + } /* Commit shadow register state. */ memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 658e8e8155cb..c88cb8145283 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3755,6 +3755,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, return EMULATE_DONE; } +restart: r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); shadow_mask = vcpu->arch.emulate_ctxt.interruptibility; @@ -3777,7 +3778,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, if (r) { if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) - return EMULATE_DONE; + goto done; if (!vcpu->mmio_needed) { kvm_report_emulation_failure(vcpu, "mmio"); return EMULATE_FAIL; @@ -3792,6 +3793,13 @@ int emulate_instruction(struct kvm_vcpu *vcpu, return EMULATE_DO_MMIO; } +done: + if (vcpu->arch.exception.pending) + vcpu->arch.emulate_ctxt.restart = false; + + if (vcpu->arch.emulate_ctxt.restart) + goto restart; + return EMULATE_DONE; } EXPORT_SYMBOL_GPL(emulate_instruction); @@ -4560,6 +4568,15 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) goto out; } } + if (vcpu->arch.emulate_ctxt.restart) { + vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); + r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE); + srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); + if (r == EMULATE_DO_MMIO) { + r = 0; + goto out; + } + } if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL) kvm_register_write(vcpu, VCPU_REGS_RAX, kvm_run->hypercall.ret); -- cgit v1.2.3-59-g8ed1b From 7b262e90fc20a49fddf3dad94c8cead1f0439751 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:27 +0200 Subject: KVM: x86 emulator: introduce pio in string read ahead. To optimize "rep ins" instruction do IO in big chunks ahead of time instead of doing it only when required during instruction emulation. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_emulate.h | 7 ++++++ arch/x86/kvm/emulate.c | 46 +++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 7fda16f89cc8..b5e12c583860 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -151,6 +151,12 @@ struct fetch_cache { unsigned long end; }; +struct read_cache { + u8 data[1024]; + unsigned long pos; + unsigned long end; +}; + struct decode_cache { u8 twobyte; u8 b; @@ -178,6 +184,7 @@ struct decode_cache { void *modrm_ptr; unsigned long modrm_val; struct fetch_cache fetch; + struct read_cache io_read; }; struct x86_emulate_ctxt { diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 6de6ad1610d8..ab3fff5bf7c4 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1257,6 +1257,36 @@ done: return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; } +static int pio_in_emulated(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + unsigned int size, unsigned short port, + void *dest) +{ + struct read_cache *rc = &ctxt->decode.io_read; + + if (rc->pos == rc->end) { /* refill pio read ahead */ + struct decode_cache *c = &ctxt->decode; + unsigned int in_page, n; + unsigned int count = c->rep_prefix ? + address_mask(c, c->regs[VCPU_REGS_RCX]) : 1; + in_page = (ctxt->eflags & EFLG_DF) ? + offset_in_page(c->regs[VCPU_REGS_RDI]) : + PAGE_SIZE - offset_in_page(c->regs[VCPU_REGS_RDI]); + n = min(min(in_page, (unsigned int)sizeof(rc->data)) / size, + count); + if (n == 0) + n = 1; + rc->pos = rc->end = 0; + if (!ops->pio_in_emulated(size, port, rc->data, n, ctxt->vcpu)) + return 0; + rc->end = n * size; + } + + memcpy(dest, rc->data + rc->pos, size); + rc->pos += size; + return 1; +} + static u32 desc_limit_scaled(struct desc_struct *desc) { u32 limit = get_desc_limit(desc); @@ -2622,8 +2652,8 @@ special_insn: kvm_inject_gp(ctxt->vcpu, 0); goto done; } - if (!ops->pio_in_emulated(c->dst.bytes, c->regs[VCPU_REGS_RDX], - &c->dst.val, 1, ctxt->vcpu)) + if (!pio_in_emulated(ctxt, ops, c->dst.bytes, + c->regs[VCPU_REGS_RDX], &c->dst.val)) goto done; /* IO is needed, skip writeback */ break; case 0x6e: /* outsb */ @@ -2839,8 +2869,8 @@ special_insn: kvm_inject_gp(ctxt->vcpu, 0); goto done; } - if (!ops->pio_in_emulated(c->dst.bytes, c->src.val, - &c->dst.val, 1, ctxt->vcpu)) + if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val, + &c->dst.val)) goto done; /* IO is needed */ break; case 0xee: /* out al,dx */ @@ -2928,8 +2958,14 @@ writeback: string_addr_inc(ctxt, es_base(ctxt), VCPU_REGS_RDI, &c->dst); if (c->rep_prefix && (c->d & String)) { + struct read_cache *rc = &ctxt->decode.io_read; register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); - if (!(c->regs[VCPU_REGS_RCX] & 0x3ff)) + /* + * Re-enter guest when pio read ahead buffer is empty or, + * if it is not used, after each 1024 iteration. + */ + if ((rc->end == 0 && !(c->regs[VCPU_REGS_RCX] & 0x3ff)) || + (rc->end != 0 && rc->end == rc->pos)) ctxt->restart = false; } -- cgit v1.2.3-59-g8ed1b From 92bf9748b5bc381070f6adf0b56efd3428e4a97b Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 18 Mar 2010 15:20:28 +0200 Subject: KVM: small kvm_arch_vcpu_ioctl_run() cleanup. Unify all conditions that get us back into emulator after returning from userspace. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c88cb8145283..cc540f27053f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4542,33 +4542,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (!irqchip_in_kernel(vcpu->kvm)) kvm_set_cr8(vcpu, kvm_run->cr8); - if (vcpu->arch.pio.count) { - vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); - r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE); - srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); - if (r == EMULATE_DO_MMIO) { - r = 0; - goto out; - } - } - if (vcpu->mmio_needed) { - memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); - vcpu->mmio_read_completed = 1; - vcpu->mmio_needed = 0; - - vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); - r = emulate_instruction(vcpu, vcpu->arch.mmio_fault_cr2, 0, - EMULTYPE_NO_DECODE); - srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); - if (r == EMULATE_DO_MMIO) { - /* - * Read-modify-write. Back to userspace. - */ - r = 0; - goto out; + if (vcpu->arch.pio.count || vcpu->mmio_needed || + vcpu->arch.emulate_ctxt.restart) { + if (vcpu->mmio_needed) { + memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); + vcpu->mmio_read_completed = 1; + vcpu->mmio_needed = 0; } - } - if (vcpu->arch.emulate_ctxt.restart) { vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE); srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); -- cgit v1.2.3-59-g8ed1b From 9749a6c0f0a4f88ae7bad4f65d7da32769e9b2b7 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sat, 20 Mar 2010 10:14:13 +0100 Subject: KVM: x86: Fix 32-bit build breakage due to typo Signed-off-by: Jan Kiszka Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index cc540f27053f..b4d3363b78e6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3328,7 +3328,7 @@ EXPORT_SYMBOL_GPL(emulator_write_emulated); # define CMPXCHG64(ptr, old, new) CMPXCHG_TYPE(u64, ptr, old, new) #else # define CMPXCHG64(ptr, old, new) \ - (cmpxchg64((u64 *)(ptr), *(u64 *)(old), *(u *)(new)) == *(u64 *)(old)) + (cmpxchg64((u64 *)(ptr), *(u64 *)(old), *(u64 *)(new)) == *(u64 *)(old)) #endif static int emulator_cmpxchg_emulated(unsigned long addr, -- cgit v1.2.3-59-g8ed1b From 482ac18ae293a3a0b1e1eea95c10dcc9ceeb4708 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Sun, 21 Mar 2010 13:08:20 +0200 Subject: KVM: x86 emulator: commit rflags as part of registers commit Make sure that rflags is committed only after successful instruction emulation. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_emulate.h | 1 + arch/x86/kvm/emulate.c | 1 + arch/x86/kvm/x86.c | 8 ++++++-- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index b5e12c583860..a1319c82050e 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -136,6 +136,7 @@ struct x86_emulate_ops { ulong (*get_cr)(int cr, struct kvm_vcpu *vcpu); void (*set_cr)(int cr, ulong val, struct kvm_vcpu *vcpu); int (*cpl)(struct kvm_vcpu *vcpu); + void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); }; /* Type, address-of, and value of an instruction's operand. */ diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index ab3fff5bf7c4..48de4b890055 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2972,6 +2972,7 @@ writeback: /* Commit shadow register state. */ memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); kvm_rip_write(ctxt->vcpu, c->eip); + ops->set_rflags(ctxt->vcpu, ctxt->eflags); done: return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b4d3363b78e6..247e805a041e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3649,6 +3649,11 @@ static void emulator_set_segment_selector(u16 sel, int seg, kvm_set_segment(vcpu, &kvm_seg, seg); } +static void emulator_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) +{ + kvm_x86_ops->set_rflags(vcpu, rflags); +} + static struct x86_emulate_ops emulate_ops = { .read_std = kvm_read_guest_virt_system, .write_std = kvm_write_guest_virt_system, @@ -3666,6 +3671,7 @@ static struct x86_emulate_ops emulate_ops = { .get_cr = emulator_get_cr, .set_cr = emulator_set_cr, .cpl = emulator_get_cpl, + .set_rflags = emulator_set_rflags, }; static void cache_all_regs(struct kvm_vcpu *vcpu) @@ -3786,8 +3792,6 @@ restart: return EMULATE_DO_MMIO; } - kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); - if (vcpu->mmio_is_write) { vcpu->mmio_needed = 0; return EMULATE_DO_MMIO; -- cgit v1.2.3-59-g8ed1b From 6550e1f165f384f3a46b60a1be9aba4bc3c2adad Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Sun, 21 Mar 2010 13:08:21 +0200 Subject: KVM: x86 emulator: add decoding of CMPXCHG8B dst operand Decode CMPXCHG8B destination operand in decoding stage. Fixes regression introduced by "If LOCK prefix is used dest arg should be memory" commit. This commit relies on dst operand be decoded at the beginning of an instruction emulation. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/kvm/emulate.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 48de4b890055..b8ce53861f68 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -52,6 +52,7 @@ #define DstMem (3<<1) /* Memory operand. */ #define DstAcc (4<<1) /* Destination Accumulator */ #define DstDI (5<<1) /* Destination is in ES:(E)DI */ +#define DstMem64 (6<<1) /* 64bit memory operand */ #define DstMask (7<<1) /* Source operand type. */ #define SrcNone (0<<4) /* No source operand. */ @@ -360,7 +361,7 @@ static u32 group_table[] = { DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock, [Group9*8] = - 0, ImplicitOps | ModRM | Lock, 0, 0, 0, 0, 0, 0, + 0, DstMem64 | ModRM | Lock, 0, 0, 0, 0, 0, 0, }; static u32 group2_table[] = { @@ -1205,6 +1206,7 @@ done_prefixes: c->twobyte && (c->b == 0xb6 || c->b == 0xb7)); break; case DstMem: + case DstMem64: if ((c->d & ModRM) && c->modrm_mod == 3) { c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.type = OP_REG; @@ -1214,7 +1216,10 @@ done_prefixes: } c->dst.type = OP_MEM; c->dst.ptr = (unsigned long *)c->modrm_ea; - c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + if ((c->d & DstMask) == DstMem64) + c->dst.bytes = 8; + else + c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.val = 0; if (c->d & BitOp) { unsigned long mask = ~(c->dst.bytes * 8 - 1); @@ -1706,12 +1711,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = &ctxt->decode; - u64 old, new; - int rc; - - rc = ops->read_emulated(c->modrm_ea, &old, 8, ctxt->vcpu); - if (rc != X86EMUL_CONTINUE) - return rc; + u64 old = c->dst.orig_val; if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) { @@ -1719,15 +1719,12 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); ctxt->eflags &= ~EFLG_ZF; - } else { - new = ((u64)c->regs[VCPU_REGS_RCX] << 32) | + c->dst.val = ((u64)c->regs[VCPU_REGS_RCX] << 32) | (u32) c->regs[VCPU_REGS_RBX]; - rc = ops->cmpxchg_emulated(c->modrm_ea, &old, &new, 8, ctxt->vcpu); - if (rc != X86EMUL_CONTINUE) - return rc; ctxt->eflags |= EFLG_ZF; + c->lock_prefix = 1; } return X86EMUL_CONTINUE; } @@ -3245,7 +3242,6 @@ twobyte_insn: rc = emulate_grp9(ctxt, ops); if (rc != X86EMUL_CONTINUE) goto done; - c->dst.type = OP_NONE; break; } goto writeback; -- cgit v1.2.3-59-g8ed1b From de3e6480f76804fe06d460ddb1920c7daa07f29b Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Sun, 21 Mar 2010 16:58:36 +0200 Subject: KVM: x86 emulator: fix unlocked CMPXCHG8B emulation When CMPXCHG8B is executed without LOCK prefix it is racy. Preserve this behaviour in emulator too. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- arch/x86/kvm/emulate.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index b8ce53861f68..64c9854f0458 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1724,7 +1724,6 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, (u32) c->regs[VCPU_REGS_RBX]; ctxt->eflags |= EFLG_ZF; - c->lock_prefix = 1; } return X86EMUL_CONTINUE; } -- cgit v1.2.3-59-g8ed1b From 041b1359a29b9301bc8baed6efcdbad29f80f6af Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Tue, 23 Mar 2010 14:15:53 -0300 Subject: KVM: x86: document KVM_REQ_PENDING_TIMER usage Document that KVM_REQ_PENDING_TIMER is implicitly used during guest entry. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- arch/x86/kvm/timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c index eea40439066c..4ddadb1a5ffe 100644 --- a/arch/x86/kvm/timer.c +++ b/arch/x86/kvm/timer.c @@ -12,7 +12,8 @@ static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer) /* * There is a race window between reading and incrementing, but we do * not care about potentially loosing timer events in the !reinject - * case anyway. + * case anyway. Note: KVM_REQ_PENDING_TIMER is implicitly checked + * in vcpu_enter_guest. */ if (ktimer->reinject || !atomic_read(&ktimer->pending)) { atomic_inc(&ktimer->pending); -- cgit v1.2.3-59-g8ed1b From f815bce8940bc28e42e6b924825bb31df2a4bff5 Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Fri, 19 Mar 2010 17:58:53 +0800 Subject: KVM: MMU: check reserved bits only if CR4.PSE=1 or CR4.PAE=1 - Check reserved bits only if CR4.PAE=1 or CR4.PSE=1 when guest #PF occurs - Fix a typo in reset_rsvds_bits_mask() Signed-off-by: Xiao Guangrong Reviewed-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 064c3efb49dc..83d2ebce9ea9 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2297,13 +2297,19 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) /* no rsvd bits for 2 level 4K page table entries */ context->rsvd_bits_mask[0][1] = 0; context->rsvd_bits_mask[0][0] = 0; + context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[0][0]; + + if (!is_pse(vcpu)) { + context->rsvd_bits_mask[1][1] = 0; + break; + } + if (is_cpuid_PSE36()) /* 36bits PSE 4MB page */ context->rsvd_bits_mask[1][1] = rsvd_bits(17, 21); else /* 32 bits PSE 4MB page */ context->rsvd_bits_mask[1][1] = rsvd_bits(13, 21); - context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; break; case PT32E_ROOT_LEVEL: context->rsvd_bits_mask[0][2] = @@ -2316,7 +2322,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) context->rsvd_bits_mask[1][1] = exb_bit_rsvd | rsvd_bits(maxphyaddr, 62) | rsvd_bits(13, 20); /* large page */ - context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; + context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[0][0]; break; case PT64_ROOT_LEVEL: context->rsvd_bits_mask[0][3] = exb_bit_rsvd | @@ -2334,7 +2340,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) context->rsvd_bits_mask[1][1] = exb_bit_rsvd | rsvd_bits(maxphyaddr, 51) | rsvd_bits(13, 20); /* large page */ - context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; + context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[0][0]; break; } } -- cgit v1.2.3-59-g8ed1b From 84b0c8c6a6f87b62bca93727dee12ec59e32e597 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 14 Mar 2010 10:16:40 +0200 Subject: KVM: MMU: Disassociate direct maps from guest levels Direct maps are linear translations for a section of memory, used for real mode or with large pages. As such, they are independent of the guest levels. Teach the mmu about this by making page->role.glevels = 0 for direct maps. This allows direct maps to be shared among real mode and the various paging modes. Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 83d2ebce9ea9..1cc60d3f445b 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1329,6 +1329,8 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, role = vcpu->arch.mmu.base_role; role.level = level; role.direct = direct; + if (role.direct) + role.glevels = 0; role.access = access; if (vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) { quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level)); -- cgit v1.2.3-59-g8ed1b From 3eeafd7da2b0293b512abe95c86843fc4ab42add Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:17 +0100 Subject: KVM: PPC: Ensure split mode works On PowerPC we can go into MMU Split Mode. That means that either data relocation is on but instruction relocation is off or vice versa. That mode didn't work properly, as we weren't always flushing entries when going into a new split mode, potentially mapping different code or data that we're supposed to. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 9 ++++--- arch/powerpc/kvm/book3s.c | 46 ++++++++++++++++++----------------- 2 files changed, 29 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index e6ea974df44e..14d0262ae00b 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -99,10 +99,11 @@ struct kvmppc_vcpu_book3s { #define CONTEXT_GUEST 1 #define CONTEXT_GUEST_END 2 -#define VSID_REAL 0xfffffffffff00000 -#define VSID_REAL_DR 0xffffffffffe00000 -#define VSID_REAL_IR 0xffffffffffd00000 -#define VSID_BAT 0xffffffffffc00000 +#define VSID_REAL_DR 0x7ffffffffff00000 +#define VSID_REAL_IR 0x7fffffffffe00000 +#define VSID_SPLIT_MASK 0x7fffffffffe00000 +#define VSID_REAL 0x7fffffffffc00000 +#define VSID_BAT 0x7fffffffffb00000 #define VSID_PR 0x8000000000000000 extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 ea, u64 ea_mask); diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 8cab902771a2..ff5a42058257 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -134,6 +134,14 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) if (((vcpu->arch.msr & (MSR_IR|MSR_DR)) != (old_msr & (MSR_IR|MSR_DR))) || (vcpu->arch.msr & MSR_PR) != (old_msr & MSR_PR)) { + bool dr = (vcpu->arch.msr & MSR_DR) ? true : false; + bool ir = (vcpu->arch.msr & MSR_IR) ? true : false; + + /* Flush split mode PTEs */ + if (dr != ir) + kvmppc_mmu_pte_vflush(vcpu, VSID_SPLIT_MASK, + VSID_SPLIT_MASK); + kvmppc_mmu_flush_segments(vcpu); kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc); } @@ -396,15 +404,7 @@ static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, } else { pte->eaddr = eaddr; pte->raddr = eaddr & 0xffffffff; - pte->vpage = eaddr >> 12; - switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) { - case 0: - pte->vpage |= VSID_REAL; - case MSR_DR: - pte->vpage |= VSID_REAL_DR; - case MSR_IR: - pte->vpage |= VSID_REAL_IR; - } + pte->vpage = VSID_REAL | eaddr >> 12; pte->may_read = true; pte->may_write = true; pte->may_execute = true; @@ -513,12 +513,10 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, int page_found = 0; struct kvmppc_pte pte; bool is_mmio = false; + bool dr = (vcpu->arch.msr & MSR_DR) ? true : false; + bool ir = (vcpu->arch.msr & MSR_IR) ? true : false; - if ( vec == BOOK3S_INTERRUPT_DATA_STORAGE ) { - relocated = (vcpu->arch.msr & MSR_DR); - } else { - relocated = (vcpu->arch.msr & MSR_IR); - } + relocated = data ? dr : ir; /* Resolve real address if translation turned on */ if (relocated) { @@ -530,14 +528,18 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, pte.raddr = eaddr & 0xffffffff; pte.eaddr = eaddr; pte.vpage = eaddr >> 12; - switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) { - case 0: - pte.vpage |= VSID_REAL; - case MSR_DR: - pte.vpage |= VSID_REAL_DR; - case MSR_IR: - pte.vpage |= VSID_REAL_IR; - } + } + + switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) { + case 0: + pte.vpage |= VSID_REAL; + break; + case MSR_DR: + pte.vpage |= VSID_REAL_DR; + break; + case MSR_IR: + pte.vpage |= VSID_REAL_IR; + break; } if (vcpu->arch.mmu.is_dcbz32(vcpu) && -- cgit v1.2.3-59-g8ed1b From 18978768d89f638165646718c50ced19f2a10164 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:18 +0100 Subject: KVM: PPC: Allow userspace to unset the IRQ line Userspace can tell us that it wants to trigger an interrupt. But so far it can't tell us that it wants to stop triggering one. So let's interpret the parameter to the ioctl that we have anyways to tell us if we want to raise or lower the interrupt line. Signed-off-by: Alexander Graf v2 -> v3: - Add CAP for unset irq Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm.h | 3 +++ arch/powerpc/include/asm/kvm_ppc.h | 2 ++ arch/powerpc/kvm/book3s.c | 6 ++++++ arch/powerpc/kvm/powerpc.c | 6 +++++- include/linux/kvm.h | 1 + 5 files changed, 17 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index 19bae31202ce..6c5547d82bbe 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -84,4 +84,7 @@ struct kvm_guest_debug_arch { #define KVM_REG_QPR 0x0040 #define KVM_REG_FQPR 0x0060 +#define KVM_INTERRUPT_SET -1U +#define KVM_INTERRUPT_UNSET -2U + #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index c7fcdd751f14..6a2464e4d6b9 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -92,6 +92,8 @@ extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu); extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu); extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq); +extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu, + struct kvm_interrupt *irq); extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, unsigned int op, int *advance); diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index ff5a42058257..34e1a342bec8 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -231,6 +231,12 @@ void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL); } +void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu, + struct kvm_interrupt *irq) +{ + kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL); +} + int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) { int deliver = 1; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 3f8677e9d8f9..0bb6a7e826d1 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -149,6 +149,7 @@ int kvm_dev_ioctl_check_extension(long ext) switch (ext) { case KVM_CAP_PPC_SEGSTATE: case KVM_CAP_PPC_PAIRED_SINGLES: + case KVM_CAP_PPC_UNSET_IRQ: r = 1; break; case KVM_CAP_COALESCED_MMIO: @@ -451,7 +452,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) { - kvmppc_core_queue_external(vcpu, irq); + if (irq->irq == KVM_INTERRUPT_UNSET) + kvmppc_core_dequeue_external(vcpu, irq); + else + kvmppc_core_queue_external(vcpu, irq); if (waitqueue_active(&vcpu->wq)) { wake_up_interruptible(&vcpu->wq); diff --git a/include/linux/kvm.h b/include/linux/kvm.h index ce2876717a8b..c36d093e9806 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -507,6 +507,7 @@ struct kvm_ioeventfd { #define KVM_CAP_DEBUGREGS 50 #endif #define KVM_CAP_X86_ROBUST_SINGLESTEP 51 +#define KVM_CAP_PPC_UNSET_IRQ 53 #ifdef KVM_CAP_IRQ_ROUTING -- cgit v1.2.3-59-g8ed1b From c8027f165228b4c62bad31609d5c9e98ddfb8ef6 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:19 +0100 Subject: KVM: PPC: Make DSISR 32 bits wide DSISR is only defined as 32 bits wide. So let's reflect that in the structs too. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 2 +- arch/powerpc/include/asm/kvm_host.h | 2 +- arch/powerpc/kvm/book3s_64_interrupts.S | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 14d0262ae00b..9f5a9921927e 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -84,8 +84,8 @@ struct kvmppc_vcpu_book3s { u64 hid[6]; u64 gqr[8]; int slb_nr; + u32 dsisr; u64 sdr1; - u64 dsisr; u64 hior; u64 msr_mask; u64 vsid_first; diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 119deb4750d9..0ebda67ad6a8 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -260,7 +260,7 @@ struct kvm_vcpu_arch { u32 last_inst; #ifdef CONFIG_PPC64 - ulong fault_dsisr; + u32 fault_dsisr; #endif ulong fault_dear; ulong fault_esr; diff --git a/arch/powerpc/kvm/book3s_64_interrupts.S b/arch/powerpc/kvm/book3s_64_interrupts.S index c1584d0cbce8..faca87610d65 100644 --- a/arch/powerpc/kvm/book3s_64_interrupts.S +++ b/arch/powerpc/kvm/book3s_64_interrupts.S @@ -171,7 +171,7 @@ kvmppc_handler_highmem: std r3, VCPU_PC(r7) std r4, VCPU_SHADOW_SRR1(r7) std r5, VCPU_FAULT_DEAR(r7) - std r6, VCPU_FAULT_DSISR(r7) + stw r6, VCPU_FAULT_DSISR(r7) ld r5, VCPU_HFLAGS(r7) rldicl. r5, r5, 0, 63 /* CR = ((r5 & 1) == 0) */ -- cgit v1.2.3-59-g8ed1b From 4b389ca2e733b986c5282690e4e0314f000e6228 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:20 +0100 Subject: KVM: PPC: Book3S_32 guest MMU fixes This patch makes the VSID of mapped pages always reflecting all special cases we have, like split mode. It also changes the tlbie mask to 0x0ffff000 according to the spec. The mask we used before was incorrect. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 1 + arch/powerpc/kvm/book3s_32_mmu.c | 30 +++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 9f5a9921927e..b47b2f516eff 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -44,6 +44,7 @@ struct kvmppc_sr { bool Ks; bool Kp; bool nx; + bool valid; }; struct kvmppc_bat { diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index 1483a9bdddae..7071e22b42ff 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c @@ -57,6 +57,8 @@ static inline bool check_debug_ip(struct kvm_vcpu *vcpu) static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, struct kvmppc_pte *pte, bool data); +static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid, + u64 *vsid); static struct kvmppc_sr *find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t eaddr) { @@ -66,13 +68,14 @@ static struct kvmppc_sr *find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t e static u64 kvmppc_mmu_book3s_32_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr, bool data) { - struct kvmppc_sr *sre = find_sr(to_book3s(vcpu), eaddr); + u64 vsid; struct kvmppc_pte pte; if (!kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, &pte, data)) return pte.vpage; - return (((u64)eaddr >> 12) & 0xffff) | (((u64)sre->vsid) << 16); + kvmppc_mmu_book3s_32_esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid); + return (((u64)eaddr >> 12) & 0xffff) | (vsid << 16); } static void kvmppc_mmu_book3s_32_reset_msr(struct kvm_vcpu *vcpu) @@ -142,8 +145,13 @@ static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, bat->bepi_mask); } if ((eaddr & bat->bepi_mask) == bat->bepi) { + u64 vsid; + kvmppc_mmu_book3s_32_esid_to_vsid(vcpu, + eaddr >> SID_SHIFT, &vsid); + vsid <<= 16; + pte->vpage = (((u64)eaddr >> 12) & 0xffff) | vsid; + pte->raddr = bat->brpn | (eaddr & ~bat->bepi_mask); - pte->vpage = (eaddr >> 12) | VSID_BAT; pte->may_read = bat->pp; pte->may_write = bat->pp > 1; pte->may_execute = true; @@ -302,6 +310,7 @@ static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum, /* And then put in the new SR */ sre->raw = value; sre->vsid = (value & 0x0fffffff); + sre->valid = (value & 0x80000000) ? false : true; sre->Ks = (value & 0x40000000) ? true : false; sre->Kp = (value & 0x20000000) ? true : false; sre->nx = (value & 0x10000000) ? true : false; @@ -312,7 +321,7 @@ static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum, static void kvmppc_mmu_book3s_32_tlbie(struct kvm_vcpu *vcpu, ulong ea, bool large) { - kvmppc_mmu_pte_flush(vcpu, ea, ~0xFFFULL); + kvmppc_mmu_pte_flush(vcpu, ea, 0x0FFFF000); } static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid, @@ -333,15 +342,22 @@ static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid, break; case MSR_DR|MSR_IR: { - ulong ea; - ea = esid << SID_SHIFT; - *vsid = find_sr(to_book3s(vcpu), ea)->vsid; + ulong ea = esid << SID_SHIFT; + struct kvmppc_sr *sr = find_sr(to_book3s(vcpu), ea); + + if (!sr->valid) + return -1; + + *vsid = sr->vsid; break; } default: BUG(); } + if (vcpu->arch.msr & MSR_PR) + *vsid |= VSID_PR; + return 0; } -- cgit v1.2.3-59-g8ed1b From 8963221d7d7244cc828dfca5649404c747599b3e Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:21 +0100 Subject: KVM: PPC: Split instruction reading out The current check_ext function reads the instruction and then does the checking. Let's split the reading out so we can reuse it for different functions. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 34e1a342bec8..358d5f78311a 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -651,26 +651,34 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) kvmppc_recalc_shadow_msr(vcpu); } -static int kvmppc_check_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr) +static int kvmppc_read_inst(struct kvm_vcpu *vcpu) { ulong srr0 = vcpu->arch.pc; int ret; - /* Need to do paired single emulation? */ - if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)) - return EMULATE_DONE; - - /* Read out the instruction */ ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &vcpu->arch.last_inst, false); if (ret == -ENOENT) { vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 33, 33, 1); vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 34, 36, 0); vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 42, 47, 0); kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE); - } else if(ret == EMULATE_DONE) { + return EMULATE_AGAIN; + } + + return EMULATE_DONE; +} + +static int kvmppc_check_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr) +{ + + /* Need to do paired single emulation? */ + if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)) + return EMULATE_DONE; + + /* Read out the instruction */ + if (kvmppc_read_inst(vcpu) == EMULATE_DONE) /* Need to emulate */ return EMULATE_FAIL; - } return EMULATE_AGAIN; } -- cgit v1.2.3-59-g8ed1b From c2453693d41f31dae1b4d39b2d59d9a9c6dcb837 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:22 +0100 Subject: KVM: PPC: Don't reload FPU with invalid values When the guest activates the FPU, we load it up. That's fine when it wasn't activated before on the host, but if it was we end up reloading FPU values from last time the FPU was deactivated on the host without writing the proper values back to the vcpu struct. This patch checks if the FPU is enabled already and if so just doesn't bother activating it, making FPU operations survive guest context switches. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 358d5f78311a..6f409c98205c 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -702,6 +702,11 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, return RESUME_GUEST; } + /* We already own the ext */ + if (vcpu->arch.guest_owned_ext & msr) { + return RESUME_GUEST; + } + #ifdef DEBUG_EXT printk(KERN_INFO "Loading up ext 0x%lx\n", msr); #endif -- cgit v1.2.3-59-g8ed1b From a56cf347c21b21d52db127672cf1edf5dd724a4b Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:23 +0100 Subject: KVM: PPC: Load VCPU for register fetching When trying to read or store vcpu register data, we should also make sure the vcpu is actually loaded, so we're 100% sure we get the correct values. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 6f409c98205c..c058f1a5c095 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -956,6 +956,8 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) { int i; + vcpu_load(vcpu); + regs->pc = vcpu->arch.pc; regs->cr = kvmppc_get_cr(vcpu); regs->ctr = vcpu->arch.ctr; @@ -976,6 +978,8 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) regs->gpr[i] = kvmppc_get_gpr(vcpu, i); + vcpu_put(vcpu); + return 0; } @@ -983,6 +987,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) { int i; + vcpu_load(vcpu); + vcpu->arch.pc = regs->pc; kvmppc_set_cr(vcpu, regs->cr); vcpu->arch.ctr = regs->ctr; @@ -1002,6 +1008,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) kvmppc_set_gpr(vcpu, i, regs->gpr[i]); + vcpu_put(vcpu); + return 0; } -- cgit v1.2.3-59-g8ed1b From c664876c6d88ff8c8e93ee05c0bbdc3e4c2af488 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:24 +0100 Subject: KVM: PPC: Implement mfsr emulation We emulate the mfsrin instruction already, that passes the SR number in a register value. But we lacked support for mfsr that encoded the SR number in the opcode. So let's implement it. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_emulate.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index c9892140dd02..8d7a78d87eff 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c @@ -35,6 +35,7 @@ #define OP_31_XOP_SLBMTE 402 #define OP_31_XOP_SLBIE 434 #define OP_31_XOP_SLBIA 498 +#define OP_31_XOP_MFSR 595 #define OP_31_XOP_MFSRIN 659 #define OP_31_XOP_SLBMFEV 851 #define OP_31_XOP_EIOIO 854 @@ -90,6 +91,18 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, case OP_31_XOP_MTMSR: kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, get_rs(inst))); break; + case OP_31_XOP_MFSR: + { + int srnum; + + srnum = kvmppc_get_field(inst, 12 + 32, 15 + 32); + if (vcpu->arch.mmu.mfsrin) { + u32 sr; + sr = vcpu->arch.mmu.mfsrin(vcpu, srnum); + kvmppc_set_gpr(vcpu, get_rt(inst), sr); + } + break; + } case OP_31_XOP_MFSRIN: { int srnum; -- cgit v1.2.3-59-g8ed1b From c04a695a4484467889d0c91c2e377c6abcecd5d5 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:25 +0100 Subject: KVM: PPC: Implement BAT reads BATs can't only be written to, you can also read them out! So let's implement emulation for reading BAT values again. While at it, I also made BAT setting flush the segment cache, so we're absolutely sure there's no MMU state left when writing BATs. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_emulate.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index 8d7a78d87eff..39d5003e01f0 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c @@ -239,6 +239,34 @@ void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper, } } +static u32 kvmppc_read_bat(struct kvm_vcpu *vcpu, int sprn) +{ + struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); + struct kvmppc_bat *bat; + + switch (sprn) { + case SPRN_IBAT0U ... SPRN_IBAT3L: + bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2]; + break; + case SPRN_IBAT4U ... SPRN_IBAT7L: + bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)]; + break; + case SPRN_DBAT0U ... SPRN_DBAT3L: + bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2]; + break; + case SPRN_DBAT4U ... SPRN_DBAT7L: + bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)]; + break; + default: + BUG(); + } + + if (sprn % 2) + return bat->raw >> 32; + else + return bat->raw; +} + static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val) { struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); @@ -290,6 +318,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) /* BAT writes happen so rarely that we're ok to flush * everything here */ kvmppc_mmu_pte_flush(vcpu, 0, 0); + kvmppc_mmu_flush_segments(vcpu); break; case SPRN_HID0: to_book3s(vcpu)->hid[0] = spr_val; @@ -373,6 +402,12 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) int emulated = EMULATE_DONE; switch (sprn) { + case SPRN_IBAT0U ... SPRN_IBAT3L: + case SPRN_IBAT4U ... SPRN_IBAT7L: + case SPRN_DBAT0U ... SPRN_DBAT3L: + case SPRN_DBAT4U ... SPRN_DBAT7L: + kvmppc_set_gpr(vcpu, rt, kvmppc_read_bat(vcpu, sprn)); + break; case SPRN_SDR1: kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1); break; -- cgit v1.2.3-59-g8ed1b From 1bec1677ca5b3406dc1f174b61beaeb832eed715 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:26 +0100 Subject: KVM: PPC: Make XER load 32 bit We have a 32 bit value in the PACA to store XER in. We also do an stw when storing XER in there. But then we load it with ld, completely screwing it up on every entry. Welcome to the Big Endian world. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_slb.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_slb.S b/arch/powerpc/kvm/book3s_64_slb.S index 35b762722187..091967907954 100644 --- a/arch/powerpc/kvm/book3s_64_slb.S +++ b/arch/powerpc/kvm/book3s_64_slb.S @@ -145,7 +145,7 @@ slb_do_enter: lwz r11, (PACA_KVM_CR)(r13) mtcr r11 - ld r11, (PACA_KVM_XER)(r13) + lwz r11, (PACA_KVM_XER)(r13) mtxer r11 ld r11, (PACA_KVM_R11)(r13) -- cgit v1.2.3-59-g8ed1b From 1c85e73303fa70cd6bc2bf138484acb4ffe30efd Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:27 +0100 Subject: KVM: PPC: Implement emulation for lbzux and lhax We get MMIOs with the weirdest instructions. But every time we do, we need to improve our emulator to implement them. So let's do that - this time it's lbzux and lhax's round. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/emulate.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index 2410ec2a756a..dbb5d6842a51 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -38,10 +38,12 @@ #define OP_31_XOP_LBZX 87 #define OP_31_XOP_STWX 151 #define OP_31_XOP_STBX 215 +#define OP_31_XOP_LBZUX 119 #define OP_31_XOP_STBUX 247 #define OP_31_XOP_LHZX 279 #define OP_31_XOP_LHZUX 311 #define OP_31_XOP_MFSPR 339 +#define OP_31_XOP_LHAX 343 #define OP_31_XOP_STHX 407 #define OP_31_XOP_STHUX 439 #define OP_31_XOP_MTSPR 467 @@ -173,6 +175,19 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); break; + case OP_31_XOP_LBZUX: + rt = get_rt(inst); + ra = get_ra(inst); + rb = get_rb(inst); + + ea = kvmppc_get_gpr(vcpu, rb); + if (ra) + ea += kvmppc_get_gpr(vcpu, ra); + + emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); + kvmppc_set_gpr(vcpu, ra, ea); + break; + case OP_31_XOP_STWX: rs = get_rs(inst); emulated = kvmppc_handle_store(run, vcpu, @@ -202,6 +217,11 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) kvmppc_set_gpr(vcpu, rs, ea); break; + case OP_31_XOP_LHAX: + rt = get_rt(inst); + emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); + break; + case OP_31_XOP_LHZX: rt = get_rt(inst); emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); -- cgit v1.2.3-59-g8ed1b From ca7f4203b9b66e12d0d9968ff7dfe781f3a9695a Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:28 +0100 Subject: KVM: PPC: Implement alignment interrupt Mac OS X has some applications - namely the Finder - that require alignment interrupts to work properly. So we need to implement them. But the spec for 970 and 750 also looks different. While 750 requires the DSISR and DAR fields to reflect some instruction bits (DSISR) and the fault address (DAR), the 970 declares this as an optional feature. So we need to reconstruct DSISR and DAR manually. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 2 + arch/powerpc/kvm/book3s.c | 10 +++++ arch/powerpc/kvm/book3s_64_emulate.c | 75 +++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index b47b2f516eff..bea76371dbe1 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -131,6 +131,8 @@ extern void kvmppc_rmcall(ulong srr0, ulong srr1); extern void kvmppc_load_up_fpu(void); extern void kvmppc_load_up_altivec(void); extern void kvmppc_load_up_vsx(void); +extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst); +extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst); static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu) { diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index c058f1a5c095..de12202fe1c6 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -906,6 +906,16 @@ program_interrupt: } break; } + case BOOK3S_INTERRUPT_ALIGNMENT: + if (kvmppc_read_inst(vcpu) == EMULATE_DONE) { + to_book3s(vcpu)->dsisr = kvmppc_alignment_dsisr(vcpu, + vcpu->arch.last_inst); + vcpu->arch.dear = kvmppc_alignment_dar(vcpu, + vcpu->arch.last_inst); + kvmppc_book3s_queue_irqprio(vcpu, exit_nr); + } + r = RESUME_GUEST; + break; case BOOK3S_INTERRUPT_MACHINE_CHECK: case BOOK3S_INTERRUPT_TRACE: kvmppc_book3s_queue_irqprio(vcpu, exit_nr); diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index 39d5003e01f0..1e5cf8d594ea 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c @@ -44,6 +44,11 @@ /* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */ #define OP_31_XOP_DCBZ 1010 +#define OP_LFS 48 +#define OP_LFD 50 +#define OP_STFS 52 +#define OP_STFD 54 + #define SPRN_GQR0 912 #define SPRN_GQR1 913 #define SPRN_GQR2 914 @@ -474,3 +479,73 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) return emulated; } +u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst) +{ + u32 dsisr = 0; + + /* + * This is what the spec says about DSISR bits (not mentioned = 0): + * + * 12:13 [DS] Set to bits 30:31 + * 15:16 [X] Set to bits 29:30 + * 17 [X] Set to bit 25 + * [D/DS] Set to bit 5 + * 18:21 [X] Set to bits 21:24 + * [D/DS] Set to bits 1:4 + * 22:26 Set to bits 6:10 (RT/RS/FRT/FRS) + * 27:31 Set to bits 11:15 (RA) + */ + + switch (get_op(inst)) { + /* D-form */ + case OP_LFS: + case OP_LFD: + case OP_STFD: + case OP_STFS: + dsisr |= (inst >> 12) & 0x4000; /* bit 17 */ + dsisr |= (inst >> 17) & 0x3c00; /* bits 18:21 */ + break; + /* X-form */ + case 31: + dsisr |= (inst << 14) & 0x18000; /* bits 15:16 */ + dsisr |= (inst << 8) & 0x04000; /* bit 17 */ + dsisr |= (inst << 3) & 0x03c00; /* bits 18:21 */ + break; + default: + printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst); + break; + } + + dsisr |= (inst >> 16) & 0x03ff; /* bits 22:31 */ + + return dsisr; +} + +ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst) +{ + ulong dar = 0; + ulong ra; + + switch (get_op(inst)) { + case OP_LFS: + case OP_LFD: + case OP_STFD: + case OP_STFS: + ra = get_ra(inst); + if (ra) + dar = kvmppc_get_gpr(vcpu, ra); + dar += (s32)((s16)inst); + break; + case 31: + ra = get_ra(inst); + if (ra) + dar = kvmppc_get_gpr(vcpu, ra); + dar += kvmppc_get_gpr(vcpu, get_rb(inst)); + break; + default: + printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst); + break; + } + + return dar; +} -- cgit v1.2.3-59-g8ed1b From 71fbfd5f38f73515f1516a68fbe04dba198b70f0 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:29 +0100 Subject: KVM: Add support for enabling capabilities per-vcpu Some times we don't want all capabilities to be available to all our vcpus. One example for that is the OSI interface, implemented in the next patch. In order to have a generic mechanism in how to enable capabilities individually, this patch introduces a new ioctl that can be used for this purpose. That way features we don't want in all guests or userspace configurations can just not be enabled and we're good. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- Documentation/kvm/api.txt | 35 +++++++++++++++++++++++++++++++++++ arch/powerpc/kvm/powerpc.c | 27 +++++++++++++++++++++++++++ include/linux/kvm.h | 11 +++++++++++ 3 files changed, 73 insertions(+) (limited to 'arch') diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index 2cc0120ccdb5..f9724dc8d079 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt @@ -813,6 +813,41 @@ This ioctl is required on Intel-based hosts. This is needed on Intel hardware because of a quirk in the virtualization implementation (see the internals documentation when it pops into existence). +4.36 KVM_ENABLE_CAP + +Capability: KVM_CAP_ENABLE_CAP +Architectures: ppc +Type: vcpu ioctl +Parameters: struct kvm_enable_cap (in) +Returns: 0 on success; -1 on error + ++Not all extensions are enabled by default. Using this ioctl the application +can enable an extension, making it available to the guest. + +On systems that do not support this ioctl, it always fails. On systems that +do support it, it only works for extensions that are supported for enablement. + +To check if a capability can be enabled, the KVM_CHECK_EXTENSION ioctl should +be used. + +struct kvm_enable_cap { + /* in */ + __u32 cap; + +The capability that is supposed to get enabled. + + __u32 flags; + +A bitfield indicating future enhancements. Has to be 0 for now. + + __u64 args[4]; + +Arguments for enabling a feature. If a feature needs initial values to +function properly, this is the place to put them. + + __u8 pad[64]; +}; + 5. The kvm_run structure Application code obtains a pointer to the kvm_run structure by diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 0bb6a7e826d1..646bfd256e5d 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -150,6 +150,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_PPC_SEGSTATE: case KVM_CAP_PPC_PAIRED_SINGLES: case KVM_CAP_PPC_UNSET_IRQ: + case KVM_CAP_ENABLE_CAP: r = 1; break; case KVM_CAP_COALESCED_MMIO: @@ -465,6 +466,23 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) return 0; } +static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, + struct kvm_enable_cap *cap) +{ + int r; + + if (cap->flags) + return -EINVAL; + + switch (cap->cap) { + default: + r = -EINVAL; + break; + } + + return r; +} + int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, struct kvm_mp_state *mp_state) { @@ -493,6 +511,15 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); break; } + case KVM_ENABLE_CAP: + { + struct kvm_enable_cap cap; + r = -EFAULT; + if (copy_from_user(&cap, argp, sizeof(cap))) + goto out; + r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); + break; + } default: r = -EINVAL; } diff --git a/include/linux/kvm.h b/include/linux/kvm.h index c36d093e9806..ecb68e433558 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -400,6 +400,15 @@ struct kvm_ioeventfd { __u8 pad[36]; }; +/* for KVM_ENABLE_CAP */ +struct kvm_enable_cap { + /* in */ + __u32 cap; + __u32 flags; + __u64 args[4]; + __u8 pad[64]; +}; + #define KVMIO 0xAE /* @@ -508,6 +517,7 @@ struct kvm_ioeventfd { #endif #define KVM_CAP_X86_ROBUST_SINGLESTEP 51 #define KVM_CAP_PPC_UNSET_IRQ 53 +#define KVM_CAP_ENABLE_CAP 54 #ifdef KVM_CAP_IRQ_ROUTING @@ -697,6 +707,7 @@ struct kvm_clock_data { /* Available with KVM_CAP_DEBUGREGS */ #define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) +#define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) -- cgit v1.2.3-59-g8ed1b From ad0a048b096ac819f28667602285453468a8d8f9 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:30 +0100 Subject: KVM: PPC: Add OSI hypercall interface MOL uses its own hypercall interface to call back into userspace when the guest wants to do something. So let's implement that as an exit reason, specify it with a CAP and only really use it when userspace wants us to. The only user of it so far is MOL. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- Documentation/kvm/api.txt | 19 ++++++++++++++++--- arch/powerpc/include/asm/kvm_book3s.h | 5 +++++ arch/powerpc/include/asm/kvm_host.h | 2 ++ arch/powerpc/kvm/book3s.c | 24 ++++++++++++++++++------ arch/powerpc/kvm/powerpc.c | 12 ++++++++++++ include/linux/kvm.h | 6 ++++++ 6 files changed, 59 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index f9724dc8d079..6f362356e738 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt @@ -958,9 +958,9 @@ executed a memory-mapped I/O instruction which could not be satisfied by kvm. The 'data' member contains the written data if 'is_write' is true, and should be filled by application code otherwise. -NOTE: For KVM_EXIT_IO and KVM_EXIT_MMIO, the corresponding operations -are complete (and guest state is consistent) only after userspace has -re-entered the kernel with KVM_RUN. The kernel side will first finish +NOTE: For KVM_EXIT_IO, KVM_EXIT_MMIO and KVM_EXIT_OSI, the corresponding +operations are complete (and guest state is consistent) only after userspace +has re-entered the kernel with KVM_RUN. The kernel side will first finish incomplete operations and then check for pending signals. Userspace can re-enter the guest with an unmasked signal pending to complete pending operations. @@ -1015,6 +1015,19 @@ s390 specific. powerpc specific. + /* KVM_EXIT_OSI */ + struct { + __u64 gprs[32]; + } osi; + +MOL uses a special hypercall interface it calls 'OSI'. To enable it, we catch +hypercalls and exit with this exit struct that contains all the guest gprs. + +If exit_reason is KVM_EXIT_OSI, then the vcpu has triggered such a hypercall. +Userspace can now handle the hypercall and when it's done modify the gprs as +necessary. Upon guest entry all guest GPRs will then be replaced by the values +in this struct. + /* Fix the size of the union. */ char padding[256]; }; diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index bea76371dbe1..7e243b2cac72 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -148,6 +148,11 @@ static inline ulong dsisr(void) extern void kvm_return_point(void); +/* Magic register values loaded into r3 and r4 before the 'sc' assembly + * instruction for the OSI hypercalls */ +#define OSI_SC_MAGIC_R3 0x113724FA +#define OSI_SC_MAGIC_R4 0x77810F9B + #define INS_DCBZ 0x7c0007ec #endif /* __ASM_KVM_BOOK3S_H__ */ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 0ebda67ad6a8..486f1cafd5f7 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -273,6 +273,8 @@ struct kvm_vcpu_arch { u8 mmio_sign_extend; u8 dcr_needed; u8 dcr_is_write; + u8 osi_needed; + u8 osi_enabled; u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index de12202fe1c6..7696d0f547e3 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -872,12 +872,24 @@ program_interrupt: break; } case BOOK3S_INTERRUPT_SYSCALL: -#ifdef EXIT_DEBUG - printk(KERN_INFO "Syscall Nr %d\n", (int)kvmppc_get_gpr(vcpu, 0)); -#endif - vcpu->stat.syscall_exits++; - kvmppc_book3s_queue_irqprio(vcpu, exit_nr); - r = RESUME_GUEST; + // XXX make user settable + if (vcpu->arch.osi_enabled && + (((u32)kvmppc_get_gpr(vcpu, 3)) == OSI_SC_MAGIC_R3) && + (((u32)kvmppc_get_gpr(vcpu, 4)) == OSI_SC_MAGIC_R4)) { + u64 *gprs = run->osi.gprs; + int i; + + run->exit_reason = KVM_EXIT_OSI; + for (i = 0; i < 32; i++) + gprs[i] = kvmppc_get_gpr(vcpu, i); + vcpu->arch.osi_needed = 1; + r = RESUME_HOST_NV; + + } else { + vcpu->stat.syscall_exits++; + kvmppc_book3s_queue_irqprio(vcpu, exit_nr); + r = RESUME_GUEST; + } break; case BOOK3S_INTERRUPT_FP_UNAVAIL: case BOOK3S_INTERRUPT_ALTIVEC: diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 646bfd256e5d..9a4dd8146d39 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -151,6 +151,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_PPC_PAIRED_SINGLES: case KVM_CAP_PPC_UNSET_IRQ: case KVM_CAP_ENABLE_CAP: + case KVM_CAP_PPC_OSI: r = 1; break; case KVM_CAP_COALESCED_MMIO: @@ -433,6 +434,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) if (!vcpu->arch.dcr_is_write) kvmppc_complete_dcr_load(vcpu, run); vcpu->arch.dcr_needed = 0; + } else if (vcpu->arch.osi_needed) { + u64 *gprs = run->osi.gprs; + int i; + + for (i = 0; i < 32; i++) + kvmppc_set_gpr(vcpu, i, gprs[i]); + vcpu->arch.osi_needed = 0; } kvmppc_core_deliver_interrupts(vcpu); @@ -475,6 +483,10 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, return -EINVAL; switch (cap->cap) { + case KVM_CAP_PPC_OSI: + r = 0; + vcpu->arch.osi_enabled = true; + break; default: r = -EINVAL; break; diff --git a/include/linux/kvm.h b/include/linux/kvm.h index ecb68e433558..23ea02253900 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -160,6 +160,7 @@ struct kvm_pit_config { #define KVM_EXIT_DCR 15 #define KVM_EXIT_NMI 16 #define KVM_EXIT_INTERNAL_ERROR 17 +#define KVM_EXIT_OSI 18 /* For KVM_EXIT_INTERNAL_ERROR */ #define KVM_INTERNAL_ERROR_EMULATION 1 @@ -259,6 +260,10 @@ struct kvm_run { __u32 ndata; __u64 data[16]; } internal; + /* KVM_EXIT_OSI */ + struct { + __u64 gprs[32]; + } osi; /* Fix the size of the union. */ char padding[256]; }; @@ -516,6 +521,7 @@ struct kvm_enable_cap { #define KVM_CAP_DEBUGREGS 50 #endif #define KVM_CAP_X86_ROBUST_SINGLESTEP 51 +#define KVM_CAP_PPC_OSI 52 #define KVM_CAP_PPC_UNSET_IRQ 53 #define KVM_CAP_ENABLE_CAP 54 -- cgit v1.2.3-59-g8ed1b From a2b07664f6cd14836ff84a77f48566673dca00bb Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:31 +0100 Subject: KVM: PPC: Make build work without CONFIG_VSX/ALTIVEC The FPU/Altivec/VSX enablement also brought access to some structure elements that are only defined when the respective config options are enabled. Unfortuately I forgot to check for the config options at some places, so let's do that now. Unbreaks the build when CONFIG_VSX is not set. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 7696d0f547e3..d2b3dabe2dc3 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -609,7 +609,9 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) { struct thread_struct *t = ¤t->thread; u64 *vcpu_fpr = vcpu->arch.fpr; +#ifdef CONFIG_VSX u64 *vcpu_vsx = vcpu->arch.vsr; +#endif u64 *thread_fpr = (u64*)t->fpr; int i; @@ -689,7 +691,9 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, { struct thread_struct *t = ¤t->thread; u64 *vcpu_fpr = vcpu->arch.fpr; +#ifdef CONFIG_VSX u64 *vcpu_vsx = vcpu->arch.vsr; +#endif u64 *thread_fpr = (u64*)t->fpr; int i; @@ -1221,8 +1225,12 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) { int ret; struct thread_struct ext_bkp; +#ifdef CONFIG_ALTIVEC bool save_vec = current->thread.used_vr; +#endif +#ifdef CONFIG_VSX bool save_vsx = current->thread.used_vsr; +#endif ulong ext_msr; /* No need to go into the guest when all we do is going out */ -- cgit v1.2.3-59-g8ed1b From 9fb244a2c215d1e16ee92cb164b7b61c8dfa3909 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:32 +0100 Subject: KVM: PPC: Fix dcbz emulation On most systems we need to emulate dcbz when running 32 bit guests. So far we've been rather slack, not giving correct DSISR values to the guest. This patch makes the emulation more accurate, introducing a difference between "page not mapped" and "write protection fault". While at it, it also speeds up dcbz emulation by an order of magnitude by using kmap. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 56 ++++++++++++++---------------------- arch/powerpc/kvm/book3s_64_emulate.c | 19 +++++++++--- 2 files changed, 37 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index d2b3dabe2dc3..ed5758496372 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -29,6 +29,7 @@ #include #include #include +#include #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU @@ -369,34 +370,29 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) */ static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte) { - bool touched = false; - hva_t hpage; + struct page *hpage; + u64 hpage_offset; u32 *page; int i; - hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT); - if (kvm_is_error_hva(hpage)) + hpage = gfn_to_page(vcpu->kvm, pte->raddr >> PAGE_SHIFT); + if (is_error_page(hpage)) return; - hpage |= pte->raddr & ~PAGE_MASK; - hpage &= ~0xFFFULL; - - page = vmalloc(HW_PAGE_SIZE); - - if (copy_from_user(page, (void __user *)hpage, HW_PAGE_SIZE)) - goto out; + hpage_offset = pte->raddr & ~PAGE_MASK; + hpage_offset &= ~0xFFFULL; + hpage_offset /= 4; - for (i=0; i < HW_PAGE_SIZE / 4; i++) - if ((page[i] & 0xff0007ff) == INS_DCBZ) { - page[i] &= 0xfffffff7; // reserved instruction, so we trap - touched = true; - } + get_page(hpage); + page = kmap_atomic(hpage, KM_USER0); - if (touched) - copy_to_user((void __user *)hpage, page, HW_PAGE_SIZE); + /* patch dcbz into reserved instruction, so we trap */ + for (i=hpage_offset; i < hpage_offset + (HW_PAGE_SIZE / 4); i++) + if ((page[i] & 0xff0007ff) == INS_DCBZ) + page[i] &= 0xfffffff7; -out: - vfree(page); + kunmap_atomic(page, KM_USER0); + put_page(hpage); } static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, @@ -449,30 +445,21 @@ int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data) { struct kvmppc_pte pte; - hva_t hva = *eaddr; vcpu->stat.st++; if (kvmppc_xlate(vcpu, *eaddr, data, &pte)) - goto nopte; + return -ENOENT; *eaddr = pte.raddr; - hva = kvmppc_pte_to_hva(vcpu, &pte, false); - if (kvm_is_error_hva(hva)) - goto mmio; + if (!pte.may_write) + return -EPERM; - if (copy_to_user((void __user *)hva, ptr, size)) { - printk(KERN_INFO "kvmppc_st at 0x%lx failed\n", hva); - goto mmio; - } + if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size)) + return EMULATE_DO_MMIO; return EMULATE_DONE; - -nopte: - return -ENOENT; -mmio: - return EMULATE_DO_MMIO; } int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, @@ -787,6 +774,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, * that no guest that needs the dcbz hack does NX. */ kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL); + r = RESUME_GUEST; } else { vcpu->arch.msr |= vcpu->arch.shadow_srr1 & 0x58000000; kvmppc_book3s_queue_irqprio(vcpu, exit_nr); diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index 1e5cf8d594ea..bbd15906900d 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c @@ -189,6 +189,8 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, ulong ra = 0; ulong addr, vaddr; u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + u32 dsisr; + int r; if (get_ra(inst)) ra = kvmppc_get_gpr(vcpu, get_ra(inst)); @@ -198,14 +200,23 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, addr &= 0xffffffff; vaddr = addr; - if (kvmppc_st(vcpu, &addr, 32, zeros, true)) { + r = kvmppc_st(vcpu, &addr, 32, zeros, true); + if ((r == -ENOENT) || (r == -EPERM)) { + *advance = 0; vcpu->arch.dear = vaddr; vcpu->arch.fault_dear = vaddr; - to_book3s(vcpu)->dsisr = DSISR_PROTFAULT | - DSISR_ISSTORE; + + dsisr = DSISR_ISSTORE; + if (r == -ENOENT) + dsisr |= DSISR_NOHPTE; + else if (r == -EPERM) + dsisr |= DSISR_PROTFAULT; + + to_book3s(vcpu)->dsisr = dsisr; + vcpu->arch.fault_dsisr = dsisr; + kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE); - kvmppc_mmu_pte_flush(vcpu, vaddr, ~0xFFFULL); } break; -- cgit v1.2.3-59-g8ed1b From bd7cdbb7fcd135a399ebb855dc9106747ee2e6ba Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:33 +0100 Subject: KVM: PPC: Add emulation for dcba Mac OS X uses the dcba instruction. According to the specification it doesn't guarantee any functionality, so let's just emulate it as nop. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_emulate.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index bbd15906900d..8f50776a9a1d 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c @@ -37,6 +37,7 @@ #define OP_31_XOP_SLBIA 498 #define OP_31_XOP_MFSR 595 #define OP_31_XOP_MFSRIN 659 +#define OP_31_XOP_DCBA 758 #define OP_31_XOP_SLBMFEV 851 #define OP_31_XOP_EIOIO 854 #define OP_31_XOP_SLBMFEE 915 @@ -183,6 +184,9 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, kvmppc_set_gpr(vcpu, get_rt(inst), t); } break; + case OP_31_XOP_DCBA: + /* Gets treated as NOP */ + break; case OP_31_XOP_DCBZ: { ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst)); -- cgit v1.2.3-59-g8ed1b From a1eda280ccd5fee71a89a94030f96bca5faebe21 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:34 +0100 Subject: KVM: PPC: Add check if pte was mapped secondary Some HTAB providers (namely the PS3) ignore the SECONDARY flag. They just put an entry in the htab as secondary when they see fit. So we need to check the return value of htab_insert to remember the correct slot id so we can actually invalidate the entry again. Fixes KVM on the PS3. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_mmu_host.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 25bd4ede722c..a01e9c5a3fc7 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -270,6 +270,13 @@ map_again: (rflags & HPTE_R_N) ? '-' : 'x', orig_pte->eaddr, hpteg, va, orig_pte->vpage, hpaddr); + /* The ppc_md code may give us a secondary entry even though we + asked for a primary. Fix up. */ + if ((ret & _PTEIDX_SECONDARY) && !(vflags & HPTE_V_SECONDARY)) { + hash = ~hash; + hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); + } + pte->slot = hpteg + (ret & 7); pte->host_va = va; pte->pte = *orig_pte; -- cgit v1.2.3-59-g8ed1b From 5a1b419fc936af9f10766c889d83d80990ecd300 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:35 +0100 Subject: KVM: PPC: Use ULL for big numbers Some constants were bigger than ints. Let's mark them as such so we don't accidently truncate them. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 7e243b2cac72..8a6b4c540862 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -100,12 +100,12 @@ struct kvmppc_vcpu_book3s { #define CONTEXT_GUEST 1 #define CONTEXT_GUEST_END 2 -#define VSID_REAL_DR 0x7ffffffffff00000 -#define VSID_REAL_IR 0x7fffffffffe00000 -#define VSID_SPLIT_MASK 0x7fffffffffe00000 -#define VSID_REAL 0x7fffffffffc00000 -#define VSID_BAT 0x7fffffffffb00000 -#define VSID_PR 0x8000000000000000 +#define VSID_REAL_DR 0x7ffffffffff00000ULL +#define VSID_REAL_IR 0x7fffffffffe00000ULL +#define VSID_SPLIT_MASK 0x7fffffffffe00000ULL +#define VSID_REAL 0x7fffffffffc00000ULL +#define VSID_BAT 0x7fffffffffb00000ULL +#define VSID_PR 0x8000000000000000ULL extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 ea, u64 ea_mask); extern void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 vp, u64 vp_mask); -- cgit v1.2.3-59-g8ed1b From 3ed9c6d2b5aa0ac365c52a2a3a370ac499f21e45 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:36 +0100 Subject: KVM: PPC: Make bools bitfields Bool defaults to at least byte width. We usually only want to waste a single bit on this. So let's move all the bool values to bitfields, potentially saving memory. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 28 ++++++++++++++-------------- arch/powerpc/include/asm/kvm_host.h | 6 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 8a6b4c540862..ee7992189c6e 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -29,40 +29,40 @@ struct kvmppc_slb { u64 vsid; u64 orige; u64 origv; - bool valid; - bool Ks; - bool Kp; - bool nx; - bool large; /* PTEs are 16MB */ - bool tb; /* 1TB segment */ - bool class; + bool valid : 1; + bool Ks : 1; + bool Kp : 1; + bool nx : 1; + bool large : 1; /* PTEs are 16MB */ + bool tb : 1; /* 1TB segment */ + bool class : 1; }; struct kvmppc_sr { u32 raw; u32 vsid; - bool Ks; - bool Kp; - bool nx; - bool valid; + bool Ks : 1; + bool Kp : 1; + bool nx : 1; + bool valid : 1; }; struct kvmppc_bat { u64 raw; u32 bepi; u32 bepi_mask; - bool vs; - bool vp; u32 brpn; u8 wimg; u8 pp; + bool vs : 1; + bool vp : 1; }; struct kvmppc_sid_map { u64 guest_vsid; u64 guest_esid; u64 host_vsid; - bool valid; + bool valid : 1; }; #define SID_MAP_BITS 9 diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 486f1cafd5f7..5869a487e2e0 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -127,9 +127,9 @@ struct kvmppc_pte { u64 eaddr; u64 vpage; u64 raddr; - bool may_read; - bool may_write; - bool may_execute; + bool may_read : 1; + bool may_write : 1; + bool may_execute : 1; }; struct kvmppc_mmu { -- cgit v1.2.3-59-g8ed1b From 05b0ab1c0bb526ac1056bab356ee92cfd6daa6fd Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 24 Mar 2010 21:48:37 +0100 Subject: KVM: PPC: Disable MSR_FEx for Cell hosts Cell can't handle MSR_FE0 and MSR_FE1 too well. It gets dog slow. So let's just override the guest whenever we see one of the two and mask them out. See commit ddf5f75a16b3e7460ffee881795aa168dffcd0cf for reference. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index ed5758496372..41c23b636f53 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -357,6 +357,10 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) !strcmp(cur_cpu_spec->platform, "ppc970")) vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; + /* Cell performs badly if MSR_FEx are set. So let's hope nobody + really needs them in a VM on Cell and force disable them. */ + if (!strcmp(cur_cpu_spec->platform, "ppc-cell-be")) + to_book3s(vcpu)->msr_mask &= ~(MSR_FE0 | MSR_FE1); } /* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To -- cgit v1.2.3-59-g8ed1b From 287d5611fab5a42214d028b6f67fbd2ee977dcf2 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 1 Apr 2010 15:33:21 +0200 Subject: KVM: PPC: Only use QPRs when available BookE KVM doesn't know about QPRs, so let's not try to access then. This fixes a build error on BookE KVM. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/powerpc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 9a4dd8146d39..ffbe4cac5b15 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -335,6 +335,7 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, case KVM_REG_FPR: vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; break; +#ifdef CONFIG_PPC_BOOK3S case KVM_REG_QPR: vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; break; @@ -342,6 +343,7 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; break; +#endif default: BUG(); } -- cgit v1.2.3-59-g8ed1b From 306d071f179c28c97688cb91c8585fd5ab840a9e Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 1 Apr 2010 15:33:22 +0200 Subject: KVM: PPC: Don't export Book3S symbols on BookE Book3S knows how to convert floats to doubles and vice versa. BookE doesn't. So let's make sure we don't export them on BookE. This fixes a link error on BookE with CONFIG_KVM=y. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kernel/ppc_ksyms.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 58fdb3a784de..bc9f39d2598b 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -101,8 +101,10 @@ EXPORT_SYMBOL(pci_dram_offset); EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(kernel_thread); +#ifndef CONFIG_BOOKE EXPORT_SYMBOL_GPL(cvt_df); EXPORT_SYMBOL_GPL(cvt_fd); +#endif EXPORT_SYMBOL(giveup_fpu); #ifdef CONFIG_ALTIVEC EXPORT_SYMBOL(giveup_altivec); -- cgit v1.2.3-59-g8ed1b From 805d32dea4dfb8319aaf7e73a681ad410a5e331a Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Thu, 1 Apr 2010 16:50:45 +0800 Subject: KVM: MMU: cleanup/fix mmu audit code This patch does: - 'sp' parameter in inspect_spte_fn() is not used, so remove it - fix 'kvm' and 'slots' is not defined in count_rmaps() - fix a bug in inspect_spte_has_rmap() Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 1cc60d3f445b..6ed7d633aefe 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3182,8 +3182,7 @@ static gva_t canonicalize(gva_t gva) } -typedef void (*inspect_spte_fn) (struct kvm *kvm, struct kvm_mmu_page *sp, - u64 *sptep); +typedef void (*inspect_spte_fn) (struct kvm *kvm, u64 *sptep); static void __mmu_spte_walk(struct kvm *kvm, struct kvm_mmu_page *sp, inspect_spte_fn fn) @@ -3199,7 +3198,7 @@ static void __mmu_spte_walk(struct kvm *kvm, struct kvm_mmu_page *sp, child = page_header(ent & PT64_BASE_ADDR_MASK); __mmu_spte_walk(kvm, child, fn); } else - fn(kvm, sp, &sp->spt[i]); + fn(kvm, &sp->spt[i]); } } } @@ -3290,6 +3289,8 @@ static void audit_mappings(struct kvm_vcpu *vcpu) static int count_rmaps(struct kvm_vcpu *vcpu) { + struct kvm *kvm = vcpu->kvm; + struct kvm_memslots *slots; int nmaps = 0; int i, j, k, idx; @@ -3323,7 +3324,7 @@ static int count_rmaps(struct kvm_vcpu *vcpu) return nmaps; } -void inspect_spte_has_rmap(struct kvm *kvm, struct kvm_mmu_page *sp, u64 *sptep) +void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep) { unsigned long *rmapp; struct kvm_mmu_page *rev_sp; @@ -3339,14 +3340,14 @@ void inspect_spte_has_rmap(struct kvm *kvm, struct kvm_mmu_page *sp, u64 *sptep) printk(KERN_ERR "%s: no memslot for gfn %ld\n", audit_msg, gfn); printk(KERN_ERR "%s: index %ld of sp (gfn=%lx)\n", - audit_msg, sptep - rev_sp->spt, + audit_msg, (long int)(sptep - rev_sp->spt), rev_sp->gfn); dump_stack(); return; } rmapp = gfn_to_rmap(kvm, rev_sp->gfns[sptep - rev_sp->spt], - is_large_pte(*sptep)); + rev_sp->role.level); if (!*rmapp) { if (!printk_ratelimit()) return; @@ -3381,7 +3382,7 @@ static void check_writable_mappings_rmap(struct kvm_vcpu *vcpu) continue; if (!(ent & PT_WRITABLE_MASK)) continue; - inspect_spte_has_rmap(vcpu->kvm, sp, &pt[i]); + inspect_spte_has_rmap(vcpu->kvm, &pt[i]); } } return; -- cgit v1.2.3-59-g8ed1b From f84cbb0561d7cefb5fc050ee99d8c82ec9ce883d Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Tue, 6 Apr 2010 18:29:05 +0800 Subject: KVM: MMU: remove unused field kvm_mmu_page.oos_link is not used, so remove it Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 2 -- arch/x86/kvm/mmu.c | 1 - 2 files changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 26c629a062db..0c49c888be6b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -187,8 +187,6 @@ struct kvm_mmu_page { struct list_head link; struct hlist_node hash_link; - struct list_head oos_link; - /* * The following two entries are used to key the shadow page in the * hash table. diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 6ed7d633aefe..ec8900b6692a 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -923,7 +923,6 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu, sp->gfns = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, PAGE_SIZE); set_page_private(virt_to_page(sp->spt), (unsigned long)sp); list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages); - INIT_LIST_HEAD(&sp->oos_link); bitmap_zero(sp->slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS); sp->multimapped = 0; sp->parent_pte = parent_pte; -- cgit v1.2.3-59-g8ed1b From 24222c2fec75df30d56d1e2014d45d2559c94f1a Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Tue, 6 Apr 2010 18:31:13 +0800 Subject: KVM: MMU: remove unnecessary NX check in walk_addr After is_rsvd_bits_set() checks, EFER.NXE must be enabled if NX bit is seted Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/paging_tmpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 067797a72768..d9dea288e51d 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -170,7 +170,7 @@ walk: goto access_error; #if PTTYPE == 64 - if (fetch_fault && is_nx(vcpu) && (pte & PT64_NX_MASK)) + if (fetch_fault && (pte & PT64_NX_MASK)) goto access_error; #endif -- cgit v1.2.3-59-g8ed1b From 4496f974825e2ee317c3cc94e41ec2db7eb73af8 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 7 Apr 2010 10:03:25 +0200 Subject: KVM: PPC: Add dequeue for external on BookE Commit a0abee86af2d1f048dbe99d2bcc4a2cefe685617 introduced unsetting of the IRQ line from userspace. This added a new core specific callback that I apparently forgot to add for BookE. So let's add the callback for BookE as well, making it build again. Signed-off-by: Alexander Graf Signed-off-by: Marcelo Tosatti --- arch/powerpc/kvm/booke.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 2a3a1953d4bd..c92224071021 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -133,6 +133,12 @@ void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_EXTERNAL); } +void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu, + struct kvm_interrupt *irq) +{ + clear_bit(BOOKE_IRQPRIO_EXTERNAL, &vcpu->arch.pending_exceptions); +} + /* Deliver the interrupt of the corresponding priority, if possible. */ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) -- cgit v1.2.3-59-g8ed1b From 2fb53ad811e238d5dec8716b99986c3f234e3337 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 11 Apr 2010 13:05:15 +0300 Subject: KVM: x86 emulator: Don't overwrite decode cache Currently if we an instruction spans a page boundary, when we fetch the second half we overwrite the first half. This prevents us from tracing the full instruction opcodes. Fix by appending the second half to the first. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 64c9854f0458..083b269a83ea 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -646,21 +646,22 @@ static unsigned long ss_base(struct x86_emulate_ctxt *ctxt) static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, - unsigned long linear, u8 *dest) + unsigned long eip, u8 *dest) { struct fetch_cache *fc = &ctxt->decode.fetch; int rc; - int size; + int size, cur_size; - if (linear < fc->start || linear >= fc->end) { - size = min(15UL, PAGE_SIZE - offset_in_page(linear)); - rc = ops->fetch(linear, fc->data, size, ctxt->vcpu, NULL); + if (eip == fc->end) { + cur_size = fc->end - fc->start; + size = min(15UL - cur_size, PAGE_SIZE - offset_in_page(eip)); + rc = ops->fetch(ctxt->cs_base + eip, fc->data + cur_size, + size, ctxt->vcpu, NULL); if (rc != X86EMUL_CONTINUE) return rc; - fc->start = linear; - fc->end = linear + size; + fc->end += size; } - *dest = fc->data[linear - fc->start]; + *dest = fc->data[eip - fc->start]; return X86EMUL_CONTINUE; } @@ -673,7 +674,6 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, /* x86 instructions are limited to 15 bytes. */ if (eip + size - ctxt->eip > 15) return X86EMUL_UNHANDLEABLE; - eip += ctxt->cs_base; while (size--) { rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++); if (rc != X86EMUL_CONTINUE) @@ -935,6 +935,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) /* Shadow copy of register state. Committed on successful emulation. */ memset(c, 0, sizeof(struct decode_cache)); c->eip = ctxt->eip; + c->fetch.start = c->fetch.end = c->eip; ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); -- cgit v1.2.3-59-g8ed1b From e46479f852adab6027e4950d69400d967bf7bc6f Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 11 Apr 2010 13:05:16 +0300 Subject: KVM: Trace emulated instructions Log emulated instructions in ftrace, especially if they failed. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/trace.h | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.c | 4 +++ 2 files changed, 90 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 32c912c40bf8..a6544b8e7c0f 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -603,6 +603,92 @@ TRACE_EVENT(kvm_skinit, __entry->rip, __entry->slb) ); +#define __print_insn(insn, ilen) ({ \ + int i; \ + const char *ret = p->buffer + p->len; \ + \ + for (i = 0; i < ilen; ++i) \ + trace_seq_printf(p, " %02x", insn[i]); \ + trace_seq_printf(p, "%c", 0); \ + ret; \ + }) + +#define KVM_EMUL_INSN_F_CR0_PE (1 << 0) +#define KVM_EMUL_INSN_F_EFL_VM (1 << 1) +#define KVM_EMUL_INSN_F_CS_D (1 << 2) +#define KVM_EMUL_INSN_F_CS_L (1 << 3) + +#define kvm_trace_symbol_emul_flags \ + { 0, "real" }, \ + { KVM_EMUL_INSN_F_CR0_PE \ + | KVM_EMUL_INSN_F_EFL_VM, "vm16" }, \ + { KVM_EMUL_INSN_F_CR0_PE, "prot16" }, \ + { KVM_EMUL_INSN_F_CR0_PE \ + | KVM_EMUL_INSN_F_CS_D, "prot32" }, \ + { KVM_EMUL_INSN_F_CR0_PE \ + | KVM_EMUL_INSN_F_CS_L, "prot64" } + +#define kei_decode_mode(mode) ({ \ + u8 flags = 0xff; \ + switch (mode) { \ + case X86EMUL_MODE_REAL: \ + flags = 0; \ + break; \ + case X86EMUL_MODE_VM86: \ + flags = KVM_EMUL_INSN_F_EFL_VM; \ + break; \ + case X86EMUL_MODE_PROT16: \ + flags = KVM_EMUL_INSN_F_CR0_PE; \ + break; \ + case X86EMUL_MODE_PROT32: \ + flags = KVM_EMUL_INSN_F_CR0_PE \ + | KVM_EMUL_INSN_F_CS_D; \ + break; \ + case X86EMUL_MODE_PROT64: \ + flags = KVM_EMUL_INSN_F_CR0_PE \ + | KVM_EMUL_INSN_F_CS_L; \ + break; \ + } \ + flags; \ + }) + +TRACE_EVENT(kvm_emulate_insn, + TP_PROTO(struct kvm_vcpu *vcpu, __u8 failed), + TP_ARGS(vcpu, failed), + + TP_STRUCT__entry( + __field( __u64, rip ) + __field( __u32, csbase ) + __field( __u8, len ) + __array( __u8, insn, 15 ) + __field( __u8, flags ) + __field( __u8, failed ) + ), + + TP_fast_assign( + __entry->rip = vcpu->arch.emulate_ctxt.decode.fetch.start; + __entry->csbase = kvm_x86_ops->get_segment_base(vcpu, VCPU_SREG_CS); + __entry->len = vcpu->arch.emulate_ctxt.decode.eip + - vcpu->arch.emulate_ctxt.decode.fetch.start; + memcpy(__entry->insn, + vcpu->arch.emulate_ctxt.decode.fetch.data, + 15); + __entry->flags = kei_decode_mode(vcpu->arch.emulate_ctxt.mode); + __entry->failed = failed; + ), + + TP_printk("%x:%llx:%s (%s)%s", + __entry->csbase, __entry->rip, + __print_insn(__entry->insn, __entry->len), + __print_symbolic(__entry->flags, + kvm_trace_symbol_emul_flags), + __entry->failed ? " failed" : "" + ) + ); + +#define trace_kvm_emulate_insn_start(vcpu) trace_kvm_emulate_insn(vcpu, 0) +#define trace_kvm_emulate_insn_failed(vcpu) trace_kvm_emulate_insn(vcpu, 1) + #endif /* _TRACE_KVM_H */ #undef TRACE_INCLUDE_PATH diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 247e805a041e..33a40c544c7a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3718,6 +3718,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); + trace_kvm_emulate_insn_start(vcpu); /* Only allow emulation of specific instructions on #UD * (namely VMMCALL, sysenter, sysexit, syscall)*/ @@ -3750,6 +3751,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, ++vcpu->stat.insn_emulation; if (r) { ++vcpu->stat.insn_emulation_fail; + trace_kvm_emulate_insn_failed(vcpu); if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) return EMULATE_DONE; return EMULATE_FAIL; @@ -3786,6 +3788,8 @@ restart: if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) goto done; if (!vcpu->mmio_needed) { + ++vcpu->stat.insn_emulation_fail; + trace_kvm_emulate_insn_failed(vcpu); kvm_report_emulation_failure(vcpu, "mmio"); return EMULATE_FAIL; } -- cgit v1.2.3-59-g8ed1b From f7a711971edd952352a89698db1d36f469e25f77 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 11 Apr 2010 15:33:32 +0300 Subject: KVM: Fix MAXPHYADDR calculation when cpuid does not support it MAXPHYADDR is derived from cpuid 0x80000008, but when that isn't present, we get some random value. Fix by checking first that cpuid 0x80000008 is supported. Acked-by: Pekka Enberg Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 33a40c544c7a..d65e481c5fa4 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4171,9 +4171,13 @@ int cpuid_maxphyaddr(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; + best = kvm_find_cpuid_entry(vcpu, 0x80000000, 0); + if (!best || best->eax < 0x80000008) + goto not_found; best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0); if (best) return best->eax & 0xff; +not_found: return 36; } -- cgit v1.2.3-59-g8ed1b From 6bc31bdc55cad6609b1610b4cecad312664f2808 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sun, 11 Apr 2010 23:07:28 +0200 Subject: KVM: SVM: implement NEXTRIPsave SVM feature On SVM we set the instruction length of skipped instructions to hard-coded, well known values, which could be wrong when (bogus, but valid) prefixes (REX, segment override) are used. Newer AMD processors (Fam10h 45nm and better, aka. PhenomII or AthlonII) have an explicit NEXTRIP field in the VMCB containing the desired information. Since it is cheap to do so, we use this field to override the guessed value on newer processors. A fix for older CPUs would be rather expensive, as it would require to fetch and partially decode the instruction. As the problem is not a security issue and needs special, handcrafted code to trigger (no compiler will ever generate such code), I omit a fix for older CPUs. If someone is interested, I have both a patch for these CPUs as well as demo code triggering this issue: It segfaults under KVM, but runs perfectly on native Linux. Signed-off-by: Andre Przywara Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/svm.h | 4 +++- arch/x86/kvm/svm.c | 13 ++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index b26a38d85356..1d91d05f9368 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -81,7 +81,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area { u32 event_inj_err; u64 nested_cr3; u64 lbr_ctl; - u8 reserved_5[832]; + u64 reserved_5; + u64 next_rip; + u8 reserved_6[816]; }; diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index e9f79619e185..64b7f60dc5b8 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -44,11 +44,11 @@ MODULE_LICENSE("GPL"); #define SEG_TYPE_LDT 2 #define SEG_TYPE_BUSY_TSS16 3 -#define SVM_FEATURE_NPT (1 << 0) -#define SVM_FEATURE_LBRV (1 << 1) -#define SVM_FEATURE_SVML (1 << 2) -#define SVM_FEATURE_NRIP (1 << 3) -#define SVM_FEATURE_PAUSE_FILTER (1 << 10) +#define SVM_FEATURE_NPT (1 << 0) +#define SVM_FEATURE_LBRV (1 << 1) +#define SVM_FEATURE_SVML (1 << 2) +#define SVM_FEATURE_NRIP (1 << 3) +#define SVM_FEATURE_PAUSE_FILTER (1 << 10) #define NESTED_EXIT_HOST 0 /* Exit handled on host level */ #define NESTED_EXIT_DONE 1 /* Exit caused nested vmexit */ @@ -320,6 +320,9 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + if (svm->vmcb->control.next_rip != 0) + svm->next_rip = svm->vmcb->control.next_rip; + if (!svm->next_rip) { if (emulate_instruction(vcpu, 0, 0, EMULTYPE_SKIP) != EMULATE_DONE) -- cgit v1.2.3-59-g8ed1b From 020df0794f5764e742feaa718be88b8f1b4ce04f Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Tue, 13 Apr 2010 10:05:23 +0300 Subject: KVM: move DR register access handling into generic code Currently both SVM and VMX have their own DR handling code. Move it to x86.c. Acked-by: Jan Kiszka Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 5 +-- arch/x86/kvm/svm.c | 66 ++-------------------------------- arch/x86/kvm/vmx.c | 78 ++++++----------------------------------- arch/x86/kvm/x86.c | 78 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 93 insertions(+), 134 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 0c49c888be6b..5d5e0a9afcf2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -496,8 +496,7 @@ struct kvm_x86_ops { void (*set_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); void (*get_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); void (*set_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); - int (*get_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long *dest); - int (*set_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long value); + void (*set_dr7)(struct kvm_vcpu *vcpu, unsigned long value); void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); @@ -602,6 +601,8 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8); +int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val); +int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val); unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu); void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw); void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 64b7f60dc5b8..87b36fbbfec8 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1307,70 +1307,11 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) svm->vmcb->control.asid = sd->next_asid++; } -static int svm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *dest) +static void svm_set_dr7(struct kvm_vcpu *vcpu, unsigned long value) { struct vcpu_svm *svm = to_svm(vcpu); - switch (dr) { - case 0 ... 3: - *dest = vcpu->arch.db[dr]; - break; - case 4: - if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) - return EMULATE_FAIL; /* will re-inject UD */ - /* fall through */ - case 6: - if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) - *dest = vcpu->arch.dr6; - else - *dest = svm->vmcb->save.dr6; - break; - case 5: - if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) - return EMULATE_FAIL; /* will re-inject UD */ - /* fall through */ - case 7: - if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) - *dest = vcpu->arch.dr7; - else - *dest = svm->vmcb->save.dr7; - break; - } - - return EMULATE_DONE; -} - -static int svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value) -{ - struct vcpu_svm *svm = to_svm(vcpu); - - switch (dr) { - case 0 ... 3: - vcpu->arch.db[dr] = value; - if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) - vcpu->arch.eff_db[dr] = value; - break; - case 4: - if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) - return EMULATE_FAIL; /* will re-inject UD */ - /* fall through */ - case 6: - vcpu->arch.dr6 = (value & DR6_VOLATILE) | DR6_FIXED_1; - break; - case 5: - if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) - return EMULATE_FAIL; /* will re-inject UD */ - /* fall through */ - case 7: - vcpu->arch.dr7 = (value & DR7_VOLATILE) | DR7_FIXED_1; - if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { - svm->vmcb->save.dr7 = vcpu->arch.dr7; - vcpu->arch.switch_db_regs = (value & DR7_BP_EN_MASK); - } - break; - } - - return EMULATE_DONE; + svm->vmcb->save.dr7 = value; } static int pf_interception(struct vcpu_svm *svm) @@ -3302,8 +3243,7 @@ static struct kvm_x86_ops svm_x86_ops = { .set_idt = svm_set_idt, .get_gdt = svm_get_gdt, .set_gdt = svm_set_gdt, - .get_dr = svm_get_dr, - .set_dr = svm_set_dr, + .set_dr7 = svm_set_dr7, .cache_reg = svm_cache_reg, .get_rflags = svm_get_rflags, .set_rflags = svm_set_rflags, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1cceca1c59be..fb4a8869bb99 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3089,19 +3089,9 @@ static int handle_cr(struct kvm_vcpu *vcpu) return 0; } -static int check_dr_alias(struct kvm_vcpu *vcpu) -{ - if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { - kvm_queue_exception(vcpu, UD_VECTOR); - return -1; - } - return 0; -} - static int handle_dr(struct kvm_vcpu *vcpu) { unsigned long exit_qualification; - unsigned long val; int dr, reg; /* Do not handle if the CPL > 0, will trigger GP on re-entry */ @@ -3136,67 +3126,20 @@ static int handle_dr(struct kvm_vcpu *vcpu) dr = exit_qualification & DEBUG_REG_ACCESS_NUM; reg = DEBUG_REG_ACCESS_REG(exit_qualification); if (exit_qualification & TYPE_MOV_FROM_DR) { - switch (dr) { - case 0 ... 3: - val = vcpu->arch.db[dr]; - break; - case 4: - if (check_dr_alias(vcpu) < 0) - return 1; - /* fall through */ - case 6: - val = vcpu->arch.dr6; - break; - case 5: - if (check_dr_alias(vcpu) < 0) - return 1; - /* fall through */ - default: /* 7 */ - val = vcpu->arch.dr7; - break; - } - kvm_register_write(vcpu, reg, val); - } else { - val = vcpu->arch.regs[reg]; - switch (dr) { - case 0 ... 3: - vcpu->arch.db[dr] = val; - if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) - vcpu->arch.eff_db[dr] = val; - break; - case 4: - if (check_dr_alias(vcpu) < 0) - return 1; - /* fall through */ - case 6: - if (val & 0xffffffff00000000ULL) { - kvm_inject_gp(vcpu, 0); - return 1; - } - vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1; - break; - case 5: - if (check_dr_alias(vcpu) < 0) - return 1; - /* fall through */ - default: /* 7 */ - if (val & 0xffffffff00000000ULL) { - kvm_inject_gp(vcpu, 0); - return 1; - } - vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1; - if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { - vmcs_writel(GUEST_DR7, vcpu->arch.dr7); - vcpu->arch.switch_db_regs = - (val & DR7_BP_EN_MASK); - } - break; - } - } + unsigned long val; + if (!kvm_get_dr(vcpu, dr, &val)) + kvm_register_write(vcpu, reg, val); + } else + kvm_set_dr(vcpu, dr, vcpu->arch.regs[reg]); skip_emulated_instruction(vcpu); return 1; } +static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val) +{ + vmcs_writel(GUEST_DR7, val); +} + static int handle_cpuid(struct kvm_vcpu *vcpu) { kvm_emulate_cpuid(vcpu); @@ -4187,6 +4130,7 @@ static struct kvm_x86_ops vmx_x86_ops = { .set_idt = vmx_set_idt, .get_gdt = vmx_get_gdt, .set_gdt = vmx_set_gdt, + .set_dr7 = vmx_set_dr7, .cache_reg = vmx_cache_reg, .get_rflags = vmx_get_rflags, .set_rflags = vmx_set_rflags, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d65e481c5fa4..09dccac2df7e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -562,6 +562,80 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu) } EXPORT_SYMBOL_GPL(kvm_get_cr8); +int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) +{ + switch (dr) { + case 0 ... 3: + vcpu->arch.db[dr] = val; + if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) + vcpu->arch.eff_db[dr] = val; + break; + case 4: + if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { + kvm_queue_exception(vcpu, UD_VECTOR); + return 1; + } + /* fall through */ + case 6: + if (val & 0xffffffff00000000ULL) { + kvm_inject_gp(vcpu, 0); + return 1; + } + vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1; + break; + case 5: + if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { + kvm_queue_exception(vcpu, UD_VECTOR); + return 1; + } + /* fall through */ + default: /* 7 */ + if (val & 0xffffffff00000000ULL) { + kvm_inject_gp(vcpu, 0); + return 1; + } + vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1; + if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { + kvm_x86_ops->set_dr7(vcpu, vcpu->arch.dr7); + vcpu->arch.switch_db_regs = (val & DR7_BP_EN_MASK); + } + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(kvm_set_dr); + +int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) +{ + switch (dr) { + case 0 ... 3: + *val = vcpu->arch.db[dr]; + break; + case 4: + if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { + kvm_queue_exception(vcpu, UD_VECTOR); + return 1; + } + /* fall through */ + case 6: + *val = vcpu->arch.dr6; + break; + case 5: + if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { + kvm_queue_exception(vcpu, UD_VECTOR); + return 1; + } + /* fall through */ + default: /* 7 */ + *val = vcpu->arch.dr7; + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(kvm_get_dr); + static inline u32 bit(int bitno) { return 1 << (bitno & 31); @@ -3483,14 +3557,14 @@ int emulate_clts(struct kvm_vcpu *vcpu) int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) { - return kvm_x86_ops->get_dr(ctxt->vcpu, dr, dest); + return kvm_get_dr(ctxt->vcpu, dr, dest); } int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) { unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U; - return kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask); + return kvm_set_dr(ctxt->vcpu, dr, value & mask); } void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) -- cgit v1.2.3-59-g8ed1b From 8f6abd06f521112a0a3bc906df273fa3ce0a9387 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Tue, 13 Apr 2010 10:21:56 +0300 Subject: KVM: x86: get rid of mmu_only parameter in emulator_write_emulated() We can call kvm_mmu_pte_write() directly from emulator_cmpxchg_emulated() instead of passing mmu_only down to emulator_write_emulated_onepage() and call it there. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 09dccac2df7e..40991527f54a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3322,8 +3322,7 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, static int emulator_write_emulated_onepage(unsigned long addr, const void *val, unsigned int bytes, - struct kvm_vcpu *vcpu, - bool mmu_only) + struct kvm_vcpu *vcpu) { gpa_t gpa; u32 error_code; @@ -3339,10 +3338,6 @@ static int emulator_write_emulated_onepage(unsigned long addr, if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) goto mmio; - if (mmu_only) { - kvm_mmu_pte_write(vcpu, gpa, val, bytes, 1); - return X86EMUL_CONTINUE; - } if (emulator_write_phys(vcpu, gpa, val, bytes)) return X86EMUL_CONTINUE; @@ -3363,35 +3358,24 @@ mmio: return X86EMUL_CONTINUE; } -int __emulator_write_emulated(unsigned long addr, - const void *val, - unsigned int bytes, - struct kvm_vcpu *vcpu, - bool mmu_only) +int emulator_write_emulated(unsigned long addr, + const void *val, + unsigned int bytes, + struct kvm_vcpu *vcpu) { /* Crossing a page boundary? */ if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { int rc, now; now = -addr & ~PAGE_MASK; - rc = emulator_write_emulated_onepage(addr, val, now, vcpu, - mmu_only); + rc = emulator_write_emulated_onepage(addr, val, now, vcpu); if (rc != X86EMUL_CONTINUE) return rc; addr += now; val += now; bytes -= now; } - return emulator_write_emulated_onepage(addr, val, bytes, vcpu, - mmu_only); -} - -int emulator_write_emulated(unsigned long addr, - const void *val, - unsigned int bytes, - struct kvm_vcpu *vcpu) -{ - return __emulator_write_emulated(addr, val, bytes, vcpu, false); + return emulator_write_emulated_onepage(addr, val, bytes, vcpu); } EXPORT_SYMBOL_GPL(emulator_write_emulated); @@ -3455,7 +3439,9 @@ static int emulator_cmpxchg_emulated(unsigned long addr, if (!exchanged) return X86EMUL_CMPXCHG_FAILED; - return __emulator_write_emulated(addr, new, bytes, vcpu, true); + kvm_mmu_pte_write(vcpu, gpa, new, bytes, 1); + + return X86EMUL_CONTINUE; emul_write: printk_once(KERN_WARNING "kvm: emulating exchange as write\n"); @@ -4165,7 +4151,7 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu) kvm_x86_ops->patch_hypercall(vcpu, instruction); - return __emulator_write_emulated(rip, instruction, 3, vcpu, false); + return emulator_write_emulated(rip, instruction, 3, vcpu); } void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) -- cgit v1.2.3-59-g8ed1b From 0760d44868f351ba30fc9a08cf1830e46aa72466 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 14 Apr 2010 15:50:57 +0200 Subject: KVM: x86: Terminate early if task_switch_16/32 failed Stop the switch immediately if task_switch_16/32 returned an error. Only if that step succeeded, the switch should actually take place and update any register states. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 083b269a83ea..aace5659bbe0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2402,6 +2402,8 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, else ret = task_switch_16(ctxt, ops, tss_selector, old_tss_sel, old_tss_base, &next_tss_desc); + if (ret != X86EMUL_CONTINUE) + return ret; if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) ctxt->eflags = ctxt->eflags | X86_EFLAGS_NT; -- cgit v1.2.3-59-g8ed1b From e269fb2189fb86d79d64c0ca74c6c1a549ad4aa3 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 14 Apr 2010 15:51:09 +0200 Subject: KVM: x86: Push potential exception error code on task switches When a fault triggers a task switch, the error code, if existent, has to be pushed on the new task's stack. Implement the missing bits. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_emulate.h | 3 ++- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/include/asm/svm.h | 1 + arch/x86/kvm/emulate.c | 22 ++++++++++++++++++---- arch/x86/kvm/svm.c | 11 ++++++++++- arch/x86/kvm/vmx.c | 12 +++++++++++- arch/x86/kvm/x86.c | 6 ++++-- 7 files changed, 48 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index a1319c82050e..0b2729bf2070 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -230,6 +230,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops); int emulator_task_switch(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, - u16 tss_selector, int reason); + u16 tss_selector, int reason, + bool has_error_code, u32 error_code); #endif /* _ASM_X86_KVM_X86_EMULATE_H */ diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 5d5e0a9afcf2..3602728d54de 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -595,7 +595,8 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg); -int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason); +int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, + bool has_error_code, u32 error_code); void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 1d91d05f9368..0e831059ac5a 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -244,6 +244,7 @@ struct __attribute__ ((__packed__)) vmcb { #define SVM_EXITINFOSHIFT_TS_REASON_IRET 36 #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 +#define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44 #define SVM_EXIT_READ_CR0 0x000 #define SVM_EXIT_READ_CR3 0x003 diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index aace5659bbe0..585d0ef4a5f6 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2344,8 +2344,9 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt, } static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, - struct x86_emulate_ops *ops, - u16 tss_selector, int reason) + struct x86_emulate_ops *ops, + u16 tss_selector, int reason, + bool has_error_code, u32 error_code) { struct desc_struct curr_tss_desc, next_tss_desc; int ret; @@ -2418,12 +2419,22 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, ops->set_cached_descriptor(&next_tss_desc, VCPU_SREG_TR, ctxt->vcpu); ops->set_segment_selector(tss_selector, VCPU_SREG_TR, ctxt->vcpu); + if (has_error_code) { + struct decode_cache *c = &ctxt->decode; + + c->op_bytes = c->ad_bytes = (next_tss_desc.type & 8) ? 4 : 2; + c->lock_prefix = 0; + c->src.val = (unsigned long) error_code; + emulate_push(ctxt); + } + return ret; } int emulator_task_switch(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, - u16 tss_selector, int reason) + u16 tss_selector, int reason, + bool has_error_code, u32 error_code) { struct decode_cache *c = &ctxt->decode; int rc; @@ -2431,12 +2442,15 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt, memset(c, 0, sizeof(struct decode_cache)); c->eip = ctxt->eip; memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); + c->dst.type = OP_NONE; - rc = emulator_do_task_switch(ctxt, ops, tss_selector, reason); + rc = emulator_do_task_switch(ctxt, ops, tss_selector, reason, + has_error_code, error_code); if (rc == X86EMUL_CONTINUE) { memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); kvm_rip_write(ctxt->vcpu, c->eip); + rc = writeback(ctxt, ops); } return rc; diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 87b36fbbfec8..78af52222fd2 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2222,6 +2222,8 @@ static int task_switch_interception(struct vcpu_svm *svm) svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_TYPE_MASK; uint32_t idt_v = svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID; + bool has_error_code = false; + u32 error_code = 0; tss_selector = (u16)svm->vmcb->control.exit_info_1; @@ -2242,6 +2244,12 @@ static int task_switch_interception(struct vcpu_svm *svm) svm->vcpu.arch.nmi_injected = false; break; case SVM_EXITINTINFO_TYPE_EXEPT: + if (svm->vmcb->control.exit_info_2 & + (1ULL << SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE)) { + has_error_code = true; + error_code = + (u32)svm->vmcb->control.exit_info_2; + } kvm_clear_exception_queue(&svm->vcpu); break; case SVM_EXITINTINFO_TYPE_INTR: @@ -2258,7 +2266,8 @@ static int task_switch_interception(struct vcpu_svm *svm) (int_vec == OF_VECTOR || int_vec == BP_VECTOR))) skip_emulated_instruction(&svm->vcpu); - return kvm_task_switch(&svm->vcpu, tss_selector, reason); + return kvm_task_switch(&svm->vcpu, tss_selector, reason, + has_error_code, error_code); } static int cpuid_interception(struct vcpu_svm *svm) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index fb4a8869bb99..1b38d8a88cf7 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3271,6 +3271,8 @@ static int handle_task_switch(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); unsigned long exit_qualification; + bool has_error_code = false; + u32 error_code = 0; u16 tss_selector; int reason, type, idt_v; @@ -3293,6 +3295,13 @@ static int handle_task_switch(struct kvm_vcpu *vcpu) kvm_clear_interrupt_queue(vcpu); break; case INTR_TYPE_HARD_EXCEPTION: + if (vmx->idt_vectoring_info & + VECTORING_INFO_DELIVER_CODE_MASK) { + has_error_code = true; + error_code = + vmcs_read32(IDT_VECTORING_ERROR_CODE); + } + /* fall through */ case INTR_TYPE_SOFT_EXCEPTION: kvm_clear_exception_queue(vcpu); break; @@ -3307,7 +3316,8 @@ static int handle_task_switch(struct kvm_vcpu *vcpu) type != INTR_TYPE_NMI_INTR)) skip_emulated_instruction(vcpu); - if (!kvm_task_switch(vcpu, tss_selector, reason)) + if (!kvm_task_switch(vcpu, tss_selector, reason, has_error_code, + error_code)) return 0; /* clear all local breakpoint enable flags */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 40991527f54a..58a295c6bf62 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4778,7 +4778,8 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, return 0; } -int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) +int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, + bool has_error_code, u32 error_code) { int cs_db, cs_l, ret; cache_all_regs(vcpu); @@ -4796,7 +4797,8 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; ret = emulator_task_switch(&vcpu->arch.emulate_ctxt, &emulate_ops, - tss_selector, reason); + tss_selector, reason, has_error_code, + error_code); if (ret == X86EMUL_CONTINUE) kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); -- cgit v1.2.3-59-g8ed1b From 5b7e0102ae744e9175b905f4267a81393bdb7a75 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 14 Apr 2010 19:20:03 +0300 Subject: KVM: MMU: Replace role.glevels with role.cr4_pae There is no real distinction between glevels=3 and glevels=4; both have exactly the same format and the code is treated exactly the same way. Drop role.glevels and replace is with role.cr4_pae (which is meaningful). This simplifies the code a bit. As a side effect, it allows sharing shadow page tables between pae and longmode guest page tables at the same guest page. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/mmu.c | 12 ++++++------ arch/x86/kvm/mmutrace.h | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 3602728d54de..707d272ae4a1 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -171,8 +171,8 @@ struct kvm_pte_chain { union kvm_mmu_page_role { unsigned word; struct { - unsigned glevels:4; unsigned level:4; + unsigned cr4_pae:1; unsigned quadrant:2; unsigned pad_for_nice_hex_output:6; unsigned direct:1; diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index ec8900b6692a..51aa580d0aa5 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1206,7 +1206,7 @@ static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp); static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) { - if (sp->role.glevels != vcpu->arch.mmu.root_level) { + if (sp->role.cr4_pae != !!is_pae(vcpu)) { kvm_mmu_zap_page(vcpu->kvm, sp); return 1; } @@ -1329,7 +1329,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, role.level = level; role.direct = direct; if (role.direct) - role.glevels = 0; + role.cr4_pae = 0; role.access = access; if (vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) { quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level)); @@ -2443,7 +2443,7 @@ static int init_kvm_softmmu(struct kvm_vcpu *vcpu) else r = paging32_init_context(vcpu); - vcpu->arch.mmu.base_role.glevels = vcpu->arch.mmu.root_level; + vcpu->arch.mmu.base_role.cr4_pae = !!is_pae(vcpu); return r; } @@ -2532,7 +2532,7 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu, } ++vcpu->kvm->stat.mmu_pte_updated; - if (sp->role.glevels == PT32_ROOT_LEVEL) + if (!sp->role.cr4_pae) paging32_update_pte(vcpu, sp, spte, new); else paging64_update_pte(vcpu, sp, spte, new); @@ -2681,7 +2681,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) { if (sp->gfn != gfn || sp->role.direct || sp->role.invalid) continue; - pte_size = sp->role.glevels == PT32_ROOT_LEVEL ? 4 : 8; + pte_size = sp->role.cr4_pae ? 8 : 4; misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1); misaligned |= bytes < 4; if (misaligned || flooded) { @@ -2705,7 +2705,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, page_offset = offset; level = sp->role.level; npte = 1; - if (sp->role.glevels == PT32_ROOT_LEVEL) { + if (!sp->role.cr4_pae) { page_offset <<= 1; /* 32->64 */ /* * A 32-bit pde maps 4MB while the shadow pdes map diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h index 1fe956ab7617..3851f1f3030c 100644 --- a/arch/x86/kvm/mmutrace.h +++ b/arch/x86/kvm/mmutrace.h @@ -28,9 +28,10 @@ \ role.word = __entry->role; \ \ - trace_seq_printf(p, "sp gfn %llx %u/%u q%u%s %s%s %spge" \ + trace_seq_printf(p, "sp gfn %llx %u%s q%u%s %s%s %spge" \ " %snxe root %u %s%c", \ - __entry->gfn, role.level, role.glevels, \ + __entry->gfn, role.level, \ + role.cr4_pae ? " pae" : "", \ role.quadrant, \ role.direct ? " direct" : "", \ access_str[role.access], \ -- cgit v1.2.3-59-g8ed1b From 19d04437267f00c7b50343513693b7a3174ff908 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 15 Apr 2010 12:29:50 +0300 Subject: KVM: fix emulator_task_switch() return value. emulator_task_switch() should return -1 for failure and 0 for success to the caller, just like x86_emulate_insn() does. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 2 +- arch/x86/kvm/x86.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 585d0ef4a5f6..5ac0bb465ed6 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2453,7 +2453,7 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt, rc = writeback(ctxt, ops); } - return rc; + return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; } static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 58a295c6bf62..30efeead4511 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4800,10 +4800,11 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, tss_selector, reason, has_error_code, error_code); - if (ret == X86EMUL_CONTINUE) - kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); + if (ret) + return EMULATE_FAIL; - return (ret != X86EMUL_CONTINUE); + kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); + return EMULATE_DONE; } EXPORT_SYMBOL_GPL(kvm_task_switch); -- cgit v1.2.3-59-g8ed1b From 1b8c7934a4063653095fb9fa88f9169f5b52f52b Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Fri, 16 Apr 2010 21:23:41 +0800 Subject: KVM: MMU: remove unused struct kvm_unsync_walk Remove 'struct kvm_unsync_walk' since it's not used. Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 51aa580d0aa5..b57be03d442c 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -173,11 +173,6 @@ struct kvm_shadow_walk_iterator { shadow_walk_okay(&(_walker)); \ shadow_walk_next(&(_walker))) - -struct kvm_unsync_walk { - int (*entry) (struct kvm_mmu_page *sp, struct kvm_unsync_walk *walk); -}; - typedef int (*mmu_parent_walk_fn) (struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp); static struct kmem_cache *pte_chain_cache; -- cgit v1.2.3-59-g8ed1b From 0571d366e0be571be14581cb5e28d9c3f6e0d0b1 Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Fri, 16 Apr 2010 21:27:54 +0800 Subject: KVM: MMU: reduce 'struct kvm_mmu_page' size Define 'multimapped' as 'bool'. Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 707d272ae4a1..3c31c5ad37ab 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -202,9 +202,9 @@ struct kvm_mmu_page { * in this shadow page. */ DECLARE_BITMAP(slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS); - int multimapped; /* More than one parent_pte? */ - int root_count; /* Currently serving as active root */ + bool multimapped; /* More than one parent_pte? */ bool unsync; + int root_count; /* Currently serving as active root */ unsigned int unsync_children; union { u64 *parent_pte; /* !multimapped */ -- cgit v1.2.3-59-g8ed1b From 6b18493d60e7f54a0feb771fa141b5fcb72ce1e4 Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Fri, 16 Apr 2010 21:29:17 +0800 Subject: KVM: MMU: remove unused parameter in mmu_parent_walk() 'vcpu' is unused, remove it Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index b57be03d442c..45f3aa5213c5 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -173,7 +173,7 @@ struct kvm_shadow_walk_iterator { shadow_walk_okay(&(_walker)); \ shadow_walk_next(&(_walker))) -typedef int (*mmu_parent_walk_fn) (struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp); +typedef int (*mmu_parent_walk_fn) (struct kvm_mmu_page *sp); static struct kmem_cache *pte_chain_cache; static struct kmem_cache *rmap_desc_cache; @@ -1001,8 +1001,7 @@ static void mmu_page_remove_parent_pte(struct kvm_mmu_page *sp, } -static void mmu_parent_walk(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, - mmu_parent_walk_fn fn) +static void mmu_parent_walk(struct kvm_mmu_page *sp, mmu_parent_walk_fn fn) { struct kvm_pte_chain *pte_chain; struct hlist_node *node; @@ -1011,8 +1010,8 @@ static void mmu_parent_walk(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, if (!sp->multimapped && sp->parent_pte) { parent_sp = page_header(__pa(sp->parent_pte)); - fn(vcpu, parent_sp); - mmu_parent_walk(vcpu, parent_sp, fn); + fn(parent_sp); + mmu_parent_walk(parent_sp, fn); return; } hlist_for_each_entry(pte_chain, node, &sp->parent_ptes, link) @@ -1020,8 +1019,8 @@ static void mmu_parent_walk(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, if (!pte_chain->parent_ptes[i]) break; parent_sp = page_header(__pa(pte_chain->parent_ptes[i])); - fn(vcpu, parent_sp); - mmu_parent_walk(vcpu, parent_sp, fn); + fn(parent_sp); + mmu_parent_walk(parent_sp, fn); } } @@ -1058,16 +1057,15 @@ static void kvm_mmu_update_parents_unsync(struct kvm_mmu_page *sp) } } -static int unsync_walk_fn(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) +static int unsync_walk_fn(struct kvm_mmu_page *sp) { kvm_mmu_update_parents_unsync(sp); return 1; } -static void kvm_mmu_mark_parents_unsync(struct kvm_vcpu *vcpu, - struct kvm_mmu_page *sp) +static void kvm_mmu_mark_parents_unsync(struct kvm_mmu_page *sp) { - mmu_parent_walk(vcpu, sp, unsync_walk_fn); + mmu_parent_walk(sp, unsync_walk_fn); kvm_mmu_update_parents_unsync(sp); } @@ -1345,7 +1343,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, mmu_page_add_parent_pte(vcpu, sp, parent_pte); if (sp->unsync_children) { set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests); - kvm_mmu_mark_parents_unsync(vcpu, sp); + kvm_mmu_mark_parents_unsync(sp); } trace_kvm_mmu_get_page(sp, false); return sp; @@ -1759,7 +1757,7 @@ static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) ++vcpu->kvm->stat.mmu_unsync; sp->unsync = 1; - kvm_mmu_mark_parents_unsync(vcpu, sp); + kvm_mmu_mark_parents_unsync(sp); mmu_convert_notrap(sp); return 0; -- cgit v1.2.3-59-g8ed1b From acb5451789f21ad51215897bb8f9306a05e8acd4 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Thu, 15 Apr 2010 21:03:50 +0300 Subject: KVM: prevent spurious exit to userspace during task switch emulation. If kvm_task_switch() fails code exits to userspace without specifying exit reason, so the previous exit reason is reused by userspace. Fix this by specifying exit reason correctly. Signed-off-by: Gleb Natapov Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/svm.c | 10 ++++++++-- arch/x86/kvm/vmx.c | 8 ++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 78af52222fd2..ab78eb8ba899 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2266,8 +2266,14 @@ static int task_switch_interception(struct vcpu_svm *svm) (int_vec == OF_VECTOR || int_vec == BP_VECTOR))) skip_emulated_instruction(&svm->vcpu); - return kvm_task_switch(&svm->vcpu, tss_selector, reason, - has_error_code, error_code); + if (kvm_task_switch(&svm->vcpu, tss_selector, reason, + has_error_code, error_code) == EMULATE_FAIL) { + svm->vcpu.run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + svm->vcpu.run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; + svm->vcpu.run->internal.ndata = 0; + return 0; + } + return 1; } static int cpuid_interception(struct vcpu_svm *svm) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1b38d8a88cf7..6e5e75e0d7d3 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3316,9 +3316,13 @@ static int handle_task_switch(struct kvm_vcpu *vcpu) type != INTR_TYPE_NMI_INTR)) skip_emulated_instruction(vcpu); - if (!kvm_task_switch(vcpu, tss_selector, reason, has_error_code, - error_code)) + if (kvm_task_switch(vcpu, tss_selector, reason, + has_error_code, error_code) == EMULATE_FAIL) { + vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; + vcpu->run->internal.ndata = 0; return 0; + } /* clear all local breakpoint enable flags */ vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~55); -- cgit v1.2.3-59-g8ed1b From 3246af0ece6c61689847417977733f0b12dc4b6f Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Fri, 16 Apr 2010 16:35:54 +0800 Subject: KVM: MMU: cleanup for hlist walk restart Quote from Avi: |Just change the assignment to a 'goto restart;' please, |I don't like playing with list_for_each internals. Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 45f3aa5213c5..7a17db1cdcd6 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1565,13 +1565,14 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn) r = 0; index = kvm_page_table_hashfn(gfn); bucket = &kvm->arch.mmu_page_hash[index]; +restart: hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) if (sp->gfn == gfn && !sp->role.direct) { pgprintk("%s: gfn %lx role %x\n", __func__, gfn, sp->role.word); r = 1; if (kvm_mmu_zap_page(kvm, sp)) - n = bucket->first; + goto restart; } return r; } @@ -1585,13 +1586,14 @@ static void mmu_unshadow(struct kvm *kvm, gfn_t gfn) index = kvm_page_table_hashfn(gfn); bucket = &kvm->arch.mmu_page_hash[index]; +restart: hlist_for_each_entry_safe(sp, node, nn, bucket, hash_link) { if (sp->gfn == gfn && !sp->role.direct && !sp->role.invalid) { pgprintk("%s: zap %lx %x\n", __func__, gfn, sp->role.word); if (kvm_mmu_zap_page(kvm, sp)) - nn = bucket->first; + goto restart; } } } @@ -2671,6 +2673,8 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, } index = kvm_page_table_hashfn(gfn); bucket = &vcpu->kvm->arch.mmu_page_hash[index]; + +restart: hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) { if (sp->gfn != gfn || sp->role.direct || sp->role.invalid) continue; @@ -2691,7 +2695,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, pgprintk("misaligned: gpa %llx bytes %d role %x\n", gpa, bytes, sp->role.word); if (kvm_mmu_zap_page(vcpu->kvm, sp)) - n = bucket->first; + goto restart; ++vcpu->kvm->stat.mmu_flooded; continue; } @@ -2900,10 +2904,11 @@ void kvm_mmu_zap_all(struct kvm *kvm) struct kvm_mmu_page *sp, *node; spin_lock(&kvm->mmu_lock); +restart: list_for_each_entry_safe(sp, node, &kvm->arch.active_mmu_pages, link) if (kvm_mmu_zap_page(kvm, sp)) - node = container_of(kvm->arch.active_mmu_pages.next, - struct kvm_mmu_page, link); + goto restart; + spin_unlock(&kvm->mmu_lock); kvm_flush_remote_tlbs(kvm); -- cgit v1.2.3-59-g8ed1b From 90d83dc3d49f5101addae962ccc1b4aff66b68d8 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Mon, 19 Apr 2010 17:41:23 +0800 Subject: KVM: use the correct RCU API for PROVE_RCU=y The RCU/SRCU API have already changed for proving RCU usage. I got the following dmesg when PROVE_RCU=y because we used incorrect API. This patch coverts rcu_deference() to srcu_dereference() or family API. =================================================== [ INFO: suspicious rcu_dereference_check() usage. ] --------------------------------------------------- arch/x86/kvm/mmu.c:3020 invoked rcu_dereference_check() without protection! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 0 2 locks held by qemu-system-x86/8550: #0: (&kvm->slots_lock){+.+.+.}, at: [] kvm_set_memory_region+0x29/0x50 [kvm] #1: (&(&kvm->mmu_lock)->rlock){+.+...}, at: [] kvm_arch_commit_memory_region+0xa6/0xe2 [kvm] stack backtrace: Pid: 8550, comm: qemu-system-x86 Not tainted 2.6.34-rc4-tip-01028-g939eab1 #27 Call Trace: [] lockdep_rcu_dereference+0xaa/0xb3 [] kvm_mmu_calculate_mmu_pages+0x44/0x7d [kvm] [] kvm_arch_commit_memory_region+0xb7/0xe2 [kvm] [] __kvm_set_memory_region+0x636/0x6e2 [kvm] [] kvm_set_memory_region+0x37/0x50 [kvm] [] vmx_set_tss_addr+0x46/0x5a [kvm_intel] [] kvm_arch_vm_ioctl+0x17a/0xcf8 [kvm] [] ? unlock_page+0x27/0x2c [] ? __do_fault+0x3a9/0x3e1 [] kvm_vm_ioctl+0x364/0x38d [kvm] [] ? up_read+0x23/0x3d [] vfs_ioctl+0x32/0xa6 [] do_vfs_ioctl+0x495/0x4db [] ? fget_light+0xc2/0x241 [] ? do_sys_open+0x104/0x116 [] ? retint_swapgs+0xe/0x13 [] sys_ioctl+0x47/0x6a [] system_call_fastpath+0x16/0x1b Signed-off-by: Lai Jiangshan Signed-off-by: Avi Kivity --- arch/ia64/kvm/kvm-ia64.c | 2 +- arch/s390/kvm/kvm-s390.h | 2 +- arch/x86/kvm/mmu.c | 7 ++++--- arch/x86/kvm/vmx.c | 2 +- arch/x86/kvm/x86.c | 4 ++-- arch/x86/kvm/x86.h | 7 +++++++ include/linux/kvm_host.h | 7 +++++++ virt/kvm/iommu.c | 4 ++-- virt/kvm/kvm_main.c | 13 ++++++++----- 9 files changed, 33 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index d7bac1f75af0..d5f4e9161201 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1381,7 +1381,7 @@ static void kvm_release_vm_pages(struct kvm *kvm) int i, j; unsigned long base_gfn; - slots = rcu_dereference(kvm->memslots); + slots = kvm_memslots(kvm); for (i = 0; i < slots->nmemslots; i++) { memslot = &slots->memslots[i]; base_gfn = memslot->base_gfn; diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 60f09ab3672c..cfa9d1777457 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -72,7 +72,7 @@ static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu) struct kvm_memslots *memslots; idx = srcu_read_lock(&vcpu->kvm->srcu); - memslots = rcu_dereference(vcpu->kvm->memslots); + memslots = kvm_memslots(vcpu->kvm); mem = &memslots->memslots[0]; diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 7a17db1cdcd6..0682a393ad90 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -787,7 +787,7 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, int retval = 0; struct kvm_memslots *slots; - slots = rcu_dereference(kvm->memslots); + slots = kvm_memslots(kvm); for (i = 0; i < slots->nmemslots; i++) { struct kvm_memory_slot *memslot = &slots->memslots[i]; @@ -3016,7 +3016,8 @@ unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm) unsigned int nr_pages = 0; struct kvm_memslots *slots; - slots = rcu_dereference(kvm->memslots); + slots = kvm_memslots(kvm); + for (i = 0; i < slots->nmemslots; i++) nr_pages += slots->memslots[i].npages; @@ -3292,7 +3293,7 @@ static int count_rmaps(struct kvm_vcpu *vcpu) int i, j, k, idx; idx = srcu_read_lock(&kvm->srcu); - slots = rcu_dereference(kvm->memslots); + slots = kvm_memslots(kvm); for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { struct kvm_memory_slot *m = &slots->memslots[i]; struct kvm_rmap_desc *d; diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 0b896ac7e4bb..d0a10b5612e9 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1558,7 +1558,7 @@ static gva_t rmode_tss_base(struct kvm *kvm) struct kvm_memslots *slots; gfn_t base_gfn; - slots = rcu_dereference(kvm->memslots); + slots = kvm_memslots(kvm); base_gfn = kvm->memslots->memslots[0].base_gfn + kvm->memslots->memslots[0].npages - 3; return base_gfn << PAGE_SHIFT; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 58a96e6a234c..638248c96999 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2497,7 +2497,7 @@ gfn_t unalias_gfn_instantiation(struct kvm *kvm, gfn_t gfn) struct kvm_mem_alias *alias; struct kvm_mem_aliases *aliases; - aliases = rcu_dereference(kvm->arch.aliases); + aliases = kvm_aliases(kvm); for (i = 0; i < aliases->naliases; ++i) { alias = &aliases->aliases[i]; @@ -2516,7 +2516,7 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) struct kvm_mem_alias *alias; struct kvm_mem_aliases *aliases; - aliases = rcu_dereference(kvm->arch.aliases); + aliases = kvm_aliases(kvm); for (i = 0; i < aliases->naliases; ++i) { alias = &aliases->aliases[i]; diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index b7a404722d2b..f4b54458285b 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -65,6 +65,13 @@ static inline int is_paging(struct kvm_vcpu *vcpu) return kvm_read_cr0_bits(vcpu, X86_CR0_PG); } +static inline struct kvm_mem_aliases *kvm_aliases(struct kvm *kvm) +{ + return rcu_dereference_check(kvm->arch.aliases, + srcu_read_lock_held(&kvm->srcu) + || lockdep_is_held(&kvm->slots_lock)); +} + void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 55830638aeb1..1ed030bad59e 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -250,6 +250,13 @@ void kvm_exit(void); void kvm_get_kvm(struct kvm *kvm); void kvm_put_kvm(struct kvm *kvm); +static inline struct kvm_memslots *kvm_memslots(struct kvm *kvm) +{ + return rcu_dereference_check(kvm->memslots, + srcu_read_lock_held(&kvm->srcu) + || lockdep_is_held(&kvm->slots_lock)); +} + #define HPA_MSB ((sizeof(hpa_t) * 8) - 1) #define HPA_ERR_MASK ((hpa_t)1 << HPA_MSB) static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; } diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index 80fd3ad3b2de..37ca71ebdba8 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c @@ -78,7 +78,7 @@ static int kvm_iommu_map_memslots(struct kvm *kvm) int i, r = 0; struct kvm_memslots *slots; - slots = rcu_dereference(kvm->memslots); + slots = kvm_memslots(kvm); for (i = 0; i < slots->nmemslots; i++) { r = kvm_iommu_map_pages(kvm, &slots->memslots[i]); @@ -217,7 +217,7 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm) int i; struct kvm_memslots *slots; - slots = rcu_dereference(kvm->memslots); + slots = kvm_memslots(kvm); for (i = 0; i < slots->nmemslots; i++) { kvm_iommu_put_pages(kvm, slots->memslots[i].base_gfn, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d6351a34b297..4901ec5061ba 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -834,7 +834,7 @@ EXPORT_SYMBOL_GPL(kvm_is_error_hva); struct kvm_memory_slot *gfn_to_memslot_unaliased(struct kvm *kvm, gfn_t gfn) { int i; - struct kvm_memslots *slots = rcu_dereference(kvm->memslots); + struct kvm_memslots *slots = kvm_memslots(kvm); for (i = 0; i < slots->nmemslots; ++i) { struct kvm_memory_slot *memslot = &slots->memslots[i]; @@ -856,7 +856,7 @@ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn) { int i; - struct kvm_memslots *slots = rcu_dereference(kvm->memslots); + struct kvm_memslots *slots = kvm_memslots(kvm); gfn = unalias_gfn_instantiation(kvm, gfn); for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { @@ -900,7 +900,7 @@ out: int memslot_id(struct kvm *kvm, gfn_t gfn) { int i; - struct kvm_memslots *slots = rcu_dereference(kvm->memslots); + struct kvm_memslots *slots = kvm_memslots(kvm); struct kvm_memory_slot *memslot = NULL; gfn = unalias_gfn(kvm, gfn); @@ -1994,7 +1994,9 @@ int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, int len, const void *val) { int i; - struct kvm_io_bus *bus = rcu_dereference(kvm->buses[bus_idx]); + struct kvm_io_bus *bus; + + bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu); for (i = 0; i < bus->dev_count; i++) if (!kvm_iodevice_write(bus->devs[i], addr, len, val)) return 0; @@ -2006,8 +2008,9 @@ int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, int len, void *val) { int i; - struct kvm_io_bus *bus = rcu_dereference(kvm->buses[bus_idx]); + struct kvm_io_bus *bus; + bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu); for (i = 0; i < bus->dev_count; i++) if (!kvm_iodevice_read(bus->devs[i], addr, len, val)) return 0; -- cgit v1.2.3-59-g8ed1b From 87bc3bf972af0585ba5415aebbc8bd09b6a2ee94 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 19 Apr 2010 17:25:53 +0300 Subject: KVM: MMU: Drop cr4.pge from shadow page role Since commit bf47a760f66ad, we no longer handle ptes with the global bit set specially, so there is no reason to distinguish between shadow pages created with cr4.gpe set and clear. Such tracking is expensive when the guest toggles cr4.pge, so drop it. Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_host.h | 1 - arch/x86/kvm/mmutrace.h | 3 +-- arch/x86/kvm/x86.c | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 3c31c5ad37ab..d47d087568fe 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -178,7 +178,6 @@ union kvm_mmu_page_role { unsigned direct:1; unsigned access:3; unsigned invalid:1; - unsigned cr4_pge:1; unsigned nxe:1; }; }; diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h index 3851f1f3030c..bc4f7f0be2b1 100644 --- a/arch/x86/kvm/mmutrace.h +++ b/arch/x86/kvm/mmutrace.h @@ -28,7 +28,7 @@ \ role.word = __entry->role; \ \ - trace_seq_printf(p, "sp gfn %llx %u%s q%u%s %s%s %spge" \ + trace_seq_printf(p, "sp gfn %llx %u%s q%u%s %s%s" \ " %snxe root %u %s%c", \ __entry->gfn, role.level, \ role.cr4_pae ? " pae" : "", \ @@ -36,7 +36,6 @@ role.direct ? " direct" : "", \ access_str[role.access], \ role.invalid ? " invalid" : "", \ - role.cr4_pge ? "" : "!", \ role.nxe ? "" : "!", \ __entry->root_count, \ __entry->unsync ? "unsync" : "sync", 0); \ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 638248c96999..cf37ac6644e0 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -488,7 +488,6 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) } kvm_x86_ops->set_cr4(vcpu, cr4); vcpu->arch.cr4 = cr4; - vcpu->arch.mmu.base_role.cr4_pge = (cr4 & X86_CR4_PGE) && !tdp_enabled; kvm_mmu_reset_context(vcpu); } EXPORT_SYMBOL_GPL(kvm_set_cr4); -- cgit v1.2.3-59-g8ed1b From 51fb60d81b483ae75614d401e7d4271884894113 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Fri, 16 Apr 2010 17:16:40 +0800 Subject: KVM: MMU: Move sync_page() first pte address calculation out of loop Move first pte address calculation out of loop to save some cycles. Signed-off-by: Gui Jianfeng Signed-off-by: Avi Kivity --- arch/x86/kvm/paging_tmpl.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index d9dea288e51d..5910557b3f33 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -572,12 +572,15 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) { int i, offset, nr_present; bool reset_host_protection; + gpa_t first_pte_gpa; offset = nr_present = 0; if (PTTYPE == 32) offset = sp->role.quadrant << PT64_LEVEL_BITS; + first_pte_gpa = gfn_to_gpa(sp->gfn) + offset * sizeof(pt_element_t); + for (i = 0; i < PT64_ENT_PER_PAGE; i++) { unsigned pte_access; pt_element_t gpte; @@ -587,8 +590,7 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) if (!is_shadow_present_pte(sp->spt[i])) continue; - pte_gpa = gfn_to_gpa(sp->gfn); - pte_gpa += (i+offset) * sizeof(pt_element_t); + pte_gpa = first_pte_gpa + i * sizeof(pt_element_t); if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte, sizeof(pt_element_t))) -- cgit v1.2.3-59-g8ed1b From 814a59d2077d630cffca7e2878c5b6f9b91ba725 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Fri, 16 Apr 2010 17:18:01 +0800 Subject: KVM: MMU: Make use of is_large_pte() in walker Make use of is_large_pte() instead of checking PT_PAGE_SIZE_MASK bit directly. Signed-off-by: Gui Jianfeng Signed-off-by: Avi Kivity --- arch/x86/kvm/paging_tmpl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 5910557b3f33..d0cc07eb6eda 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -190,10 +190,10 @@ walk: if ((walker->level == PT_PAGE_TABLE_LEVEL) || ((walker->level == PT_DIRECTORY_LEVEL) && - (pte & PT_PAGE_SIZE_MASK) && + is_large_pte(pte) && (PTTYPE == 64 || is_pse(vcpu))) || ((walker->level == PT_PDPE_LEVEL) && - (pte & PT_PAGE_SIZE_MASK) && + is_large_pte(pte) && is_long_mode(vcpu))) { int lvl = walker->level; -- cgit v1.2.3-59-g8ed1b From b2fc15a5ef6679a5f87fee012a836294532bc628 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Fri, 16 Apr 2010 17:18:54 +0800 Subject: KVM: MMU: Remove unused varialbe in rmap_next() Remove unused varialbe in rmap_next() Signed-off-by: Gui Jianfeng Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 0682a393ad90..7eff794457f3 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -647,7 +647,6 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte) { struct kvm_rmap_desc *desc; - struct kvm_rmap_desc *prev_desc; u64 *prev_spte; int i; @@ -659,7 +658,6 @@ static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte) return NULL; } desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); - prev_desc = NULL; prev_spte = NULL; while (desc) { for (i = 0; i < RMAP_EXT && desc->sptes[i]; ++i) { -- cgit v1.2.3-59-g8ed1b From 2a059bf444dd7758ccf48f217cd981570132be85 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Fri, 16 Apr 2010 17:19:48 +0800 Subject: KVM: Get rid of dead function gva_to_page() Nobody use gva_to_page() anymore, get rid of it. Signed-off-by: Gui Jianfeng Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 14 -------------- include/linux/kvm_host.h | 1 - 2 files changed, 15 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 7eff794457f3..d2a110e870fa 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1618,20 +1618,6 @@ static void mmu_convert_notrap(struct kvm_mmu_page *sp) } } -struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva) -{ - struct page *page; - - gpa_t gpa = kvm_mmu_gva_to_gpa_read(vcpu, gva, NULL); - - if (gpa == UNMAPPED_GVA) - return NULL; - - page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); - - return page; -} - /* * The function is based on mtrr_type_lookup() in * arch/x86/kernel/cpu/mtrr/generic.c diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 1ed030bad59e..ce027d518096 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -260,7 +260,6 @@ static inline struct kvm_memslots *kvm_memslots(struct kvm *kvm) #define HPA_MSB ((sizeof(hpa_t) * 8) - 1) #define HPA_ERR_MASK ((hpa_t)1 << HPA_MSB) static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; } -struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva); extern struct page *bad_page; extern pfn_t bad_pfn; -- cgit v1.2.3-59-g8ed1b From 77a1a715707d0f60ce0cfbe44070527a0a561f01 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 16 Apr 2010 16:21:42 +0800 Subject: KVM: MMU: cleanup for function unaccount_shadowed() Since gfn is not changed in the for loop, we do not need to call gfn_to_memslot_unaliased() under the loop, and it is safe to move it out. Signed-off-by: Wei Yongjun Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index d2a110e870fa..ddfa8658fb6d 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -431,9 +431,9 @@ static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn) int i; gfn = unalias_gfn(kvm, gfn); + slot = gfn_to_memslot_unaliased(kvm, gfn); for (i = PT_DIRECTORY_LEVEL; i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { - slot = gfn_to_memslot_unaliased(kvm, gfn); write_count = slot_largepage_idx(gfn, slot, i); *write_count -= 1; WARN_ON(*write_count < 0); -- cgit v1.2.3-59-g8ed1b From 2191d657c9eaa4c444c33e014199ed9de1ac339d Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:32 +0200 Subject: KVM: PPC: Name generic 64-bit code generic We have quite some code that can be used by Book3S_32 and Book3S_64 alike, so let's call it "Book3S" instead of "Book3S_64", so we can later on use it from the 32 bit port too. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 2 +- arch/powerpc/include/asm/kvm_book3s_64_asm.h | 76 ---- arch/powerpc/include/asm/kvm_book3s_asm.h | 76 ++++ arch/powerpc/include/asm/paca.h | 2 +- arch/powerpc/kernel/head_64.S | 4 +- arch/powerpc/kvm/Makefile | 6 +- arch/powerpc/kvm/book3s_64_emulate.c | 566 --------------------------- arch/powerpc/kvm/book3s_64_exports.c | 32 -- arch/powerpc/kvm/book3s_64_interrupts.S | 318 --------------- arch/powerpc/kvm/book3s_64_rmhandlers.S | 195 --------- arch/powerpc/kvm/book3s_emulate.c | 566 +++++++++++++++++++++++++++ arch/powerpc/kvm/book3s_exports.c | 32 ++ arch/powerpc/kvm/book3s_interrupts.S | 317 +++++++++++++++ arch/powerpc/kvm/book3s_rmhandlers.S | 194 +++++++++ 14 files changed, 1192 insertions(+), 1194 deletions(-) delete mode 100644 arch/powerpc/include/asm/kvm_book3s_64_asm.h create mode 100644 arch/powerpc/include/asm/kvm_book3s_asm.h delete mode 100644 arch/powerpc/kvm/book3s_64_emulate.c delete mode 100644 arch/powerpc/kvm/book3s_64_exports.c delete mode 100644 arch/powerpc/kvm/book3s_64_interrupts.S delete mode 100644 arch/powerpc/kvm/book3s_64_rmhandlers.S create mode 100644 arch/powerpc/kvm/book3s_emulate.c create mode 100644 arch/powerpc/kvm/book3s_exports.c create mode 100644 arch/powerpc/kvm/book3s_interrupts.S create mode 100644 arch/powerpc/kvm/book3s_rmhandlers.S (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index ee7992189c6e..7670e2a12867 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -22,7 +22,7 @@ #include #include -#include +#include struct kvmppc_slb { u64 esid; diff --git a/arch/powerpc/include/asm/kvm_book3s_64_asm.h b/arch/powerpc/include/asm/kvm_book3s_64_asm.h deleted file mode 100644 index 183461b48407..000000000000 --- a/arch/powerpc/include/asm/kvm_book3s_64_asm.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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. - * - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright SUSE Linux Products GmbH 2009 - * - * Authors: Alexander Graf - */ - -#ifndef __ASM_KVM_BOOK3S_ASM_H__ -#define __ASM_KVM_BOOK3S_ASM_H__ - -#ifdef __ASSEMBLY__ - -#ifdef CONFIG_KVM_BOOK3S_64_HANDLER - -#include - -.macro DO_KVM intno - .if (\intno == BOOK3S_INTERRUPT_SYSTEM_RESET) || \ - (\intno == BOOK3S_INTERRUPT_MACHINE_CHECK) || \ - (\intno == BOOK3S_INTERRUPT_DATA_STORAGE) || \ - (\intno == BOOK3S_INTERRUPT_INST_STORAGE) || \ - (\intno == BOOK3S_INTERRUPT_DATA_SEGMENT) || \ - (\intno == BOOK3S_INTERRUPT_INST_SEGMENT) || \ - (\intno == BOOK3S_INTERRUPT_EXTERNAL) || \ - (\intno == BOOK3S_INTERRUPT_ALIGNMENT) || \ - (\intno == BOOK3S_INTERRUPT_PROGRAM) || \ - (\intno == BOOK3S_INTERRUPT_FP_UNAVAIL) || \ - (\intno == BOOK3S_INTERRUPT_DECREMENTER) || \ - (\intno == BOOK3S_INTERRUPT_SYSCALL) || \ - (\intno == BOOK3S_INTERRUPT_TRACE) || \ - (\intno == BOOK3S_INTERRUPT_PERFMON) || \ - (\intno == BOOK3S_INTERRUPT_ALTIVEC) || \ - (\intno == BOOK3S_INTERRUPT_VSX) - - b kvmppc_trampoline_\intno -kvmppc_resume_\intno: - - .endif -.endm - -#else - -.macro DO_KVM intno -.endm - -#endif /* CONFIG_KVM_BOOK3S_64_HANDLER */ - -#else /*__ASSEMBLY__ */ - -struct kvmppc_book3s_shadow_vcpu { - ulong gpr[14]; - u32 cr; - u32 xer; - ulong host_r1; - ulong host_r2; - ulong handler; - ulong scratch0; - ulong scratch1; - ulong vmhandler; -}; - -#endif /*__ASSEMBLY__ */ - -#endif /* __ASM_KVM_BOOK3S_ASM_H__ */ diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h new file mode 100644 index 000000000000..183461b48407 --- /dev/null +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h @@ -0,0 +1,76 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2009 + * + * Authors: Alexander Graf + */ + +#ifndef __ASM_KVM_BOOK3S_ASM_H__ +#define __ASM_KVM_BOOK3S_ASM_H__ + +#ifdef __ASSEMBLY__ + +#ifdef CONFIG_KVM_BOOK3S_64_HANDLER + +#include + +.macro DO_KVM intno + .if (\intno == BOOK3S_INTERRUPT_SYSTEM_RESET) || \ + (\intno == BOOK3S_INTERRUPT_MACHINE_CHECK) || \ + (\intno == BOOK3S_INTERRUPT_DATA_STORAGE) || \ + (\intno == BOOK3S_INTERRUPT_INST_STORAGE) || \ + (\intno == BOOK3S_INTERRUPT_DATA_SEGMENT) || \ + (\intno == BOOK3S_INTERRUPT_INST_SEGMENT) || \ + (\intno == BOOK3S_INTERRUPT_EXTERNAL) || \ + (\intno == BOOK3S_INTERRUPT_ALIGNMENT) || \ + (\intno == BOOK3S_INTERRUPT_PROGRAM) || \ + (\intno == BOOK3S_INTERRUPT_FP_UNAVAIL) || \ + (\intno == BOOK3S_INTERRUPT_DECREMENTER) || \ + (\intno == BOOK3S_INTERRUPT_SYSCALL) || \ + (\intno == BOOK3S_INTERRUPT_TRACE) || \ + (\intno == BOOK3S_INTERRUPT_PERFMON) || \ + (\intno == BOOK3S_INTERRUPT_ALTIVEC) || \ + (\intno == BOOK3S_INTERRUPT_VSX) + + b kvmppc_trampoline_\intno +kvmppc_resume_\intno: + + .endif +.endm + +#else + +.macro DO_KVM intno +.endm + +#endif /* CONFIG_KVM_BOOK3S_64_HANDLER */ + +#else /*__ASSEMBLY__ */ + +struct kvmppc_book3s_shadow_vcpu { + ulong gpr[14]; + u32 cr; + u32 xer; + ulong host_r1; + ulong host_r2; + ulong handler; + ulong scratch0; + ulong scratch1; + ulong vmhandler; +}; + +#endif /*__ASSEMBLY__ */ + +#endif /* __ASM_KVM_BOOK3S_ASM_H__ */ diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index a011603d4079..dc3ccdf81996 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -23,7 +23,7 @@ #include #include #ifdef CONFIG_KVM_BOOK3S_64_HANDLER -#include +#include #endif register struct paca_struct *local_paca asm("r13"); diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index bed9a29ee383..844a44b64472 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -37,7 +37,7 @@ #include #include #include -#include +#include /* The physical memory is layed out such that the secondary processor * spin code sits at 0x0000...0x00ff. On server, the vectors follow @@ -169,7 +169,7 @@ exception_marker: /* KVM trampoline code needs to be close to the interrupt handlers */ #ifdef CONFIG_KVM_BOOK3S_64_HANDLER -#include "../kvm/book3s_64_rmhandlers.S" +#include "../kvm/book3s_rmhandlers.S" #endif _GLOBAL(generic_secondary_thread_init) diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index eba721e39328..0a67310299a6 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -14,7 +14,7 @@ CFLAGS_emulate.o := -I. common-objs-y += powerpc.o emulate.o obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o -obj-$(CONFIG_KVM_BOOK3S_64_HANDLER) += book3s_64_exports.o +obj-$(CONFIG_KVM_BOOK3S_64_HANDLER) += book3s_exports.o AFLAGS_booke_interrupts.o := -I$(obj) @@ -43,8 +43,8 @@ kvm-book3s_64-objs := \ fpu.o \ book3s_paired_singles.o \ book3s.o \ - book3s_64_emulate.o \ - book3s_64_interrupts.o \ + book3s_emulate.o \ + book3s_interrupts.o \ book3s_64_mmu_host.o \ book3s_64_mmu.o \ book3s_32_mmu.o diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c deleted file mode 100644 index 8f50776a9a1d..000000000000 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * 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. - * - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright SUSE Linux Products GmbH 2009 - * - * Authors: Alexander Graf - */ - -#include -#include -#include -#include - -#define OP_19_XOP_RFID 18 -#define OP_19_XOP_RFI 50 - -#define OP_31_XOP_MFMSR 83 -#define OP_31_XOP_MTMSR 146 -#define OP_31_XOP_MTMSRD 178 -#define OP_31_XOP_MTSR 210 -#define OP_31_XOP_MTSRIN 242 -#define OP_31_XOP_TLBIEL 274 -#define OP_31_XOP_TLBIE 306 -#define OP_31_XOP_SLBMTE 402 -#define OP_31_XOP_SLBIE 434 -#define OP_31_XOP_SLBIA 498 -#define OP_31_XOP_MFSR 595 -#define OP_31_XOP_MFSRIN 659 -#define OP_31_XOP_DCBA 758 -#define OP_31_XOP_SLBMFEV 851 -#define OP_31_XOP_EIOIO 854 -#define OP_31_XOP_SLBMFEE 915 - -/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */ -#define OP_31_XOP_DCBZ 1010 - -#define OP_LFS 48 -#define OP_LFD 50 -#define OP_STFS 52 -#define OP_STFD 54 - -#define SPRN_GQR0 912 -#define SPRN_GQR1 913 -#define SPRN_GQR2 914 -#define SPRN_GQR3 915 -#define SPRN_GQR4 916 -#define SPRN_GQR5 917 -#define SPRN_GQR6 918 -#define SPRN_GQR7 919 - -int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, - unsigned int inst, int *advance) -{ - int emulated = EMULATE_DONE; - - switch (get_op(inst)) { - case 19: - switch (get_xop(inst)) { - case OP_19_XOP_RFID: - case OP_19_XOP_RFI: - vcpu->arch.pc = vcpu->arch.srr0; - kvmppc_set_msr(vcpu, vcpu->arch.srr1); - *advance = 0; - break; - - default: - emulated = EMULATE_FAIL; - break; - } - break; - case 31: - switch (get_xop(inst)) { - case OP_31_XOP_MFMSR: - kvmppc_set_gpr(vcpu, get_rt(inst), vcpu->arch.msr); - break; - case OP_31_XOP_MTMSRD: - { - ulong rs = kvmppc_get_gpr(vcpu, get_rs(inst)); - if (inst & 0x10000) { - vcpu->arch.msr &= ~(MSR_RI | MSR_EE); - vcpu->arch.msr |= rs & (MSR_RI | MSR_EE); - } else - kvmppc_set_msr(vcpu, rs); - break; - } - case OP_31_XOP_MTMSR: - kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, get_rs(inst))); - break; - case OP_31_XOP_MFSR: - { - int srnum; - - srnum = kvmppc_get_field(inst, 12 + 32, 15 + 32); - if (vcpu->arch.mmu.mfsrin) { - u32 sr; - sr = vcpu->arch.mmu.mfsrin(vcpu, srnum); - kvmppc_set_gpr(vcpu, get_rt(inst), sr); - } - break; - } - case OP_31_XOP_MFSRIN: - { - int srnum; - - srnum = (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf; - if (vcpu->arch.mmu.mfsrin) { - u32 sr; - sr = vcpu->arch.mmu.mfsrin(vcpu, srnum); - kvmppc_set_gpr(vcpu, get_rt(inst), sr); - } - break; - } - case OP_31_XOP_MTSR: - vcpu->arch.mmu.mtsrin(vcpu, - (inst >> 16) & 0xf, - kvmppc_get_gpr(vcpu, get_rs(inst))); - break; - case OP_31_XOP_MTSRIN: - vcpu->arch.mmu.mtsrin(vcpu, - (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf, - kvmppc_get_gpr(vcpu, get_rs(inst))); - break; - case OP_31_XOP_TLBIE: - case OP_31_XOP_TLBIEL: - { - bool large = (inst & 0x00200000) ? true : false; - ulong addr = kvmppc_get_gpr(vcpu, get_rb(inst)); - vcpu->arch.mmu.tlbie(vcpu, addr, large); - break; - } - case OP_31_XOP_EIOIO: - break; - case OP_31_XOP_SLBMTE: - if (!vcpu->arch.mmu.slbmte) - return EMULATE_FAIL; - - vcpu->arch.mmu.slbmte(vcpu, - kvmppc_get_gpr(vcpu, get_rs(inst)), - kvmppc_get_gpr(vcpu, get_rb(inst))); - break; - case OP_31_XOP_SLBIE: - if (!vcpu->arch.mmu.slbie) - return EMULATE_FAIL; - - vcpu->arch.mmu.slbie(vcpu, - kvmppc_get_gpr(vcpu, get_rb(inst))); - break; - case OP_31_XOP_SLBIA: - if (!vcpu->arch.mmu.slbia) - return EMULATE_FAIL; - - vcpu->arch.mmu.slbia(vcpu); - break; - case OP_31_XOP_SLBMFEE: - if (!vcpu->arch.mmu.slbmfee) { - emulated = EMULATE_FAIL; - } else { - ulong t, rb; - - rb = kvmppc_get_gpr(vcpu, get_rb(inst)); - t = vcpu->arch.mmu.slbmfee(vcpu, rb); - kvmppc_set_gpr(vcpu, get_rt(inst), t); - } - break; - case OP_31_XOP_SLBMFEV: - if (!vcpu->arch.mmu.slbmfev) { - emulated = EMULATE_FAIL; - } else { - ulong t, rb; - - rb = kvmppc_get_gpr(vcpu, get_rb(inst)); - t = vcpu->arch.mmu.slbmfev(vcpu, rb); - kvmppc_set_gpr(vcpu, get_rt(inst), t); - } - break; - case OP_31_XOP_DCBA: - /* Gets treated as NOP */ - break; - case OP_31_XOP_DCBZ: - { - ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst)); - ulong ra = 0; - ulong addr, vaddr; - u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - u32 dsisr; - int r; - - if (get_ra(inst)) - ra = kvmppc_get_gpr(vcpu, get_ra(inst)); - - addr = (ra + rb) & ~31ULL; - if (!(vcpu->arch.msr & MSR_SF)) - addr &= 0xffffffff; - vaddr = addr; - - r = kvmppc_st(vcpu, &addr, 32, zeros, true); - if ((r == -ENOENT) || (r == -EPERM)) { - *advance = 0; - vcpu->arch.dear = vaddr; - vcpu->arch.fault_dear = vaddr; - - dsisr = DSISR_ISSTORE; - if (r == -ENOENT) - dsisr |= DSISR_NOHPTE; - else if (r == -EPERM) - dsisr |= DSISR_PROTFAULT; - - to_book3s(vcpu)->dsisr = dsisr; - vcpu->arch.fault_dsisr = dsisr; - - kvmppc_book3s_queue_irqprio(vcpu, - BOOK3S_INTERRUPT_DATA_STORAGE); - } - - break; - } - default: - emulated = EMULATE_FAIL; - } - break; - default: - emulated = EMULATE_FAIL; - } - - if (emulated == EMULATE_FAIL) - emulated = kvmppc_emulate_paired_single(run, vcpu); - - return emulated; -} - -void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper, - u32 val) -{ - if (upper) { - /* Upper BAT */ - u32 bl = (val >> 2) & 0x7ff; - bat->bepi_mask = (~bl << 17); - bat->bepi = val & 0xfffe0000; - bat->vs = (val & 2) ? 1 : 0; - bat->vp = (val & 1) ? 1 : 0; - bat->raw = (bat->raw & 0xffffffff00000000ULL) | val; - } else { - /* Lower BAT */ - bat->brpn = val & 0xfffe0000; - bat->wimg = (val >> 3) & 0xf; - bat->pp = val & 3; - bat->raw = (bat->raw & 0x00000000ffffffffULL) | ((u64)val << 32); - } -} - -static u32 kvmppc_read_bat(struct kvm_vcpu *vcpu, int sprn) -{ - struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); - struct kvmppc_bat *bat; - - switch (sprn) { - case SPRN_IBAT0U ... SPRN_IBAT3L: - bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2]; - break; - case SPRN_IBAT4U ... SPRN_IBAT7L: - bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)]; - break; - case SPRN_DBAT0U ... SPRN_DBAT3L: - bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2]; - break; - case SPRN_DBAT4U ... SPRN_DBAT7L: - bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)]; - break; - default: - BUG(); - } - - if (sprn % 2) - return bat->raw >> 32; - else - return bat->raw; -} - -static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val) -{ - struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); - struct kvmppc_bat *bat; - - switch (sprn) { - case SPRN_IBAT0U ... SPRN_IBAT3L: - bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2]; - break; - case SPRN_IBAT4U ... SPRN_IBAT7L: - bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)]; - break; - case SPRN_DBAT0U ... SPRN_DBAT3L: - bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2]; - break; - case SPRN_DBAT4U ... SPRN_DBAT7L: - bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)]; - break; - default: - BUG(); - } - - kvmppc_set_bat(vcpu, bat, !(sprn % 2), val); -} - -int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) -{ - int emulated = EMULATE_DONE; - ulong spr_val = kvmppc_get_gpr(vcpu, rs); - - switch (sprn) { - case SPRN_SDR1: - to_book3s(vcpu)->sdr1 = spr_val; - break; - case SPRN_DSISR: - to_book3s(vcpu)->dsisr = spr_val; - break; - case SPRN_DAR: - vcpu->arch.dear = spr_val; - break; - case SPRN_HIOR: - to_book3s(vcpu)->hior = spr_val; - break; - case SPRN_IBAT0U ... SPRN_IBAT3L: - case SPRN_IBAT4U ... SPRN_IBAT7L: - case SPRN_DBAT0U ... SPRN_DBAT3L: - case SPRN_DBAT4U ... SPRN_DBAT7L: - kvmppc_write_bat(vcpu, sprn, (u32)spr_val); - /* BAT writes happen so rarely that we're ok to flush - * everything here */ - kvmppc_mmu_pte_flush(vcpu, 0, 0); - kvmppc_mmu_flush_segments(vcpu); - break; - case SPRN_HID0: - to_book3s(vcpu)->hid[0] = spr_val; - break; - case SPRN_HID1: - to_book3s(vcpu)->hid[1] = spr_val; - break; - case SPRN_HID2: - to_book3s(vcpu)->hid[2] = spr_val; - break; - case SPRN_HID2_GEKKO: - to_book3s(vcpu)->hid[2] = spr_val; - /* HID2.PSE controls paired single on gekko */ - switch (vcpu->arch.pvr) { - case 0x00080200: /* lonestar 2.0 */ - case 0x00088202: /* lonestar 2.2 */ - case 0x70000100: /* gekko 1.0 */ - case 0x00080100: /* gekko 2.0 */ - case 0x00083203: /* gekko 2.3a */ - case 0x00083213: /* gekko 2.3b */ - case 0x00083204: /* gekko 2.4 */ - case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */ - if (spr_val & (1 << 29)) { /* HID2.PSE */ - vcpu->arch.hflags |= BOOK3S_HFLAG_PAIRED_SINGLE; - kvmppc_giveup_ext(vcpu, MSR_FP); - } else { - vcpu->arch.hflags &= ~BOOK3S_HFLAG_PAIRED_SINGLE; - } - break; - } - break; - case SPRN_HID4: - case SPRN_HID4_GEKKO: - to_book3s(vcpu)->hid[4] = spr_val; - break; - case SPRN_HID5: - to_book3s(vcpu)->hid[5] = spr_val; - /* guest HID5 set can change is_dcbz32 */ - if (vcpu->arch.mmu.is_dcbz32(vcpu) && - (mfmsr() & MSR_HV)) - vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; - break; - case SPRN_GQR0: - case SPRN_GQR1: - case SPRN_GQR2: - case SPRN_GQR3: - case SPRN_GQR4: - case SPRN_GQR5: - case SPRN_GQR6: - case SPRN_GQR7: - to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val; - break; - case SPRN_ICTC: - case SPRN_THRM1: - case SPRN_THRM2: - case SPRN_THRM3: - case SPRN_CTRLF: - case SPRN_CTRLT: - case SPRN_L2CR: - case SPRN_MMCR0_GEKKO: - case SPRN_MMCR1_GEKKO: - case SPRN_PMC1_GEKKO: - case SPRN_PMC2_GEKKO: - case SPRN_PMC3_GEKKO: - case SPRN_PMC4_GEKKO: - case SPRN_WPAR_GEKKO: - break; - default: - printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn); -#ifndef DEBUG_SPR - emulated = EMULATE_FAIL; -#endif - break; - } - - return emulated; -} - -int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) -{ - int emulated = EMULATE_DONE; - - switch (sprn) { - case SPRN_IBAT0U ... SPRN_IBAT3L: - case SPRN_IBAT4U ... SPRN_IBAT7L: - case SPRN_DBAT0U ... SPRN_DBAT3L: - case SPRN_DBAT4U ... SPRN_DBAT7L: - kvmppc_set_gpr(vcpu, rt, kvmppc_read_bat(vcpu, sprn)); - break; - case SPRN_SDR1: - kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1); - break; - case SPRN_DSISR: - kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->dsisr); - break; - case SPRN_DAR: - kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear); - break; - case SPRN_HIOR: - kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hior); - break; - case SPRN_HID0: - kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[0]); - break; - case SPRN_HID1: - kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[1]); - break; - case SPRN_HID2: - case SPRN_HID2_GEKKO: - kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[2]); - break; - case SPRN_HID4: - case SPRN_HID4_GEKKO: - kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[4]); - break; - case SPRN_HID5: - kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[5]); - break; - case SPRN_GQR0: - case SPRN_GQR1: - case SPRN_GQR2: - case SPRN_GQR3: - case SPRN_GQR4: - case SPRN_GQR5: - case SPRN_GQR6: - case SPRN_GQR7: - kvmppc_set_gpr(vcpu, rt, - to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]); - break; - case SPRN_THRM1: - case SPRN_THRM2: - case SPRN_THRM3: - case SPRN_CTRLF: - case SPRN_CTRLT: - case SPRN_L2CR: - case SPRN_MMCR0_GEKKO: - case SPRN_MMCR1_GEKKO: - case SPRN_PMC1_GEKKO: - case SPRN_PMC2_GEKKO: - case SPRN_PMC3_GEKKO: - case SPRN_PMC4_GEKKO: - case SPRN_WPAR_GEKKO: - kvmppc_set_gpr(vcpu, rt, 0); - break; - default: - printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn); -#ifndef DEBUG_SPR - emulated = EMULATE_FAIL; -#endif - break; - } - - return emulated; -} - -u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst) -{ - u32 dsisr = 0; - - /* - * This is what the spec says about DSISR bits (not mentioned = 0): - * - * 12:13 [DS] Set to bits 30:31 - * 15:16 [X] Set to bits 29:30 - * 17 [X] Set to bit 25 - * [D/DS] Set to bit 5 - * 18:21 [X] Set to bits 21:24 - * [D/DS] Set to bits 1:4 - * 22:26 Set to bits 6:10 (RT/RS/FRT/FRS) - * 27:31 Set to bits 11:15 (RA) - */ - - switch (get_op(inst)) { - /* D-form */ - case OP_LFS: - case OP_LFD: - case OP_STFD: - case OP_STFS: - dsisr |= (inst >> 12) & 0x4000; /* bit 17 */ - dsisr |= (inst >> 17) & 0x3c00; /* bits 18:21 */ - break; - /* X-form */ - case 31: - dsisr |= (inst << 14) & 0x18000; /* bits 15:16 */ - dsisr |= (inst << 8) & 0x04000; /* bit 17 */ - dsisr |= (inst << 3) & 0x03c00; /* bits 18:21 */ - break; - default: - printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst); - break; - } - - dsisr |= (inst >> 16) & 0x03ff; /* bits 22:31 */ - - return dsisr; -} - -ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst) -{ - ulong dar = 0; - ulong ra; - - switch (get_op(inst)) { - case OP_LFS: - case OP_LFD: - case OP_STFD: - case OP_STFS: - ra = get_ra(inst); - if (ra) - dar = kvmppc_get_gpr(vcpu, ra); - dar += (s32)((s16)inst); - break; - case 31: - ra = get_ra(inst); - if (ra) - dar = kvmppc_get_gpr(vcpu, ra); - dar += kvmppc_get_gpr(vcpu, get_rb(inst)); - break; - default: - printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst); - break; - } - - return dar; -} diff --git a/arch/powerpc/kvm/book3s_64_exports.c b/arch/powerpc/kvm/book3s_64_exports.c deleted file mode 100644 index 1dd5a1ddfd0d..000000000000 --- a/arch/powerpc/kvm/book3s_64_exports.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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. - * - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright SUSE Linux Products GmbH 2009 - * - * Authors: Alexander Graf - */ - -#include -#include - -EXPORT_SYMBOL_GPL(kvmppc_trampoline_enter); -EXPORT_SYMBOL_GPL(kvmppc_trampoline_lowmem); -EXPORT_SYMBOL_GPL(kvmppc_rmcall); -EXPORT_SYMBOL_GPL(kvmppc_load_up_fpu); -#ifdef CONFIG_ALTIVEC -EXPORT_SYMBOL_GPL(kvmppc_load_up_altivec); -#endif -#ifdef CONFIG_VSX -EXPORT_SYMBOL_GPL(kvmppc_load_up_vsx); -#endif diff --git a/arch/powerpc/kvm/book3s_64_interrupts.S b/arch/powerpc/kvm/book3s_64_interrupts.S deleted file mode 100644 index faca87610d65..000000000000 --- a/arch/powerpc/kvm/book3s_64_interrupts.S +++ /dev/null @@ -1,318 +0,0 @@ -/* - * 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. - * - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright SUSE Linux Products GmbH 2009 - * - * Authors: Alexander Graf - */ - -#include -#include -#include -#include -#include -#include - -#define KVMPPC_HANDLE_EXIT .kvmppc_handle_exit -#define ULONG_SIZE 8 -#define VCPU_GPR(n) (VCPU_GPRS + (n * ULONG_SIZE)) - -.macro DISABLE_INTERRUPTS - mfmsr r0 - rldicl r0,r0,48,1 - rotldi r0,r0,16 - mtmsrd r0,1 -.endm - -#define VCPU_LOAD_NVGPRS(vcpu) \ - ld r14, VCPU_GPR(r14)(vcpu); \ - ld r15, VCPU_GPR(r15)(vcpu); \ - ld r16, VCPU_GPR(r16)(vcpu); \ - ld r17, VCPU_GPR(r17)(vcpu); \ - ld r18, VCPU_GPR(r18)(vcpu); \ - ld r19, VCPU_GPR(r19)(vcpu); \ - ld r20, VCPU_GPR(r20)(vcpu); \ - ld r21, VCPU_GPR(r21)(vcpu); \ - ld r22, VCPU_GPR(r22)(vcpu); \ - ld r23, VCPU_GPR(r23)(vcpu); \ - ld r24, VCPU_GPR(r24)(vcpu); \ - ld r25, VCPU_GPR(r25)(vcpu); \ - ld r26, VCPU_GPR(r26)(vcpu); \ - ld r27, VCPU_GPR(r27)(vcpu); \ - ld r28, VCPU_GPR(r28)(vcpu); \ - ld r29, VCPU_GPR(r29)(vcpu); \ - ld r30, VCPU_GPR(r30)(vcpu); \ - ld r31, VCPU_GPR(r31)(vcpu); \ - -/***************************************************************************** - * * - * Guest entry / exit code that is in kernel module memory (highmem) * - * * - ****************************************************************************/ - -/* Registers: - * r3: kvm_run pointer - * r4: vcpu pointer - */ -_GLOBAL(__kvmppc_vcpu_entry) - -kvm_start_entry: - /* Write correct stack frame */ - mflr r0 - std r0,16(r1) - - /* Save host state to the stack */ - stdu r1, -SWITCH_FRAME_SIZE(r1) - - /* Save r3 (kvm_run) and r4 (vcpu) */ - SAVE_2GPRS(3, r1) - - /* Save non-volatile registers (r14 - r31) */ - SAVE_NVGPRS(r1) - - /* Save LR */ - std r0, _LINK(r1) - - /* Load non-volatile guest state from the vcpu */ - VCPU_LOAD_NVGPRS(r4) - - /* Save R1/R2 in the PACA */ - std r1, PACA_KVM_HOST_R1(r13) - std r2, PACA_KVM_HOST_R2(r13) - - /* XXX swap in/out on load? */ - ld r3, VCPU_HIGHMEM_HANDLER(r4) - std r3, PACA_KVM_VMHANDLER(r13) - -kvm_start_lightweight: - - ld r9, VCPU_PC(r4) /* r9 = vcpu->arch.pc */ - ld r10, VCPU_SHADOW_MSR(r4) /* r10 = vcpu->arch.shadow_msr */ - - /* Load some guest state in the respective registers */ - ld r5, VCPU_CTR(r4) /* r5 = vcpu->arch.ctr */ - /* will be swapped in by rmcall */ - - ld r3, VCPU_LR(r4) /* r3 = vcpu->arch.lr */ - mtlr r3 /* LR = r3 */ - - DISABLE_INTERRUPTS - - /* Some guests may need to have dcbz set to 32 byte length. - * - * Usually we ensure that by patching the guest's instructions - * to trap on dcbz and emulate it in the hypervisor. - * - * If we can, we should tell the CPU to use 32 byte dcbz though, - * because that's a lot faster. - */ - - ld r3, VCPU_HFLAGS(r4) - rldicl. r3, r3, 0, 63 /* CR = ((r3 & 1) == 0) */ - beq no_dcbz32_on - - mfspr r3,SPRN_HID5 - ori r3, r3, 0x80 /* XXX HID5_dcbz32 = 0x80 */ - mtspr SPRN_HID5,r3 - -no_dcbz32_on: - - ld r6, VCPU_RMCALL(r4) - mtctr r6 - - ld r3, VCPU_TRAMPOLINE_ENTER(r4) - LOAD_REG_IMMEDIATE(r4, MSR_KERNEL & ~(MSR_IR | MSR_DR)) - - /* Jump to SLB patching handlder and into our guest */ - bctr - -/* - * This is the handler in module memory. It gets jumped at from the - * lowmem trampoline code, so it's basically the guest exit code. - * - */ - -.global kvmppc_handler_highmem -kvmppc_handler_highmem: - - /* - * Register usage at this point: - * - * R0 = guest last inst - * R1 = host R1 - * R2 = host R2 - * R3 = guest PC - * R4 = guest MSR - * R5 = guest DAR - * R6 = guest DSISR - * R13 = PACA - * PACA.KVM.* = guest * - * - */ - - /* R7 = vcpu */ - ld r7, GPR4(r1) - - /* Now save the guest state */ - - stw r0, VCPU_LAST_INST(r7) - - std r3, VCPU_PC(r7) - std r4, VCPU_SHADOW_SRR1(r7) - std r5, VCPU_FAULT_DEAR(r7) - stw r6, VCPU_FAULT_DSISR(r7) - - ld r5, VCPU_HFLAGS(r7) - rldicl. r5, r5, 0, 63 /* CR = ((r5 & 1) == 0) */ - beq no_dcbz32_off - - li r4, 0 - mfspr r5,SPRN_HID5 - rldimi r5,r4,6,56 - mtspr SPRN_HID5,r5 - -no_dcbz32_off: - - std r14, VCPU_GPR(r14)(r7) - std r15, VCPU_GPR(r15)(r7) - std r16, VCPU_GPR(r16)(r7) - std r17, VCPU_GPR(r17)(r7) - std r18, VCPU_GPR(r18)(r7) - std r19, VCPU_GPR(r19)(r7) - std r20, VCPU_GPR(r20)(r7) - std r21, VCPU_GPR(r21)(r7) - std r22, VCPU_GPR(r22)(r7) - std r23, VCPU_GPR(r23)(r7) - std r24, VCPU_GPR(r24)(r7) - std r25, VCPU_GPR(r25)(r7) - std r26, VCPU_GPR(r26)(r7) - std r27, VCPU_GPR(r27)(r7) - std r28, VCPU_GPR(r28)(r7) - std r29, VCPU_GPR(r29)(r7) - std r30, VCPU_GPR(r30)(r7) - std r31, VCPU_GPR(r31)(r7) - - /* Save guest CTR */ - mfctr r5 - std r5, VCPU_CTR(r7) - - /* Save guest LR */ - mflr r5 - std r5, VCPU_LR(r7) - - /* Restore host msr -> SRR1 */ - ld r6, VCPU_HOST_MSR(r7) - - /* - * For some interrupts, we need to call the real Linux - * handler, so it can do work for us. This has to happen - * as if the interrupt arrived from the kernel though, - * so let's fake it here where most state is restored. - * - * Call Linux for hardware interrupts/decrementer - * r3 = address of interrupt handler (exit reason) - */ - - cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL - beq call_linux_handler - cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER - beq call_linux_handler - - /* Back to EE=1 */ - mtmsr r6 - b kvm_return_point - -call_linux_handler: - - /* - * If we land here we need to jump back to the handler we - * came from. - * - * We have a page that we can access from real mode, so let's - * jump back to that and use it as a trampoline to get back into the - * interrupt handler! - * - * R3 still contains the exit code, - * R5 VCPU_HOST_RETIP and - * R6 VCPU_HOST_MSR - */ - - /* Restore host IP -> SRR0 */ - ld r5, VCPU_HOST_RETIP(r7) - - /* XXX Better move to a safe function? - * What if we get an HTAB flush in between mtsrr0 and mtsrr1? */ - - mtlr r12 - - ld r4, VCPU_TRAMPOLINE_LOWMEM(r7) - mtsrr0 r4 - LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR)) - mtsrr1 r3 - - RFI - -.global kvm_return_point -kvm_return_point: - - /* Jump back to lightweight entry if we're supposed to */ - /* go back into the guest */ - - /* Pass the exit number as 3rd argument to kvmppc_handle_exit */ - mr r5, r12 - - /* Restore r3 (kvm_run) and r4 (vcpu) */ - REST_2GPRS(3, r1) - bl KVMPPC_HANDLE_EXIT - - /* If RESUME_GUEST, get back in the loop */ - cmpwi r3, RESUME_GUEST - beq kvm_loop_lightweight - - cmpwi r3, RESUME_GUEST_NV - beq kvm_loop_heavyweight - -kvm_exit_loop: - - ld r4, _LINK(r1) - mtlr r4 - - /* Restore non-volatile host registers (r14 - r31) */ - REST_NVGPRS(r1) - - addi r1, r1, SWITCH_FRAME_SIZE - blr - -kvm_loop_heavyweight: - - ld r4, _LINK(r1) - std r4, (16 + SWITCH_FRAME_SIZE)(r1) - - /* Load vcpu and cpu_run */ - REST_2GPRS(3, r1) - - /* Load non-volatile guest state from the vcpu */ - VCPU_LOAD_NVGPRS(r4) - - /* Jump back into the beginning of this function */ - b kvm_start_lightweight - -kvm_loop_lightweight: - - /* We'll need the vcpu pointer */ - REST_GPR(4, r1) - - /* Jump back into the beginning of this function */ - b kvm_start_lightweight - diff --git a/arch/powerpc/kvm/book3s_64_rmhandlers.S b/arch/powerpc/kvm/book3s_64_rmhandlers.S deleted file mode 100644 index bd08535fcdc8..000000000000 --- a/arch/powerpc/kvm/book3s_64_rmhandlers.S +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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. - * - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright SUSE Linux Products GmbH 2009 - * - * Authors: Alexander Graf - */ - -#include -#include -#include -#include -#include -#include - -/***************************************************************************** - * * - * Real Mode handlers that need to be in low physical memory * - * * - ****************************************************************************/ - - -.macro INTERRUPT_TRAMPOLINE intno - -.global kvmppc_trampoline_\intno -kvmppc_trampoline_\intno: - - mtspr SPRN_SPRG_SCRATCH0, r13 /* Save r13 */ - - /* - * First thing to do is to find out if we're coming - * from a KVM guest or a Linux process. - * - * To distinguish, we check a magic byte in the PACA - */ - mfspr r13, SPRN_SPRG_PACA /* r13 = PACA */ - std r12, PACA_KVM_SCRATCH0(r13) - mfcr r12 - stw r12, PACA_KVM_SCRATCH1(r13) - lbz r12, PACA_KVM_IN_GUEST(r13) - cmpwi r12, KVM_GUEST_MODE_NONE - bne ..kvmppc_handler_hasmagic_\intno - /* No KVM guest? Then jump back to the Linux handler! */ - lwz r12, PACA_KVM_SCRATCH1(r13) - mtcr r12 - ld r12, PACA_KVM_SCRATCH0(r13) - mfspr r13, SPRN_SPRG_SCRATCH0 /* r13 = original r13 */ - b kvmppc_resume_\intno /* Get back original handler */ - - /* Now we know we're handling a KVM guest */ -..kvmppc_handler_hasmagic_\intno: - - /* Should we just skip the faulting instruction? */ - cmpwi r12, KVM_GUEST_MODE_SKIP - beq kvmppc_handler_skip_ins - - /* Let's store which interrupt we're handling */ - li r12, \intno - - /* Jump into the SLB exit code that goes to the highmem handler */ - b kvmppc_handler_trampoline_exit - -.endm - -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSTEM_RESET -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_MACHINE_CHECK -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_STORAGE -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_SEGMENT -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_STORAGE -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_SEGMENT -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_EXTERNAL -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALIGNMENT -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PROGRAM -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_FP_UNAVAIL -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DECREMENTER -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSCALL -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_TRACE -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PERFMON -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALTIVEC -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_VSX - -/* - * Bring us back to the faulting code, but skip the - * faulting instruction. - * - * This is a generic exit path from the interrupt - * trampolines above. - * - * Input Registers: - * - * R12 = free - * R13 = PACA - * PACA.KVM.SCRATCH0 = guest R12 - * PACA.KVM.SCRATCH1 = guest CR - * SPRG_SCRATCH0 = guest R13 - * - */ -kvmppc_handler_skip_ins: - - /* Patch the IP to the next instruction */ - mfsrr0 r12 - addi r12, r12, 4 - mtsrr0 r12 - - /* Clean up all state */ - lwz r12, PACA_KVM_SCRATCH1(r13) - mtcr r12 - ld r12, PACA_KVM_SCRATCH0(r13) - mfspr r13, SPRN_SPRG_SCRATCH0 - - /* And get back into the code */ - RFI - -/* - * This trampoline brings us back to a real mode handler - * - * Input Registers: - * - * R5 = SRR0 - * R6 = SRR1 - * LR = real-mode IP - * - */ -.global kvmppc_handler_lowmem_trampoline -kvmppc_handler_lowmem_trampoline: - - mtsrr0 r5 - mtsrr1 r6 - blr -kvmppc_handler_lowmem_trampoline_end: - -/* - * Call a function in real mode - * - * Input Registers: - * - * R3 = function - * R4 = MSR - * R5 = CTR - * - */ -_GLOBAL(kvmppc_rmcall) - mtmsr r4 /* Disable relocation, so mtsrr - doesn't get interrupted */ - mtctr r5 - mtsrr0 r3 - mtsrr1 r4 - RFI - -/* - * Activate current's external feature (FPU/Altivec/VSX) - */ -#define define_load_up(what) \ - \ -_GLOBAL(kvmppc_load_up_ ## what); \ - stdu r1, -INT_FRAME_SIZE(r1); \ - mflr r3; \ - std r3, _LINK(r1); \ - \ - bl .load_up_ ## what; \ - \ - ld r3, _LINK(r1); \ - mtlr r3; \ - addi r1, r1, INT_FRAME_SIZE; \ - blr - -define_load_up(fpu) -#ifdef CONFIG_ALTIVEC -define_load_up(altivec) -#endif -#ifdef CONFIG_VSX -define_load_up(vsx) -#endif - -.global kvmppc_trampoline_lowmem -kvmppc_trampoline_lowmem: - .long kvmppc_handler_lowmem_trampoline - _stext - -.global kvmppc_trampoline_enter -kvmppc_trampoline_enter: - .long kvmppc_handler_trampoline_enter - _stext - -#include "book3s_64_slb.S" - diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c new file mode 100644 index 000000000000..8f50776a9a1d --- /dev/null +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -0,0 +1,566 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2009 + * + * Authors: Alexander Graf + */ + +#include +#include +#include +#include + +#define OP_19_XOP_RFID 18 +#define OP_19_XOP_RFI 50 + +#define OP_31_XOP_MFMSR 83 +#define OP_31_XOP_MTMSR 146 +#define OP_31_XOP_MTMSRD 178 +#define OP_31_XOP_MTSR 210 +#define OP_31_XOP_MTSRIN 242 +#define OP_31_XOP_TLBIEL 274 +#define OP_31_XOP_TLBIE 306 +#define OP_31_XOP_SLBMTE 402 +#define OP_31_XOP_SLBIE 434 +#define OP_31_XOP_SLBIA 498 +#define OP_31_XOP_MFSR 595 +#define OP_31_XOP_MFSRIN 659 +#define OP_31_XOP_DCBA 758 +#define OP_31_XOP_SLBMFEV 851 +#define OP_31_XOP_EIOIO 854 +#define OP_31_XOP_SLBMFEE 915 + +/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */ +#define OP_31_XOP_DCBZ 1010 + +#define OP_LFS 48 +#define OP_LFD 50 +#define OP_STFS 52 +#define OP_STFD 54 + +#define SPRN_GQR0 912 +#define SPRN_GQR1 913 +#define SPRN_GQR2 914 +#define SPRN_GQR3 915 +#define SPRN_GQR4 916 +#define SPRN_GQR5 917 +#define SPRN_GQR6 918 +#define SPRN_GQR7 919 + +int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int inst, int *advance) +{ + int emulated = EMULATE_DONE; + + switch (get_op(inst)) { + case 19: + switch (get_xop(inst)) { + case OP_19_XOP_RFID: + case OP_19_XOP_RFI: + vcpu->arch.pc = vcpu->arch.srr0; + kvmppc_set_msr(vcpu, vcpu->arch.srr1); + *advance = 0; + break; + + default: + emulated = EMULATE_FAIL; + break; + } + break; + case 31: + switch (get_xop(inst)) { + case OP_31_XOP_MFMSR: + kvmppc_set_gpr(vcpu, get_rt(inst), vcpu->arch.msr); + break; + case OP_31_XOP_MTMSRD: + { + ulong rs = kvmppc_get_gpr(vcpu, get_rs(inst)); + if (inst & 0x10000) { + vcpu->arch.msr &= ~(MSR_RI | MSR_EE); + vcpu->arch.msr |= rs & (MSR_RI | MSR_EE); + } else + kvmppc_set_msr(vcpu, rs); + break; + } + case OP_31_XOP_MTMSR: + kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, get_rs(inst))); + break; + case OP_31_XOP_MFSR: + { + int srnum; + + srnum = kvmppc_get_field(inst, 12 + 32, 15 + 32); + if (vcpu->arch.mmu.mfsrin) { + u32 sr; + sr = vcpu->arch.mmu.mfsrin(vcpu, srnum); + kvmppc_set_gpr(vcpu, get_rt(inst), sr); + } + break; + } + case OP_31_XOP_MFSRIN: + { + int srnum; + + srnum = (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf; + if (vcpu->arch.mmu.mfsrin) { + u32 sr; + sr = vcpu->arch.mmu.mfsrin(vcpu, srnum); + kvmppc_set_gpr(vcpu, get_rt(inst), sr); + } + break; + } + case OP_31_XOP_MTSR: + vcpu->arch.mmu.mtsrin(vcpu, + (inst >> 16) & 0xf, + kvmppc_get_gpr(vcpu, get_rs(inst))); + break; + case OP_31_XOP_MTSRIN: + vcpu->arch.mmu.mtsrin(vcpu, + (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf, + kvmppc_get_gpr(vcpu, get_rs(inst))); + break; + case OP_31_XOP_TLBIE: + case OP_31_XOP_TLBIEL: + { + bool large = (inst & 0x00200000) ? true : false; + ulong addr = kvmppc_get_gpr(vcpu, get_rb(inst)); + vcpu->arch.mmu.tlbie(vcpu, addr, large); + break; + } + case OP_31_XOP_EIOIO: + break; + case OP_31_XOP_SLBMTE: + if (!vcpu->arch.mmu.slbmte) + return EMULATE_FAIL; + + vcpu->arch.mmu.slbmte(vcpu, + kvmppc_get_gpr(vcpu, get_rs(inst)), + kvmppc_get_gpr(vcpu, get_rb(inst))); + break; + case OP_31_XOP_SLBIE: + if (!vcpu->arch.mmu.slbie) + return EMULATE_FAIL; + + vcpu->arch.mmu.slbie(vcpu, + kvmppc_get_gpr(vcpu, get_rb(inst))); + break; + case OP_31_XOP_SLBIA: + if (!vcpu->arch.mmu.slbia) + return EMULATE_FAIL; + + vcpu->arch.mmu.slbia(vcpu); + break; + case OP_31_XOP_SLBMFEE: + if (!vcpu->arch.mmu.slbmfee) { + emulated = EMULATE_FAIL; + } else { + ulong t, rb; + + rb = kvmppc_get_gpr(vcpu, get_rb(inst)); + t = vcpu->arch.mmu.slbmfee(vcpu, rb); + kvmppc_set_gpr(vcpu, get_rt(inst), t); + } + break; + case OP_31_XOP_SLBMFEV: + if (!vcpu->arch.mmu.slbmfev) { + emulated = EMULATE_FAIL; + } else { + ulong t, rb; + + rb = kvmppc_get_gpr(vcpu, get_rb(inst)); + t = vcpu->arch.mmu.slbmfev(vcpu, rb); + kvmppc_set_gpr(vcpu, get_rt(inst), t); + } + break; + case OP_31_XOP_DCBA: + /* Gets treated as NOP */ + break; + case OP_31_XOP_DCBZ: + { + ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst)); + ulong ra = 0; + ulong addr, vaddr; + u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + u32 dsisr; + int r; + + if (get_ra(inst)) + ra = kvmppc_get_gpr(vcpu, get_ra(inst)); + + addr = (ra + rb) & ~31ULL; + if (!(vcpu->arch.msr & MSR_SF)) + addr &= 0xffffffff; + vaddr = addr; + + r = kvmppc_st(vcpu, &addr, 32, zeros, true); + if ((r == -ENOENT) || (r == -EPERM)) { + *advance = 0; + vcpu->arch.dear = vaddr; + vcpu->arch.fault_dear = vaddr; + + dsisr = DSISR_ISSTORE; + if (r == -ENOENT) + dsisr |= DSISR_NOHPTE; + else if (r == -EPERM) + dsisr |= DSISR_PROTFAULT; + + to_book3s(vcpu)->dsisr = dsisr; + vcpu->arch.fault_dsisr = dsisr; + + kvmppc_book3s_queue_irqprio(vcpu, + BOOK3S_INTERRUPT_DATA_STORAGE); + } + + break; + } + default: + emulated = EMULATE_FAIL; + } + break; + default: + emulated = EMULATE_FAIL; + } + + if (emulated == EMULATE_FAIL) + emulated = kvmppc_emulate_paired_single(run, vcpu); + + return emulated; +} + +void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper, + u32 val) +{ + if (upper) { + /* Upper BAT */ + u32 bl = (val >> 2) & 0x7ff; + bat->bepi_mask = (~bl << 17); + bat->bepi = val & 0xfffe0000; + bat->vs = (val & 2) ? 1 : 0; + bat->vp = (val & 1) ? 1 : 0; + bat->raw = (bat->raw & 0xffffffff00000000ULL) | val; + } else { + /* Lower BAT */ + bat->brpn = val & 0xfffe0000; + bat->wimg = (val >> 3) & 0xf; + bat->pp = val & 3; + bat->raw = (bat->raw & 0x00000000ffffffffULL) | ((u64)val << 32); + } +} + +static u32 kvmppc_read_bat(struct kvm_vcpu *vcpu, int sprn) +{ + struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); + struct kvmppc_bat *bat; + + switch (sprn) { + case SPRN_IBAT0U ... SPRN_IBAT3L: + bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2]; + break; + case SPRN_IBAT4U ... SPRN_IBAT7L: + bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)]; + break; + case SPRN_DBAT0U ... SPRN_DBAT3L: + bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2]; + break; + case SPRN_DBAT4U ... SPRN_DBAT7L: + bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)]; + break; + default: + BUG(); + } + + if (sprn % 2) + return bat->raw >> 32; + else + return bat->raw; +} + +static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val) +{ + struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); + struct kvmppc_bat *bat; + + switch (sprn) { + case SPRN_IBAT0U ... SPRN_IBAT3L: + bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2]; + break; + case SPRN_IBAT4U ... SPRN_IBAT7L: + bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)]; + break; + case SPRN_DBAT0U ... SPRN_DBAT3L: + bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2]; + break; + case SPRN_DBAT4U ... SPRN_DBAT7L: + bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)]; + break; + default: + BUG(); + } + + kvmppc_set_bat(vcpu, bat, !(sprn % 2), val); +} + +int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) +{ + int emulated = EMULATE_DONE; + ulong spr_val = kvmppc_get_gpr(vcpu, rs); + + switch (sprn) { + case SPRN_SDR1: + to_book3s(vcpu)->sdr1 = spr_val; + break; + case SPRN_DSISR: + to_book3s(vcpu)->dsisr = spr_val; + break; + case SPRN_DAR: + vcpu->arch.dear = spr_val; + break; + case SPRN_HIOR: + to_book3s(vcpu)->hior = spr_val; + break; + case SPRN_IBAT0U ... SPRN_IBAT3L: + case SPRN_IBAT4U ... SPRN_IBAT7L: + case SPRN_DBAT0U ... SPRN_DBAT3L: + case SPRN_DBAT4U ... SPRN_DBAT7L: + kvmppc_write_bat(vcpu, sprn, (u32)spr_val); + /* BAT writes happen so rarely that we're ok to flush + * everything here */ + kvmppc_mmu_pte_flush(vcpu, 0, 0); + kvmppc_mmu_flush_segments(vcpu); + break; + case SPRN_HID0: + to_book3s(vcpu)->hid[0] = spr_val; + break; + case SPRN_HID1: + to_book3s(vcpu)->hid[1] = spr_val; + break; + case SPRN_HID2: + to_book3s(vcpu)->hid[2] = spr_val; + break; + case SPRN_HID2_GEKKO: + to_book3s(vcpu)->hid[2] = spr_val; + /* HID2.PSE controls paired single on gekko */ + switch (vcpu->arch.pvr) { + case 0x00080200: /* lonestar 2.0 */ + case 0x00088202: /* lonestar 2.2 */ + case 0x70000100: /* gekko 1.0 */ + case 0x00080100: /* gekko 2.0 */ + case 0x00083203: /* gekko 2.3a */ + case 0x00083213: /* gekko 2.3b */ + case 0x00083204: /* gekko 2.4 */ + case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */ + if (spr_val & (1 << 29)) { /* HID2.PSE */ + vcpu->arch.hflags |= BOOK3S_HFLAG_PAIRED_SINGLE; + kvmppc_giveup_ext(vcpu, MSR_FP); + } else { + vcpu->arch.hflags &= ~BOOK3S_HFLAG_PAIRED_SINGLE; + } + break; + } + break; + case SPRN_HID4: + case SPRN_HID4_GEKKO: + to_book3s(vcpu)->hid[4] = spr_val; + break; + case SPRN_HID5: + to_book3s(vcpu)->hid[5] = spr_val; + /* guest HID5 set can change is_dcbz32 */ + if (vcpu->arch.mmu.is_dcbz32(vcpu) && + (mfmsr() & MSR_HV)) + vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; + break; + case SPRN_GQR0: + case SPRN_GQR1: + case SPRN_GQR2: + case SPRN_GQR3: + case SPRN_GQR4: + case SPRN_GQR5: + case SPRN_GQR6: + case SPRN_GQR7: + to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val; + break; + case SPRN_ICTC: + case SPRN_THRM1: + case SPRN_THRM2: + case SPRN_THRM3: + case SPRN_CTRLF: + case SPRN_CTRLT: + case SPRN_L2CR: + case SPRN_MMCR0_GEKKO: + case SPRN_MMCR1_GEKKO: + case SPRN_PMC1_GEKKO: + case SPRN_PMC2_GEKKO: + case SPRN_PMC3_GEKKO: + case SPRN_PMC4_GEKKO: + case SPRN_WPAR_GEKKO: + break; + default: + printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn); +#ifndef DEBUG_SPR + emulated = EMULATE_FAIL; +#endif + break; + } + + return emulated; +} + +int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) +{ + int emulated = EMULATE_DONE; + + switch (sprn) { + case SPRN_IBAT0U ... SPRN_IBAT3L: + case SPRN_IBAT4U ... SPRN_IBAT7L: + case SPRN_DBAT0U ... SPRN_DBAT3L: + case SPRN_DBAT4U ... SPRN_DBAT7L: + kvmppc_set_gpr(vcpu, rt, kvmppc_read_bat(vcpu, sprn)); + break; + case SPRN_SDR1: + kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1); + break; + case SPRN_DSISR: + kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->dsisr); + break; + case SPRN_DAR: + kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear); + break; + case SPRN_HIOR: + kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hior); + break; + case SPRN_HID0: + kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[0]); + break; + case SPRN_HID1: + kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[1]); + break; + case SPRN_HID2: + case SPRN_HID2_GEKKO: + kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[2]); + break; + case SPRN_HID4: + case SPRN_HID4_GEKKO: + kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[4]); + break; + case SPRN_HID5: + kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[5]); + break; + case SPRN_GQR0: + case SPRN_GQR1: + case SPRN_GQR2: + case SPRN_GQR3: + case SPRN_GQR4: + case SPRN_GQR5: + case SPRN_GQR6: + case SPRN_GQR7: + kvmppc_set_gpr(vcpu, rt, + to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]); + break; + case SPRN_THRM1: + case SPRN_THRM2: + case SPRN_THRM3: + case SPRN_CTRLF: + case SPRN_CTRLT: + case SPRN_L2CR: + case SPRN_MMCR0_GEKKO: + case SPRN_MMCR1_GEKKO: + case SPRN_PMC1_GEKKO: + case SPRN_PMC2_GEKKO: + case SPRN_PMC3_GEKKO: + case SPRN_PMC4_GEKKO: + case SPRN_WPAR_GEKKO: + kvmppc_set_gpr(vcpu, rt, 0); + break; + default: + printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn); +#ifndef DEBUG_SPR + emulated = EMULATE_FAIL; +#endif + break; + } + + return emulated; +} + +u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst) +{ + u32 dsisr = 0; + + /* + * This is what the spec says about DSISR bits (not mentioned = 0): + * + * 12:13 [DS] Set to bits 30:31 + * 15:16 [X] Set to bits 29:30 + * 17 [X] Set to bit 25 + * [D/DS] Set to bit 5 + * 18:21 [X] Set to bits 21:24 + * [D/DS] Set to bits 1:4 + * 22:26 Set to bits 6:10 (RT/RS/FRT/FRS) + * 27:31 Set to bits 11:15 (RA) + */ + + switch (get_op(inst)) { + /* D-form */ + case OP_LFS: + case OP_LFD: + case OP_STFD: + case OP_STFS: + dsisr |= (inst >> 12) & 0x4000; /* bit 17 */ + dsisr |= (inst >> 17) & 0x3c00; /* bits 18:21 */ + break; + /* X-form */ + case 31: + dsisr |= (inst << 14) & 0x18000; /* bits 15:16 */ + dsisr |= (inst << 8) & 0x04000; /* bit 17 */ + dsisr |= (inst << 3) & 0x03c00; /* bits 18:21 */ + break; + default: + printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst); + break; + } + + dsisr |= (inst >> 16) & 0x03ff; /* bits 22:31 */ + + return dsisr; +} + +ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst) +{ + ulong dar = 0; + ulong ra; + + switch (get_op(inst)) { + case OP_LFS: + case OP_LFD: + case OP_STFD: + case OP_STFS: + ra = get_ra(inst); + if (ra) + dar = kvmppc_get_gpr(vcpu, ra); + dar += (s32)((s16)inst); + break; + case 31: + ra = get_ra(inst); + if (ra) + dar = kvmppc_get_gpr(vcpu, ra); + dar += kvmppc_get_gpr(vcpu, get_rb(inst)); + break; + default: + printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst); + break; + } + + return dar; +} diff --git a/arch/powerpc/kvm/book3s_exports.c b/arch/powerpc/kvm/book3s_exports.c new file mode 100644 index 000000000000..1dd5a1ddfd0d --- /dev/null +++ b/arch/powerpc/kvm/book3s_exports.c @@ -0,0 +1,32 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2009 + * + * Authors: Alexander Graf + */ + +#include +#include + +EXPORT_SYMBOL_GPL(kvmppc_trampoline_enter); +EXPORT_SYMBOL_GPL(kvmppc_trampoline_lowmem); +EXPORT_SYMBOL_GPL(kvmppc_rmcall); +EXPORT_SYMBOL_GPL(kvmppc_load_up_fpu); +#ifdef CONFIG_ALTIVEC +EXPORT_SYMBOL_GPL(kvmppc_load_up_altivec); +#endif +#ifdef CONFIG_VSX +EXPORT_SYMBOL_GPL(kvmppc_load_up_vsx); +#endif diff --git a/arch/powerpc/kvm/book3s_interrupts.S b/arch/powerpc/kvm/book3s_interrupts.S new file mode 100644 index 000000000000..570f87407691 --- /dev/null +++ b/arch/powerpc/kvm/book3s_interrupts.S @@ -0,0 +1,317 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2009 + * + * Authors: Alexander Graf + */ + +#include +#include +#include +#include +#include +#include + +#define KVMPPC_HANDLE_EXIT .kvmppc_handle_exit +#define ULONG_SIZE 8 +#define VCPU_GPR(n) (VCPU_GPRS + (n * ULONG_SIZE)) + +.macro DISABLE_INTERRUPTS + mfmsr r0 + rldicl r0,r0,48,1 + rotldi r0,r0,16 + mtmsrd r0,1 +.endm + +#define VCPU_LOAD_NVGPRS(vcpu) \ + ld r14, VCPU_GPR(r14)(vcpu); \ + ld r15, VCPU_GPR(r15)(vcpu); \ + ld r16, VCPU_GPR(r16)(vcpu); \ + ld r17, VCPU_GPR(r17)(vcpu); \ + ld r18, VCPU_GPR(r18)(vcpu); \ + ld r19, VCPU_GPR(r19)(vcpu); \ + ld r20, VCPU_GPR(r20)(vcpu); \ + ld r21, VCPU_GPR(r21)(vcpu); \ + ld r22, VCPU_GPR(r22)(vcpu); \ + ld r23, VCPU_GPR(r23)(vcpu); \ + ld r24, VCPU_GPR(r24)(vcpu); \ + ld r25, VCPU_GPR(r25)(vcpu); \ + ld r26, VCPU_GPR(r26)(vcpu); \ + ld r27, VCPU_GPR(r27)(vcpu); \ + ld r28, VCPU_GPR(r28)(vcpu); \ + ld r29, VCPU_GPR(r29)(vcpu); \ + ld r30, VCPU_GPR(r30)(vcpu); \ + ld r31, VCPU_GPR(r31)(vcpu); \ + +/***************************************************************************** + * * + * Guest entry / exit code that is in kernel module memory (highmem) * + * * + ****************************************************************************/ + +/* Registers: + * r3: kvm_run pointer + * r4: vcpu pointer + */ +_GLOBAL(__kvmppc_vcpu_entry) + +kvm_start_entry: + /* Write correct stack frame */ + mflr r0 + std r0,16(r1) + + /* Save host state to the stack */ + stdu r1, -SWITCH_FRAME_SIZE(r1) + + /* Save r3 (kvm_run) and r4 (vcpu) */ + SAVE_2GPRS(3, r1) + + /* Save non-volatile registers (r14 - r31) */ + SAVE_NVGPRS(r1) + + /* Save LR */ + std r0, _LINK(r1) + + /* Load non-volatile guest state from the vcpu */ + VCPU_LOAD_NVGPRS(r4) + + /* Save R1/R2 in the PACA */ + std r1, PACA_KVM_HOST_R1(r13) + std r2, PACA_KVM_HOST_R2(r13) + + /* XXX swap in/out on load? */ + ld r3, VCPU_HIGHMEM_HANDLER(r4) + std r3, PACA_KVM_VMHANDLER(r13) + +kvm_start_lightweight: + + ld r9, VCPU_PC(r4) /* r9 = vcpu->arch.pc */ + ld r10, VCPU_SHADOW_MSR(r4) /* r10 = vcpu->arch.shadow_msr */ + + /* Load some guest state in the respective registers */ + ld r5, VCPU_CTR(r4) /* r5 = vcpu->arch.ctr */ + /* will be swapped in by rmcall */ + + ld r3, VCPU_LR(r4) /* r3 = vcpu->arch.lr */ + mtlr r3 /* LR = r3 */ + + DISABLE_INTERRUPTS + + /* Some guests may need to have dcbz set to 32 byte length. + * + * Usually we ensure that by patching the guest's instructions + * to trap on dcbz and emulate it in the hypervisor. + * + * If we can, we should tell the CPU to use 32 byte dcbz though, + * because that's a lot faster. + */ + + ld r3, VCPU_HFLAGS(r4) + rldicl. r3, r3, 0, 63 /* CR = ((r3 & 1) == 0) */ + beq no_dcbz32_on + + mfspr r3,SPRN_HID5 + ori r3, r3, 0x80 /* XXX HID5_dcbz32 = 0x80 */ + mtspr SPRN_HID5,r3 + +no_dcbz32_on: + + ld r6, VCPU_RMCALL(r4) + mtctr r6 + + ld r3, VCPU_TRAMPOLINE_ENTER(r4) + LOAD_REG_IMMEDIATE(r4, MSR_KERNEL & ~(MSR_IR | MSR_DR)) + + /* Jump to SLB patching handlder and into our guest */ + bctr + +/* + * This is the handler in module memory. It gets jumped at from the + * lowmem trampoline code, so it's basically the guest exit code. + * + */ + +.global kvmppc_handler_highmem +kvmppc_handler_highmem: + + /* + * Register usage at this point: + * + * R0 = guest last inst + * R1 = host R1 + * R2 = host R2 + * R3 = guest PC + * R4 = guest MSR + * R5 = guest DAR + * R6 = guest DSISR + * R13 = PACA + * PACA.KVM.* = guest * + * + */ + + /* R7 = vcpu */ + ld r7, GPR4(r1) + + /* Now save the guest state */ + + stw r0, VCPU_LAST_INST(r7) + + std r3, VCPU_PC(r7) + std r4, VCPU_SHADOW_SRR1(r7) + std r5, VCPU_FAULT_DEAR(r7) + stw r6, VCPU_FAULT_DSISR(r7) + + ld r5, VCPU_HFLAGS(r7) + rldicl. r5, r5, 0, 63 /* CR = ((r5 & 1) == 0) */ + beq no_dcbz32_off + + li r4, 0 + mfspr r5,SPRN_HID5 + rldimi r5,r4,6,56 + mtspr SPRN_HID5,r5 + +no_dcbz32_off: + + std r14, VCPU_GPR(r14)(r7) + std r15, VCPU_GPR(r15)(r7) + std r16, VCPU_GPR(r16)(r7) + std r17, VCPU_GPR(r17)(r7) + std r18, VCPU_GPR(r18)(r7) + std r19, VCPU_GPR(r19)(r7) + std r20, VCPU_GPR(r20)(r7) + std r21, VCPU_GPR(r21)(r7) + std r22, VCPU_GPR(r22)(r7) + std r23, VCPU_GPR(r23)(r7) + std r24, VCPU_GPR(r24)(r7) + std r25, VCPU_GPR(r25)(r7) + std r26, VCPU_GPR(r26)(r7) + std r27, VCPU_GPR(r27)(r7) + std r28, VCPU_GPR(r28)(r7) + std r29, VCPU_GPR(r29)(r7) + std r30, VCPU_GPR(r30)(r7) + std r31, VCPU_GPR(r31)(r7) + + /* Save guest CTR */ + mfctr r5 + std r5, VCPU_CTR(r7) + + /* Save guest LR */ + mflr r5 + std r5, VCPU_LR(r7) + + /* Restore host msr -> SRR1 */ + ld r6, VCPU_HOST_MSR(r7) + + /* + * For some interrupts, we need to call the real Linux + * handler, so it can do work for us. This has to happen + * as if the interrupt arrived from the kernel though, + * so let's fake it here where most state is restored. + * + * Call Linux for hardware interrupts/decrementer + * r3 = address of interrupt handler (exit reason) + */ + + cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL + beq call_linux_handler + cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER + beq call_linux_handler + + /* Back to EE=1 */ + mtmsr r6 + b kvm_return_point + +call_linux_handler: + + /* + * If we land here we need to jump back to the handler we + * came from. + * + * We have a page that we can access from real mode, so let's + * jump back to that and use it as a trampoline to get back into the + * interrupt handler! + * + * R3 still contains the exit code, + * R5 VCPU_HOST_RETIP and + * R6 VCPU_HOST_MSR + */ + + /* Restore host IP -> SRR0 */ + ld r5, VCPU_HOST_RETIP(r7) + + /* XXX Better move to a safe function? + * What if we get an HTAB flush in between mtsrr0 and mtsrr1? */ + + mtlr r12 + + ld r4, VCPU_TRAMPOLINE_LOWMEM(r7) + mtsrr0 r4 + LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR)) + mtsrr1 r3 + + RFI + +.global kvm_return_point +kvm_return_point: + + /* Jump back to lightweight entry if we're supposed to */ + /* go back into the guest */ + + /* Pass the exit number as 3rd argument to kvmppc_handle_exit */ + mr r5, r12 + + /* Restore r3 (kvm_run) and r4 (vcpu) */ + REST_2GPRS(3, r1) + bl KVMPPC_HANDLE_EXIT + + /* If RESUME_GUEST, get back in the loop */ + cmpwi r3, RESUME_GUEST + beq kvm_loop_lightweight + + cmpwi r3, RESUME_GUEST_NV + beq kvm_loop_heavyweight + +kvm_exit_loop: + + ld r4, _LINK(r1) + mtlr r4 + + /* Restore non-volatile host registers (r14 - r31) */ + REST_NVGPRS(r1) + + addi r1, r1, SWITCH_FRAME_SIZE + blr + +kvm_loop_heavyweight: + + ld r4, _LINK(r1) + std r4, (16 + SWITCH_FRAME_SIZE)(r1) + + /* Load vcpu and cpu_run */ + REST_2GPRS(3, r1) + + /* Load non-volatile guest state from the vcpu */ + VCPU_LOAD_NVGPRS(r4) + + /* Jump back into the beginning of this function */ + b kvm_start_lightweight + +kvm_loop_lightweight: + + /* We'll need the vcpu pointer */ + REST_GPR(4, r1) + + /* Jump back into the beginning of this function */ + b kvm_start_lightweight diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S new file mode 100644 index 000000000000..d89e315615bc --- /dev/null +++ b/arch/powerpc/kvm/book3s_rmhandlers.S @@ -0,0 +1,194 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2009 + * + * Authors: Alexander Graf + */ + +#include +#include +#include +#include +#include +#include + +/***************************************************************************** + * * + * Real Mode handlers that need to be in low physical memory * + * * + ****************************************************************************/ + + +.macro INTERRUPT_TRAMPOLINE intno + +.global kvmppc_trampoline_\intno +kvmppc_trampoline_\intno: + + mtspr SPRN_SPRG_SCRATCH0, r13 /* Save r13 */ + + /* + * First thing to do is to find out if we're coming + * from a KVM guest or a Linux process. + * + * To distinguish, we check a magic byte in the PACA + */ + mfspr r13, SPRN_SPRG_PACA /* r13 = PACA */ + std r12, PACA_KVM_SCRATCH0(r13) + mfcr r12 + stw r12, PACA_KVM_SCRATCH1(r13) + lbz r12, PACA_KVM_IN_GUEST(r13) + cmpwi r12, KVM_GUEST_MODE_NONE + bne ..kvmppc_handler_hasmagic_\intno + /* No KVM guest? Then jump back to the Linux handler! */ + lwz r12, PACA_KVM_SCRATCH1(r13) + mtcr r12 + ld r12, PACA_KVM_SCRATCH0(r13) + mfspr r13, SPRN_SPRG_SCRATCH0 /* r13 = original r13 */ + b kvmppc_resume_\intno /* Get back original handler */ + + /* Now we know we're handling a KVM guest */ +..kvmppc_handler_hasmagic_\intno: + + /* Should we just skip the faulting instruction? */ + cmpwi r12, KVM_GUEST_MODE_SKIP + beq kvmppc_handler_skip_ins + + /* Let's store which interrupt we're handling */ + li r12, \intno + + /* Jump into the SLB exit code that goes to the highmem handler */ + b kvmppc_handler_trampoline_exit + +.endm + +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSTEM_RESET +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_MACHINE_CHECK +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_STORAGE +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_SEGMENT +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_STORAGE +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_SEGMENT +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_EXTERNAL +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALIGNMENT +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PROGRAM +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_FP_UNAVAIL +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DECREMENTER +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSCALL +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_TRACE +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PERFMON +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALTIVEC +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_VSX + +/* + * Bring us back to the faulting code, but skip the + * faulting instruction. + * + * This is a generic exit path from the interrupt + * trampolines above. + * + * Input Registers: + * + * R12 = free + * R13 = PACA + * PACA.KVM.SCRATCH0 = guest R12 + * PACA.KVM.SCRATCH1 = guest CR + * SPRG_SCRATCH0 = guest R13 + * + */ +kvmppc_handler_skip_ins: + + /* Patch the IP to the next instruction */ + mfsrr0 r12 + addi r12, r12, 4 + mtsrr0 r12 + + /* Clean up all state */ + lwz r12, PACA_KVM_SCRATCH1(r13) + mtcr r12 + ld r12, PACA_KVM_SCRATCH0(r13) + mfspr r13, SPRN_SPRG_SCRATCH0 + + /* And get back into the code */ + RFI + +/* + * This trampoline brings us back to a real mode handler + * + * Input Registers: + * + * R5 = SRR0 + * R6 = SRR1 + * LR = real-mode IP + * + */ +.global kvmppc_handler_lowmem_trampoline +kvmppc_handler_lowmem_trampoline: + + mtsrr0 r5 + mtsrr1 r6 + blr +kvmppc_handler_lowmem_trampoline_end: + +/* + * Call a function in real mode + * + * Input Registers: + * + * R3 = function + * R4 = MSR + * R5 = CTR + * + */ +_GLOBAL(kvmppc_rmcall) + mtmsr r4 /* Disable relocation, so mtsrr + doesn't get interrupted */ + mtctr r5 + mtsrr0 r3 + mtsrr1 r4 + RFI + +/* + * Activate current's external feature (FPU/Altivec/VSX) + */ +#define define_load_up(what) \ + \ +_GLOBAL(kvmppc_load_up_ ## what); \ + stdu r1, -INT_FRAME_SIZE(r1); \ + mflr r3; \ + std r3, _LINK(r1); \ + \ + bl .load_up_ ## what; \ + \ + ld r3, _LINK(r1); \ + mtlr r3; \ + addi r1, r1, INT_FRAME_SIZE; \ + blr + +define_load_up(fpu) +#ifdef CONFIG_ALTIVEC +define_load_up(altivec) +#endif +#ifdef CONFIG_VSX +define_load_up(vsx) +#endif + +.global kvmppc_trampoline_lowmem +kvmppc_trampoline_lowmem: + .long kvmppc_handler_lowmem_trampoline - _stext + +.global kvmppc_trampoline_enter +kvmppc_trampoline_enter: + .long kvmppc_handler_trampoline_enter - _stext + +#include "book3s_64_slb.S" -- cgit v1.2.3-59-g8ed1b From d32154f1b8b748ea23edc90b06f640304a979012 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:33 +0200 Subject: KVM: PPC: Add host MMU Support In order to support 32 bit Book3S, we need to add code to enable our shadow MMU to actually add shadow PTEs. This is the module enabling that support. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_32_mmu_host.c | 480 ++++++++++++++++++++++++++++++++++ 1 file changed, 480 insertions(+) create mode 100644 arch/powerpc/kvm/book3s_32_mmu_host.c (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c new file mode 100644 index 000000000000..ce1bfb19c4c1 --- /dev/null +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c @@ -0,0 +1,480 @@ +/* + * Copyright (C) 2010 SUSE Linux Products GmbH. All rights reserved. + * + * Authors: + * Alexander Graf + * + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include +#include +#include +#include + +/* #define DEBUG_MMU */ +/* #define DEBUG_SR */ + +#ifdef DEBUG_MMU +#define dprintk_mmu(a, ...) printk(KERN_INFO a, __VA_ARGS__) +#else +#define dprintk_mmu(a, ...) do { } while(0) +#endif + +#ifdef DEBUG_SR +#define dprintk_sr(a, ...) printk(KERN_INFO a, __VA_ARGS__) +#else +#define dprintk_sr(a, ...) do { } while(0) +#endif + +#if PAGE_SHIFT != 12 +#error Unknown page size +#endif + +#ifdef CONFIG_SMP +#error XXX need to grab mmu_hash_lock +#endif + +#ifdef CONFIG_PTE_64BIT +#error Only 32 bit pages are supported for now +#endif + +static void invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) +{ + volatile u32 *pteg; + + dprintk_mmu("KVM: Flushing SPTE: 0x%llx (0x%llx) -> 0x%llx\n", + pte->pte.eaddr, pte->pte.vpage, pte->host_va); + + pteg = (u32*)pte->slot; + + pteg[0] = 0; + asm volatile ("sync"); + asm volatile ("tlbie %0" : : "r" (pte->pte.eaddr) : "memory"); + asm volatile ("sync"); + asm volatile ("tlbsync"); + + pte->host_va = 0; + + if (pte->pte.may_write) + kvm_release_pfn_dirty(pte->pfn); + else + kvm_release_pfn_clean(pte->pfn); +} + +void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 _guest_ea, u64 _ea_mask) +{ + int i; + u32 guest_ea = _guest_ea; + u32 ea_mask = _ea_mask; + + dprintk_mmu("KVM: Flushing %d Shadow PTEs: 0x%x & 0x%x\n", + vcpu->arch.hpte_cache_offset, guest_ea, ea_mask); + BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); + + guest_ea &= ea_mask; + for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) { + struct hpte_cache *pte; + + pte = &vcpu->arch.hpte_cache[i]; + if (!pte->host_va) + continue; + + if ((pte->pte.eaddr & ea_mask) == guest_ea) { + invalidate_pte(vcpu, pte); + } + } + + /* Doing a complete flush -> start from scratch */ + if (!ea_mask) + vcpu->arch.hpte_cache_offset = 0; +} + +void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask) +{ + int i; + + dprintk_mmu("KVM: Flushing %d Shadow vPTEs: 0x%llx & 0x%llx\n", + vcpu->arch.hpte_cache_offset, guest_vp, vp_mask); + BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); + + guest_vp &= vp_mask; + for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) { + struct hpte_cache *pte; + + pte = &vcpu->arch.hpte_cache[i]; + if (!pte->host_va) + continue; + + if ((pte->pte.vpage & vp_mask) == guest_vp) { + invalidate_pte(vcpu, pte); + } + } +} + +void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, u64 pa_start, u64 pa_end) +{ + int i; + + dprintk_mmu("KVM: Flushing %d Shadow pPTEs: 0x%llx & 0x%llx\n", + vcpu->arch.hpte_cache_offset, pa_start, pa_end); + BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); + + for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) { + struct hpte_cache *pte; + + pte = &vcpu->arch.hpte_cache[i]; + if (!pte->host_va) + continue; + + if ((pte->pte.raddr >= pa_start) && + (pte->pte.raddr < pa_end)) { + invalidate_pte(vcpu, pte); + } + } +} + +struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data) +{ + int i; + u64 guest_vp; + + guest_vp = vcpu->arch.mmu.ea_to_vp(vcpu, ea, false); + for (i=0; iarch.hpte_cache_offset; i++) { + struct hpte_cache *pte; + + pte = &vcpu->arch.hpte_cache[i]; + if (!pte->host_va) + continue; + + if (pte->pte.vpage == guest_vp) + return &pte->pte; + } + + return NULL; +} + +static int kvmppc_mmu_hpte_cache_next(struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.hpte_cache_offset == HPTEG_CACHE_NUM) + kvmppc_mmu_pte_flush(vcpu, 0, 0); + + return vcpu->arch.hpte_cache_offset++; +} + +/* We keep 512 gvsid->hvsid entries, mapping the guest ones to the array using + * a hash, so we don't waste cycles on looping */ +static u16 kvmppc_sid_hash(struct kvm_vcpu *vcpu, u64 gvsid) +{ + return (u16)(((gvsid >> (SID_MAP_BITS * 7)) & SID_MAP_MASK) ^ + ((gvsid >> (SID_MAP_BITS * 6)) & SID_MAP_MASK) ^ + ((gvsid >> (SID_MAP_BITS * 5)) & SID_MAP_MASK) ^ + ((gvsid >> (SID_MAP_BITS * 4)) & SID_MAP_MASK) ^ + ((gvsid >> (SID_MAP_BITS * 3)) & SID_MAP_MASK) ^ + ((gvsid >> (SID_MAP_BITS * 2)) & SID_MAP_MASK) ^ + ((gvsid >> (SID_MAP_BITS * 1)) & SID_MAP_MASK) ^ + ((gvsid >> (SID_MAP_BITS * 0)) & SID_MAP_MASK)); +} + + +static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid) +{ + struct kvmppc_sid_map *map; + u16 sid_map_mask; + + if (vcpu->arch.msr & MSR_PR) + gvsid |= VSID_PR; + + sid_map_mask = kvmppc_sid_hash(vcpu, gvsid); + map = &to_book3s(vcpu)->sid_map[sid_map_mask]; + if (map->guest_vsid == gvsid) { + dprintk_sr("SR: Searching 0x%llx -> 0x%llx\n", + gvsid, map->host_vsid); + return map; + } + + map = &to_book3s(vcpu)->sid_map[SID_MAP_MASK - sid_map_mask]; + if (map->guest_vsid == gvsid) { + dprintk_sr("SR: Searching 0x%llx -> 0x%llx\n", + gvsid, map->host_vsid); + return map; + } + + dprintk_sr("SR: Searching 0x%llx -> not found\n", gvsid); + return NULL; +} + +extern struct hash_pte *Hash; +extern unsigned long _SDR1; + +static u32 *kvmppc_mmu_get_pteg(struct kvm_vcpu *vcpu, u32 vsid, u32 eaddr, + bool primary) +{ + u32 page, hash, htabmask; + ulong pteg = (ulong)Hash; + + page = (eaddr & ~ESID_MASK) >> 12; + + hash = ((vsid ^ page) << 6); + if (!primary) + hash = ~hash; + + htabmask = ((_SDR1 & 0x1FF) << 16) | 0xFFC0; + hash &= htabmask; + + pteg |= hash; + + dprintk_mmu("htab: %p | hash: %x | htabmask: %x | pteg: %lx\n", + Hash, hash, htabmask, pteg); + + return (u32*)pteg; +} + +extern char etext[]; + +int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) +{ + pfn_t hpaddr; + u64 va; + u64 vsid; + struct kvmppc_sid_map *map; + volatile u32 *pteg; + u32 eaddr = orig_pte->eaddr; + u32 pteg0, pteg1; + register int rr = 0; + bool primary = false; + bool evict = false; + int hpte_id; + struct hpte_cache *pte; + + /* Get host physical address for gpa */ + hpaddr = gfn_to_pfn(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT); + if (kvm_is_error_hva(hpaddr)) { + printk(KERN_INFO "Couldn't get guest page for gfn %llx!\n", + orig_pte->eaddr); + return -EINVAL; + } + hpaddr <<= PAGE_SHIFT; + + /* and write the mapping ea -> hpa into the pt */ + vcpu->arch.mmu.esid_to_vsid(vcpu, orig_pte->eaddr >> SID_SHIFT, &vsid); + map = find_sid_vsid(vcpu, vsid); + if (!map) { + kvmppc_mmu_map_segment(vcpu, eaddr); + map = find_sid_vsid(vcpu, vsid); + } + BUG_ON(!map); + + vsid = map->host_vsid; + va = (vsid << SID_SHIFT) | (eaddr & ~ESID_MASK); + +next_pteg: + if (rr == 16) { + primary = !primary; + evict = true; + rr = 0; + } + + pteg = kvmppc_mmu_get_pteg(vcpu, vsid, eaddr, primary); + + /* not evicting yet */ + if (!evict && (pteg[rr] & PTE_V)) { + rr += 2; + goto next_pteg; + } + + dprintk_mmu("KVM: old PTEG: %p (%d)\n", pteg, rr); + dprintk_mmu("KVM: %08x - %08x\n", pteg[0], pteg[1]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[2], pteg[3]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[4], pteg[5]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[6], pteg[7]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[8], pteg[9]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[10], pteg[11]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[12], pteg[13]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[14], pteg[15]); + + pteg0 = ((eaddr & 0x0fffffff) >> 22) | (vsid << 7) | PTE_V | + (primary ? 0 : PTE_SEC); + pteg1 = hpaddr | PTE_M | PTE_R | PTE_C; + + if (orig_pte->may_write) { + pteg1 |= PP_RWRW; + mark_page_dirty(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT); + } else { + pteg1 |= PP_RWRX; + } + + local_irq_disable(); + + if (pteg[rr]) { + pteg[rr] = 0; + asm volatile ("sync"); + } + pteg[rr + 1] = pteg1; + pteg[rr] = pteg0; + asm volatile ("sync"); + + local_irq_enable(); + + dprintk_mmu("KVM: new PTEG: %p\n", pteg); + dprintk_mmu("KVM: %08x - %08x\n", pteg[0], pteg[1]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[2], pteg[3]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[4], pteg[5]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[6], pteg[7]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[8], pteg[9]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[10], pteg[11]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[12], pteg[13]); + dprintk_mmu("KVM: %08x - %08x\n", pteg[14], pteg[15]); + + + /* Now tell our Shadow PTE code about the new page */ + + hpte_id = kvmppc_mmu_hpte_cache_next(vcpu); + pte = &vcpu->arch.hpte_cache[hpte_id]; + + dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%llx (0x%llx) -> %lx\n", + orig_pte->may_write ? 'w' : '-', + orig_pte->may_execute ? 'x' : '-', + orig_pte->eaddr, (ulong)pteg, va, + orig_pte->vpage, hpaddr); + + pte->slot = (ulong)&pteg[rr]; + pte->host_va = va; + pte->pte = *orig_pte; + pte->pfn = hpaddr >> PAGE_SHIFT; + + return 0; +} + +static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid) +{ + struct kvmppc_sid_map *map; + struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); + u16 sid_map_mask; + static int backwards_map = 0; + + if (vcpu->arch.msr & MSR_PR) + gvsid |= VSID_PR; + + /* We might get collisions that trap in preceding order, so let's + map them differently */ + + sid_map_mask = kvmppc_sid_hash(vcpu, gvsid); + if (backwards_map) + sid_map_mask = SID_MAP_MASK - sid_map_mask; + + map = &to_book3s(vcpu)->sid_map[sid_map_mask]; + + /* Make sure we're taking the other map next time */ + backwards_map = !backwards_map; + + /* Uh-oh ... out of mappings. Let's flush! */ + if (vcpu_book3s->vsid_next >= vcpu_book3s->vsid_max) { + vcpu_book3s->vsid_next = vcpu_book3s->vsid_first; + memset(vcpu_book3s->sid_map, 0, + sizeof(struct kvmppc_sid_map) * SID_MAP_NUM); + kvmppc_mmu_pte_flush(vcpu, 0, 0); + kvmppc_mmu_flush_segments(vcpu); + } + map->host_vsid = vcpu_book3s->vsid_next; + + /* Would have to be 111 to be completely aligned with the rest of + Linux, but that is just way too little space! */ + vcpu_book3s->vsid_next+=1; + + map->guest_vsid = gvsid; + map->valid = true; + + return map; +} + +int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr) +{ + u32 esid = eaddr >> SID_SHIFT; + u64 gvsid; + u32 sr; + struct kvmppc_sid_map *map; + struct kvmppc_book3s_shadow_vcpu *svcpu = to_svcpu(vcpu); + + if (vcpu->arch.mmu.esid_to_vsid(vcpu, esid, &gvsid)) { + /* Invalidate an entry */ + svcpu->sr[esid] = SR_INVALID; + return -ENOENT; + } + + map = find_sid_vsid(vcpu, gvsid); + if (!map) + map = create_sid_map(vcpu, gvsid); + + map->guest_esid = esid; + sr = map->host_vsid | SR_KP; + svcpu->sr[esid] = sr; + + dprintk_sr("MMU: mtsr %d, 0x%x\n", esid, sr); + + return 0; +} + +void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu) +{ + int i; + struct kvmppc_book3s_shadow_vcpu *svcpu = to_svcpu(vcpu); + + dprintk_sr("MMU: flushing all segments (%d)\n", ARRAY_SIZE(svcpu->sr)); + for (i = 0; i < ARRAY_SIZE(svcpu->sr); i++) + svcpu->sr[i] = SR_INVALID; +} + +void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) +{ + kvmppc_mmu_pte_flush(vcpu, 0, 0); + preempt_disable(); + __destroy_context(to_book3s(vcpu)->context_id); + preempt_enable(); +} + +/* From mm/mmu_context_hash32.c */ +#define CTX_TO_VSID(ctx) (((ctx) * (897 * 16)) & 0xffffff) + +int kvmppc_mmu_init(struct kvm_vcpu *vcpu) +{ + struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); + int err; + + err = __init_new_context(); + if (err < 0) + return -1; + vcpu3s->context_id = err; + + vcpu3s->vsid_max = CTX_TO_VSID(vcpu3s->context_id + 1) - 1; + vcpu3s->vsid_first = CTX_TO_VSID(vcpu3s->context_id); + +#if 0 /* XXX still doesn't guarantee uniqueness */ + /* We could collide with the Linux vsid space because the vsid + * wraps around at 24 bits. We're safe if we do our own space + * though, so let's always set the highest bit. */ + + vcpu3s->vsid_max |= 0x00800000; + vcpu3s->vsid_first |= 0x00800000; +#endif + BUG_ON(vcpu3s->vsid_max < vcpu3s->vsid_first); + + vcpu3s->vsid_next = vcpu3s->vsid_first; + + return 0; +} -- cgit v1.2.3-59-g8ed1b From 786f19daa8b109ae6b96a351eee3a14b9f8b57d0 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:34 +0200 Subject: KVM: PPC: Add SR swapping code Later in this series we will move the current segment switch code to generic code and make that call hooks for the specific sub-archs (32 vs. 64 bit). This is the hook for 32 bits. It enabled the entry and exit code to swap segment registers with values from the shadow cpu structure. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_32_sr.S | 143 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 arch/powerpc/kvm/book3s_32_sr.S (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_32_sr.S b/arch/powerpc/kvm/book3s_32_sr.S new file mode 100644 index 000000000000..3608471ad2d8 --- /dev/null +++ b/arch/powerpc/kvm/book3s_32_sr.S @@ -0,0 +1,143 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2009 + * + * Authors: Alexander Graf + */ + +/****************************************************************************** + * * + * Entry code * + * * + *****************************************************************************/ + +.macro LOAD_GUEST_SEGMENTS + + /* Required state: + * + * MSR = ~IR|DR + * R1 = host R1 + * R2 = host R2 + * R3 = shadow vcpu + * all other volatile GPRS = free + * SVCPU[CR] = guest CR + * SVCPU[XER] = guest XER + * SVCPU[CTR] = guest CTR + * SVCPU[LR] = guest LR + */ + +#define XCHG_SR(n) lwz r9, (SVCPU_SR+(n*4))(r3); \ + mtsr n, r9 + + XCHG_SR(0) + XCHG_SR(1) + XCHG_SR(2) + XCHG_SR(3) + XCHG_SR(4) + XCHG_SR(5) + XCHG_SR(6) + XCHG_SR(7) + XCHG_SR(8) + XCHG_SR(9) + XCHG_SR(10) + XCHG_SR(11) + XCHG_SR(12) + XCHG_SR(13) + XCHG_SR(14) + XCHG_SR(15) + + /* Clear BATs. */ + +#define KVM_KILL_BAT(n, reg) \ + mtspr SPRN_IBAT##n##U,reg; \ + mtspr SPRN_IBAT##n##L,reg; \ + mtspr SPRN_DBAT##n##U,reg; \ + mtspr SPRN_DBAT##n##L,reg; \ + + li r9, 0 + KVM_KILL_BAT(0, r9) + KVM_KILL_BAT(1, r9) + KVM_KILL_BAT(2, r9) + KVM_KILL_BAT(3, r9) + +.endm + +/****************************************************************************** + * * + * Exit code * + * * + *****************************************************************************/ + +.macro LOAD_HOST_SEGMENTS + + /* Register usage at this point: + * + * R1 = host R1 + * R2 = host R2 + * R12 = exit handler id + * R13 = shadow vcpu - SHADOW_VCPU_OFF + * SVCPU.* = guest * + * SVCPU[CR] = guest CR + * SVCPU[XER] = guest XER + * SVCPU[CTR] = guest CTR + * SVCPU[LR] = guest LR + * + */ + + /* Restore BATs */ + + /* We only overwrite the upper part, so we only restoree + the upper part. */ +#define KVM_LOAD_BAT(n, reg, RA, RB) \ + lwz RA,(n*16)+0(reg); \ + lwz RB,(n*16)+4(reg); \ + mtspr SPRN_IBAT##n##U,RA; \ + mtspr SPRN_IBAT##n##L,RB; \ + lwz RA,(n*16)+8(reg); \ + lwz RB,(n*16)+12(reg); \ + mtspr SPRN_DBAT##n##U,RA; \ + mtspr SPRN_DBAT##n##L,RB; \ + + lis r9, BATS@ha + addi r9, r9, BATS@l + tophys(r9, r9) + KVM_LOAD_BAT(0, r9, r10, r11) + KVM_LOAD_BAT(1, r9, r10, r11) + KVM_LOAD_BAT(2, r9, r10, r11) + KVM_LOAD_BAT(3, r9, r10, r11) + + /* Restore Segment Registers */ + + /* 0xc - 0xf */ + + li r0, 4 + mtctr r0 + LOAD_REG_IMMEDIATE(r3, 0x20000000 | (0x111 * 0xc)) + lis r4, 0xc000 +3: mtsrin r3, r4 + addi r3, r3, 0x111 /* increment VSID */ + addis r4, r4, 0x1000 /* address of next segment */ + bdnz 3b + + /* 0x0 - 0xb */ + + /* 'current->mm' needs to be in r4 */ + tophys(r4, r2) + lwz r4, MM(r4) + tophys(r4, r4) + /* This only clobbers r0, r3, r4 and r5 */ + bl switch_mmu_context + +.endm -- cgit v1.2.3-59-g8ed1b From 0737279427bef48f552b3ab63a6c0ba7491fe29f Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:35 +0200 Subject: KVM: PPC: Add generic segment switching code This is the code that will later be used instead of book3s_64_slb.S. It does the last step of guest entry and the first generic steps of guest exiting, once we have determined the interrupt is a KVM interrupt. It also reads the last used instruction from the guest virtual address space if necessary, to speed up that path. The new thing about this file is that it makes use of generic long load and store functions and calls a macro to fill in the actual segment switching code. That still needs to be done differently for book3s_32 and book3s_64. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_segment.S | 257 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 arch/powerpc/kvm/book3s_segment.S (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S new file mode 100644 index 000000000000..4c0d1d85d20a --- /dev/null +++ b/arch/powerpc/kvm/book3s_segment.S @@ -0,0 +1,257 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2010 + * + * Authors: Alexander Graf + */ + +/* Real mode helpers */ + +#if defined(CONFIG_PPC_BOOK3S_64) + +#define GET_SHADOW_VCPU(reg) \ + addi reg, r13, PACA_KVM_SVCPU + +#elif defined(CONFIG_PPC_BOOK3S_32) + +#define GET_SHADOW_VCPU(reg) \ + tophys(reg, r2); \ + lwz reg, (THREAD + THREAD_KVM_SVCPU)(reg); \ + tophys(reg, reg) + +#endif + +/* Disable for nested KVM */ +#define USE_QUICK_LAST_INST + + +/* Get helper functions for subarch specific functionality */ + +#if defined(CONFIG_PPC_BOOK3S_64) +#include "book3s_64_slb.S" +#elif defined(CONFIG_PPC_BOOK3S_32) +#include "book3s_32_sr.S" +#endif + +/****************************************************************************** + * * + * Entry code * + * * + *****************************************************************************/ + +.global kvmppc_handler_trampoline_enter +kvmppc_handler_trampoline_enter: + + /* Required state: + * + * MSR = ~IR|DR + * R13 = PACA + * R1 = host R1 + * R2 = host R2 + * R10 = guest MSR + * all other volatile GPRS = free + * SVCPU[CR] = guest CR + * SVCPU[XER] = guest XER + * SVCPU[CTR] = guest CTR + * SVCPU[LR] = guest LR + */ + + /* r3 = shadow vcpu */ + GET_SHADOW_VCPU(r3) + + /* Move SRR0 and SRR1 into the respective regs */ + PPC_LL r9, SVCPU_PC(r3) + mtsrr0 r9 + mtsrr1 r10 + + /* Activate guest mode, so faults get handled by KVM */ + li r11, KVM_GUEST_MODE_GUEST + stb r11, SVCPU_IN_GUEST(r3) + + /* Switch to guest segment. This is subarch specific. */ + LOAD_GUEST_SEGMENTS + + /* Enter guest */ + + PPC_LL r4, (SVCPU_CTR)(r3) + PPC_LL r5, (SVCPU_LR)(r3) + lwz r6, (SVCPU_CR)(r3) + lwz r7, (SVCPU_XER)(r3) + + mtctr r4 + mtlr r5 + mtcr r6 + mtxer r7 + + PPC_LL r0, (SVCPU_R0)(r3) + PPC_LL r1, (SVCPU_R1)(r3) + PPC_LL r2, (SVCPU_R2)(r3) + PPC_LL r4, (SVCPU_R4)(r3) + PPC_LL r5, (SVCPU_R5)(r3) + PPC_LL r6, (SVCPU_R6)(r3) + PPC_LL r7, (SVCPU_R7)(r3) + PPC_LL r8, (SVCPU_R8)(r3) + PPC_LL r9, (SVCPU_R9)(r3) + PPC_LL r10, (SVCPU_R10)(r3) + PPC_LL r11, (SVCPU_R11)(r3) + PPC_LL r12, (SVCPU_R12)(r3) + PPC_LL r13, (SVCPU_R13)(r3) + + PPC_LL r3, (SVCPU_R3)(r3) + + RFI +kvmppc_handler_trampoline_enter_end: + + + +/****************************************************************************** + * * + * Exit code * + * * + *****************************************************************************/ + +.global kvmppc_handler_trampoline_exit +kvmppc_handler_trampoline_exit: + + /* Register usage at this point: + * + * SPRG_SCRATCH0 = guest R13 + * R12 = exit handler id + * R13 = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64] + * SVCPU.SCRATCH0 = guest R12 + * SVCPU.SCRATCH1 = guest CR + * + */ + + /* Save registers */ + + PPC_STL r0, (SHADOW_VCPU_OFF + SVCPU_R0)(r13) + PPC_STL r1, (SHADOW_VCPU_OFF + SVCPU_R1)(r13) + PPC_STL r2, (SHADOW_VCPU_OFF + SVCPU_R2)(r13) + PPC_STL r3, (SHADOW_VCPU_OFF + SVCPU_R3)(r13) + PPC_STL r4, (SHADOW_VCPU_OFF + SVCPU_R4)(r13) + PPC_STL r5, (SHADOW_VCPU_OFF + SVCPU_R5)(r13) + PPC_STL r6, (SHADOW_VCPU_OFF + SVCPU_R6)(r13) + PPC_STL r7, (SHADOW_VCPU_OFF + SVCPU_R7)(r13) + PPC_STL r8, (SHADOW_VCPU_OFF + SVCPU_R8)(r13) + PPC_STL r9, (SHADOW_VCPU_OFF + SVCPU_R9)(r13) + PPC_STL r10, (SHADOW_VCPU_OFF + SVCPU_R10)(r13) + PPC_STL r11, (SHADOW_VCPU_OFF + SVCPU_R11)(r13) + + /* Restore R1/R2 so we can handle faults */ + PPC_LL r1, (SHADOW_VCPU_OFF + SVCPU_HOST_R1)(r13) + PPC_LL r2, (SHADOW_VCPU_OFF + SVCPU_HOST_R2)(r13) + + /* Save guest PC and MSR */ + mfsrr0 r3 + mfsrr1 r4 + + PPC_STL r3, (SHADOW_VCPU_OFF + SVCPU_PC)(r13) + PPC_STL r4, (SHADOW_VCPU_OFF + SVCPU_SHADOW_SRR1)(r13) + + /* Get scratch'ed off registers */ + mfspr r9, SPRN_SPRG_SCRATCH0 + PPC_LL r8, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13) + lwz r7, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13) + + PPC_STL r9, (SHADOW_VCPU_OFF + SVCPU_R13)(r13) + PPC_STL r8, (SHADOW_VCPU_OFF + SVCPU_R12)(r13) + stw r7, (SHADOW_VCPU_OFF + SVCPU_CR)(r13) + + /* Save more register state */ + + mfxer r5 + mfdar r6 + mfdsisr r7 + mfctr r8 + mflr r9 + + stw r5, (SHADOW_VCPU_OFF + SVCPU_XER)(r13) + PPC_STL r6, (SHADOW_VCPU_OFF + SVCPU_FAULT_DAR)(r13) + stw r7, (SHADOW_VCPU_OFF + SVCPU_FAULT_DSISR)(r13) + PPC_STL r8, (SHADOW_VCPU_OFF + SVCPU_CTR)(r13) + PPC_STL r9, (SHADOW_VCPU_OFF + SVCPU_LR)(r13) + + /* + * In order for us to easily get the last instruction, + * we got the #vmexit at, we exploit the fact that the + * virtual layout is still the same here, so we can just + * ld from the guest's PC address + */ + + /* We only load the last instruction when it's safe */ + cmpwi r12, BOOK3S_INTERRUPT_DATA_STORAGE + beq ld_last_inst + cmpwi r12, BOOK3S_INTERRUPT_PROGRAM + beq ld_last_inst + + b no_ld_last_inst + +ld_last_inst: + /* Save off the guest instruction we're at */ + + /* In case lwz faults */ + li r0, KVM_INST_FETCH_FAILED + +#ifdef USE_QUICK_LAST_INST + + /* Set guest mode to 'jump over instruction' so if lwz faults + * we'll just continue at the next IP. */ + li r9, KVM_GUEST_MODE_SKIP + stb r9, (SHADOW_VCPU_OFF + SVCPU_IN_GUEST)(r13) + + /* 1) enable paging for data */ + mfmsr r9 + ori r11, r9, MSR_DR /* Enable paging for data */ + mtmsr r11 + sync + /* 2) fetch the instruction */ + lwz r0, 0(r3) + /* 3) disable paging again */ + mtmsr r9 + sync + +#endif + stw r0, (SHADOW_VCPU_OFF + SVCPU_LAST_INST)(r13) + +no_ld_last_inst: + + /* Unset guest mode */ + li r9, KVM_GUEST_MODE_NONE + stb r9, (SHADOW_VCPU_OFF + SVCPU_IN_GUEST)(r13) + + /* Switch back to host MMU */ + LOAD_HOST_SEGMENTS + + /* Register usage at this point: + * + * R1 = host R1 + * R2 = host R2 + * R12 = exit handler id + * R13 = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64] + * SVCPU.* = guest * + * + */ + + /* RFI into the highmem handler */ + mfmsr r7 + ori r7, r7, MSR_IR|MSR_DR|MSR_RI|MSR_ME /* Enable paging */ + mtsrr1 r7 + /* Load highmem handler address */ + PPC_LL r8, (SHADOW_VCPU_OFF + SVCPU_VMHANDLER)(r13) + mtsrr0 r8 + + RFI +kvmppc_handler_trampoline_exit_end: -- cgit v1.2.3-59-g8ed1b From c83ec269e6931edf61abe1ed777ebb867b06a85c Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:36 +0200 Subject: PPC: Split context init/destroy functions We need to reserve a context from KVM to make sure we have our own segment space. While we did that split for Book3S_64 already, 32 bit is still outstanding. So let's split it now. Signed-off-by: Alexander Graf Acked-by: Benjamin Herrenschmidt CC: Benjamin Herrenschmidt Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/mmu_context.h | 2 ++ arch/powerpc/mm/mmu_context_hash32.c | 29 ++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 26383e0778aa..81fb41289d6c 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -27,6 +27,8 @@ extern int __init_new_context(void); extern void __destroy_context(int context_id); static inline void mmu_context_init(void) { } #else +extern unsigned long __init_new_context(void); +extern void __destroy_context(unsigned long context_id); extern void mmu_context_init(void); #endif diff --git a/arch/powerpc/mm/mmu_context_hash32.c b/arch/powerpc/mm/mmu_context_hash32.c index 0dfba2bf7f31..d0ee554e86e4 100644 --- a/arch/powerpc/mm/mmu_context_hash32.c +++ b/arch/powerpc/mm/mmu_context_hash32.c @@ -60,11 +60,7 @@ static unsigned long next_mmu_context; static unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1]; - -/* - * Set up the context for a new address space. - */ -int init_new_context(struct task_struct *t, struct mm_struct *mm) +unsigned long __init_new_context(void) { unsigned long ctx = next_mmu_context; @@ -74,11 +70,30 @@ int init_new_context(struct task_struct *t, struct mm_struct *mm) ctx = 0; } next_mmu_context = (ctx + 1) & LAST_CONTEXT; - mm->context.id = ctx; + + return ctx; +} +EXPORT_SYMBOL_GPL(__init_new_context); + +/* + * Set up the context for a new address space. + */ +int init_new_context(struct task_struct *t, struct mm_struct *mm) +{ + mm->context.id = __init_new_context(); return 0; } +/* + * Free a context ID. Make sure to call this with preempt disabled! + */ +void __destroy_context(unsigned long ctx) +{ + clear_bit(ctx, context_map); +} +EXPORT_SYMBOL_GPL(__destroy_context); + /* * We're finished using the context for an address space. */ @@ -86,7 +101,7 @@ void destroy_context(struct mm_struct *mm) { preempt_disable(); if (mm->context.id != NO_CONTEXT) { - clear_bit(mm->context.id, context_map); + __destroy_context(mm->context.id); mm->context.id = NO_CONTEXT; } preempt_enable(); -- cgit v1.2.3-59-g8ed1b From 3ae07890dd40e40fa78270900894fba3bb448439 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:37 +0200 Subject: KVM: PPC: Add kvm_book3s_64.h In the process of generalizing as much code as possible, I also moved the shadow vcpu code together to a generic book3s file. Unfortunately the location of the shadow vcpu is different on 32 and 64 bit, so we need a wrapper function to tell us where it is. That sounded like a perfect fit for a subarch specific header file. Here we can put anything that needs to be different between those two. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s_64.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 arch/powerpc/include/asm/kvm_book3s_64.h (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h new file mode 100644 index 000000000000..4cadd612d575 --- /dev/null +++ b/arch/powerpc/include/asm/kvm_book3s_64.h @@ -0,0 +1,28 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2010 + * + * Authors: Alexander Graf + */ + +#ifndef __ASM_KVM_BOOK3S_64_H__ +#define __ASM_KVM_BOOK3S_64_H__ + +static inline struct kvmppc_book3s_shadow_vcpu *to_svcpu(struct kvm_vcpu *vcpu) +{ + return &get_paca()->shadow_vcpu; +} + +#endif /* __ASM_KVM_BOOK3S_64_H__ */ -- cgit v1.2.3-59-g8ed1b From 8c60b9fb0f9dca8adb0143456245041e7a036c2f Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:38 +0200 Subject: KVM: PPC: Add kvm_book3s_32.h In analogy to the 64 bit specific header file, this is the 32 bit pendant. With this in place we can just always call to_svcpu and be assured we get the right pointer anywhere. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s_32.h | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 arch/powerpc/include/asm/kvm_book3s_32.h (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s_32.h b/arch/powerpc/include/asm/kvm_book3s_32.h new file mode 100644 index 000000000000..de604db135f5 --- /dev/null +++ b/arch/powerpc/include/asm/kvm_book3s_32.h @@ -0,0 +1,42 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2010 + * + * Authors: Alexander Graf + */ + +#ifndef __ASM_KVM_BOOK3S_32_H__ +#define __ASM_KVM_BOOK3S_32_H__ + +static inline struct kvmppc_book3s_shadow_vcpu *to_svcpu(struct kvm_vcpu *vcpu) +{ + return to_book3s(vcpu)->shadow_vcpu; +} + +#define PTE_SIZE 12 +#define VSID_ALL 0 +#define SR_INVALID 0x00000001 /* VSID 1 should always be unused */ +#define SR_KP 0x20000000 +#define PTE_V 0x80000000 +#define PTE_SEC 0x00000040 +#define PTE_M 0x00000010 +#define PTE_R 0x00000100 +#define PTE_C 0x00000080 + +#define SID_SHIFT 28 +#define ESID_MASK 0xf0000000 +#define VSID_MASK 0x00fffffff0000000ULL + +#endif /* __ASM_KVM_BOOK3S_32_H__ */ -- cgit v1.2.3-59-g8ed1b From 66bb170655799a0149df0844fb8232f27e54323c Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:39 +0200 Subject: KVM: PPC: Add fields to shadow vcpu After a lot of thought on how to make the entry / exit code easier, I figured it'd be clever to put even more register state into the shadow vcpu. That way we have more registers available to use, making the code easier to read. So this patch adds a few new fields to that shadow vcpu. Later on we will remove the originals from the vcpu and paca. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s_asm.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h index 183461b48407..e915e7dfa622 100644 --- a/arch/powerpc/include/asm/kvm_book3s_asm.h +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h @@ -63,12 +63,33 @@ struct kvmppc_book3s_shadow_vcpu { ulong gpr[14]; u32 cr; u32 xer; + + u32 fault_dsisr; + u32 last_inst; + ulong ctr; + ulong lr; + ulong pc; + ulong shadow_srr1; + ulong fault_dar; + ulong host_r1; ulong host_r2; ulong handler; ulong scratch0; ulong scratch1; ulong vmhandler; + u8 in_guest; + +#ifdef CONFIG_PPC_BOOK3S_32 + u32 sr[16]; /* Guest SRs */ +#endif +#ifdef CONFIG_PPC_BOOK3S_64 + u8 slb_max; /* highest used guest slb entry */ + struct { + u64 esid; + u64 vsid; + } slb[64]; /* guest SLB */ +#endif }; #endif /*__ASSEMBLY__ */ -- cgit v1.2.3-59-g8ed1b From c7f38f46f2a98d232147e47284cb4e7363296a3e Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:40 +0200 Subject: KVM: PPC: Improve indirect svcpu accessors We already have some inline fuctions we use to access vcpu or svcpu structs, depending on whether we're on booke or book3s. Since we just put a few more registers into the svcpu, we also need to make sure the respective callbacks are available and get used. So this patch moves direct use of the now in the svcpu struct fields to inline function calls. While at it, it also moves the definition of those inline function calls to respective header files for booke and book3s, greatly improving readability. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 98 +++++++++++++++++++++++- arch/powerpc/include/asm/kvm_booke.h | 96 ++++++++++++++++++++++++ arch/powerpc/include/asm/kvm_ppc.h | 79 +------------------ arch/powerpc/kvm/book3s.c | 125 ++++++++++++++++++------------- arch/powerpc/kvm/book3s_64_mmu.c | 2 +- arch/powerpc/kvm/book3s_64_mmu_host.c | 26 +++---- arch/powerpc/kvm/book3s_emulate.c | 6 +- arch/powerpc/kvm/book3s_paired_singles.c | 2 +- arch/powerpc/kvm/emulate.c | 7 +- arch/powerpc/kvm/powerpc.c | 2 +- 10 files changed, 290 insertions(+), 153 deletions(-) create mode 100644 arch/powerpc/include/asm/kvm_booke.h (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 7670e2a12867..9517b8deafed 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -71,7 +71,7 @@ struct kvmppc_sid_map { struct kvmppc_vcpu_book3s { struct kvm_vcpu vcpu; - struct kvmppc_book3s_shadow_vcpu shadow_vcpu; + struct kvmppc_book3s_shadow_vcpu *shadow_vcpu; struct kvmppc_sid_map sid_map[SID_MAP_NUM]; struct kvmppc_slb slb[64]; struct { @@ -147,6 +147,94 @@ static inline ulong dsisr(void) } extern void kvm_return_point(void); +static inline struct kvmppc_book3s_shadow_vcpu *to_svcpu(struct kvm_vcpu *vcpu); + +static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) +{ + if ( num < 14 ) { + to_svcpu(vcpu)->gpr[num] = val; + to_book3s(vcpu)->shadow_vcpu->gpr[num] = val; + } else + vcpu->arch.gpr[num] = val; +} + +static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num) +{ + if ( num < 14 ) + return to_svcpu(vcpu)->gpr[num]; + else + return vcpu->arch.gpr[num]; +} + +static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val) +{ + to_svcpu(vcpu)->cr = val; + to_book3s(vcpu)->shadow_vcpu->cr = val; +} + +static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu) +{ + return to_svcpu(vcpu)->cr; +} + +static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val) +{ + to_svcpu(vcpu)->xer = val; + to_book3s(vcpu)->shadow_vcpu->xer = val; +} + +static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu) +{ + return to_svcpu(vcpu)->xer; +} + +static inline void kvmppc_set_ctr(struct kvm_vcpu *vcpu, ulong val) +{ + to_svcpu(vcpu)->ctr = val; +} + +static inline ulong kvmppc_get_ctr(struct kvm_vcpu *vcpu) +{ + return to_svcpu(vcpu)->ctr; +} + +static inline void kvmppc_set_lr(struct kvm_vcpu *vcpu, ulong val) +{ + to_svcpu(vcpu)->lr = val; +} + +static inline ulong kvmppc_get_lr(struct kvm_vcpu *vcpu) +{ + return to_svcpu(vcpu)->lr; +} + +static inline void kvmppc_set_pc(struct kvm_vcpu *vcpu, ulong val) +{ + to_svcpu(vcpu)->pc = val; +} + +static inline ulong kvmppc_get_pc(struct kvm_vcpu *vcpu) +{ + return to_svcpu(vcpu)->pc; +} + +static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) +{ + ulong pc = kvmppc_get_pc(vcpu); + struct kvmppc_book3s_shadow_vcpu *svcpu = to_svcpu(vcpu); + + /* Load the instruction manually if it failed to do so in the + * exit path */ + if (svcpu->last_inst == KVM_INST_FETCH_FAILED) + kvmppc_ld(vcpu, &pc, sizeof(u32), &svcpu->last_inst, false); + + return svcpu->last_inst; +} + +static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) +{ + return to_svcpu(vcpu)->fault_dar; +} /* Magic register values loaded into r3 and r4 before the 'sc' assembly * instruction for the OSI hypercalls */ @@ -155,4 +243,12 @@ extern void kvm_return_point(void); #define INS_DCBZ 0x7c0007ec +/* Also add subarch specific defines */ + +#ifdef CONFIG_PPC_BOOK3S_32 +#include +#else +#include +#endif + #endif /* __ASM_KVM_BOOK3S_H__ */ diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h new file mode 100644 index 000000000000..9c9ba3d59b1b --- /dev/null +++ b/arch/powerpc/include/asm/kvm_booke.h @@ -0,0 +1,96 @@ +/* + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2010 + * + * Authors: Alexander Graf + */ + +#ifndef __ASM_KVM_BOOKE_H__ +#define __ASM_KVM_BOOKE_H__ + +#include +#include + +static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) +{ + vcpu->arch.gpr[num] = val; +} + +static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num) +{ + return vcpu->arch.gpr[num]; +} + +static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val) +{ + vcpu->arch.cr = val; +} + +static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.cr; +} + +static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val) +{ + vcpu->arch.xer = val; +} + +static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.xer; +} + +static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.last_inst; +} + +static inline void kvmppc_set_ctr(struct kvm_vcpu *vcpu, ulong val) +{ + vcpu->arch.ctr = val; +} + +static inline ulong kvmppc_get_ctr(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.ctr; +} + +static inline void kvmppc_set_lr(struct kvm_vcpu *vcpu, ulong val) +{ + vcpu->arch.lr = val; +} + +static inline ulong kvmppc_get_lr(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.lr; +} + +static inline void kvmppc_set_pc(struct kvm_vcpu *vcpu, ulong val) +{ + vcpu->arch.pc = val; +} + +static inline ulong kvmppc_get_pc(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.pc; +} + +static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.fault_dear; +} + +#endif /* __ASM_KVM_BOOKE_H__ */ diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 6a2464e4d6b9..edade847b8f8 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -30,6 +30,8 @@ #include #ifdef CONFIG_PPC_BOOK3S #include +#else +#include #endif enum emulation_result { @@ -138,81 +140,4 @@ static inline u32 kvmppc_set_field(u64 inst, int msb, int lsb, int value) return r; } -#ifdef CONFIG_PPC_BOOK3S - -/* We assume we're always acting on the current vcpu */ - -static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) -{ - if ( num < 14 ) { - get_paca()->shadow_vcpu.gpr[num] = val; - to_book3s(vcpu)->shadow_vcpu.gpr[num] = val; - } else - vcpu->arch.gpr[num] = val; -} - -static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num) -{ - if ( num < 14 ) - return get_paca()->shadow_vcpu.gpr[num]; - else - return vcpu->arch.gpr[num]; -} - -static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val) -{ - get_paca()->shadow_vcpu.cr = val; - to_book3s(vcpu)->shadow_vcpu.cr = val; -} - -static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu) -{ - return get_paca()->shadow_vcpu.cr; -} - -static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val) -{ - get_paca()->shadow_vcpu.xer = val; - to_book3s(vcpu)->shadow_vcpu.xer = val; -} - -static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu) -{ - return get_paca()->shadow_vcpu.xer; -} - -#else - -static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) -{ - vcpu->arch.gpr[num] = val; -} - -static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num) -{ - return vcpu->arch.gpr[num]; -} - -static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val) -{ - vcpu->arch.cr = val; -} - -static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu) -{ - return vcpu->arch.cr; -} - -static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val) -{ - vcpu->arch.xer = val; -} - -static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu) -{ - return vcpu->arch.xer; -} - -#endif - #endif /* __POWERPC_KVM_PPC_H__ */ diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 41c23b636f53..7ff80f9f13a8 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -71,18 +71,26 @@ void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu) void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { - memcpy(get_paca()->kvm_slb, to_book3s(vcpu)->slb_shadow, sizeof(get_paca()->kvm_slb)); - memcpy(&get_paca()->shadow_vcpu, &to_book3s(vcpu)->shadow_vcpu, +#ifdef CONFIG_PPC_BOOK3S_64 + memcpy(to_svcpu(vcpu)->slb, to_book3s(vcpu)->slb_shadow, sizeof(to_svcpu(vcpu)->slb)); + memcpy(&get_paca()->shadow_vcpu, to_book3s(vcpu)->shadow_vcpu, sizeof(get_paca()->shadow_vcpu)); - get_paca()->kvm_slb_max = to_book3s(vcpu)->slb_shadow_max; + to_svcpu(vcpu)->slb_max = to_book3s(vcpu)->slb_shadow_max; +#endif + +#ifdef CONFIG_PPC_BOOK3S_32 + current->thread.kvm_shadow_vcpu = to_book3s(vcpu)->shadow_vcpu; +#endif } void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) { - memcpy(to_book3s(vcpu)->slb_shadow, get_paca()->kvm_slb, sizeof(get_paca()->kvm_slb)); - memcpy(&to_book3s(vcpu)->shadow_vcpu, &get_paca()->shadow_vcpu, +#ifdef CONFIG_PPC_BOOK3S_64 + memcpy(to_book3s(vcpu)->slb_shadow, to_svcpu(vcpu)->slb, sizeof(to_svcpu(vcpu)->slb)); + memcpy(to_book3s(vcpu)->shadow_vcpu, &get_paca()->shadow_vcpu, sizeof(get_paca()->shadow_vcpu)); - to_book3s(vcpu)->slb_shadow_max = get_paca()->kvm_slb_max; + to_book3s(vcpu)->slb_shadow_max = to_svcpu(vcpu)->slb_max; +#endif kvmppc_giveup_ext(vcpu, MSR_FP); kvmppc_giveup_ext(vcpu, MSR_VEC); @@ -144,7 +152,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) VSID_SPLIT_MASK); kvmppc_mmu_flush_segments(vcpu); - kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc); + kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu)); } /* Preload FPU if it's enabled */ @@ -154,9 +162,9 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags) { - vcpu->arch.srr0 = vcpu->arch.pc; + vcpu->arch.srr0 = kvmppc_get_pc(vcpu); vcpu->arch.srr1 = vcpu->arch.msr | flags; - vcpu->arch.pc = to_book3s(vcpu)->hior + vec; + kvmppc_set_pc(vcpu, to_book3s(vcpu)->hior + vec); vcpu->arch.mmu.reset_msr(vcpu); } @@ -551,20 +559,20 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, if (page_found == -ENOENT) { /* Page not found in guest PTE entries */ - vcpu->arch.dear = vcpu->arch.fault_dear; - to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr; - vcpu->arch.msr |= (vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL); + vcpu->arch.dear = kvmppc_get_fault_dar(vcpu); + to_book3s(vcpu)->dsisr = to_svcpu(vcpu)->fault_dsisr; + vcpu->arch.msr |= (to_svcpu(vcpu)->shadow_srr1 & 0x00000000f8000000ULL); kvmppc_book3s_queue_irqprio(vcpu, vec); } else if (page_found == -EPERM) { /* Storage protection */ - vcpu->arch.dear = vcpu->arch.fault_dear; - to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr & ~DSISR_NOHPTE; + vcpu->arch.dear = kvmppc_get_fault_dar(vcpu); + to_book3s(vcpu)->dsisr = to_svcpu(vcpu)->fault_dsisr & ~DSISR_NOHPTE; to_book3s(vcpu)->dsisr |= DSISR_PROTFAULT; - vcpu->arch.msr |= (vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL); + vcpu->arch.msr |= (to_svcpu(vcpu)->shadow_srr1 & 0x00000000f8000000ULL); kvmppc_book3s_queue_irqprio(vcpu, vec); } else if (page_found == -EINVAL) { /* Page not found in guest SLB */ - vcpu->arch.dear = vcpu->arch.fault_dear; + vcpu->arch.dear = kvmppc_get_fault_dar(vcpu); kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80); } else if (!is_mmio && kvmppc_visible_gfn(vcpu, pte.raddr >> PAGE_SHIFT)) { @@ -646,10 +654,11 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) static int kvmppc_read_inst(struct kvm_vcpu *vcpu) { - ulong srr0 = vcpu->arch.pc; + ulong srr0 = kvmppc_get_pc(vcpu); + u32 last_inst = kvmppc_get_last_inst(vcpu); int ret; - ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &vcpu->arch.last_inst, false); + ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &last_inst, false); if (ret == -ENOENT) { vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 33, 33, 1); vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 34, 36, 0); @@ -754,12 +763,12 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, run->ready_for_interrupt_injection = 1; #ifdef EXIT_DEBUG printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | dar=0x%lx | dec=0x%x | msr=0x%lx\n", - exit_nr, vcpu->arch.pc, vcpu->arch.fault_dear, - kvmppc_get_dec(vcpu), vcpu->arch.msr); + exit_nr, kvmppc_get_pc(vcpu), kvmppc_get_fault_dar(vcpu), + kvmppc_get_dec(vcpu), to_svcpu(vcpu)->shadow_srr1); #elif defined (EXIT_DEBUG_SIMPLE) if ((exit_nr != 0x900) && (exit_nr != 0x500)) printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | dar=0x%lx | msr=0x%lx\n", - exit_nr, vcpu->arch.pc, vcpu->arch.fault_dear, + exit_nr, kvmppc_get_pc(vcpu), kvmppc_get_fault_dar(vcpu), vcpu->arch.msr); #endif kvm_resched(vcpu); @@ -767,8 +776,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, case BOOK3S_INTERRUPT_INST_STORAGE: vcpu->stat.pf_instruc++; /* only care about PTEG not found errors, but leave NX alone */ - if (vcpu->arch.shadow_srr1 & 0x40000000) { - r = kvmppc_handle_pagefault(run, vcpu, vcpu->arch.pc, exit_nr); + if (to_svcpu(vcpu)->shadow_srr1 & 0x40000000) { + r = kvmppc_handle_pagefault(run, vcpu, kvmppc_get_pc(vcpu), exit_nr); vcpu->stat.sp_instruc++; } else if (vcpu->arch.mmu.is_dcbz32(vcpu) && (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) { @@ -777,38 +786,41 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, * so we can't use the NX bit inside the guest. Let's cross our fingers, * that no guest that needs the dcbz hack does NX. */ - kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL); + kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFULL); r = RESUME_GUEST; } else { - vcpu->arch.msr |= vcpu->arch.shadow_srr1 & 0x58000000; + vcpu->arch.msr |= to_svcpu(vcpu)->shadow_srr1 & 0x58000000; kvmppc_book3s_queue_irqprio(vcpu, exit_nr); - kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL); + kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFULL); r = RESUME_GUEST; } break; case BOOK3S_INTERRUPT_DATA_STORAGE: + { + ulong dar = kvmppc_get_fault_dar(vcpu); vcpu->stat.pf_storage++; /* The only case we need to handle is missing shadow PTEs */ - if (vcpu->arch.fault_dsisr & DSISR_NOHPTE) { - r = kvmppc_handle_pagefault(run, vcpu, vcpu->arch.fault_dear, exit_nr); + if (to_svcpu(vcpu)->fault_dsisr & DSISR_NOHPTE) { + r = kvmppc_handle_pagefault(run, vcpu, dar, exit_nr); } else { - vcpu->arch.dear = vcpu->arch.fault_dear; - to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr; + vcpu->arch.dear = dar; + to_book3s(vcpu)->dsisr = to_svcpu(vcpu)->fault_dsisr; kvmppc_book3s_queue_irqprio(vcpu, exit_nr); kvmppc_mmu_pte_flush(vcpu, vcpu->arch.dear, ~0xFFFULL); r = RESUME_GUEST; } break; + } case BOOK3S_INTERRUPT_DATA_SEGMENT: - if (kvmppc_mmu_map_segment(vcpu, vcpu->arch.fault_dear) < 0) { - vcpu->arch.dear = vcpu->arch.fault_dear; + if (kvmppc_mmu_map_segment(vcpu, kvmppc_get_fault_dar(vcpu)) < 0) { + vcpu->arch.dear = kvmppc_get_fault_dar(vcpu); kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_SEGMENT); } r = RESUME_GUEST; break; case BOOK3S_INTERRUPT_INST_SEGMENT: - if (kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc) < 0) { + if (kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu)) < 0) { kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_SEGMENT); } @@ -829,13 +841,13 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, ulong flags; program_interrupt: - flags = vcpu->arch.shadow_srr1 & 0x1f0000ull; + flags = to_svcpu(vcpu)->shadow_srr1 & 0x1f0000ull; if (vcpu->arch.msr & MSR_PR) { #ifdef EXIT_DEBUG - printk(KERN_INFO "Userspace triggered 0x700 exception at 0x%lx (0x%x)\n", vcpu->arch.pc, vcpu->arch.last_inst); + printk(KERN_INFO "Userspace triggered 0x700 exception at 0x%lx (0x%x)\n", kvmppc_get_pc(vcpu), kvmppc_get_last_inst(vcpu)); #endif - if ((vcpu->arch.last_inst & 0xff0007ff) != + if ((kvmppc_get_last_inst(vcpu) & 0xff0007ff) != (INS_DCBZ & 0xfffffff7)) { kvmppc_core_queue_program(vcpu, flags); r = RESUME_GUEST; @@ -854,7 +866,7 @@ program_interrupt: break; case EMULATE_FAIL: printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", - __func__, vcpu->arch.pc, vcpu->arch.last_inst); + __func__, kvmppc_get_pc(vcpu), kvmppc_get_last_inst(vcpu)); kvmppc_core_queue_program(vcpu, flags); r = RESUME_GUEST; break; @@ -917,9 +929,9 @@ program_interrupt: case BOOK3S_INTERRUPT_ALIGNMENT: if (kvmppc_read_inst(vcpu) == EMULATE_DONE) { to_book3s(vcpu)->dsisr = kvmppc_alignment_dsisr(vcpu, - vcpu->arch.last_inst); + kvmppc_get_last_inst(vcpu)); vcpu->arch.dear = kvmppc_alignment_dar(vcpu, - vcpu->arch.last_inst); + kvmppc_get_last_inst(vcpu)); kvmppc_book3s_queue_irqprio(vcpu, exit_nr); } r = RESUME_GUEST; @@ -932,7 +944,7 @@ program_interrupt: default: /* Ugh - bork here! What did we get? */ printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n", - exit_nr, vcpu->arch.pc, vcpu->arch.shadow_srr1); + exit_nr, kvmppc_get_pc(vcpu), to_svcpu(vcpu)->shadow_srr1); r = RESUME_HOST; BUG(); break; @@ -959,7 +971,7 @@ program_interrupt: } #ifdef EXIT_DEBUG - printk(KERN_EMERG "KVM exit: vcpu=0x%p pc=0x%lx r=0x%x\n", vcpu, vcpu->arch.pc, r); + printk(KERN_EMERG "KVM exit: vcpu=0x%p pc=0x%lx r=0x%x\n", vcpu, kvmppc_get_pc(vcpu), r); #endif return r; @@ -976,10 +988,10 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) vcpu_load(vcpu); - regs->pc = vcpu->arch.pc; + regs->pc = kvmppc_get_pc(vcpu); regs->cr = kvmppc_get_cr(vcpu); - regs->ctr = vcpu->arch.ctr; - regs->lr = vcpu->arch.lr; + regs->ctr = kvmppc_get_ctr(vcpu); + regs->lr = kvmppc_get_lr(vcpu); regs->xer = kvmppc_get_xer(vcpu); regs->msr = vcpu->arch.msr; regs->srr0 = vcpu->arch.srr0; @@ -1007,10 +1019,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) vcpu_load(vcpu); - vcpu->arch.pc = regs->pc; + kvmppc_set_pc(vcpu, regs->pc); kvmppc_set_cr(vcpu, regs->cr); - vcpu->arch.ctr = regs->ctr; - vcpu->arch.lr = regs->lr; + kvmppc_set_ctr(vcpu, regs->ctr); + kvmppc_set_lr(vcpu, regs->lr); kvmppc_set_xer(vcpu, regs->xer); kvmppc_set_msr(vcpu, regs->msr); vcpu->arch.srr0 = regs->srr0; @@ -1157,19 +1169,23 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) { struct kvmppc_vcpu_book3s *vcpu_book3s; struct kvm_vcpu *vcpu; - int err; + int err = -ENOMEM; vcpu_book3s = vmalloc(sizeof(struct kvmppc_vcpu_book3s)); - if (!vcpu_book3s) { - err = -ENOMEM; + if (!vcpu_book3s) goto out; - } + memset(vcpu_book3s, 0, sizeof(struct kvmppc_vcpu_book3s)); + vcpu_book3s->shadow_vcpu = (struct kvmppc_book3s_shadow_vcpu *) + kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL); + if (!vcpu_book3s->shadow_vcpu) + goto free_vcpu; + vcpu = &vcpu_book3s->vcpu; err = kvm_vcpu_init(vcpu, kvm, id); if (err) - goto free_vcpu; + goto free_shadow_vcpu; vcpu->arch.host_retip = kvm_return_point; vcpu->arch.host_msr = mfmsr(); @@ -1188,7 +1204,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) err = __init_new_context(); if (err < 0) - goto free_vcpu; + goto free_shadow_vcpu; vcpu_book3s->context_id = err; vcpu_book3s->vsid_max = ((vcpu_book3s->context_id + 1) << USER_ESID_BITS) - 1; @@ -1197,6 +1213,8 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) return vcpu; +free_shadow_vcpu: + kfree(vcpu_book3s->shadow_vcpu); free_vcpu: vfree(vcpu_book3s); out: @@ -1209,6 +1227,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) __destroy_context(vcpu_book3s->context_id); kvm_vcpu_uninit(vcpu); + kfree(vcpu_book3s->shadow_vcpu); vfree(vcpu_book3s); } diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 512dcff77554..12e4c975a376 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c @@ -383,7 +383,7 @@ static void kvmppc_mmu_book3s_64_slbia(struct kvm_vcpu *vcpu) if (vcpu->arch.msr & MSR_IR) { kvmppc_mmu_flush_segments(vcpu); - kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc); + kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu)); } } diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index a01e9c5a3fc7..b0f5b4edaec2 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -331,14 +331,14 @@ static int kvmppc_mmu_next_segment(struct kvm_vcpu *vcpu, ulong esid) int found_inval = -1; int r; - if (!get_paca()->kvm_slb_max) - get_paca()->kvm_slb_max = 1; + if (!to_svcpu(vcpu)->slb_max) + to_svcpu(vcpu)->slb_max = 1; /* Are we overwriting? */ - for (i = 1; i < get_paca()->kvm_slb_max; i++) { - if (!(get_paca()->kvm_slb[i].esid & SLB_ESID_V)) + for (i = 1; i < to_svcpu(vcpu)->slb_max; i++) { + if (!(to_svcpu(vcpu)->slb[i].esid & SLB_ESID_V)) found_inval = i; - else if ((get_paca()->kvm_slb[i].esid & ESID_MASK) == esid) + else if ((to_svcpu(vcpu)->slb[i].esid & ESID_MASK) == esid) return i; } @@ -352,11 +352,11 @@ static int kvmppc_mmu_next_segment(struct kvm_vcpu *vcpu, ulong esid) max_slb_size = mmu_slb_size; /* Overflowing -> purge */ - if ((get_paca()->kvm_slb_max) == max_slb_size) + if ((to_svcpu(vcpu)->slb_max) == max_slb_size) kvmppc_mmu_flush_segments(vcpu); - r = get_paca()->kvm_slb_max; - get_paca()->kvm_slb_max++; + r = to_svcpu(vcpu)->slb_max; + to_svcpu(vcpu)->slb_max++; return r; } @@ -374,7 +374,7 @@ int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr) if (vcpu->arch.mmu.esid_to_vsid(vcpu, esid, &gvsid)) { /* Invalidate an entry */ - get_paca()->kvm_slb[slb_index].esid = 0; + to_svcpu(vcpu)->slb[slb_index].esid = 0; return -ENOENT; } @@ -388,8 +388,8 @@ int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr) slb_vsid &= ~SLB_VSID_KP; slb_esid |= slb_index; - get_paca()->kvm_slb[slb_index].esid = slb_esid; - get_paca()->kvm_slb[slb_index].vsid = slb_vsid; + to_svcpu(vcpu)->slb[slb_index].esid = slb_esid; + to_svcpu(vcpu)->slb[slb_index].vsid = slb_vsid; dprintk_slb("slbmte %#llx, %#llx\n", slb_vsid, slb_esid); @@ -398,8 +398,8 @@ int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr) void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu) { - get_paca()->kvm_slb_max = 1; - get_paca()->kvm_slb[0].esid = 0; + to_svcpu(vcpu)->slb_max = 1; + to_svcpu(vcpu)->slb[0].esid = 0; } void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 8f50776a9a1d..daa829b8f1f1 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -69,7 +69,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, switch (get_xop(inst)) { case OP_19_XOP_RFID: case OP_19_XOP_RFI: - vcpu->arch.pc = vcpu->arch.srr0; + kvmppc_set_pc(vcpu, vcpu->arch.srr0); kvmppc_set_msr(vcpu, vcpu->arch.srr1); *advance = 0; break; @@ -208,7 +208,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, if ((r == -ENOENT) || (r == -EPERM)) { *advance = 0; vcpu->arch.dear = vaddr; - vcpu->arch.fault_dear = vaddr; + to_svcpu(vcpu)->fault_dar = vaddr; dsisr = DSISR_ISSTORE; if (r == -ENOENT) @@ -217,7 +217,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, dsisr |= DSISR_PROTFAULT; to_book3s(vcpu)->dsisr = dsisr; - vcpu->arch.fault_dsisr = dsisr; + to_svcpu(vcpu)->fault_dsisr = dsisr; kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE); diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c index 7a27bac8c44a..a9f66abafcb3 100644 --- a/arch/powerpc/kvm/book3s_paired_singles.c +++ b/arch/powerpc/kvm/book3s_paired_singles.c @@ -656,7 +656,7 @@ static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc, int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) { - u32 inst = vcpu->arch.last_inst; + u32 inst = kvmppc_get_last_inst(vcpu); enum emulation_result emulated = EMULATE_DONE; int ax_rd = inst_get_field(inst, 6, 10); diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index dbb5d6842a51..c6db28cdc594 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -132,7 +132,7 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu) * from opcode tables in the future. */ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) { - u32 inst = vcpu->arch.last_inst; + u32 inst = kvmppc_get_last_inst(vcpu); u32 ea; int ra; int rb; @@ -516,10 +516,11 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) } } - trace_kvm_ppc_instr(inst, vcpu->arch.pc, emulated); + trace_kvm_ppc_instr(inst, kvmppc_get_pc(vcpu), emulated); + /* Advance past emulated instruction. */ if (advance) - vcpu->arch.pc += 4; /* Advance past emulated instruction. */ + kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) + 4); return emulated; } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index ffbe4cac5b15..9b8683f39e05 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -70,7 +70,7 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) case EMULATE_FAIL: /* XXX Deliver Program interrupt to guest. */ printk(KERN_EMERG "%s: emulation failed (%08x)\n", __func__, - vcpu->arch.last_inst); + kvmppc_get_last_inst(vcpu)); r = RESUME_HOST; break; default: -- cgit v1.2.3-59-g8ed1b From c14dea04a248a59fe01f1b49ac94615042016558 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:41 +0200 Subject: KVM: PPC: Use KVM_BOOK3S_HANDLER So far we had a lot of conditional code on CONFIG_KVM_BOOK3S_64_HANDLER. As we're moving towards common code between 32 and 64 bits, most of these ifdefs can be moved to a more generic term define, called CONFIG_KVM_BOOK3S_HANDLER. This patch adds the new generic config option and moves ifdefs over. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s_asm.h | 4 ++-- arch/powerpc/include/asm/paca.h | 2 +- arch/powerpc/kvm/Kconfig | 4 ++++ arch/powerpc/kvm/Makefile | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h index e915e7dfa622..36fdb3aff30b 100644 --- a/arch/powerpc/include/asm/kvm_book3s_asm.h +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h @@ -22,7 +22,7 @@ #ifdef __ASSEMBLY__ -#ifdef CONFIG_KVM_BOOK3S_64_HANDLER +#ifdef CONFIG_KVM_BOOK3S_HANDLER #include @@ -55,7 +55,7 @@ kvmppc_resume_\intno: .macro DO_KVM intno .endm -#endif /* CONFIG_KVM_BOOK3S_64_HANDLER */ +#endif /* CONFIG_KVM_BOOK3S_HANDLER */ #else /*__ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index dc3ccdf81996..33347ea4b47a 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -136,7 +136,7 @@ struct paca_struct { u64 startpurr; /* PURR/TB value snapshot */ u64 startspurr; /* SPURR value snapshot */ -#ifdef CONFIG_KVM_BOOK3S_64_HANDLER +#ifdef CONFIG_KVM_BOOK3S_HANDLER struct { u64 esid; u64 vsid; diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 60624cc9f4d4..8ef37664fda1 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -22,8 +22,12 @@ config KVM select ANON_INODES select KVM_MMIO +config KVM_BOOK3S_HANDLER + bool + config KVM_BOOK3S_64_HANDLER bool + select KVM_BOOK3S_HANDLER config KVM_BOOK3S_64 tristate "KVM support for PowerPC book3s_64 processors" diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 0a67310299a6..f621ce64363b 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -14,7 +14,7 @@ CFLAGS_emulate.o := -I. common-objs-y += powerpc.o emulate.o obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o -obj-$(CONFIG_KVM_BOOK3S_64_HANDLER) += book3s_exports.o +obj-$(CONFIG_KVM_BOOK3S_HANDLER) += book3s_exports.o AFLAGS_booke_interrupts.o := -I$(obj) -- cgit v1.2.3-59-g8ed1b From 00c3a37ca332f54f2187720e51f7c0e18e91d7c9 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:42 +0200 Subject: KVM: PPC: Use CONFIG_PPC_BOOK3S define Upstream recently added a new name for PPC64: Book3S_64. So instead of using CONFIG_PPC64 we should use CONFIG_PPC_BOOK3S consotently. That makes understanding the code easier (I hope). Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_host.h | 8 ++++---- arch/powerpc/kernel/asm-offsets.c | 6 +++--- arch/powerpc/kvm/Kconfig | 2 +- arch/powerpc/kvm/emulate.c | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 5869a487e2e0..22801f802312 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -66,7 +66,7 @@ struct kvm_vcpu_stat { u32 dec_exits; u32 ext_intr_exits; u32 halt_wakeup; -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S u32 pf_storage; u32 pf_instruc; u32 sp_storage; @@ -160,7 +160,7 @@ struct hpte_cache { struct kvm_vcpu_arch { ulong host_stack; u32 host_pid; -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S ulong host_msr; ulong host_r2; void *host_retip; @@ -201,7 +201,7 @@ struct kvm_vcpu_arch { #endif ulong msr; -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S ulong shadow_msr; ulong shadow_srr1; ulong hflags; @@ -283,7 +283,7 @@ struct kvm_vcpu_arch { u64 dec_jiffies; unsigned long pending_exceptions; -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S struct hpte_cache hpte_cache[HPTEG_CACHE_NUM]; int hpte_cache_offset; #endif diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 957ceb7059c5..57a8c49c8830 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -426,8 +426,8 @@ int main(void) DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); - /* book3s_64 */ -#ifdef CONFIG_PPC64 + /* book3s */ +#ifdef CONFIG_PPC_BOOK3S DEFINE(VCPU_FAULT_DSISR, offsetof(struct kvm_vcpu, arch.fault_dsisr)); DEFINE(VCPU_HOST_RETIP, offsetof(struct kvm_vcpu, arch.host_retip)); DEFINE(VCPU_HOST_R2, offsetof(struct kvm_vcpu, arch.host_r2)); @@ -442,7 +442,7 @@ int main(void) #else DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr)); DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer)); -#endif /* CONFIG_PPC64 */ +#endif /* CONFIG_PPC_BOOK3S */ #endif #ifdef CONFIG_44x DEFINE(PGD_T_LOG2, PGD_T_LOG2); diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 8ef37664fda1..d864698860c6 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -31,7 +31,7 @@ config KVM_BOOK3S_64_HANDLER config KVM_BOOK3S_64 tristate "KVM support for PowerPC book3s_64 processors" - depends on EXPERIMENTAL && PPC64 + depends on EXPERIMENTAL && PPC_BOOK3S_64 select KVM select KVM_BOOK3S_64_HANDLER ---help--- diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index c6db28cdc594..b608c0b0beb5 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -69,7 +69,7 @@ #define OP_STH 44 #define OP_STHU 45 -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S static int kvmppc_dec_enabled(struct kvm_vcpu *vcpu) { return 1; @@ -86,7 +86,7 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu) unsigned long dec_nsec; pr_debug("mtDEC: %x\n", vcpu->arch.dec); -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S /* mtdec lowers the interrupt line when positive. */ kvmppc_core_dequeue_dec(vcpu); @@ -153,7 +153,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) switch (get_op(inst)) { case OP_TRAP: -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S case OP_TRAP_64: kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP); #else -- cgit v1.2.3-59-g8ed1b From 56db45a5cd06e3a6a7823a8cd7541e6bafe8427b Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:43 +0200 Subject: PPC: Add STLU For assembly code there are several "long" load and store defines already. The one that's missing is the typical stack store, stdu/stwu. So let's add that define as well, making my KVM code happy. CC: Benjamin Herrenschmidt Signed-off-by: Alexander Graf Acked-by: Benjamin Herrenschmidt Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/asm-compat.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index a9b91ed3d4b9..2048a6aeea91 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h @@ -21,6 +21,7 @@ /* operations for longs and pointers */ #define PPC_LL stringify_in_c(ld) #define PPC_STL stringify_in_c(std) +#define PPC_STLU stringify_in_c(stdu) #define PPC_LCMPI stringify_in_c(cmpdi) #define PPC_LONG stringify_in_c(.llong) #define PPC_LONG_ALIGN stringify_in_c(.balign 8) @@ -44,6 +45,7 @@ /* operations for longs and pointers */ #define PPC_LL stringify_in_c(lwz) #define PPC_STL stringify_in_c(stw) +#define PPC_STLU stringify_in_c(stwu) #define PPC_LCMPI stringify_in_c(cmpwi) #define PPC_LONG stringify_in_c(.long) #define PPC_LONG_ALIGN stringify_in_c(.balign 4) -- cgit v1.2.3-59-g8ed1b From 0604675fe17f68741730cebe74422605bb79d972 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:44 +0200 Subject: KVM: PPC: Use now shadowed vcpu fields The shadow vcpu now contains some fields we don't use from the vcpu anymore. Access to them happens using inline functions that happily use the shadow vcpu fields. So let's now ifdef them out to booke only and add asm-offsets. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_host.h | 8 ++-- arch/powerpc/include/asm/paca.h | 6 --- arch/powerpc/kernel/asm-offsets.c | 91 ++++++++++++++++++++++--------------- 3 files changed, 57 insertions(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 22801f802312..5a83995105f8 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -191,11 +191,11 @@ struct kvm_vcpu_arch { u32 qpr[32]; #endif +#ifdef CONFIG_BOOKE ulong pc; ulong ctr; ulong lr; -#ifdef CONFIG_BOOKE ulong xer; u32 cr; #endif @@ -203,7 +203,6 @@ struct kvm_vcpu_arch { ulong msr; #ifdef CONFIG_PPC_BOOK3S ulong shadow_msr; - ulong shadow_srr1; ulong hflags; ulong guest_owned_ext; #endif @@ -258,14 +257,13 @@ struct kvm_vcpu_arch { struct dentry *debugfs_exit_timing; #endif +#ifdef CONFIG_BOOKE u32 last_inst; -#ifdef CONFIG_PPC64 - u32 fault_dsisr; -#endif ulong fault_dear; ulong fault_esr; ulong queued_dear; ulong queued_esr; +#endif gpa_t paddr_accessed; u8 io_gpr; /* GPR used as IO source/target */ diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 33347ea4b47a..224eb371ca1d 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -137,14 +137,8 @@ struct paca_struct { u64 startspurr; /* SPURR value snapshot */ #ifdef CONFIG_KVM_BOOK3S_HANDLER - struct { - u64 esid; - u64 vsid; - } kvm_slb[64]; /* guest SLB */ /* We use this to store guest state in */ struct kvmppc_book3s_shadow_vcpu shadow_vcpu; - u8 kvm_slb_max; /* highest used guest slb entry */ - u8 kvm_in_guest; /* are we inside the guest? */ #endif }; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 57a8c49c8830..e8003ff81eef 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -50,6 +50,9 @@ #endif #ifdef CONFIG_KVM #include +#ifndef CONFIG_BOOKE +#include +#endif #endif #ifdef CONFIG_PPC32 @@ -191,33 +194,9 @@ int main(void) DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset)); DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); #ifdef CONFIG_KVM_BOOK3S_64_HANDLER - DEFINE(PACA_KVM_IN_GUEST, offsetof(struct paca_struct, kvm_in_guest)); - DEFINE(PACA_KVM_SLB, offsetof(struct paca_struct, kvm_slb)); - DEFINE(PACA_KVM_SLB_MAX, offsetof(struct paca_struct, kvm_slb_max)); - DEFINE(PACA_KVM_CR, offsetof(struct paca_struct, shadow_vcpu.cr)); - DEFINE(PACA_KVM_XER, offsetof(struct paca_struct, shadow_vcpu.xer)); - DEFINE(PACA_KVM_R0, offsetof(struct paca_struct, shadow_vcpu.gpr[0])); - DEFINE(PACA_KVM_R1, offsetof(struct paca_struct, shadow_vcpu.gpr[1])); - DEFINE(PACA_KVM_R2, offsetof(struct paca_struct, shadow_vcpu.gpr[2])); - DEFINE(PACA_KVM_R3, offsetof(struct paca_struct, shadow_vcpu.gpr[3])); - DEFINE(PACA_KVM_R4, offsetof(struct paca_struct, shadow_vcpu.gpr[4])); - DEFINE(PACA_KVM_R5, offsetof(struct paca_struct, shadow_vcpu.gpr[5])); - DEFINE(PACA_KVM_R6, offsetof(struct paca_struct, shadow_vcpu.gpr[6])); - DEFINE(PACA_KVM_R7, offsetof(struct paca_struct, shadow_vcpu.gpr[7])); - DEFINE(PACA_KVM_R8, offsetof(struct paca_struct, shadow_vcpu.gpr[8])); - DEFINE(PACA_KVM_R9, offsetof(struct paca_struct, shadow_vcpu.gpr[9])); - DEFINE(PACA_KVM_R10, offsetof(struct paca_struct, shadow_vcpu.gpr[10])); - DEFINE(PACA_KVM_R11, offsetof(struct paca_struct, shadow_vcpu.gpr[11])); - DEFINE(PACA_KVM_R12, offsetof(struct paca_struct, shadow_vcpu.gpr[12])); - DEFINE(PACA_KVM_R13, offsetof(struct paca_struct, shadow_vcpu.gpr[13])); - DEFINE(PACA_KVM_HOST_R1, offsetof(struct paca_struct, shadow_vcpu.host_r1)); - DEFINE(PACA_KVM_HOST_R2, offsetof(struct paca_struct, shadow_vcpu.host_r2)); - DEFINE(PACA_KVM_VMHANDLER, offsetof(struct paca_struct, - shadow_vcpu.vmhandler)); - DEFINE(PACA_KVM_SCRATCH0, offsetof(struct paca_struct, - shadow_vcpu.scratch0)); - DEFINE(PACA_KVM_SCRATCH1, offsetof(struct paca_struct, - shadow_vcpu.scratch1)); + DEFINE(PACA_KVM_SVCPU, offsetof(struct paca_struct, shadow_vcpu)); + DEFINE(SVCPU_SLB, offsetof(struct kvmppc_book3s_shadow_vcpu, slb)); + DEFINE(SVCPU_SLB_MAX, offsetof(struct kvmppc_book3s_shadow_vcpu, slb_max)); #endif #endif /* CONFIG_PPC64 */ @@ -412,9 +391,6 @@ int main(void) DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack)); DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid)); DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr)); - DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); - DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr)); - DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc)); DEFINE(VCPU_MSR, offsetof(struct kvm_vcpu, arch.msr)); DEFINE(VCPU_SPRG4, offsetof(struct kvm_vcpu, arch.sprg4)); DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5)); @@ -422,26 +398,67 @@ int main(void) DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7)); DEFINE(VCPU_SHADOW_PID, offsetof(struct kvm_vcpu, arch.shadow_pid)); - DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); - DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); - DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); - /* book3s */ #ifdef CONFIG_PPC_BOOK3S - DEFINE(VCPU_FAULT_DSISR, offsetof(struct kvm_vcpu, arch.fault_dsisr)); DEFINE(VCPU_HOST_RETIP, offsetof(struct kvm_vcpu, arch.host_retip)); - DEFINE(VCPU_HOST_R2, offsetof(struct kvm_vcpu, arch.host_r2)); DEFINE(VCPU_HOST_MSR, offsetof(struct kvm_vcpu, arch.host_msr)); DEFINE(VCPU_SHADOW_MSR, offsetof(struct kvm_vcpu, arch.shadow_msr)); - DEFINE(VCPU_SHADOW_SRR1, offsetof(struct kvm_vcpu, arch.shadow_srr1)); DEFINE(VCPU_TRAMPOLINE_LOWMEM, offsetof(struct kvm_vcpu, arch.trampoline_lowmem)); DEFINE(VCPU_TRAMPOLINE_ENTER, offsetof(struct kvm_vcpu, arch.trampoline_enter)); DEFINE(VCPU_HIGHMEM_HANDLER, offsetof(struct kvm_vcpu, arch.highmem_handler)); DEFINE(VCPU_RMCALL, offsetof(struct kvm_vcpu, arch.rmcall)); DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags)); + DEFINE(VCPU_SVCPU, offsetof(struct kvmppc_vcpu_book3s, shadow_vcpu) - + offsetof(struct kvmppc_vcpu_book3s, vcpu)); + DEFINE(SVCPU_CR, offsetof(struct kvmppc_book3s_shadow_vcpu, cr)); + DEFINE(SVCPU_XER, offsetof(struct kvmppc_book3s_shadow_vcpu, xer)); + DEFINE(SVCPU_CTR, offsetof(struct kvmppc_book3s_shadow_vcpu, ctr)); + DEFINE(SVCPU_LR, offsetof(struct kvmppc_book3s_shadow_vcpu, lr)); + DEFINE(SVCPU_PC, offsetof(struct kvmppc_book3s_shadow_vcpu, pc)); + DEFINE(SVCPU_R0, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[0])); + DEFINE(SVCPU_R1, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[1])); + DEFINE(SVCPU_R2, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[2])); + DEFINE(SVCPU_R3, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[3])); + DEFINE(SVCPU_R4, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[4])); + DEFINE(SVCPU_R5, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[5])); + DEFINE(SVCPU_R6, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[6])); + DEFINE(SVCPU_R7, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[7])); + DEFINE(SVCPU_R8, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[8])); + DEFINE(SVCPU_R9, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[9])); + DEFINE(SVCPU_R10, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[10])); + DEFINE(SVCPU_R11, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[11])); + DEFINE(SVCPU_R12, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[12])); + DEFINE(SVCPU_R13, offsetof(struct kvmppc_book3s_shadow_vcpu, gpr[13])); + DEFINE(SVCPU_HOST_R1, offsetof(struct kvmppc_book3s_shadow_vcpu, host_r1)); + DEFINE(SVCPU_HOST_R2, offsetof(struct kvmppc_book3s_shadow_vcpu, host_r2)); + DEFINE(SVCPU_VMHANDLER, offsetof(struct kvmppc_book3s_shadow_vcpu, + vmhandler)); + DEFINE(SVCPU_SCRATCH0, offsetof(struct kvmppc_book3s_shadow_vcpu, + scratch0)); + DEFINE(SVCPU_SCRATCH1, offsetof(struct kvmppc_book3s_shadow_vcpu, + scratch1)); + DEFINE(SVCPU_IN_GUEST, offsetof(struct kvmppc_book3s_shadow_vcpu, + in_guest)); + DEFINE(SVCPU_FAULT_DSISR, offsetof(struct kvmppc_book3s_shadow_vcpu, + fault_dsisr)); + DEFINE(SVCPU_FAULT_DAR, offsetof(struct kvmppc_book3s_shadow_vcpu, + fault_dar)); + DEFINE(SVCPU_LAST_INST, offsetof(struct kvmppc_book3s_shadow_vcpu, + last_inst)); + DEFINE(SVCPU_SHADOW_SRR1, offsetof(struct kvmppc_book3s_shadow_vcpu, + shadow_srr1)); +#ifdef CONFIG_PPC_BOOK3S_32 + DEFINE(SVCPU_SR, offsetof(struct kvmppc_book3s_shadow_vcpu, sr)); +#endif #else DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr)); DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer)); + DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); + DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr)); + DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc)); + DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); + DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); + DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); #endif /* CONFIG_PPC_BOOK3S */ #endif #ifdef CONFIG_44x -- cgit v1.2.3-59-g8ed1b From 9cc5e9538ab7cbbfb1d7263373d2f58ab2af2bad Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:45 +0200 Subject: KVM: PPC: Extract MMU init The host shadow mmu code needs to get initialized. It needs to fetch a segment it can use to put shadow PTEs into. That initialization code was in generic code, which is icky. Let's move it over to the respective MMU file. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_ppc.h | 1 + arch/powerpc/kvm/book3s.c | 8 +------- arch/powerpc/kvm/book3s_64_mmu_host.c | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index edade847b8f8..18d139ec2d22 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -69,6 +69,7 @@ extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr, extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode); extern void kvmppc_mmu_switch_pid(struct kvm_vcpu *vcpu, u32 pid); extern void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu); +extern int kvmppc_mmu_init(struct kvm_vcpu *vcpu); extern int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr); extern int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr); extern gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index, diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 7ff80f9f13a8..d0986968a611 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -1202,14 +1202,9 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) vcpu->arch.shadow_msr = MSR_USER64; - err = __init_new_context(); + err = kvmppc_mmu_init(vcpu); if (err < 0) goto free_shadow_vcpu; - vcpu_book3s->context_id = err; - - vcpu_book3s->vsid_max = ((vcpu_book3s->context_id + 1) << USER_ESID_BITS) - 1; - vcpu_book3s->vsid_first = vcpu_book3s->context_id << USER_ESID_BITS; - vcpu_book3s->vsid_next = vcpu_book3s->vsid_first; return vcpu; @@ -1225,7 +1220,6 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) { struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); - __destroy_context(vcpu_book3s->context_id); kvm_vcpu_uninit(vcpu); kfree(vcpu_book3s->shadow_vcpu); vfree(vcpu_book3s); diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index b0f5b4edaec2..0eea589dbef0 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -405,4 +405,22 @@ void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu) void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) { kvmppc_mmu_pte_flush(vcpu, 0, 0); + __destroy_context(to_book3s(vcpu)->context_id); +} + +int kvmppc_mmu_init(struct kvm_vcpu *vcpu) +{ + struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); + int err; + + err = __init_new_context(); + if (err < 0) + return -1; + vcpu3s->context_id = err; + + vcpu3s->vsid_max = ((vcpu3s->context_id + 1) << USER_ESID_BITS) - 1; + vcpu3s->vsid_first = vcpu3s->context_id << USER_ESID_BITS; + vcpu3s->vsid_next = vcpu3s->vsid_first; + + return 0; } -- cgit v1.2.3-59-g8ed1b From 8c3a4e0b673ba8b274399f575dc803a89a953a66 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:46 +0200 Subject: KVM: PPC: Make real mode handler generic The real mode handler code was originally writen for 64 bit Book3S only. But since we not add 32 bit functionality too, we need to make some tweaks to it. This patch basically combines using the "long" access defines and using fields from the shadow VCPU we just moved there. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_rmhandlers.S | 119 ++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S index d89e315615bc..284f0a03891f 100644 --- a/arch/powerpc/kvm/book3s_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_rmhandlers.S @@ -22,7 +22,10 @@ #include #include #include + +#ifdef CONFIG_PPC_BOOK3S_64 #include +#endif /***************************************************************************** * * @@ -30,6 +33,39 @@ * * ****************************************************************************/ +#if defined(CONFIG_PPC_BOOK3S_64) + +#define LOAD_SHADOW_VCPU(reg) \ + mfspr reg, SPRN_SPRG_PACA + +#define SHADOW_VCPU_OFF PACA_KVM_SVCPU +#define MSR_NOIRQ MSR_KERNEL & ~(MSR_IR | MSR_DR) +#define FUNC(name) GLUE(.,name) + +#elif defined(CONFIG_PPC_BOOK3S_32) + +#define LOAD_SHADOW_VCPU(reg) \ + mfspr reg, SPRN_SPRG_THREAD; \ + lwz reg, THREAD_KVM_SVCPU(reg); \ + /* PPC32 can have a NULL pointer - let's check for that */ \ + mtspr SPRN_SPRG_SCRATCH1, r12; /* Save r12 */ \ + mfcr r12; \ + cmpwi reg, 0; \ + bne 1f; \ + mfspr reg, SPRN_SPRG_SCRATCH0; \ + mtcr r12; \ + mfspr r12, SPRN_SPRG_SCRATCH1; \ + b kvmppc_resume_\intno; \ +1:; \ + mtcr r12; \ + mfspr r12, SPRN_SPRG_SCRATCH1; \ + tophys(reg, reg) + +#define SHADOW_VCPU_OFF 0 +#define MSR_NOIRQ MSR_KERNEL +#define FUNC(name) name + +#endif .macro INTERRUPT_TRAMPOLINE intno @@ -42,19 +78,19 @@ kvmppc_trampoline_\intno: * First thing to do is to find out if we're coming * from a KVM guest or a Linux process. * - * To distinguish, we check a magic byte in the PACA + * To distinguish, we check a magic byte in the PACA/current */ - mfspr r13, SPRN_SPRG_PACA /* r13 = PACA */ - std r12, PACA_KVM_SCRATCH0(r13) + LOAD_SHADOW_VCPU(r13) + PPC_STL r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13) mfcr r12 - stw r12, PACA_KVM_SCRATCH1(r13) - lbz r12, PACA_KVM_IN_GUEST(r13) + stw r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13) + lbz r12, (SHADOW_VCPU_OFF + SVCPU_IN_GUEST)(r13) cmpwi r12, KVM_GUEST_MODE_NONE bne ..kvmppc_handler_hasmagic_\intno /* No KVM guest? Then jump back to the Linux handler! */ - lwz r12, PACA_KVM_SCRATCH1(r13) + lwz r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13) mtcr r12 - ld r12, PACA_KVM_SCRATCH0(r13) + PPC_LL r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13) mfspr r13, SPRN_SPRG_SCRATCH0 /* r13 = original r13 */ b kvmppc_resume_\intno /* Get back original handler */ @@ -76,9 +112,7 @@ kvmppc_trampoline_\intno: INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSTEM_RESET INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_MACHINE_CHECK INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_STORAGE -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_SEGMENT INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_STORAGE -INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_SEGMENT INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_EXTERNAL INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALIGNMENT INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PROGRAM @@ -88,7 +122,14 @@ INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSCALL INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_TRACE INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PERFMON INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALTIVEC + +/* Those are only available on 64 bit machines */ + +#ifdef CONFIG_PPC_BOOK3S_64 +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_SEGMENT +INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_SEGMENT INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_VSX +#endif /* * Bring us back to the faulting code, but skip the @@ -99,11 +140,11 @@ INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_VSX * * Input Registers: * - * R12 = free - * R13 = PACA - * PACA.KVM.SCRATCH0 = guest R12 - * PACA.KVM.SCRATCH1 = guest CR - * SPRG_SCRATCH0 = guest R13 + * R12 = free + * R13 = Shadow VCPU (PACA) + * SVCPU.SCRATCH0 = guest R12 + * SVCPU.SCRATCH1 = guest CR + * SPRG_SCRATCH0 = guest R13 * */ kvmppc_handler_skip_ins: @@ -114,9 +155,9 @@ kvmppc_handler_skip_ins: mtsrr0 r12 /* Clean up all state */ - lwz r12, PACA_KVM_SCRATCH1(r13) + lwz r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13) mtcr r12 - ld r12, PACA_KVM_SCRATCH0(r13) + PPC_LL r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13) mfspr r13, SPRN_SPRG_SCRATCH0 /* And get back into the code */ @@ -147,32 +188,48 @@ kvmppc_handler_lowmem_trampoline_end: * * R3 = function * R4 = MSR - * R5 = CTR + * R5 = scratch register * */ _GLOBAL(kvmppc_rmcall) - mtmsr r4 /* Disable relocation, so mtsrr + LOAD_REG_IMMEDIATE(r5, MSR_NOIRQ) + mtmsr r5 /* Disable relocation and interrupts, so mtsrr doesn't get interrupted */ - mtctr r5 + sync mtsrr0 r3 mtsrr1 r4 RFI +#if defined(CONFIG_PPC_BOOK3S_32) +#define STACK_LR INT_FRAME_SIZE+4 +#elif defined(CONFIG_PPC_BOOK3S_64) +#define STACK_LR _LINK +#endif + /* * Activate current's external feature (FPU/Altivec/VSX) */ -#define define_load_up(what) \ - \ -_GLOBAL(kvmppc_load_up_ ## what); \ - stdu r1, -INT_FRAME_SIZE(r1); \ - mflr r3; \ - std r3, _LINK(r1); \ - \ - bl .load_up_ ## what; \ - \ - ld r3, _LINK(r1); \ - mtlr r3; \ - addi r1, r1, INT_FRAME_SIZE; \ +#define define_load_up(what) \ + \ +_GLOBAL(kvmppc_load_up_ ## what); \ + PPC_STLU r1, -INT_FRAME_SIZE(r1); \ + mflr r3; \ + PPC_STL r3, STACK_LR(r1); \ + PPC_STL r20, _NIP(r1); \ + mfmsr r20; \ + LOAD_REG_IMMEDIATE(r3, MSR_DR|MSR_EE); \ + andc r3,r20,r3; /* Disable DR,EE */ \ + mtmsr r3; \ + sync; \ + \ + bl FUNC(load_up_ ## what); \ + \ + mtmsr r20; /* Enable DR,EE */ \ + sync; \ + PPC_LL r3, STACK_LR(r1); \ + PPC_LL r20, _NIP(r1); \ + mtlr r3; \ + addi r1, r1, INT_FRAME_SIZE; \ blr define_load_up(fpu) -- cgit v1.2.3-59-g8ed1b From b79fcdf67e9e03773fb032679675d8008d5cc2dc Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:47 +0200 Subject: KVM: PPC: Make highmem code generic Since we now have several fields in the shadow VCPU, we also change the internal calling convention between the different entry/exit code layers. Let's reflect that in the IR=1 code and make sure we use "long" defines for long field access. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_interrupts.S | 201 ++++++++++++++++++----------------- 1 file changed, 101 insertions(+), 100 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_interrupts.S b/arch/powerpc/kvm/book3s_interrupts.S index 570f87407691..a1b50280dc47 100644 --- a/arch/powerpc/kvm/book3s_interrupts.S +++ b/arch/powerpc/kvm/book3s_interrupts.S @@ -24,36 +24,56 @@ #include #include -#define KVMPPC_HANDLE_EXIT .kvmppc_handle_exit -#define ULONG_SIZE 8 -#define VCPU_GPR(n) (VCPU_GPRS + (n * ULONG_SIZE)) +#if defined(CONFIG_PPC_BOOK3S_64) -.macro DISABLE_INTERRUPTS - mfmsr r0 - rldicl r0,r0,48,1 - rotldi r0,r0,16 - mtmsrd r0,1 -.endm +#define ULONG_SIZE 8 +#define FUNC(name) GLUE(.,name) +#define GET_SHADOW_VCPU(reg) \ + addi reg, r13, PACA_KVM_SVCPU + +#define DISABLE_INTERRUPTS \ + mfmsr r0; \ + rldicl r0,r0,48,1; \ + rotldi r0,r0,16; \ + mtmsrd r0,1; \ + +#elif defined(CONFIG_PPC_BOOK3S_32) + +#define ULONG_SIZE 4 +#define FUNC(name) name + +#define GET_SHADOW_VCPU(reg) \ + lwz reg, (THREAD + THREAD_KVM_SVCPU)(r2) + +#define DISABLE_INTERRUPTS \ + mfmsr r0; \ + rlwinm r0,r0,0,17,15; \ + mtmsr r0; \ + +#endif /* CONFIG_PPC_BOOK3S_XX */ + + +#define VCPU_GPR(n) (VCPU_GPRS + (n * ULONG_SIZE)) #define VCPU_LOAD_NVGPRS(vcpu) \ - ld r14, VCPU_GPR(r14)(vcpu); \ - ld r15, VCPU_GPR(r15)(vcpu); \ - ld r16, VCPU_GPR(r16)(vcpu); \ - ld r17, VCPU_GPR(r17)(vcpu); \ - ld r18, VCPU_GPR(r18)(vcpu); \ - ld r19, VCPU_GPR(r19)(vcpu); \ - ld r20, VCPU_GPR(r20)(vcpu); \ - ld r21, VCPU_GPR(r21)(vcpu); \ - ld r22, VCPU_GPR(r22)(vcpu); \ - ld r23, VCPU_GPR(r23)(vcpu); \ - ld r24, VCPU_GPR(r24)(vcpu); \ - ld r25, VCPU_GPR(r25)(vcpu); \ - ld r26, VCPU_GPR(r26)(vcpu); \ - ld r27, VCPU_GPR(r27)(vcpu); \ - ld r28, VCPU_GPR(r28)(vcpu); \ - ld r29, VCPU_GPR(r29)(vcpu); \ - ld r30, VCPU_GPR(r30)(vcpu); \ - ld r31, VCPU_GPR(r31)(vcpu); \ + PPC_LL r14, VCPU_GPR(r14)(vcpu); \ + PPC_LL r15, VCPU_GPR(r15)(vcpu); \ + PPC_LL r16, VCPU_GPR(r16)(vcpu); \ + PPC_LL r17, VCPU_GPR(r17)(vcpu); \ + PPC_LL r18, VCPU_GPR(r18)(vcpu); \ + PPC_LL r19, VCPU_GPR(r19)(vcpu); \ + PPC_LL r20, VCPU_GPR(r20)(vcpu); \ + PPC_LL r21, VCPU_GPR(r21)(vcpu); \ + PPC_LL r22, VCPU_GPR(r22)(vcpu); \ + PPC_LL r23, VCPU_GPR(r23)(vcpu); \ + PPC_LL r24, VCPU_GPR(r24)(vcpu); \ + PPC_LL r25, VCPU_GPR(r25)(vcpu); \ + PPC_LL r26, VCPU_GPR(r26)(vcpu); \ + PPC_LL r27, VCPU_GPR(r27)(vcpu); \ + PPC_LL r28, VCPU_GPR(r28)(vcpu); \ + PPC_LL r29, VCPU_GPR(r29)(vcpu); \ + PPC_LL r30, VCPU_GPR(r30)(vcpu); \ + PPC_LL r31, VCPU_GPR(r31)(vcpu); \ /***************************************************************************** * * @@ -69,11 +89,11 @@ _GLOBAL(__kvmppc_vcpu_entry) kvm_start_entry: /* Write correct stack frame */ - mflr r0 - std r0,16(r1) + mflr r0 + PPC_STL r0,PPC_LR_STKOFF(r1) /* Save host state to the stack */ - stdu r1, -SWITCH_FRAME_SIZE(r1) + PPC_STLU r1, -SWITCH_FRAME_SIZE(r1) /* Save r3 (kvm_run) and r4 (vcpu) */ SAVE_2GPRS(3, r1) @@ -82,33 +102,28 @@ kvm_start_entry: SAVE_NVGPRS(r1) /* Save LR */ - std r0, _LINK(r1) + PPC_STL r0, _LINK(r1) /* Load non-volatile guest state from the vcpu */ VCPU_LOAD_NVGPRS(r4) + GET_SHADOW_VCPU(r5) + /* Save R1/R2 in the PACA */ - std r1, PACA_KVM_HOST_R1(r13) - std r2, PACA_KVM_HOST_R2(r13) + PPC_STL r1, SVCPU_HOST_R1(r5) + PPC_STL r2, SVCPU_HOST_R2(r5) /* XXX swap in/out on load? */ - ld r3, VCPU_HIGHMEM_HANDLER(r4) - std r3, PACA_KVM_VMHANDLER(r13) + PPC_LL r3, VCPU_HIGHMEM_HANDLER(r4) + PPC_STL r3, SVCPU_VMHANDLER(r5) kvm_start_lightweight: - ld r9, VCPU_PC(r4) /* r9 = vcpu->arch.pc */ - ld r10, VCPU_SHADOW_MSR(r4) /* r10 = vcpu->arch.shadow_msr */ - - /* Load some guest state in the respective registers */ - ld r5, VCPU_CTR(r4) /* r5 = vcpu->arch.ctr */ - /* will be swapped in by rmcall */ - - ld r3, VCPU_LR(r4) /* r3 = vcpu->arch.lr */ - mtlr r3 /* LR = r3 */ + PPC_LL r10, VCPU_SHADOW_MSR(r4) /* r10 = vcpu->arch.shadow_msr */ DISABLE_INTERRUPTS +#ifdef CONFIG_PPC_BOOK3S_64 /* Some guests may need to have dcbz set to 32 byte length. * * Usually we ensure that by patching the guest's instructions @@ -118,7 +133,7 @@ kvm_start_lightweight: * because that's a lot faster. */ - ld r3, VCPU_HFLAGS(r4) + PPC_LL r3, VCPU_HFLAGS(r4) rldicl. r3, r3, 0, 63 /* CR = ((r3 & 1) == 0) */ beq no_dcbz32_on @@ -128,13 +143,15 @@ kvm_start_lightweight: no_dcbz32_on: - ld r6, VCPU_RMCALL(r4) +#endif /* CONFIG_PPC_BOOK3S_64 */ + + PPC_LL r6, VCPU_RMCALL(r4) mtctr r6 - ld r3, VCPU_TRAMPOLINE_ENTER(r4) + PPC_LL r3, VCPU_TRAMPOLINE_ENTER(r4) LOAD_REG_IMMEDIATE(r4, MSR_KERNEL & ~(MSR_IR | MSR_DR)) - /* Jump to SLB patching handlder and into our guest */ + /* Jump to segment patching handler and into our guest */ bctr /* @@ -149,31 +166,20 @@ kvmppc_handler_highmem: /* * Register usage at this point: * - * R0 = guest last inst - * R1 = host R1 - * R2 = host R2 - * R3 = guest PC - * R4 = guest MSR - * R5 = guest DAR - * R6 = guest DSISR - * R13 = PACA - * PACA.KVM.* = guest * + * R1 = host R1 + * R2 = host R2 + * R12 = exit handler id + * R13 = PACA + * SVCPU.* = guest * * */ /* R7 = vcpu */ - ld r7, GPR4(r1) - - /* Now save the guest state */ - - stw r0, VCPU_LAST_INST(r7) + PPC_LL r7, GPR4(r1) - std r3, VCPU_PC(r7) - std r4, VCPU_SHADOW_SRR1(r7) - std r5, VCPU_FAULT_DEAR(r7) - stw r6, VCPU_FAULT_DSISR(r7) +#ifdef CONFIG_PPC_BOOK3S_64 - ld r5, VCPU_HFLAGS(r7) + PPC_LL r5, VCPU_HFLAGS(r7) rldicl. r5, r5, 0, 63 /* CR = ((r5 & 1) == 0) */ beq no_dcbz32_off @@ -184,35 +190,29 @@ kvmppc_handler_highmem: no_dcbz32_off: - std r14, VCPU_GPR(r14)(r7) - std r15, VCPU_GPR(r15)(r7) - std r16, VCPU_GPR(r16)(r7) - std r17, VCPU_GPR(r17)(r7) - std r18, VCPU_GPR(r18)(r7) - std r19, VCPU_GPR(r19)(r7) - std r20, VCPU_GPR(r20)(r7) - std r21, VCPU_GPR(r21)(r7) - std r22, VCPU_GPR(r22)(r7) - std r23, VCPU_GPR(r23)(r7) - std r24, VCPU_GPR(r24)(r7) - std r25, VCPU_GPR(r25)(r7) - std r26, VCPU_GPR(r26)(r7) - std r27, VCPU_GPR(r27)(r7) - std r28, VCPU_GPR(r28)(r7) - std r29, VCPU_GPR(r29)(r7) - std r30, VCPU_GPR(r30)(r7) - std r31, VCPU_GPR(r31)(r7) - - /* Save guest CTR */ - mfctr r5 - std r5, VCPU_CTR(r7) - - /* Save guest LR */ - mflr r5 - std r5, VCPU_LR(r7) +#endif /* CONFIG_PPC_BOOK3S_64 */ + + PPC_STL r14, VCPU_GPR(r14)(r7) + PPC_STL r15, VCPU_GPR(r15)(r7) + PPC_STL r16, VCPU_GPR(r16)(r7) + PPC_STL r17, VCPU_GPR(r17)(r7) + PPC_STL r18, VCPU_GPR(r18)(r7) + PPC_STL r19, VCPU_GPR(r19)(r7) + PPC_STL r20, VCPU_GPR(r20)(r7) + PPC_STL r21, VCPU_GPR(r21)(r7) + PPC_STL r22, VCPU_GPR(r22)(r7) + PPC_STL r23, VCPU_GPR(r23)(r7) + PPC_STL r24, VCPU_GPR(r24)(r7) + PPC_STL r25, VCPU_GPR(r25)(r7) + PPC_STL r26, VCPU_GPR(r26)(r7) + PPC_STL r27, VCPU_GPR(r27)(r7) + PPC_STL r28, VCPU_GPR(r28)(r7) + PPC_STL r29, VCPU_GPR(r29)(r7) + PPC_STL r30, VCPU_GPR(r30)(r7) + PPC_STL r31, VCPU_GPR(r31)(r7) /* Restore host msr -> SRR1 */ - ld r6, VCPU_HOST_MSR(r7) + PPC_LL r6, VCPU_HOST_MSR(r7) /* * For some interrupts, we need to call the real Linux @@ -231,6 +231,7 @@ no_dcbz32_off: /* Back to EE=1 */ mtmsr r6 + sync b kvm_return_point call_linux_handler: @@ -249,14 +250,14 @@ call_linux_handler: */ /* Restore host IP -> SRR0 */ - ld r5, VCPU_HOST_RETIP(r7) + PPC_LL r5, VCPU_HOST_RETIP(r7) /* XXX Better move to a safe function? * What if we get an HTAB flush in between mtsrr0 and mtsrr1? */ mtlr r12 - ld r4, VCPU_TRAMPOLINE_LOWMEM(r7) + PPC_LL r4, VCPU_TRAMPOLINE_LOWMEM(r7) mtsrr0 r4 LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR)) mtsrr1 r3 @@ -274,7 +275,7 @@ kvm_return_point: /* Restore r3 (kvm_run) and r4 (vcpu) */ REST_2GPRS(3, r1) - bl KVMPPC_HANDLE_EXIT + bl FUNC(kvmppc_handle_exit) /* If RESUME_GUEST, get back in the loop */ cmpwi r3, RESUME_GUEST @@ -285,7 +286,7 @@ kvm_return_point: kvm_exit_loop: - ld r4, _LINK(r1) + PPC_LL r4, _LINK(r1) mtlr r4 /* Restore non-volatile host registers (r14 - r31) */ @@ -296,8 +297,8 @@ kvm_exit_loop: kvm_loop_heavyweight: - ld r4, _LINK(r1) - std r4, (16 + SWITCH_FRAME_SIZE)(r1) + PPC_LL r4, _LINK(r1) + PPC_STL r4, (PPC_LR_STKOFF + SWITCH_FRAME_SIZE)(r1) /* Load vcpu and cpu_run */ REST_2GPRS(3, r1) -- cgit v1.2.3-59-g8ed1b From 53e5b8bbbd0d0305234b2cfeae400183db98f993 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:48 +0200 Subject: KVM: PPC: Make SLB switching code the new segment framework We just introduced generic segment switching code that only needs to call small macros to do the actual switching, but keeps most of the entry / exit code generic. So let's move the SLB switching code over to use this new mechanism. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_slb.S | 183 +++++------------------------------ arch/powerpc/kvm/book3s_rmhandlers.S | 2 +- 2 files changed, 25 insertions(+), 160 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_slb.S b/arch/powerpc/kvm/book3s_64_slb.S index 091967907954..04e7d3bbfe8b 100644 --- a/arch/powerpc/kvm/book3s_64_slb.S +++ b/arch/powerpc/kvm/book3s_64_slb.S @@ -44,8 +44,7 @@ slb_exit_skip_ ## num: * * *****************************************************************************/ -.global kvmppc_handler_trampoline_enter -kvmppc_handler_trampoline_enter: +.macro LOAD_GUEST_SEGMENTS /* Required state: * @@ -53,20 +52,14 @@ kvmppc_handler_trampoline_enter: * R13 = PACA * R1 = host R1 * R2 = host R2 - * R9 = guest IP - * R10 = guest MSR - * all other GPRS = free - * PACA[KVM_CR] = guest CR - * PACA[KVM_XER] = guest XER + * R3 = shadow vcpu + * all other volatile GPRS = free + * SVCPU[CR] = guest CR + * SVCPU[XER] = guest XER + * SVCPU[CTR] = guest CTR + * SVCPU[LR] = guest LR */ - mtsrr0 r9 - mtsrr1 r10 - - /* Activate guest mode, so faults get handled by KVM */ - li r11, KVM_GUEST_MODE_GUEST - stb r11, PACA_KVM_IN_GUEST(r13) - /* Remove LPAR shadow entries */ #if SLB_NUM_BOLTED == 3 @@ -101,14 +94,14 @@ kvmppc_handler_trampoline_enter: /* Fill SLB with our shadow */ - lbz r12, PACA_KVM_SLB_MAX(r13) + lbz r12, SVCPU_SLB_MAX(r3) mulli r12, r12, 16 - addi r12, r12, PACA_KVM_SLB - add r12, r12, r13 + addi r12, r12, SVCPU_SLB + add r12, r12, r3 /* for (r11 = kvm_slb; r11 < kvm_slb + kvm_slb_size; r11+=slb_entry) */ - li r11, PACA_KVM_SLB - add r11, r11, r13 + li r11, SVCPU_SLB + add r11, r11, r3 slb_loop_enter: @@ -127,34 +120,7 @@ slb_loop_enter_skip: slb_do_enter: - /* Enter guest */ - - ld r0, (PACA_KVM_R0)(r13) - ld r1, (PACA_KVM_R1)(r13) - ld r2, (PACA_KVM_R2)(r13) - ld r3, (PACA_KVM_R3)(r13) - ld r4, (PACA_KVM_R4)(r13) - ld r5, (PACA_KVM_R5)(r13) - ld r6, (PACA_KVM_R6)(r13) - ld r7, (PACA_KVM_R7)(r13) - ld r8, (PACA_KVM_R8)(r13) - ld r9, (PACA_KVM_R9)(r13) - ld r10, (PACA_KVM_R10)(r13) - ld r12, (PACA_KVM_R12)(r13) - - lwz r11, (PACA_KVM_CR)(r13) - mtcr r11 - - lwz r11, (PACA_KVM_XER)(r13) - mtxer r11 - - ld r11, (PACA_KVM_R11)(r13) - ld r13, (PACA_KVM_R13)(r13) - - RFI -kvmppc_handler_trampoline_enter_end: - - +.endm /****************************************************************************** * * @@ -162,99 +128,22 @@ kvmppc_handler_trampoline_enter_end: * * *****************************************************************************/ -.global kvmppc_handler_trampoline_exit -kvmppc_handler_trampoline_exit: +.macro LOAD_HOST_SEGMENTS /* Register usage at this point: * - * SPRG_SCRATCH0 = guest R13 - * R12 = exit handler id - * R13 = PACA - * PACA.KVM.SCRATCH0 = guest R12 - * PACA.KVM.SCRATCH1 = guest CR + * R1 = host R1 + * R2 = host R2 + * R12 = exit handler id + * R13 = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64] + * SVCPU.* = guest * + * SVCPU[CR] = guest CR + * SVCPU[XER] = guest XER + * SVCPU[CTR] = guest CTR + * SVCPU[LR] = guest LR * */ - /* Save registers */ - - std r0, PACA_KVM_R0(r13) - std r1, PACA_KVM_R1(r13) - std r2, PACA_KVM_R2(r13) - std r3, PACA_KVM_R3(r13) - std r4, PACA_KVM_R4(r13) - std r5, PACA_KVM_R5(r13) - std r6, PACA_KVM_R6(r13) - std r7, PACA_KVM_R7(r13) - std r8, PACA_KVM_R8(r13) - std r9, PACA_KVM_R9(r13) - std r10, PACA_KVM_R10(r13) - std r11, PACA_KVM_R11(r13) - - /* Restore R1/R2 so we can handle faults */ - ld r1, PACA_KVM_HOST_R1(r13) - ld r2, PACA_KVM_HOST_R2(r13) - - /* Save guest PC and MSR in GPRs */ - mfsrr0 r3 - mfsrr1 r4 - - /* Get scratch'ed off registers */ - mfspr r9, SPRN_SPRG_SCRATCH0 - std r9, PACA_KVM_R13(r13) - - ld r8, PACA_KVM_SCRATCH0(r13) - std r8, PACA_KVM_R12(r13) - - lwz r7, PACA_KVM_SCRATCH1(r13) - stw r7, PACA_KVM_CR(r13) - - /* Save more register state */ - - mfxer r6 - stw r6, PACA_KVM_XER(r13) - - mfdar r5 - mfdsisr r6 - - /* - * In order for us to easily get the last instruction, - * we got the #vmexit at, we exploit the fact that the - * virtual layout is still the same here, so we can just - * ld from the guest's PC address - */ - - /* We only load the last instruction when it's safe */ - cmpwi r12, BOOK3S_INTERRUPT_DATA_STORAGE - beq ld_last_inst - cmpwi r12, BOOK3S_INTERRUPT_PROGRAM - beq ld_last_inst - - b no_ld_last_inst - -ld_last_inst: - /* Save off the guest instruction we're at */ - - /* Set guest mode to 'jump over instruction' so if lwz faults - * we'll just continue at the next IP. */ - li r9, KVM_GUEST_MODE_SKIP - stb r9, PACA_KVM_IN_GUEST(r13) - - /* 1) enable paging for data */ - mfmsr r9 - ori r11, r9, MSR_DR /* Enable paging for data */ - mtmsr r11 - /* 2) fetch the instruction */ - li r0, KVM_INST_FETCH_FAILED /* In case lwz faults */ - lwz r0, 0(r3) - /* 3) disable paging again */ - mtmsr r9 - -no_ld_last_inst: - - /* Unset guest mode */ - li r9, KVM_GUEST_MODE_NONE - stb r9, PACA_KVM_IN_GUEST(r13) - /* Restore bolted entries from the shadow and fix it along the way */ /* We don't store anything in entry 0, so we don't need to take care of it */ @@ -275,28 +164,4 @@ no_ld_last_inst: slb_do_exit: - /* Register usage at this point: - * - * R0 = guest last inst - * R1 = host R1 - * R2 = host R2 - * R3 = guest PC - * R4 = guest MSR - * R5 = guest DAR - * R6 = guest DSISR - * R12 = exit handler id - * R13 = PACA - * PACA.KVM.* = guest * - * - */ - - /* RFI into the highmem handler */ - mfmsr r7 - ori r7, r7, MSR_IR|MSR_DR|MSR_RI /* Enable paging */ - mtsrr1 r7 - ld r8, PACA_KVM_VMHANDLER(r13) /* Highmem handler address */ - mtsrr0 r8 - - RFI -kvmppc_handler_trampoline_exit_end: - +.endm diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S index 284f0a03891f..8a1c4bdb58b3 100644 --- a/arch/powerpc/kvm/book3s_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_rmhandlers.S @@ -248,4 +248,4 @@ kvmppc_trampoline_lowmem: kvmppc_trampoline_enter: .long kvmppc_handler_trampoline_enter - _stext -#include "book3s_64_slb.S" +#include "book3s_segment.S" -- cgit v1.2.3-59-g8ed1b From 33fd27c7d26ec869f637634526e7293027bd8746 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:49 +0200 Subject: KVM: PPC: Release clean pages as clean When we mapped a page as read-only, we can just release it as clean to KVM's page claim mechanisms, because we're pretty sure it hasn't been touched. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_mmu_host.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 0eea589dbef0..b23015438371 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -55,7 +55,11 @@ static void invalidate_pte(struct hpte_cache *pte) MMU_PAGE_4K, MMU_SEGSIZE_256M, false); pte->host_va = 0; - kvm_release_pfn_dirty(pte->pfn); + + if (pte->pte.may_write) + kvm_release_pfn_dirty(pte->pfn); + else + kvm_release_pfn_clean(pte->pfn); } void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 guest_ea, u64 ea_mask) -- cgit v1.2.3-59-g8ed1b From 0474b259d0366a70ea83b94534c333093c189421 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:50 +0200 Subject: KVM: PPC: Remove fetch fail code When instruction fetch failed, the inline function hook automatically detects that and starts the internal guest memory load function. So whenever we access kvmppc_get_last_inst(), we're sure the result is sane. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/emulate.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index b608c0b0beb5..4568ec386c2a 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -147,10 +147,6 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst)); - /* Try again next time */ - if (inst == KVM_INST_FETCH_FAILED) - return EMULATE_DONE; - switch (get_op(inst)) { case OP_TRAP: #ifdef CONFIG_PPC_BOOK3S -- cgit v1.2.3-59-g8ed1b From 97e492558f423d99c51eb934506b7a3d7c64613b Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:51 +0200 Subject: KVM: PPC: Add SVCPU to Book3S_32 We need to keep the pointer to the shadow vcpu somewhere accessible from within really early interrupt code. The best fit I found was the thread struct, as that resides in an SPRG. So let's put a pointer to the shadow vcpu in the thread struct and add an asm-offset so we can find it. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/processor.h | 3 +++ arch/powerpc/kernel/asm-offsets.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 221ba6240464..7492fe8ad6e4 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -229,6 +229,9 @@ struct thread_struct { unsigned long spefscr; /* SPE & eFP status */ int used_spe; /* set if process has used spe */ #endif /* CONFIG_SPE */ +#ifdef CONFIG_KVM_BOOK3S_32_HANDLER + void* kvm_shadow_vcpu; /* KVM internal data */ +#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */ }; #define ARCH_MIN_TASKALIGN 16 diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index e8003ff81eef..1804c2cd1dfd 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -108,6 +108,9 @@ int main(void) DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe)); #endif /* CONFIG_SPE */ #endif /* CONFIG_PPC64 */ +#ifdef CONFIG_KVM_BOOK3S_32_HANDLER + DEFINE(THREAD_KVM_SVCPU, offsetof(struct thread_struct, kvm_shadow_vcpu)); +#endif DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); -- cgit v1.2.3-59-g8ed1b From 61db97cc1e7fce4fd16f72b1350e1728797fa26f Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:52 +0200 Subject: KVM: PPC: Emulate segment fault Book3S_32 doesn't know about segment faults. It only knows about page faults. So in order to know that we didn't map a segment, we need to fake segment faults. We do this by setting invalid segment registers to an invalid VSID and then check for that VSID on normal page faults. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index d0986968a611..f8ac26599f6d 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -775,6 +775,18 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, switch (exit_nr) { case BOOK3S_INTERRUPT_INST_STORAGE: vcpu->stat.pf_instruc++; + +#ifdef CONFIG_PPC_BOOK3S_32 + /* We set segments as unused segments when invalidating them. So + * treat the respective fault as segment fault. */ + if (to_svcpu(vcpu)->sr[kvmppc_get_pc(vcpu) >> SID_SHIFT] + == SR_INVALID) { + kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu)); + r = RESUME_GUEST; + break; + } +#endif + /* only care about PTEG not found errors, but leave NX alone */ if (to_svcpu(vcpu)->shadow_srr1 & 0x40000000) { r = kvmppc_handle_pagefault(run, vcpu, kvmppc_get_pc(vcpu), exit_nr); @@ -799,6 +811,17 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, { ulong dar = kvmppc_get_fault_dar(vcpu); vcpu->stat.pf_storage++; + +#ifdef CONFIG_PPC_BOOK3S_32 + /* We set segments as unused segments when invalidating them. So + * treat the respective fault as segment fault. */ + if ((to_svcpu(vcpu)->sr[dar >> SID_SHIFT]) == SR_INVALID) { + kvmppc_mmu_map_segment(vcpu, dar); + r = RESUME_GUEST; + break; + } +#endif + /* The only case we need to handle is missing shadow PTEs */ if (to_svcpu(vcpu)->fault_dsisr & DSISR_NOHPTE) { r = kvmppc_handle_pagefault(run, vcpu, dar, exit_nr); -- cgit v1.2.3-59-g8ed1b From 07b0907db19d28dc74e7927d565655690b96daf7 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:53 +0200 Subject: KVM: PPC: Add Book3S compatibility code Some code we had so far required defines and had code that was completely Book3S_64 specific. Since we now opened book3s.c to Book3S_32 too, we need to take care of these pieces. So let's add some minor code where it makes sense to not go the Book3S_64 code paths and add compat defines on others. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 26 +++++++++++++++++++++++++- arch/powerpc/kvm/book3s_32_mmu.c | 3 +++ arch/powerpc/kvm/book3s_emulate.c | 4 ++++ arch/powerpc/kvm/book3s_rmhandlers.S | 4 ++-- 4 files changed, 34 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index f8ac26599f6d..61ae0faf0d24 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -40,6 +40,13 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, ulong msr); +/* Some compatibility defines */ +#ifdef CONFIG_PPC_BOOK3S_32 +#define MSR_USER32 MSR_USER +#define MSR_USER64 MSR_USER +#define HW_PAGE_SIZE PAGE_SIZE +#endif + struct kvm_stats_debugfs_item debugfs_entries[] = { { "exits", VCPU_STAT(sum_exits) }, { "mmio", VCPU_STAT(mmio_exits) }, @@ -348,11 +355,14 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) { vcpu->arch.hflags &= ~BOOK3S_HFLAG_SLB; vcpu->arch.pvr = pvr; +#ifdef CONFIG_PPC_BOOK3S_64 if ((pvr >= 0x330000) && (pvr < 0x70330000)) { kvmppc_mmu_book3s_64_init(vcpu); to_book3s(vcpu)->hior = 0xfff00000; to_book3s(vcpu)->msr_mask = 0xffffffffffffffffULL; - } else { + } else +#endif + { kvmppc_mmu_book3s_32_init(vcpu); to_book3s(vcpu)->hior = 0; to_book3s(vcpu)->msr_mask = 0xffffffffULL; @@ -369,6 +379,11 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) really needs them in a VM on Cell and force disable them. */ if (!strcmp(cur_cpu_spec->platform, "ppc-cell-be")) to_book3s(vcpu)->msr_mask &= ~(MSR_FE0 | MSR_FE1); + +#ifdef CONFIG_PPC_BOOK3S_32 + /* 32 bit Book3S always has 32 byte dcbz */ + vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; +#endif } /* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To @@ -1212,8 +1227,13 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) vcpu->arch.host_retip = kvm_return_point; vcpu->arch.host_msr = mfmsr(); +#ifdef CONFIG_PPC_BOOK3S_64 /* default to book3s_64 (970fx) */ vcpu->arch.pvr = 0x3C0301; +#else + /* default to book3s_32 (750) */ + vcpu->arch.pvr = 0x84202; +#endif kvmppc_set_pvr(vcpu, vcpu->arch.pvr); vcpu_book3s->slb_nr = 64; @@ -1221,7 +1241,11 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) vcpu->arch.trampoline_lowmem = kvmppc_trampoline_lowmem; vcpu->arch.trampoline_enter = kvmppc_trampoline_enter; vcpu->arch.highmem_handler = (ulong)kvmppc_handler_highmem; +#ifdef CONFIG_PPC_BOOK3S_64 vcpu->arch.rmcall = *(ulong*)kvmppc_rmcall; +#else + vcpu->arch.rmcall = (ulong)kvmppc_rmcall; +#endif vcpu->arch.shadow_msr = MSR_USER64; diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index 7071e22b42ff..48efb37500a1 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c @@ -45,6 +45,9 @@ #define PTEG_FLAG_ACCESSED 0x00000100 #define PTEG_FLAG_DIRTY 0x00000080 +#ifndef SID_SHIFT +#define SID_SHIFT 28 +#endif static inline bool check_debug_ip(struct kvm_vcpu *vcpu) { diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index daa829b8f1f1..3f7afb5f3483 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -59,6 +59,10 @@ #define SPRN_GQR6 918 #define SPRN_GQR7 919 +/* Book3S_32 defines mfsrin(v) - but that messes up our abstract + * function pointers, so let's just disable the define. */ +#undef mfsrin + int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, unsigned int inst, int *advance) { diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S index 8a1c4bdb58b3..506d5c316c96 100644 --- a/arch/powerpc/kvm/book3s_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_rmhandlers.S @@ -242,10 +242,10 @@ define_load_up(vsx) .global kvmppc_trampoline_lowmem kvmppc_trampoline_lowmem: - .long kvmppc_handler_lowmem_trampoline - _stext + .long kvmppc_handler_lowmem_trampoline - CONFIG_KERNEL_START .global kvmppc_trampoline_enter kvmppc_trampoline_enter: - .long kvmppc_handler_trampoline_enter - _stext + .long kvmppc_handler_trampoline_enter - CONFIG_KERNEL_START #include "book3s_segment.S" -- cgit v1.2.3-59-g8ed1b From be85669886776faa496b026b344691c325727731 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:54 +0200 Subject: KVM: PPC: Export MMU variables Our shadow MMU code needs to know where the HTAB is located and how big it is. So we need some variables from the kernel exported to module space if KVM is built as a module. CC: Benjamin Herrenschmidt Signed-off-by: Alexander Graf Acked-by: Benjamin Herrenschmidt Signed-off-by: Avi Kivity --- arch/powerpc/kernel/ppc_ksyms.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index bc9f39d2598b..2b7c43f95bb2 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -178,6 +178,11 @@ EXPORT_SYMBOL(switch_mmu_context); extern long mol_trampoline; EXPORT_SYMBOL(mol_trampoline); /* For MOL */ EXPORT_SYMBOL(flush_hash_pages); /* For MOL */ + +extern struct hash_pte *Hash; +extern unsigned long _SDR1; +EXPORT_SYMBOL_GPL(Hash); /* For KVM */ +EXPORT_SYMBOL_GPL(_SDR1); /* For KVM */ #ifdef CONFIG_SMP extern int mmu_hash_lock; EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */ -- cgit v1.2.3-59-g8ed1b From 218d169c4c856eee7df56ea0fb8cbb32167e63d3 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:55 +0200 Subject: PPC: Export SWITCH_FRAME_SIZE We need the SWITCH_FRAME_SIZE define on Book3S_32 now too. So let's export it unconditionally. CC: Benjamin Herrenschmidt Signed-off-by: Alexander Graf Acked-by: Benjamin Herrenschmidt Signed-off-by: Avi Kivity --- arch/powerpc/kernel/asm-offsets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 1804c2cd1dfd..2716c51906d6 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -210,8 +210,8 @@ int main(void) /* Interrupt register frame */ DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD); DEFINE(INT_FRAME_SIZE, STACK_INT_FRAME_SIZE); -#ifdef CONFIG_PPC64 DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); +#ifdef CONFIG_PPC64 /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */ DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); -- cgit v1.2.3-59-g8ed1b From ada7ba17b4054f303ad62d91ffd22bc4afad1657 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:56 +0200 Subject: KVM: PPC: Check max IRQ prio We have a define on what the highest bit of IRQ priorities is. So we can just as well use it in the bit checking code and avoid invalid IRQ values to be triggered. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 61ae0faf0d24..ec0a6512ab09 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -337,7 +337,7 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions); #endif priority = __ffs(*pending); - while (priority <= (sizeof(unsigned int) * 8)) { + while (priority < BOOK3S_IRQPRIO_MAX) { if (kvmppc_book3s_irqprio_deliver(vcpu, priority) && (priority != BOOK3S_IRQPRIO_DECREMENTER)) { /* DEC interrupts get cleared by mtdec */ -- cgit v1.2.3-59-g8ed1b From dd84c21748d9280f210565429b1bdb9b6353e8d2 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:57 +0200 Subject: KVM: PPC: Add KVM intercept handlers When an interrupt occurs we don't know yet if we're in guest context or in host context. When in guest context, KVM needs to handle it. So let's pull the same trick we did on Book3S_64: Just add a macro to determine if we're in guest context or not and if so jump on to KVM code. CC: Benjamin Herrenschmidt Signed-off-by: Alexander Graf Acked-by: Benjamin Herrenschmidt Signed-off-by: Avi Kivity --- arch/powerpc/kernel/head_32.S | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index e025e89fe93e..98c4b29a56f4 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -33,6 +33,7 @@ #include #include #include +#include /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ #define LOAD_BAT(n, reg, RA, RB) \ @@ -303,6 +304,7 @@ __secondary_hold_acknowledge: */ #define EXCEPTION(n, label, hdlr, xfer) \ . = n; \ + DO_KVM n; \ label: \ EXCEPTION_PROLOG; \ addi r3,r1,STACK_FRAME_OVERHEAD; \ @@ -358,6 +360,7 @@ i##n: \ * -- paulus. */ . = 0x200 + DO_KVM 0x200 mtspr SPRN_SPRG_SCRATCH0,r10 mtspr SPRN_SPRG_SCRATCH1,r11 mfcr r10 @@ -381,6 +384,7 @@ i##n: \ /* Data access exception. */ . = 0x300 + DO_KVM 0x300 DataAccess: EXCEPTION_PROLOG mfspr r10,SPRN_DSISR @@ -397,6 +401,7 @@ DataAccess: /* Instruction access exception. */ . = 0x400 + DO_KVM 0x400 InstructionAccess: EXCEPTION_PROLOG andis. r0,r9,0x4000 /* no pte found? */ @@ -413,6 +418,7 @@ InstructionAccess: /* Alignment exception */ . = 0x600 + DO_KVM 0x600 Alignment: EXCEPTION_PROLOG mfspr r4,SPRN_DAR @@ -427,6 +433,7 @@ Alignment: /* Floating-point unavailable */ . = 0x800 + DO_KVM 0x800 FPUnavailable: BEGIN_FTR_SECTION /* @@ -450,6 +457,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE) /* System call */ . = 0xc00 + DO_KVM 0xc00 SystemCall: EXCEPTION_PROLOG EXC_XFER_EE_LITE(0xc00, DoSyscall) @@ -467,9 +475,11 @@ SystemCall: * by executing an altivec instruction. */ . = 0xf00 + DO_KVM 0xf00 b PerformanceMonitor . = 0xf20 + DO_KVM 0xf20 b AltiVecUnavailable /* @@ -882,6 +892,10 @@ __secondary_start: RFI #endif /* CONFIG_SMP */ +#ifdef CONFIG_KVM_BOOK3S_HANDLER +#include "../kvm/book3s_rmhandlers.S" +#endif + /* * Those generic dummy functions are kept for CPUs not * included in CONFIG_6xx -- cgit v1.2.3-59-g8ed1b From 4f84139037b0c006c906cacbe904b25ccd4dfff9 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 16 Apr 2010 00:11:58 +0200 Subject: KVM: PPC: Enable Book3S_32 KVM building Now that we have all the bits and pieces in place, let's enable building of the Book3S_32 target. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/Kconfig | 18 ++++++++++++++++++ arch/powerpc/kvm/Makefile | 12 ++++++++++++ 2 files changed, 30 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index d864698860c6..b7baff78f90c 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -25,10 +25,28 @@ config KVM config KVM_BOOK3S_HANDLER bool +config KVM_BOOK3S_32_HANDLER + bool + select KVM_BOOK3S_HANDLER + config KVM_BOOK3S_64_HANDLER bool select KVM_BOOK3S_HANDLER +config KVM_BOOK3S_32 + tristate "KVM support for PowerPC book3s_32 processors" + depends on EXPERIMENTAL && PPC_BOOK3S_32 && !SMP && !PTE_64BIT + select KVM + select KVM_BOOK3S_32_HANDLER + ---help--- + Support running unmodified book3s_32 guest kernels + in virtual machines on book3s_32 host processors. + + This module provides access to the hardware capabilities through + a character device node named /dev/kvm. + + If unsure, say N. + config KVM_BOOK3S_64 tristate "KVM support for PowerPC book3s_64 processors" depends on EXPERIMENTAL && PPC_BOOK3S_64 diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index f621ce64363b..ff436066bf77 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -50,9 +50,21 @@ kvm-book3s_64-objs := \ book3s_32_mmu.o kvm-objs-$(CONFIG_KVM_BOOK3S_64) := $(kvm-book3s_64-objs) +kvm-book3s_32-objs := \ + $(common-objs-y) \ + fpu.o \ + book3s_paired_singles.o \ + book3s.o \ + book3s_emulate.o \ + book3s_interrupts.o \ + book3s_32_mmu_host.o \ + book3s_32_mmu.o +kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs) + kvm-objs := $(kvm-objs-m) $(kvm-objs-y) obj-$(CONFIG_KVM_440) += kvm.o obj-$(CONFIG_KVM_E500) += kvm.o obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o +obj-$(CONFIG_KVM_BOOK3S_32) += kvm.o -- cgit v1.2.3-59-g8ed1b From af7b4d104b36e782a5a97dd55958c3c63964e088 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 20 Apr 2010 02:49:46 +0200 Subject: KVM: PPC: Convert u64 -> ulong There are some pieces in the code that I overlooked that still use u64s instead of longs. This slows down 32 bit hosts unnecessarily, so let's just move them to ulong. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 4 ++-- arch/powerpc/include/asm/kvm_host.h | 6 +++--- arch/powerpc/kvm/book3s.c | 6 +++--- arch/powerpc/kvm/book3s_32_mmu.c | 6 +++--- arch/powerpc/kvm/book3s_32_mmu_host.c | 8 +++----- arch/powerpc/kvm/book3s_64_mmu.c | 4 ++-- arch/powerpc/kvm/book3s_64_mmu_host.c | 6 +++--- 7 files changed, 19 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 9517b8deafed..5d3bd0cc4116 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -107,9 +107,9 @@ struct kvmppc_vcpu_book3s { #define VSID_BAT 0x7fffffffffb00000ULL #define VSID_PR 0x8000000000000000ULL -extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 ea, u64 ea_mask); +extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong ea, ulong ea_mask); extern void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 vp, u64 vp_mask); -extern void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, u64 pa_start, u64 pa_end); +extern void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, ulong pa_start, ulong pa_end); extern void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 new_msr); extern void kvmppc_mmu_book3s_64_init(struct kvm_vcpu *vcpu); extern void kvmppc_mmu_book3s_32_init(struct kvm_vcpu *vcpu); diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 5a83995105f8..0c9ad869decd 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -124,9 +124,9 @@ struct kvm_arch { }; struct kvmppc_pte { - u64 eaddr; + ulong eaddr; u64 vpage; - u64 raddr; + ulong raddr; bool may_read : 1; bool may_write : 1; bool may_execute : 1; @@ -145,7 +145,7 @@ struct kvmppc_mmu { int (*xlate)(struct kvm_vcpu *vcpu, gva_t eaddr, struct kvmppc_pte *pte, bool data); void (*reset_msr)(struct kvm_vcpu *vcpu); void (*tlbie)(struct kvm_vcpu *vcpu, ulong addr, bool large); - int (*esid_to_vsid)(struct kvm_vcpu *vcpu, u64 esid, u64 *vsid); + int (*esid_to_vsid)(struct kvm_vcpu *vcpu, ulong esid, u64 *vsid); u64 (*ea_to_vp)(struct kvm_vcpu *vcpu, gva_t eaddr, bool data); bool (*is_dcbz32)(struct kvm_vcpu *vcpu); }; diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index ec0a6512ab09..6ee9c5e1ffe2 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -813,12 +813,12 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, * so we can't use the NX bit inside the guest. Let's cross our fingers, * that no guest that needs the dcbz hack does NX. */ - kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFULL); + kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFUL); r = RESUME_GUEST; } else { vcpu->arch.msr |= to_svcpu(vcpu)->shadow_srr1 & 0x58000000; kvmppc_book3s_queue_irqprio(vcpu, exit_nr); - kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFULL); + kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFUL); r = RESUME_GUEST; } break; @@ -844,7 +844,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, vcpu->arch.dear = dar; to_book3s(vcpu)->dsisr = to_svcpu(vcpu)->fault_dsisr; kvmppc_book3s_queue_irqprio(vcpu, exit_nr); - kvmppc_mmu_pte_flush(vcpu, vcpu->arch.dear, ~0xFFFULL); + kvmppc_mmu_pte_flush(vcpu, vcpu->arch.dear, ~0xFFFUL); r = RESUME_GUEST; } break; diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index 48efb37500a1..33186b745c90 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c @@ -60,7 +60,7 @@ static inline bool check_debug_ip(struct kvm_vcpu *vcpu) static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, struct kvmppc_pte *pte, bool data); -static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid, +static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, u64 *vsid); static struct kvmppc_sr *find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t eaddr) @@ -183,7 +183,7 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr, struct kvmppc_sr *sre; hva_t ptegp; u32 pteg[16]; - u64 ptem = 0; + u32 ptem = 0; int i; int found = 0; @@ -327,7 +327,7 @@ static void kvmppc_mmu_book3s_32_tlbie(struct kvm_vcpu *vcpu, ulong ea, bool lar kvmppc_mmu_pte_flush(vcpu, ea, 0x0FFFF000); } -static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid, +static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, u64 *vsid) { /* In case we only have one of MSR_IR or MSR_DR set, let's put diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index ce1bfb19c4c1..2bb67e633de2 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c @@ -77,11 +77,9 @@ static void invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) kvm_release_pfn_clean(pte->pfn); } -void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 _guest_ea, u64 _ea_mask) +void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong guest_ea, ulong ea_mask) { int i; - u32 guest_ea = _guest_ea; - u32 ea_mask = _ea_mask; dprintk_mmu("KVM: Flushing %d Shadow PTEs: 0x%x & 0x%x\n", vcpu->arch.hpte_cache_offset, guest_ea, ea_mask); @@ -127,7 +125,7 @@ void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask) } } -void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, u64 pa_start, u64 pa_end) +void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, ulong pa_start, ulong pa_end) { int i; @@ -265,7 +263,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) /* Get host physical address for gpa */ hpaddr = gfn_to_pfn(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT); if (kvm_is_error_hva(hpaddr)) { - printk(KERN_INFO "Couldn't get guest page for gfn %llx!\n", + printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", orig_pte->eaddr); return -EINVAL; } diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 12e4c975a376..a9241e90a68b 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c @@ -232,7 +232,7 @@ do_second: } dprintk("KVM MMU: Translated 0x%lx [0x%llx] -> 0x%llx " - "-> 0x%llx\n", + "-> 0x%lx\n", eaddr, avpn, gpte->vpage, gpte->raddr); found = true; break; @@ -439,7 +439,7 @@ static void kvmppc_mmu_book3s_64_tlbie(struct kvm_vcpu *vcpu, ulong va, kvmppc_mmu_pte_vflush(vcpu, va >> 12, mask); } -static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid, +static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, u64 *vsid) { switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) { diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index b23015438371..41af12fb1260 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -62,7 +62,7 @@ static void invalidate_pte(struct hpte_cache *pte) kvm_release_pfn_clean(pte->pfn); } -void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 guest_ea, u64 ea_mask) +void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong guest_ea, ulong ea_mask) { int i; @@ -110,7 +110,7 @@ void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask) } } -void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, u64 pa_start, u64 pa_end) +void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, ulong pa_start, ulong pa_end) { int i; @@ -216,7 +216,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) /* Get host physical address for gpa */ hpaddr = gfn_to_pfn(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT); if (kvm_is_error_hva(hpaddr)) { - printk(KERN_INFO "Couldn't get guest page for gfn %llx!\n", orig_pte->eaddr); + printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", orig_pte->eaddr); return -EINVAL; } hpaddr <<= PAGE_SHIFT; -- cgit v1.2.3-59-g8ed1b From 7fdaec997cc8ef77e8da7ed70f3d9f074b61c31f Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 20 Apr 2010 02:49:47 +0200 Subject: KVM: PPC: Make Performance Counters work When we get a performance counter interrupt we need to route it on to the Linux handler after we got out of the guest context. We also need to tell our handling code that this particular interrupt doesn't need treatment. So let's add those two bits in, making perf work while having a KVM guest running. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 3 +++ arch/powerpc/kvm/book3s_interrupts.S | 2 ++ 2 files changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 6ee9c5e1ffe2..f66de7e518f7 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -873,6 +873,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, vcpu->stat.ext_intr_exits++; r = RESUME_GUEST; break; + case BOOK3S_INTERRUPT_PERFMON: + r = RESUME_GUEST; + break; case BOOK3S_INTERRUPT_PROGRAM: { enum emulation_result er; diff --git a/arch/powerpc/kvm/book3s_interrupts.S b/arch/powerpc/kvm/book3s_interrupts.S index a1b50280dc47..2f0bc928b08a 100644 --- a/arch/powerpc/kvm/book3s_interrupts.S +++ b/arch/powerpc/kvm/book3s_interrupts.S @@ -228,6 +228,8 @@ no_dcbz32_off: beq call_linux_handler cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER beq call_linux_handler + cmpwi r12, BOOK3S_INTERRUPT_PERFMON + beq call_linux_handler /* Back to EE=1 */ mtmsr r6 -- cgit v1.2.3-59-g8ed1b From f7bc74e1c306636a659a04805474b2f8fcbd1f7e Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 20 Apr 2010 02:49:48 +0200 Subject: KVM: PPC: Improve split mode When in split mode, instruction relocation and data relocation are not equal. So far we implemented this mode by reserving a special pseudo-VSID for the two cases and flushing all PTEs when going into split mode, which is slow. Unfortunately 32bit Linux and Mac OS X use split mode extensively. So to not slow down things too much, I came up with a different idea: Mark the split mode with a bit in the VSID and then treat it like any other segment. This means we can just flush the shadow segment cache, but keep the PTEs intact. I verified that this works with ppc32 Linux and Mac OS X 10.4 guests and does speed them up. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_book3s.h | 9 ++++----- arch/powerpc/kvm/book3s.c | 28 ++++++++++++++-------------- arch/powerpc/kvm/book3s_32_mmu.c | 21 +++++++++++++-------- arch/powerpc/kvm/book3s_64_mmu.c | 27 +++++++++++++++------------ 4 files changed, 46 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 5d3bd0cc4116..6f74d93725a0 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -100,11 +100,10 @@ struct kvmppc_vcpu_book3s { #define CONTEXT_GUEST 1 #define CONTEXT_GUEST_END 2 -#define VSID_REAL_DR 0x7ffffffffff00000ULL -#define VSID_REAL_IR 0x7fffffffffe00000ULL -#define VSID_SPLIT_MASK 0x7fffffffffe00000ULL -#define VSID_REAL 0x7fffffffffc00000ULL -#define VSID_BAT 0x7fffffffffb00000ULL +#define VSID_REAL 0x1fffffffffc00000ULL +#define VSID_BAT 0x1fffffffffb00000ULL +#define VSID_REAL_DR 0x2000000000000000ULL +#define VSID_REAL_IR 0x4000000000000000ULL #define VSID_PR 0x8000000000000000ULL extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong ea, ulong ea_mask); diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index f66de7e518f7..397701d39ae7 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -148,16 +148,8 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) } } - if (((vcpu->arch.msr & (MSR_IR|MSR_DR)) != (old_msr & (MSR_IR|MSR_DR))) || - (vcpu->arch.msr & MSR_PR) != (old_msr & MSR_PR)) { - bool dr = (vcpu->arch.msr & MSR_DR) ? true : false; - bool ir = (vcpu->arch.msr & MSR_IR) ? true : false; - - /* Flush split mode PTEs */ - if (dr != ir) - kvmppc_mmu_pte_vflush(vcpu, VSID_SPLIT_MASK, - VSID_SPLIT_MASK); - + if ((vcpu->arch.msr & (MSR_PR|MSR_IR|MSR_DR)) != + (old_msr & (MSR_PR|MSR_IR|MSR_DR))) { kvmppc_mmu_flush_segments(vcpu); kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu)); } @@ -535,6 +527,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, bool is_mmio = false; bool dr = (vcpu->arch.msr & MSR_DR) ? true : false; bool ir = (vcpu->arch.msr & MSR_IR) ? true : false; + u64 vsid; relocated = data ? dr : ir; @@ -552,13 +545,20 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) { case 0: - pte.vpage |= VSID_REAL; + pte.vpage |= ((u64)VSID_REAL << (SID_SHIFT - 12)); break; case MSR_DR: - pte.vpage |= VSID_REAL_DR; - break; case MSR_IR: - pte.vpage |= VSID_REAL_IR; + vcpu->arch.mmu.esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid); + + if ((vcpu->arch.msr & (MSR_DR|MSR_IR)) == MSR_DR) + pte.vpage |= ((u64)VSID_REAL_DR << (SID_SHIFT - 12)); + else + pte.vpage |= ((u64)VSID_REAL_IR << (SID_SHIFT - 12)); + pte.vpage |= vsid; + + if (vsid == -1) + page_found = -EINVAL; break; } diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index 33186b745c90..0b10503c8a4a 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c @@ -330,30 +330,35 @@ static void kvmppc_mmu_book3s_32_tlbie(struct kvm_vcpu *vcpu, ulong ea, bool lar static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, u64 *vsid) { + ulong ea = esid << SID_SHIFT; + struct kvmppc_sr *sr; + u64 gvsid = esid; + + if (vcpu->arch.msr & (MSR_DR|MSR_IR)) { + sr = find_sr(to_book3s(vcpu), ea); + if (sr->valid) + gvsid = sr->vsid; + } + /* In case we only have one of MSR_IR or MSR_DR set, let's put that in the real-mode context (and hope RM doesn't access high memory) */ switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) { case 0: - *vsid = (VSID_REAL >> 16) | esid; + *vsid = VSID_REAL | esid; break; case MSR_IR: - *vsid = (VSID_REAL_IR >> 16) | esid; + *vsid = VSID_REAL_IR | gvsid; break; case MSR_DR: - *vsid = (VSID_REAL_DR >> 16) | esid; + *vsid = VSID_REAL_DR | gvsid; break; case MSR_DR|MSR_IR: - { - ulong ea = esid << SID_SHIFT; - struct kvmppc_sr *sr = find_sr(to_book3s(vcpu), ea); - if (!sr->valid) return -1; *vsid = sr->vsid; break; - } default: BUG(); } diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index a9241e90a68b..612de6e4d74b 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c @@ -442,29 +442,32 @@ static void kvmppc_mmu_book3s_64_tlbie(struct kvm_vcpu *vcpu, ulong va, static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, u64 *vsid) { + ulong ea = esid << SID_SHIFT; + struct kvmppc_slb *slb; + u64 gvsid = esid; + + if (vcpu->arch.msr & (MSR_DR|MSR_IR)) { + slb = kvmppc_mmu_book3s_64_find_slbe(to_book3s(vcpu), ea); + if (slb) + gvsid = slb->vsid; + } + switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) { case 0: - *vsid = (VSID_REAL >> 16) | esid; + *vsid = VSID_REAL | esid; break; case MSR_IR: - *vsid = (VSID_REAL_IR >> 16) | esid; + *vsid = VSID_REAL_IR | gvsid; break; case MSR_DR: - *vsid = (VSID_REAL_DR >> 16) | esid; + *vsid = VSID_REAL_DR | gvsid; break; case MSR_DR|MSR_IR: - { - ulong ea; - struct kvmppc_slb *slb; - ea = esid << SID_SHIFT; - slb = kvmppc_mmu_book3s_64_find_slbe(to_book3s(vcpu), ea); - if (slb) - *vsid = slb->vsid; - else + if (!slb) return -ENOENT; + *vsid = gvsid; break; - } default: BUG(); break; -- cgit v1.2.3-59-g8ed1b From 6fc558258077d4e44b1780c0fd4ef93dd96c6fca Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 20 Apr 2010 02:49:49 +0200 Subject: KVM: PPC: Make Alignment interrupts work again In the process of merging Book3S_32 and 64 I somehow ended up having the alignment interrupt handler take last_inst, but the fetching code not fetching it. So we ended up with stale last_inst values. Let's just enable last_inst fetching for alignment interrupts too. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_segment.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S index 4c0d1d85d20a..7c52ed0b7051 100644 --- a/arch/powerpc/kvm/book3s_segment.S +++ b/arch/powerpc/kvm/book3s_segment.S @@ -196,6 +196,8 @@ kvmppc_handler_trampoline_exit: beq ld_last_inst cmpwi r12, BOOK3S_INTERRUPT_PROGRAM beq ld_last_inst + cmpwi r12, BOOK3S_INTERRUPT_ALIGNMENT + beq- ld_last_inst b no_ld_last_inst -- cgit v1.2.3-59-g8ed1b From ac21467182e562a71d8b4e098ea054e42700c0ff Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 20 Apr 2010 02:49:50 +0200 Subject: KVM: PPC: Be more informative on BUG We have a condition in the ppc64 host mmu code that should never occur. Unfortunately, it just did happen to me and I was rather puzzled on why, because BUG_ON doesn't tell me anything useful. So let's add some more debug output in case this goes wrong. Also change BUG to WARN, since I don't want to reboot every time I mess something up. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_mmu_host.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 41af12fb1260..5545c45ea57f 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -231,10 +231,16 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) vcpu->arch.mmu.esid_to_vsid(vcpu, orig_pte->eaddr >> SID_SHIFT, &vsid); map = find_sid_vsid(vcpu, vsid); if (!map) { - kvmppc_mmu_map_segment(vcpu, orig_pte->eaddr); + ret = kvmppc_mmu_map_segment(vcpu, orig_pte->eaddr); + WARN_ON(ret < 0); map = find_sid_vsid(vcpu, vsid); } - BUG_ON(!map); + if (!map) { + printk(KERN_ERR "KVM: Segment map for 0x%llx (0x%lx) failed\n", + vsid, orig_pte->eaddr); + WARN_ON(true); + return -EINVAL; + } vsid = map->host_vsid; va = hpt_va(orig_pte->eaddr, vsid, MMU_SEGSIZE_256M); -- cgit v1.2.3-59-g8ed1b From 6355644190f67326f5a16d0269c3e612fcfd6889 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 20 Apr 2010 02:49:51 +0200 Subject: KVM: PPC: Set VSID_PR also for Book3S_64 Book3S_64 didn't set VSID_PR when we're in PR=1. This lead to pretty bad behavior when searching for the shadow segment, as part of the code relied on VSID_PR being set. This patch fixes booting Book3S_64 guests. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_mmu.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 612de6e4d74b..4025ea26b3c1 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c @@ -473,6 +473,9 @@ static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid, break; } + if (vcpu->arch.msr & MSR_PR) + *vsid |= VSID_PR; + return 0; } -- cgit v1.2.3-59-g8ed1b From 5156f274bb1ee1cfc22240445ef94f7dcfc9929d Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 20 Apr 2010 02:49:52 +0200 Subject: KVM: PPC: Fix Book3S_64 Host MMU debug output We have some debug output in Book3S_64. Some of that was invalid though, partially not even compiling because it accessed incorrect variables. So let's fix that up, making debugging more fun again. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s_64_mmu_host.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 5545c45ea57f..e4b5744977f6 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -48,8 +48,8 @@ static void invalidate_pte(struct hpte_cache *pte) { - dprintk_mmu("KVM: Flushing SPT %d: 0x%llx (0x%llx) -> 0x%llx\n", - i, pte->pte.eaddr, pte->pte.vpage, pte->host_va); + dprintk_mmu("KVM: Flushing SPT: 0x%lx (0x%llx) -> 0x%llx\n", + pte->pte.eaddr, pte->pte.vpage, pte->host_va); ppc_md.hpte_invalidate(pte->slot, pte->host_va, MMU_PAGE_4K, MMU_SEGSIZE_256M, @@ -66,7 +66,7 @@ void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, ulong guest_ea, ulong ea_mask) { int i; - dprintk_mmu("KVM: Flushing %d Shadow PTEs: 0x%llx & 0x%llx\n", + dprintk_mmu("KVM: Flushing %d Shadow PTEs: 0x%lx & 0x%lx\n", vcpu->arch.hpte_cache_offset, guest_ea, ea_mask); BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); @@ -114,8 +114,8 @@ void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, ulong pa_start, ulong pa_end) { int i; - dprintk_mmu("KVM: Flushing %d Shadow pPTEs: 0x%llx & 0x%llx\n", - vcpu->arch.hpte_cache_offset, guest_pa, pa_mask); + dprintk_mmu("KVM: Flushing %d Shadow pPTEs: 0x%lx & 0x%lx\n", + vcpu->arch.hpte_cache_offset, pa_start, pa_end); BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM); for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) { @@ -186,7 +186,7 @@ static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid) sid_map_mask = kvmppc_sid_hash(vcpu, gvsid); map = &to_book3s(vcpu)->sid_map[sid_map_mask]; if (map->guest_vsid == gvsid) { - dprintk_slb("SLB: Searching 0x%llx -> 0x%llx\n", + dprintk_slb("SLB: Searching: 0x%llx -> 0x%llx\n", gvsid, map->host_vsid); return map; } @@ -198,7 +198,8 @@ static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid) return map; } - dprintk_slb("SLB: Searching 0x%llx -> not found\n", gvsid); + dprintk_slb("SLB: Searching %d/%d: 0x%llx -> not found\n", + sid_map_mask, SID_MAP_MASK - sid_map_mask, gvsid); return NULL; } @@ -275,7 +276,7 @@ map_again: int hpte_id = kvmppc_mmu_hpte_cache_next(vcpu); struct hpte_cache *pte = &vcpu->arch.hpte_cache[hpte_id]; - dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%lx (0x%llx) -> %lx\n", + dprintk_mmu("KVM: %c%c Map 0x%lx: [%lx] 0x%lx (0x%llx) -> %lx\n", ((rflags & HPTE_R_PP) == 3) ? '-' : 'w', (rflags & HPTE_R_N) ? '-' : 'x', orig_pte->eaddr, hpteg, va, orig_pte->vpage, hpaddr); @@ -331,6 +332,9 @@ static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid) map->guest_vsid = gvsid; map->valid = true; + dprintk_slb("SLB: New mapping at %d: 0x%llx -> 0x%llx\n", + sid_map_mask, gvsid, map->host_vsid); + return map; } -- cgit v1.2.3-59-g8ed1b From 251585b5d02152973dbc24c803ca322bb977d4a2 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 20 Apr 2010 02:49:53 +0200 Subject: KVM: PPC: Find HTAB ourselves For KVM we need to find the location of the HTAB. We can either rely on internal data structures of the kernel or ask the hardware. Ben issued complaints about the internal data structure method, so let's switch it to our own inquiry of the HTAB. Now we're fully independend :-). CC: Benjamin Herrenschmidt Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/kernel/ppc_ksyms.c | 5 ----- arch/powerpc/kvm/book3s_32_mmu_host.c | 21 +++++++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 2b7c43f95bb2..bc9f39d2598b 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -178,11 +178,6 @@ EXPORT_SYMBOL(switch_mmu_context); extern long mol_trampoline; EXPORT_SYMBOL(mol_trampoline); /* For MOL */ EXPORT_SYMBOL(flush_hash_pages); /* For MOL */ - -extern struct hash_pte *Hash; -extern unsigned long _SDR1; -EXPORT_SYMBOL_GPL(Hash); /* For KVM */ -EXPORT_SYMBOL_GPL(_SDR1); /* For KVM */ #ifdef CONFIG_SMP extern int mmu_hash_lock; EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */ diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index 2bb67e633de2..0bb66005338f 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c @@ -54,6 +54,9 @@ #error Only 32 bit pages are supported for now #endif +static ulong htab; +static u32 htabmask; + static void invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) { volatile u32 *pteg; @@ -217,14 +220,11 @@ static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid) return NULL; } -extern struct hash_pte *Hash; -extern unsigned long _SDR1; - static u32 *kvmppc_mmu_get_pteg(struct kvm_vcpu *vcpu, u32 vsid, u32 eaddr, bool primary) { - u32 page, hash, htabmask; - ulong pteg = (ulong)Hash; + u32 page, hash; + ulong pteg = htab; page = (eaddr & ~ESID_MASK) >> 12; @@ -232,13 +232,12 @@ static u32 *kvmppc_mmu_get_pteg(struct kvm_vcpu *vcpu, u32 vsid, u32 eaddr, if (!primary) hash = ~hash; - htabmask = ((_SDR1 & 0x1FF) << 16) | 0xFFC0; hash &= htabmask; pteg |= hash; - dprintk_mmu("htab: %p | hash: %x | htabmask: %x | pteg: %lx\n", - Hash, hash, htabmask, pteg); + dprintk_mmu("htab: %lx | hash: %x | htabmask: %x | pteg: %lx\n", + htab, hash, htabmask, pteg); return (u32*)pteg; } @@ -453,6 +452,7 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu) { struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); int err; + ulong sdr1; err = __init_new_context(); if (err < 0) @@ -474,5 +474,10 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu) vcpu3s->vsid_next = vcpu3s->vsid_first; + /* Remember where the HTAB is */ + asm ( "mfsdr1 %0" : "=r"(sdr1) ); + htabmask = ((sdr1 & 0x1FF) << 16) | 0xFFC0; + htab = (ulong)__va(sdr1 & 0xffff0000); + return 0; } -- cgit v1.2.3-59-g8ed1b From b83d4a9cfc81503a082331cc5d1e480d99f3a531 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 20 Apr 2010 02:49:54 +0200 Subject: KVM: PPC: Enable native paired singles When we're on a paired single capable host, we can just always enable paired singles and expose them to the guest directly. This approach breaks when multiple VMs run and access PS concurrently, but this should suffice until we get a proper framework for it in Linux. Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/powerpc/include/asm/kvm_asm.h | 1 + arch/powerpc/kvm/book3s.c | 19 +++++++++++++++++++ arch/powerpc/kvm/book3s_emulate.c | 5 ++++- 3 files changed, 24 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index 7238c048e5bb..c5ea4cda34b3 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h @@ -89,6 +89,7 @@ #define BOOK3S_HFLAG_DCBZ32 0x1 #define BOOK3S_HFLAG_SLB 0x2 #define BOOK3S_HFLAG_PAIRED_SINGLE 0x4 +#define BOOK3S_HFLAG_NATIVE_PS 0x8 #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 397701d39ae7..9f97dbe25e4e 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -345,6 +345,8 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) { + u32 host_pvr; + vcpu->arch.hflags &= ~BOOK3S_HFLAG_SLB; vcpu->arch.pvr = pvr; #ifdef CONFIG_PPC_BOOK3S_64 @@ -376,6 +378,23 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) /* 32 bit Book3S always has 32 byte dcbz */ vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; #endif + + /* On some CPUs we can execute paired single operations natively */ + asm ( "mfpvr %0" : "=r"(host_pvr)); + switch (host_pvr) { + case 0x00080200: /* lonestar 2.0 */ + case 0x00088202: /* lonestar 2.2 */ + case 0x70000100: /* gekko 1.0 */ + case 0x00080100: /* gekko 2.0 */ + case 0x00083203: /* gekko 2.3a */ + case 0x00083213: /* gekko 2.3b */ + case 0x00083204: /* gekko 2.4 */ + case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */ + case 0x00087200: /* broadway */ + vcpu->arch.hflags |= BOOK3S_HFLAG_NATIVE_PS; + /* Enable HID2.PSE - in case we need it later */ + mtspr(SPRN_HID2_GEKKO, mfspr(SPRN_HID2_GEKKO) | (1 << 29)); + } } /* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 3f7afb5f3483..c85f906038ce 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -365,7 +365,10 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) case 0x00083213: /* gekko 2.3b */ case 0x00083204: /* gekko 2.4 */ case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */ - if (spr_val & (1 << 29)) { /* HID2.PSE */ + case 0x00087200: /* broadway */ + if (vcpu->arch.hflags & BOOK3S_HFLAG_NATIVE_PS) { + /* Native paired singles */ + } else if (spr_val & (1 << 29)) { /* HID2.PSE */ vcpu->arch.hflags |= BOOK3S_HFLAG_PAIRED_SINGLE; kvmppc_giveup_ext(vcpu, MSR_FP); } else { -- cgit v1.2.3-59-g8ed1b From cdbecfc398a904ce9f5c126638b09a2429fb86ed Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sat, 17 Apr 2010 16:41:47 +0800 Subject: KVM: VMX: free vpid when fail to create vcpu Fix bug of the exception path, free allocated vpid when fail to create vcpu. Signed-off-by: Lai Jiangshan Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index d0a10b5612e9..54c0035a63f0 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2333,6 +2333,16 @@ static void allocate_vpid(struct vcpu_vmx *vmx) spin_unlock(&vmx_vpid_lock); } +static void free_vpid(struct vcpu_vmx *vmx) +{ + if (!enable_vpid) + return; + spin_lock(&vmx_vpid_lock); + if (vmx->vpid != 0) + __clear_bit(vmx->vpid, vmx_vpid_bitmap); + spin_unlock(&vmx_vpid_lock); +} + static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, u32 msr) { int f = sizeof(unsigned long); @@ -3916,10 +3926,7 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); - spin_lock(&vmx_vpid_lock); - if (vmx->vpid != 0) - __clear_bit(vmx->vpid, vmx_vpid_bitmap); - spin_unlock(&vmx_vpid_lock); + free_vpid(vmx); vmx_free_vmcs(vcpu); kfree(vmx->guest_msrs); kvm_vcpu_uninit(vcpu); @@ -3981,6 +3988,7 @@ free_msrs: uninit_vcpu: kvm_vcpu_uninit(&vmx->vcpu); free_vcpu: + free_vpid(vmx); kmem_cache_free(kvm_vcpu_cache, vmx); return ERR_PTR(err); } -- cgit v1.2.3-59-g8ed1b From 924584ccb08c338ebd2f40936ff2321c1cce6a6d Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 22 Apr 2010 12:33:07 +0200 Subject: KVM: SVM: Fix nested nmi handling The patch introducing nested nmi handling had a bug. The check does not belong to enable_nmi_window but must be in nmi_allowed. This patch fixes this. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index ab78eb8ba899..ec205847be6a 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2771,8 +2771,12 @@ static int svm_nmi_allowed(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); struct vmcb *vmcb = svm->vmcb; - return !(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) && - !(svm->vcpu.arch.hflags & HF_NMI_MASK); + int ret; + ret = !(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) && + !(svm->vcpu.arch.hflags & HF_NMI_MASK); + ret = ret && gif_set(svm) && nested_svm_nmi(svm); + + return ret; } static bool svm_get_nmi_mask(struct kvm_vcpu *vcpu) @@ -2841,11 +2845,9 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu) * Something prevents NMI from been injected. Single step over possible * problem (IRET or exception injection or interrupt shadow) */ - if (gif_set(svm) && nested_svm_nmi(svm)) { - svm->nmi_singlestep = true; - svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); - update_db_intercept(vcpu); - } + svm->nmi_singlestep = true; + svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); + update_db_intercept(vcpu); } static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) -- cgit v1.2.3-59-g8ed1b From 2041a06a50a2ef4062c8454482aa06e25f6cccde Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 22 Apr 2010 12:33:08 +0200 Subject: KVM: SVM: Make sure rip is synced to vmcb before nested vmexit This patch fixes a bug where a nested guest always went over the same instruction because the rip was not advanced on a nested vmexit. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index ec205847be6a..c480d7f64a60 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2960,6 +2960,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) u16 gs_selector; u16 ldt_selector; + svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; + svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP]; + svm->vmcb->save.rip = vcpu->arch.regs[VCPU_REGS_RIP]; + /* * A vmexit emulation is required before the vcpu can be executed * again. @@ -2967,10 +2971,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) if (unlikely(svm->nested.exit_required)) return; - svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; - svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP]; - svm->vmcb->save.rip = vcpu->arch.regs[VCPU_REGS_RIP]; - pre_svm_run(svm); sync_lapic_to_cr8(vcpu); -- cgit v1.2.3-59-g8ed1b From 2be4fc7a02c368dcfda83a386a5101c211b9535e Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 22 Apr 2010 12:33:09 +0200 Subject: KVM: SVM: Sync cr0 and cr3 to kvm state before nested handling This patch syncs cr0 and cr3 from the vmcb to the kvm state before nested intercept handling is done. This allows to simplify the vmexit path. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c480d7f64a60..5ad9d802bd16 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1799,10 +1799,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) nested_vmcb->save.gdtr = vmcb->save.gdtr; nested_vmcb->save.idtr = vmcb->save.idtr; nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu); - if (npt_enabled) - nested_vmcb->save.cr3 = vmcb->save.cr3; - else - nested_vmcb->save.cr3 = svm->vcpu.arch.cr3; + nested_vmcb->save.cr3 = svm->vcpu.arch.cr3; nested_vmcb->save.cr2 = vmcb->save.cr2; nested_vmcb->save.cr4 = svm->vcpu.arch.cr4; nested_vmcb->save.rflags = vmcb->save.rflags; @@ -2641,6 +2638,11 @@ static int handle_exit(struct kvm_vcpu *vcpu) trace_kvm_exit(exit_code, vcpu); + if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR0_MASK)) + vcpu->arch.cr0 = svm->vmcb->save.cr0; + if (npt_enabled) + vcpu->arch.cr3 = svm->vmcb->save.cr3; + if (unlikely(svm->nested.exit_required)) { nested_svm_vmexit(svm); svm->nested.exit_required = false; @@ -2668,11 +2670,6 @@ static int handle_exit(struct kvm_vcpu *vcpu) svm_complete_interrupts(svm); - if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR0_MASK)) - vcpu->arch.cr0 = svm->vmcb->save.cr0; - if (npt_enabled) - vcpu->arch.cr3 = svm->vmcb->save.cr3; - if (svm->vmcb->control.exit_code == SVM_EXIT_ERR) { kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; kvm_run->fail_entry.hardware_entry_failure_reason -- cgit v1.2.3-59-g8ed1b From 228070b1b31abc16c331b57bf965101c6eb1d167 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 22 Apr 2010 12:33:10 +0200 Subject: KVM: SVM: Propagate nested entry failure into guest hypervisor This patch implements propagation of a failes guest vmrun back into the guest instead of killing the whole guest. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 5ad9d802bd16..b10d1630c203 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1715,6 +1715,10 @@ static int nested_svm_intercept(struct vcpu_svm *svm) vmexit = NESTED_EXIT_DONE; break; } + case SVM_EXIT_ERR: { + vmexit = NESTED_EXIT_DONE; + break; + } default: { u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR); if (svm->nested.intercept & exit_bits) -- cgit v1.2.3-59-g8ed1b From d4330ef2fb2236a1e3a176f0f68360f4c0a8661b Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 22 Apr 2010 12:33:11 +0200 Subject: KVM: x86: Add callback to let modules decide over some supported cpuid bits This patch adds the get_supported_cpuid callback to kvm_x86_ops. It will be used in do_cpuid_ent to delegate the decission about some supported cpuid bits to the architecture modules. Cc: stable@kernel.org Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/svm.c | 6 ++++++ arch/x86/kvm/vmx.c | 6 ++++++ arch/x86/kvm/x86.c | 3 +++ 4 files changed, 17 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index d47d087568fe..357573af974f 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -528,6 +528,8 @@ struct kvm_x86_ops { int (*get_lpage_level)(void); bool (*rdtscp_supported)(void); + void (*set_supported_cpuid)(u32 func, struct kvm_cpuid_entry2 *entry); + const struct trace_print_flags *exit_reasons_str; }; diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index b10d1630c203..0fa2035bd8e7 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3152,6 +3152,10 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) { } +static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) +{ +} + static const struct trace_print_flags svm_exit_reasons_str[] = { { SVM_EXIT_READ_CR0, "read_cr0" }, { SVM_EXIT_READ_CR3, "read_cr3" }, @@ -3297,6 +3301,8 @@ static struct kvm_x86_ops svm_x86_ops = { .cpuid_update = svm_cpuid_update, .rdtscp_supported = svm_rdtscp_supported, + + .set_supported_cpuid = svm_set_supported_cpuid, }; static int __init svm_init(void) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 54c0035a63f0..9f8532b1fa9a 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -4119,6 +4119,10 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) } } +static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) +{ +} + static struct kvm_x86_ops vmx_x86_ops = { .cpu_has_kvm_support = cpu_has_kvm_support, .disabled_by_bios = vmx_disabled_by_bios, @@ -4191,6 +4195,8 @@ static struct kvm_x86_ops vmx_x86_ops = { .cpuid_update = vmx_cpuid_update, .rdtscp_supported = vmx_rdtscp_supported, + + .set_supported_cpuid = vmx_set_supported_cpuid, }; static int __init vmx_init(void) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 848c814e8c3c..6e6434332f21 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1960,6 +1960,9 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, entry->ecx &= kvm_supported_word6_x86_features; break; } + + kvm_x86_ops->set_supported_cpuid(function, entry); + put_cpu(); } -- cgit v1.2.3-59-g8ed1b From c2c63a493924e09a1984d1374a0e60dfd54fc0b0 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 22 Apr 2010 12:33:12 +0200 Subject: KVM: SVM: Report emulated SVM features to userspace This patch implements the reporting of the emulated SVM features to userspace instead of the real hardware capabilities. Every real hardware capability needs emulation in nested svm so the old behavior was broken. Cc: stable@kernel.org Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 0fa2035bd8e7..65fc11438b75 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3154,6 +3154,16 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) { + switch (func) { + case 0x8000000A: + entry->eax = 1; /* SVM revision 1 */ + entry->ebx = 8; /* Lets support 8 ASIDs in case we add proper + ASID emulation to nested SVM */ + entry->ecx = 0; /* Reserved */ + entry->edx = 0; /* Do not support any additional features */ + + break; + } } static const struct trace_print_flags svm_exit_reasons_str[] = { -- cgit v1.2.3-59-g8ed1b From ce7ddec4bbbc08f0c2901cc103773aed864b09fd Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 22 Apr 2010 12:33:13 +0200 Subject: KVM: x86: Allow marking an exception as reinjected This patch adds logic to kvm/x86 which allows to mark an injected exception as reinjected. This allows to remove an ugly hack from svm_complete_interrupts that prevented exceptions from being reinjected at all in the nested case. The hack was necessary because an reinjected exception into the nested guest could cause a nested vmexit emulation. But reinjected exceptions must not intercept. The downside of the hack is that a exception that in injected could get lost. This patch fixes the problem and puts the code for it into generic x86 files because. Nested-VMX will likely have the same problem and could reuse the code. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_host.h | 6 +++++- arch/x86/kvm/svm.c | 12 ++++++------ arch/x86/kvm/vmx.c | 3 ++- arch/x86/kvm/x86.c | 23 +++++++++++++++++++---- 4 files changed, 32 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 357573af974f..3f0007b076da 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -312,6 +312,7 @@ struct kvm_vcpu_arch { struct kvm_queued_exception { bool pending; bool has_error_code; + bool reinject; u8 nr; u32 error_code; } exception; @@ -514,7 +515,8 @@ struct kvm_x86_ops { void (*set_irq)(struct kvm_vcpu *vcpu); void (*set_nmi)(struct kvm_vcpu *vcpu); void (*queue_exception)(struct kvm_vcpu *vcpu, unsigned nr, - bool has_error_code, u32 error_code); + bool has_error_code, u32 error_code, + bool reinject); int (*interrupt_allowed)(struct kvm_vcpu *vcpu); int (*nmi_allowed)(struct kvm_vcpu *vcpu); bool (*get_nmi_mask)(struct kvm_vcpu *vcpu); @@ -617,6 +619,8 @@ void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags); void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr); void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); +void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr); +void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2, u32 error_code); bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 65fc11438b75..30e49fe7f8c0 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -338,7 +338,8 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) } static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, - bool has_error_code, u32 error_code) + bool has_error_code, u32 error_code, + bool reinject) { struct vcpu_svm *svm = to_svm(vcpu); @@ -346,7 +347,8 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, * If we are within a nested VM we'd better #VMEXIT and let the guest * handle the exception */ - if (nested_svm_check_exception(svm, nr, has_error_code, error_code)) + if (!reinject && + nested_svm_check_exception(svm, nr, has_error_code, error_code)) return; if (nr == BP_VECTOR && !svm_has(SVM_FEATURE_NRIP)) { @@ -2918,8 +2920,6 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) svm->vcpu.arch.nmi_injected = true; break; case SVM_EXITINTINFO_TYPE_EXEPT: - if (is_nested(svm)) - break; /* * In case of software exceptions, do not reinject the vector, * but re-execute the instruction instead. Rewind RIP first @@ -2935,10 +2935,10 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) } if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { u32 err = svm->vmcb->control.exit_int_info_err; - kvm_queue_exception_e(&svm->vcpu, vector, err); + kvm_requeue_exception_e(&svm->vcpu, vector, err); } else - kvm_queue_exception(&svm->vcpu, vector); + kvm_requeue_exception(&svm->vcpu, vector); break; case SVM_EXITINTINFO_TYPE_INTR: kvm_queue_interrupt(&svm->vcpu, vector, false); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 9f8532b1fa9a..875b785228f6 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -919,7 +919,8 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) } static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, - bool has_error_code, u32 error_code) + bool has_error_code, u32 error_code, + bool reinject) { struct vcpu_vmx *vmx = to_vmx(vcpu); u32 intr_info = nr | INTR_INFO_VALID_MASK; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6e6434332f21..6b2ce1d2d748 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -265,7 +265,8 @@ static int exception_class(int vector) } static void kvm_multiple_exception(struct kvm_vcpu *vcpu, - unsigned nr, bool has_error, u32 error_code) + unsigned nr, bool has_error, u32 error_code, + bool reinject) { u32 prev_nr; int class1, class2; @@ -276,6 +277,7 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, vcpu->arch.exception.has_error_code = has_error; vcpu->arch.exception.nr = nr; vcpu->arch.exception.error_code = error_code; + vcpu->arch.exception.reinject = true; return; } @@ -304,10 +306,16 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr) { - kvm_multiple_exception(vcpu, nr, false, 0); + kvm_multiple_exception(vcpu, nr, false, 0, false); } EXPORT_SYMBOL_GPL(kvm_queue_exception); +void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr) +{ + kvm_multiple_exception(vcpu, nr, false, 0, true); +} +EXPORT_SYMBOL_GPL(kvm_requeue_exception); + void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr, u32 error_code) { @@ -324,10 +332,16 @@ EXPORT_SYMBOL_GPL(kvm_inject_nmi); void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) { - kvm_multiple_exception(vcpu, nr, true, error_code); + kvm_multiple_exception(vcpu, nr, true, error_code, false); } EXPORT_SYMBOL_GPL(kvm_queue_exception_e); +void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) +{ + kvm_multiple_exception(vcpu, nr, true, error_code, true); +} +EXPORT_SYMBOL_GPL(kvm_requeue_exception_e); + /* * Checks if cpl <= required_cpl; if true, return true. Otherwise queue * a #GP and return false. @@ -4408,7 +4422,8 @@ static void inject_pending_event(struct kvm_vcpu *vcpu) vcpu->arch.exception.error_code); kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, vcpu->arch.exception.has_error_code, - vcpu->arch.exception.error_code); + vcpu->arch.exception.error_code, + vcpu->arch.exception.reinject); return; } -- cgit v1.2.3-59-g8ed1b From ff47a49b235e59e606e1cb267a08f7fbeb5719d1 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 22 Apr 2010 12:33:14 +0200 Subject: KVM: SVM: Handle MCE intercepts always on host level This patch prevents MCE intercepts from being propagated into the L1 guest if they happened in an L2 guest. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 30e49fe7f8c0..889f66022e57 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1651,6 +1651,7 @@ static int nested_svm_exit_special(struct vcpu_svm *svm) switch (exit_code) { case SVM_EXIT_INTR: case SVM_EXIT_NMI: + case SVM_EXIT_EXCP_BASE + MC_VECTOR: return NESTED_EXIT_HOST; case SVM_EXIT_NPF: /* For now we are always handling NPFs when using them */ -- cgit v1.2.3-59-g8ed1b From df2fb6e7106dd0b76e3576bfaecbeb6f34843709 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Thu, 22 Apr 2010 17:33:57 +0800 Subject: KVM: MMU: fix sp->unsync type error in trace event definition sp->unsync is bool now, so update trace event declaration. Signed-off-by: Gui Jianfeng Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmutrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h index bc4f7f0be2b1..40a1786f36c7 100644 --- a/arch/x86/kvm/mmutrace.h +++ b/arch/x86/kvm/mmutrace.h @@ -11,7 +11,7 @@ __field(__u64, gfn) \ __field(__u32, role) \ __field(__u32, root_count) \ - __field(__u32, unsync) + __field(bool, unsync) #define KVM_MMU_PAGE_ASSIGN(sp) \ __entry->gfn = sp->gfn; \ -- cgit v1.2.3-59-g8ed1b From 47ab0dee661dbd5aca67abe44a333e471134fbf9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 15 May 2010 11:02:43 +0100 Subject: ARM: Optionally allow ARMv6 to use 'normal, bufferable' memory for DMA Provide a configuration option to allow the ARMv6 to use normal bufferable memory for coherent DMA. This option is forced to 'y' for ARMv7, and offered as a configuration option on ARMv6. Enabling this option requires drivers to have the necessary barriers to ensure that data in DMA coherent memory is visible prior to the DMA operation commencing. Reviewed-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/include/asm/pgtable.h | 2 +- arch/arm/include/asm/system.h | 2 +- arch/arm/mm/Kconfig | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 11397687f42c..ab68cf1ef80f 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -314,7 +314,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED) #define pgprot_writecombine(prot) \ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE) -#if __LINUX_ARM_ARCH__ >= 7 +#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE #define pgprot_dmacoherent(prot) \ __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE) #else diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index ca88e6a84707..02f5d99adbc0 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -137,7 +137,7 @@ extern unsigned int user_debug; #define dmb() __asm__ __volatile__ ("" : : : "memory") #endif -#if __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP) +#if defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP) #define mb() dmb() #define rmb() dmb() #define wmb() dmb() diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c4ed9f93f646..573528d9c6d8 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -781,3 +781,22 @@ config ARM_L1_CACHE_SHIFT int default 6 if ARM_L1_CACHE_SHIFT_6 default 5 + +config ARM_DMA_MEM_BUFFERABLE + bool "Use non-cacheable memory for DMA" if CPU_V6 && !CPU_V7 + default y if CPU_V6 || CPU_V7 + help + Historically, the kernel has used strongly ordered mappings to + provide DMA coherent memory. With the advent of ARMv7, mapping + memory with differing types results in unpredictable behaviour, + so on these CPUs, this option is forced on. + + Multiple mappings with differing attributes is also unpredictable + on ARMv6 CPUs, but since they do not have aggressive speculative + prefetch, no harm appears to occur. + + However, drivers may be missing the necessary barriers for ARMv6, + and therefore turning this on may result in unpredictable driver + behaviour. Therefore, we offer this as an option. + + You are recommended say 'Y' here and debug any affected drivers. -- cgit v1.2.3-59-g8ed1b From 49c006b93769a86bec2b32b9234abf016ac0d50e Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 29 Apr 2010 17:13:24 +0100 Subject: ARM: 6064/1: pmu: register IRQs at runtime The current PMU infrastructure for ARM requires that the IRQs for the PMU device are fixed at compile time and are selected based on the ARCH_ or MACH_ flags. This has the disadvantage of tying the Kernel down to a particular board as far as profiling is concerned. This patch replaces the compile-time IRQ registration with a runtime mechanism which allows the IRQs to be registered with the framework as a platform_device. A further advantage of this change is that there is scope for registering different types of performance counters in the future by changing the id of the platform_device and attaching different resources to it. Acked-by: Jamie Iles Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/pmu.h | 27 ++++----- arch/arm/kernel/perf_event.c | 52 +++++++++++------- arch/arm/kernel/pmu.c | 127 ++++++++++++++++++++++++++++--------------- 3 files changed, 126 insertions(+), 80 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 44bec1f02cb0..8ccea012722c 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h @@ -19,31 +19,26 @@ enum arm_pmu_type { #ifdef CONFIG_CPU_HAS_PMU -struct pmu_irqs { - const int *irqs; - int num_irqs; -}; - /** * reserve_pmu() - reserve the hardware performance counters * * Reserve the hardware performance counters in the system for exclusive use. - * The 'struct pmu_irqs' for the system is returned on success, ERR_PTR() + * The platform_device for the system is returned on success, ERR_PTR() * encoded error on failure. */ -extern const struct pmu_irqs * -reserve_pmu(void); +extern struct platform_device * +reserve_pmu(enum arm_pmu_type device); /** * release_pmu() - Relinquish control of the performance counters * * Release the performance counters and allow someone else to use them. * Callers must have disabled the counters and released IRQs before calling - * this. The 'struct pmu_irqs' returned from reserve_pmu() must be passed as + * this. The platform_device returned from reserve_pmu() must be passed as * a cookie. */ extern int -release_pmu(const struct pmu_irqs *irqs); +release_pmu(struct platform_device *pdev); /** * init_pmu() - Initialise the PMU. @@ -53,24 +48,26 @@ release_pmu(const struct pmu_irqs *irqs); * the actual hardware initialisation. */ extern int -init_pmu(void); +init_pmu(enum arm_pmu_type device); #else /* CONFIG_CPU_HAS_PMU */ -static inline const struct pmu_irqs * -reserve_pmu(void) +#include + +static inline struct platform_device * +reserve_pmu(enum arm_pmu_type device) { return ERR_PTR(-ENODEV); } static inline int -release_pmu(const struct pmu_irqs *irqs) +release_pmu(struct platform_device *pdev) { return -ENODEV; } static inline int -init_pmu(void) +init_pmu(enum arm_pmu_type device) { return -ENODEV; } diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 9e70f2053f9a..89a77fcb13e3 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -26,7 +27,7 @@ #include #include -static const struct pmu_irqs *pmu_irqs; +static struct platform_device *pmu_device; /* * Hardware lock to serialize accesses to PMU registers. Needed for the @@ -314,38 +315,44 @@ validate_group(struct perf_event *event) static int armpmu_reserve_hardware(void) { - int i; - int err; + int i, err = -ENODEV, irq; - pmu_irqs = reserve_pmu(); - if (IS_ERR(pmu_irqs)) { + pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU); + if (IS_ERR(pmu_device)) { pr_warning("unable to reserve pmu\n"); - return PTR_ERR(pmu_irqs); + return PTR_ERR(pmu_device); } - init_pmu(); + init_pmu(ARM_PMU_DEVICE_CPU); - if (pmu_irqs->num_irqs < 1) { + if (pmu_device->num_resources < 1) { pr_err("no irqs for PMUs defined\n"); return -ENODEV; } - for (i = 0; i < pmu_irqs->num_irqs; ++i) { - err = request_irq(pmu_irqs->irqs[i], armpmu->handle_irq, + for (i = 0; i < pmu_device->num_resources; ++i) { + irq = platform_get_irq(pmu_device, i); + if (irq < 0) + continue; + + err = request_irq(irq, armpmu->handle_irq, IRQF_DISABLED | IRQF_NOBALANCING, "armpmu", NULL); if (err) { - pr_warning("unable to request IRQ%d for ARM " - "perf counters\n", pmu_irqs->irqs[i]); + pr_warning("unable to request IRQ%d for ARM perf " + "counters\n", irq); break; } } if (err) { - for (i = i - 1; i >= 0; --i) - free_irq(pmu_irqs->irqs[i], NULL); - release_pmu(pmu_irqs); - pmu_irqs = NULL; + for (i = i - 1; i >= 0; --i) { + irq = platform_get_irq(pmu_device, i); + if (irq >= 0) + free_irq(irq, NULL); + } + release_pmu(pmu_device); + pmu_device = NULL; } return err; @@ -354,14 +361,17 @@ armpmu_reserve_hardware(void) static void armpmu_release_hardware(void) { - int i; + int i, irq; - for (i = pmu_irqs->num_irqs - 1; i >= 0; --i) - free_irq(pmu_irqs->irqs[i], NULL); + for (i = pmu_device->num_resources - 1; i >= 0; --i) { + irq = platform_get_irq(pmu_device, i); + if (irq >= 0) + free_irq(irq, NULL); + } armpmu->stop(); - release_pmu(pmu_irqs); - pmu_irqs = NULL; + release_pmu(pmu_device); + pmu_device = NULL; } static atomic_t active_events = ATOMIC_INIT(0); diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c index a124312e343f..b8af96ea62e6 100644 --- a/arch/arm/kernel/pmu.c +++ b/arch/arm/kernel/pmu.c @@ -2,6 +2,7 @@ * linux/arch/arm/kernel/pmu.c * * Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles + * Copyright (C) 2010 ARM Ltd, Will Deacon * * 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 @@ -9,65 +10,78 @@ * */ +#define pr_fmt(fmt) "PMU: " fmt + #include #include #include #include #include +#include #include -/* - * Define the IRQs for the system. We could use something like a platform - * device but that seems fairly heavyweight for this. Also, the performance - * counters can't be removed or hotplugged. - * - * Ordering is important: init_pmu() will use the ordering to set the affinity - * to the corresponding core. e.g. the first interrupt will go to cpu 0, the - * second goes to cpu 1 etc. - */ -static const int irqs[] = { -#if defined(CONFIG_ARCH_OMAP2) - 3, -#elif defined(CONFIG_ARCH_BCMRING) - IRQ_PMUIRQ, -#elif defined(CONFIG_MACH_REALVIEW_EB) - IRQ_EB11MP_PMU_CPU0, - IRQ_EB11MP_PMU_CPU1, - IRQ_EB11MP_PMU_CPU2, - IRQ_EB11MP_PMU_CPU3, -#elif defined(CONFIG_ARCH_OMAP3) - INT_34XX_BENCH_MPU_EMUL, -#elif defined(CONFIG_ARCH_IOP32X) - IRQ_IOP32X_CORE_PMU, -#elif defined(CONFIG_ARCH_IOP33X) - IRQ_IOP33X_CORE_PMU, -#elif defined(CONFIG_ARCH_PXA) - IRQ_PMU, -#endif -}; +static volatile long pmu_lock; + +static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES]; + +static int __devinit pmu_device_probe(struct platform_device *pdev) +{ + + if (pdev->id < 0 || pdev->id >= ARM_NUM_PMU_DEVICES) { + pr_warning("received registration request for unknown " + "device %d\n", pdev->id); + return -EINVAL; + } + + if (pmu_devices[pdev->id]) + pr_warning("registering new PMU device type %d overwrites " + "previous registration!\n", pdev->id); + else + pr_info("registered new PMU device of type %d\n", + pdev->id); -static const struct pmu_irqs pmu_irqs = { - .irqs = irqs, - .num_irqs = ARRAY_SIZE(irqs), + pmu_devices[pdev->id] = pdev; + return 0; +} + +static struct platform_driver pmu_driver = { + .driver = { + .name = "arm-pmu", + }, + .probe = pmu_device_probe, }; -static volatile long pmu_lock; +static int __init register_pmu_driver(void) +{ + return platform_driver_register(&pmu_driver); +} +device_initcall(register_pmu_driver); -const struct pmu_irqs * -reserve_pmu(void) +struct platform_device * +reserve_pmu(enum arm_pmu_type device) { - return test_and_set_bit_lock(0, &pmu_lock) ? ERR_PTR(-EBUSY) : - &pmu_irqs; + struct platform_device *pdev; + + if (test_and_set_bit_lock(device, &pmu_lock)) { + pdev = ERR_PTR(-EBUSY); + } else if (pmu_devices[device] == NULL) { + clear_bit_unlock(device, &pmu_lock); + pdev = ERR_PTR(-ENODEV); + } else { + pdev = pmu_devices[device]; + } + + return pdev; } EXPORT_SYMBOL_GPL(reserve_pmu); int -release_pmu(const struct pmu_irqs *irqs) +release_pmu(struct platform_device *pdev) { - if (WARN_ON(irqs != &pmu_irqs)) + if (WARN_ON(pdev != pmu_devices[pdev->id])) return -EINVAL; - clear_bit_unlock(0, &pmu_lock); + clear_bit_unlock(pdev->id, &pmu_lock); return 0; } EXPORT_SYMBOL_GPL(release_pmu); @@ -87,17 +101,42 @@ set_irq_affinity(int irq, #endif } -int -init_pmu(void) +static int +init_cpu_pmu(void) { int i, err = 0; + struct platform_device *pdev = pmu_devices[ARM_PMU_DEVICE_CPU]; + + if (!pdev) { + err = -ENODEV; + goto out; + } - for (i = 0; i < pmu_irqs.num_irqs; ++i) { - err = set_irq_affinity(pmu_irqs.irqs[i], i); + for (i = 0; i < pdev->num_resources; ++i) { + err = set_irq_affinity(platform_get_irq(pdev, i), i); if (err) break; } +out: + return err; +} + +int +init_pmu(enum arm_pmu_type device) +{ + int err = 0; + + switch (device) { + case ARM_PMU_DEVICE_CPU: + err = init_cpu_pmu(); + break; + default: + pr_warning("attempt to initialise unknown device %d\n", + device); + err = -EINVAL; + } + return err; } EXPORT_SYMBOL_GPL(init_pmu); -- cgit v1.2.3-59-g8ed1b From 181193f398e7d8da6b1196138f0e219709621743 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 30 Apr 2010 11:32:44 +0100 Subject: ARM: 6069/1: perf-events: use numeric ID to identify PMU The ARM perf-events framework provides support for a number of different PMUs using struct arm_pmu. The char *name field of this struct can be used to identify the PMU, but this is cumbersome if used outside of perf. This patch replaces the name string for a PMU with an enum, which holds a unique ID for the PMU being represented. This ID can be used to index an array of names within perf, so no functionality is lost. The presence of the ID field, allows other kernel subsystems [currently oprofile] to use their own mappings for the PMU name. Cc: Jean Pihet Acked-by: Jamie Iles Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/perf_event.h | 14 ++++++++++++++ arch/arm/kernel/perf_event.c | 39 +++++++++++++++++++++++++++++---------- 2 files changed, 43 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index 49e3049aba32..fa4b32625d37 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h @@ -28,4 +28,18 @@ set_perf_event_pending(void) * same indexes here for consistency. */ #define PERF_EVENT_INDEX_OFFSET 1 +/* ARM perf PMU IDs for use by internal perf clients. */ +enum arm_perf_pmu_ids { + ARM_PERF_PMU_ID_XSCALE1 = 0, + ARM_PERF_PMU_ID_XSCALE2, + ARM_PERF_PMU_ID_V6, + ARM_PERF_PMU_ID_V6MP, + ARM_PERF_PMU_ID_CA8, + ARM_PERF_PMU_ID_CA9, + ARM_NUM_PMU_IDS, +}; + +extern enum arm_perf_pmu_ids +armpmu_get_pmu_id(void); + #endif /* __ARM_PERF_EVENT_H__ */ diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 89a77fcb13e3..10a0bcdf2158 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -68,8 +69,18 @@ struct cpu_hw_events { }; DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); +/* PMU names. */ +static const char *arm_pmu_names[] = { + [ARM_PERF_PMU_ID_XSCALE1] = "xscale1", + [ARM_PERF_PMU_ID_XSCALE2] = "xscale2", + [ARM_PERF_PMU_ID_V6] = "v6", + [ARM_PERF_PMU_ID_V6MP] = "v6mpcore", + [ARM_PERF_PMU_ID_CA8] = "ARMv7 Cortex-A8", + [ARM_PERF_PMU_ID_CA9] = "ARMv7 Cortex-A9", +}; + struct arm_pmu { - char *name; + enum arm_perf_pmu_ids id; irqreturn_t (*handle_irq)(int irq_num, void *dev); void (*enable)(struct hw_perf_event *evt, int idx); void (*disable)(struct hw_perf_event *evt, int idx); @@ -88,6 +99,18 @@ struct arm_pmu { /* Set at runtime when we know what CPU type we are. */ static const struct arm_pmu *armpmu; +enum arm_perf_pmu_ids +armpmu_get_pmu_id(void) +{ + int id = -ENODEV; + + if (armpmu != NULL) + id = armpmu->id; + + return id; +} +EXPORT_SYMBOL_GPL(armpmu_get_pmu_id); + #define HW_OP_UNSUPPORTED 0xFFFF #define C(_x) \ @@ -1154,7 +1177,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, } static const struct arm_pmu armv6pmu = { - .name = "v6", + .id = ARM_PERF_PMU_ID_V6, .handle_irq = armv6pmu_handle_irq, .enable = armv6pmu_enable_event, .disable = armv6pmu_disable_event, @@ -1177,7 +1200,7 @@ static const struct arm_pmu armv6pmu = { * reset the period and enable the interrupt reporting. */ static const struct arm_pmu armv6mpcore_pmu = { - .name = "v6mpcore", + .id = ARM_PERF_PMU_ID_V6MP, .handle_irq = armv6pmu_handle_irq, .enable = armv6pmu_enable_event, .disable = armv6mpcore_pmu_disable_event, @@ -1207,10 +1230,6 @@ static const struct arm_pmu armv6mpcore_pmu = { * counter and all 4 performance counters together can be reset separately. */ -#define ARMV7_PMU_CORTEX_A8_NAME "ARMv7 Cortex-A8" - -#define ARMV7_PMU_CORTEX_A9_NAME "ARMv7 Cortex-A9" - /* Common ARMv7 event types */ enum armv7_perf_types { ARMV7_PERFCTR_PMNC_SW_INCR = 0x00, @@ -2115,7 +2134,7 @@ init_hw_perf_events(void) perf_max_events = armv6mpcore_pmu.num_events; break; case 0xC080: /* Cortex-A8 */ - armv7pmu.name = ARMV7_PMU_CORTEX_A8_NAME; + armv7pmu.id = ARM_PERF_PMU_ID_CA8; memcpy(armpmu_perf_cache_map, armv7_a8_perf_cache_map, sizeof(armv7_a8_perf_cache_map)); armv7pmu.event_map = armv7_a8_pmu_event_map; @@ -2127,7 +2146,7 @@ init_hw_perf_events(void) perf_max_events = armv7pmu.num_events; break; case 0xC090: /* Cortex-A9 */ - armv7pmu.name = ARMV7_PMU_CORTEX_A9_NAME; + armv7pmu.id = ARM_PERF_PMU_ID_CA9; memcpy(armpmu_perf_cache_map, armv7_a9_perf_cache_map, sizeof(armv7_a9_perf_cache_map)); armv7pmu.event_map = armv7_a9_pmu_event_map; @@ -2146,7 +2165,7 @@ init_hw_perf_events(void) if (armpmu) pr_info("enabled with %s PMU driver, %d counters available\n", - armpmu->name, armpmu->num_events); + arm_pmu_names[armpmu->id], armpmu->num_events); return 0; } -- cgit v1.2.3-59-g8ed1b From 49e6a32f2f0876b6267584d9c7e0e213bca6e2b8 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 30 Apr 2010 11:33:33 +0100 Subject: ARM: 6070/1: perf-events: add support for xscale PMUs The perf-events framework for ARM only supports v6 and v7 cores. This patch adds support for xscale v1 and v2 PMUs to perf, based on the OProfile drivers in arch/arm/oprofile/op_model_xscale.c Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/perf_event.c | 827 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 821 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 10a0bcdf2158..381f1211233e 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -2108,6 +2108,803 @@ static u32 __init armv7_reset_read_pmnc(void) return nb_cnt + 1; } +/* + * ARMv5 [xscale] Performance counter handling code. + * + * Based on xscale OProfile code. + * + * There are two variants of the xscale PMU that we support: + * - xscale1pmu: 2 event counters and a cycle counter + * - xscale2pmu: 4 event counters and a cycle counter + * The two variants share event definitions, but have different + * PMU structures. + */ + +enum xscale_perf_types { + XSCALE_PERFCTR_ICACHE_MISS = 0x00, + XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01, + XSCALE_PERFCTR_DATA_STALL = 0x02, + XSCALE_PERFCTR_ITLB_MISS = 0x03, + XSCALE_PERFCTR_DTLB_MISS = 0x04, + XSCALE_PERFCTR_BRANCH = 0x05, + XSCALE_PERFCTR_BRANCH_MISS = 0x06, + XSCALE_PERFCTR_INSTRUCTION = 0x07, + XSCALE_PERFCTR_DCACHE_FULL_STALL = 0x08, + XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09, + XSCALE_PERFCTR_DCACHE_ACCESS = 0x0A, + XSCALE_PERFCTR_DCACHE_MISS = 0x0B, + XSCALE_PERFCTR_DCACHE_WRITE_BACK = 0x0C, + XSCALE_PERFCTR_PC_CHANGED = 0x0D, + XSCALE_PERFCTR_BCU_REQUEST = 0x10, + XSCALE_PERFCTR_BCU_FULL = 0x11, + XSCALE_PERFCTR_BCU_DRAIN = 0x12, + XSCALE_PERFCTR_BCU_ECC_NO_ELOG = 0x14, + XSCALE_PERFCTR_BCU_1_BIT_ERR = 0x15, + XSCALE_PERFCTR_RMW = 0x16, + /* XSCALE_PERFCTR_CCNT is not hardware defined */ + XSCALE_PERFCTR_CCNT = 0xFE, + XSCALE_PERFCTR_UNUSED = 0xFF, +}; + +enum xscale_counters { + XSCALE_CYCLE_COUNTER = 1, + XSCALE_COUNTER0, + XSCALE_COUNTER1, + XSCALE_COUNTER2, + XSCALE_COUNTER3, +}; + +static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = { + [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT, + [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION, + [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH, + [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS, + [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, +}; + +static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { + [C(L1D)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS, + [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS, + [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(L1I)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(LL)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(DTLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(ITLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(BPU)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, +}; + +#define XSCALE_PMU_ENABLE 0x001 +#define XSCALE_PMN_RESET 0x002 +#define XSCALE_CCNT_RESET 0x004 +#define XSCALE_PMU_RESET (CCNT_RESET | PMN_RESET) +#define XSCALE_PMU_CNT64 0x008 + +static inline int +xscalepmu_event_map(int config) +{ + int mapping = xscale_perf_map[config]; + if (HW_OP_UNSUPPORTED == mapping) + mapping = -EOPNOTSUPP; + return mapping; +} + +static u64 +xscalepmu_raw_event(u64 config) +{ + return config & 0xff; +} + +#define XSCALE1_OVERFLOWED_MASK 0x700 +#define XSCALE1_CCOUNT_OVERFLOW 0x400 +#define XSCALE1_COUNT0_OVERFLOW 0x100 +#define XSCALE1_COUNT1_OVERFLOW 0x200 +#define XSCALE1_CCOUNT_INT_EN 0x040 +#define XSCALE1_COUNT0_INT_EN 0x010 +#define XSCALE1_COUNT1_INT_EN 0x020 +#define XSCALE1_COUNT0_EVT_SHFT 12 +#define XSCALE1_COUNT0_EVT_MASK (0xff << XSCALE1_COUNT0_EVT_SHFT) +#define XSCALE1_COUNT1_EVT_SHFT 20 +#define XSCALE1_COUNT1_EVT_MASK (0xff << XSCALE1_COUNT1_EVT_SHFT) + +static inline u32 +xscale1pmu_read_pmnc(void) +{ + u32 val; + asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val)); + return val; +} + +static inline void +xscale1pmu_write_pmnc(u32 val) +{ + /* upper 4bits and 7, 11 are write-as-0 */ + val &= 0xffff77f; + asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val)); +} + +static inline int +xscale1_pmnc_counter_has_overflowed(unsigned long pmnc, + enum xscale_counters counter) +{ + int ret = 0; + + switch (counter) { + case XSCALE_CYCLE_COUNTER: + ret = pmnc & XSCALE1_CCOUNT_OVERFLOW; + break; + case XSCALE_COUNTER0: + ret = pmnc & XSCALE1_COUNT0_OVERFLOW; + break; + case XSCALE_COUNTER1: + ret = pmnc & XSCALE1_COUNT1_OVERFLOW; + break; + default: + WARN_ONCE(1, "invalid counter number (%d)\n", counter); + } + + return ret; +} + +static irqreturn_t +xscale1pmu_handle_irq(int irq_num, void *dev) +{ + unsigned long pmnc; + struct perf_sample_data data; + struct cpu_hw_events *cpuc; + struct pt_regs *regs; + int idx; + + /* + * NOTE: there's an A stepping erratum that states if an overflow + * bit already exists and another occurs, the previous + * Overflow bit gets cleared. There's no workaround. + * Fixed in B stepping or later. + */ + pmnc = xscale1pmu_read_pmnc(); + + /* + * Write the value back to clear the overflow flags. Overflow + * flags remain in pmnc for use below. We also disable the PMU + * while we process the interrupt. + */ + xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE); + + if (!(pmnc & XSCALE1_OVERFLOWED_MASK)) + return IRQ_NONE; + + regs = get_irq_regs(); + + perf_sample_data_init(&data, 0); + + cpuc = &__get_cpu_var(cpu_hw_events); + for (idx = 0; idx <= armpmu->num_events; ++idx) { + struct perf_event *event = cpuc->events[idx]; + struct hw_perf_event *hwc; + + if (!test_bit(idx, cpuc->active_mask)) + continue; + + if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx)) + continue; + + hwc = &event->hw; + armpmu_event_update(event, hwc, idx); + data.period = event->hw.last_period; + if (!armpmu_event_set_period(event, hwc, idx)) + continue; + + if (perf_event_overflow(event, 0, &data, regs)) + armpmu->disable(hwc, idx); + } + + perf_event_do_pending(); + + /* + * Re-enable the PMU. + */ + pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE; + xscale1pmu_write_pmnc(pmnc); + + return IRQ_HANDLED; +} + +static void +xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx) +{ + unsigned long val, mask, evt, flags; + + switch (idx) { + case XSCALE_CYCLE_COUNTER: + mask = 0; + evt = XSCALE1_CCOUNT_INT_EN; + break; + case XSCALE_COUNTER0: + mask = XSCALE1_COUNT0_EVT_MASK; + evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) | + XSCALE1_COUNT0_INT_EN; + break; + case XSCALE_COUNTER1: + mask = XSCALE1_COUNT1_EVT_MASK; + evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) | + XSCALE1_COUNT1_INT_EN; + break; + default: + WARN_ONCE(1, "invalid counter number (%d)\n", idx); + return; + } + + spin_lock_irqsave(&pmu_lock, flags); + val = xscale1pmu_read_pmnc(); + val &= ~mask; + val |= evt; + xscale1pmu_write_pmnc(val); + spin_unlock_irqrestore(&pmu_lock, flags); +} + +static void +xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx) +{ + unsigned long val, mask, evt, flags; + + switch (idx) { + case XSCALE_CYCLE_COUNTER: + mask = XSCALE1_CCOUNT_INT_EN; + evt = 0; + break; + case XSCALE_COUNTER0: + mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK; + evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT; + break; + case XSCALE_COUNTER1: + mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK; + evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT; + break; + default: + WARN_ONCE(1, "invalid counter number (%d)\n", idx); + return; + } + + spin_lock_irqsave(&pmu_lock, flags); + val = xscale1pmu_read_pmnc(); + val &= ~mask; + val |= evt; + xscale1pmu_write_pmnc(val); + spin_unlock_irqrestore(&pmu_lock, flags); +} + +static int +xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc, + struct hw_perf_event *event) +{ + if (XSCALE_PERFCTR_CCNT == event->config_base) { + if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask)) + return -EAGAIN; + + return XSCALE_CYCLE_COUNTER; + } else { + if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask)) { + return XSCALE_COUNTER1; + } + + if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask)) { + return XSCALE_COUNTER0; + } + + return -EAGAIN; + } +} + +static void +xscale1pmu_start(void) +{ + unsigned long flags, val; + + spin_lock_irqsave(&pmu_lock, flags); + val = xscale1pmu_read_pmnc(); + val |= XSCALE_PMU_ENABLE; + xscale1pmu_write_pmnc(val); + spin_unlock_irqrestore(&pmu_lock, flags); +} + +static void +xscale1pmu_stop(void) +{ + unsigned long flags, val; + + spin_lock_irqsave(&pmu_lock, flags); + val = xscale1pmu_read_pmnc(); + val &= ~XSCALE_PMU_ENABLE; + xscale1pmu_write_pmnc(val); + spin_unlock_irqrestore(&pmu_lock, flags); +} + +static inline u32 +xscale1pmu_read_counter(int counter) +{ + u32 val = 0; + + switch (counter) { + case XSCALE_CYCLE_COUNTER: + asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val)); + break; + case XSCALE_COUNTER0: + asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val)); + break; + case XSCALE_COUNTER1: + asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val)); + break; + } + + return val; +} + +static inline void +xscale1pmu_write_counter(int counter, u32 val) +{ + switch (counter) { + case XSCALE_CYCLE_COUNTER: + asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val)); + break; + case XSCALE_COUNTER0: + asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val)); + break; + case XSCALE_COUNTER1: + asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val)); + break; + } +} + +static const struct arm_pmu xscale1pmu = { + .id = ARM_PERF_PMU_ID_XSCALE1, + .handle_irq = xscale1pmu_handle_irq, + .enable = xscale1pmu_enable_event, + .disable = xscale1pmu_disable_event, + .event_map = xscalepmu_event_map, + .raw_event = xscalepmu_raw_event, + .read_counter = xscale1pmu_read_counter, + .write_counter = xscale1pmu_write_counter, + .get_event_idx = xscale1pmu_get_event_idx, + .start = xscale1pmu_start, + .stop = xscale1pmu_stop, + .num_events = 3, + .max_period = (1LLU << 32) - 1, +}; + +#define XSCALE2_OVERFLOWED_MASK 0x01f +#define XSCALE2_CCOUNT_OVERFLOW 0x001 +#define XSCALE2_COUNT0_OVERFLOW 0x002 +#define XSCALE2_COUNT1_OVERFLOW 0x004 +#define XSCALE2_COUNT2_OVERFLOW 0x008 +#define XSCALE2_COUNT3_OVERFLOW 0x010 +#define XSCALE2_CCOUNT_INT_EN 0x001 +#define XSCALE2_COUNT0_INT_EN 0x002 +#define XSCALE2_COUNT1_INT_EN 0x004 +#define XSCALE2_COUNT2_INT_EN 0x008 +#define XSCALE2_COUNT3_INT_EN 0x010 +#define XSCALE2_COUNT0_EVT_SHFT 0 +#define XSCALE2_COUNT0_EVT_MASK (0xff << XSCALE2_COUNT0_EVT_SHFT) +#define XSCALE2_COUNT1_EVT_SHFT 8 +#define XSCALE2_COUNT1_EVT_MASK (0xff << XSCALE2_COUNT1_EVT_SHFT) +#define XSCALE2_COUNT2_EVT_SHFT 16 +#define XSCALE2_COUNT2_EVT_MASK (0xff << XSCALE2_COUNT2_EVT_SHFT) +#define XSCALE2_COUNT3_EVT_SHFT 24 +#define XSCALE2_COUNT3_EVT_MASK (0xff << XSCALE2_COUNT3_EVT_SHFT) + +static inline u32 +xscale2pmu_read_pmnc(void) +{ + u32 val; + asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val)); + /* bits 1-2 and 4-23 are read-unpredictable */ + return val & 0xff000009; +} + +static inline void +xscale2pmu_write_pmnc(u32 val) +{ + /* bits 4-23 are write-as-0, 24-31 are write ignored */ + val &= 0xf; + asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val)); +} + +static inline u32 +xscale2pmu_read_overflow_flags(void) +{ + u32 val; + asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val)); + return val; +} + +static inline void +xscale2pmu_write_overflow_flags(u32 val) +{ + asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val)); +} + +static inline u32 +xscale2pmu_read_event_select(void) +{ + u32 val; + asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val)); + return val; +} + +static inline void +xscale2pmu_write_event_select(u32 val) +{ + asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val)); +} + +static inline u32 +xscale2pmu_read_int_enable(void) +{ + u32 val; + asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val)); + return val; +} + +static void +xscale2pmu_write_int_enable(u32 val) +{ + asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val)); +} + +static inline int +xscale2_pmnc_counter_has_overflowed(unsigned long of_flags, + enum xscale_counters counter) +{ + int ret = 0; + + switch (counter) { + case XSCALE_CYCLE_COUNTER: + ret = of_flags & XSCALE2_CCOUNT_OVERFLOW; + break; + case XSCALE_COUNTER0: + ret = of_flags & XSCALE2_COUNT0_OVERFLOW; + break; + case XSCALE_COUNTER1: + ret = of_flags & XSCALE2_COUNT1_OVERFLOW; + break; + case XSCALE_COUNTER2: + ret = of_flags & XSCALE2_COUNT2_OVERFLOW; + break; + case XSCALE_COUNTER3: + ret = of_flags & XSCALE2_COUNT3_OVERFLOW; + break; + default: + WARN_ONCE(1, "invalid counter number (%d)\n", counter); + } + + return ret; +} + +static irqreturn_t +xscale2pmu_handle_irq(int irq_num, void *dev) +{ + unsigned long pmnc, of_flags; + struct perf_sample_data data; + struct cpu_hw_events *cpuc; + struct pt_regs *regs; + int idx; + + /* Disable the PMU. */ + pmnc = xscale2pmu_read_pmnc(); + xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE); + + /* Check the overflow flag register. */ + of_flags = xscale2pmu_read_overflow_flags(); + if (!(of_flags & XSCALE2_OVERFLOWED_MASK)) + return IRQ_NONE; + + /* Clear the overflow bits. */ + xscale2pmu_write_overflow_flags(of_flags); + + regs = get_irq_regs(); + + perf_sample_data_init(&data, 0); + + cpuc = &__get_cpu_var(cpu_hw_events); + for (idx = 0; idx <= armpmu->num_events; ++idx) { + struct perf_event *event = cpuc->events[idx]; + struct hw_perf_event *hwc; + + if (!test_bit(idx, cpuc->active_mask)) + continue; + + if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx)) + continue; + + hwc = &event->hw; + armpmu_event_update(event, hwc, idx); + data.period = event->hw.last_period; + if (!armpmu_event_set_period(event, hwc, idx)) + continue; + + if (perf_event_overflow(event, 0, &data, regs)) + armpmu->disable(hwc, idx); + } + + perf_event_do_pending(); + + /* + * Re-enable the PMU. + */ + pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE; + xscale2pmu_write_pmnc(pmnc); + + return IRQ_HANDLED; +} + +static void +xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx) +{ + unsigned long flags, ien, evtsel; + + ien = xscale2pmu_read_int_enable(); + evtsel = xscale2pmu_read_event_select(); + + switch (idx) { + case XSCALE_CYCLE_COUNTER: + ien |= XSCALE2_CCOUNT_INT_EN; + break; + case XSCALE_COUNTER0: + ien |= XSCALE2_COUNT0_INT_EN; + evtsel &= ~XSCALE2_COUNT0_EVT_MASK; + evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT; + break; + case XSCALE_COUNTER1: + ien |= XSCALE2_COUNT1_INT_EN; + evtsel &= ~XSCALE2_COUNT1_EVT_MASK; + evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT; + break; + case XSCALE_COUNTER2: + ien |= XSCALE2_COUNT2_INT_EN; + evtsel &= ~XSCALE2_COUNT2_EVT_MASK; + evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT; + break; + case XSCALE_COUNTER3: + ien |= XSCALE2_COUNT3_INT_EN; + evtsel &= ~XSCALE2_COUNT3_EVT_MASK; + evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT; + break; + default: + WARN_ONCE(1, "invalid counter number (%d)\n", idx); + return; + } + + spin_lock_irqsave(&pmu_lock, flags); + xscale2pmu_write_event_select(evtsel); + xscale2pmu_write_int_enable(ien); + spin_unlock_irqrestore(&pmu_lock, flags); +} + +static void +xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx) +{ + unsigned long flags, ien, evtsel; + + ien = xscale2pmu_read_int_enable(); + evtsel = xscale2pmu_read_event_select(); + + switch (idx) { + case XSCALE_CYCLE_COUNTER: + ien &= ~XSCALE2_CCOUNT_INT_EN; + break; + case XSCALE_COUNTER0: + ien &= ~XSCALE2_COUNT0_INT_EN; + evtsel &= ~XSCALE2_COUNT0_EVT_MASK; + evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT; + break; + case XSCALE_COUNTER1: + ien &= ~XSCALE2_COUNT1_INT_EN; + evtsel &= ~XSCALE2_COUNT1_EVT_MASK; + evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT; + break; + case XSCALE_COUNTER2: + ien &= ~XSCALE2_COUNT2_INT_EN; + evtsel &= ~XSCALE2_COUNT2_EVT_MASK; + evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT; + break; + case XSCALE_COUNTER3: + ien &= ~XSCALE2_COUNT3_INT_EN; + evtsel &= ~XSCALE2_COUNT3_EVT_MASK; + evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT; + break; + default: + WARN_ONCE(1, "invalid counter number (%d)\n", idx); + return; + } + + spin_lock_irqsave(&pmu_lock, flags); + xscale2pmu_write_event_select(evtsel); + xscale2pmu_write_int_enable(ien); + spin_unlock_irqrestore(&pmu_lock, flags); +} + +static int +xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc, + struct hw_perf_event *event) +{ + int idx = xscale1pmu_get_event_idx(cpuc, event); + if (idx >= 0) + goto out; + + if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask)) + idx = XSCALE_COUNTER3; + else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask)) + idx = XSCALE_COUNTER2; +out: + return idx; +} + +static void +xscale2pmu_start(void) +{ + unsigned long flags, val; + + spin_lock_irqsave(&pmu_lock, flags); + val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64; + val |= XSCALE_PMU_ENABLE; + xscale2pmu_write_pmnc(val); + spin_unlock_irqrestore(&pmu_lock, flags); +} + +static void +xscale2pmu_stop(void) +{ + unsigned long flags, val; + + spin_lock_irqsave(&pmu_lock, flags); + val = xscale2pmu_read_pmnc(); + val &= ~XSCALE_PMU_ENABLE; + xscale2pmu_write_pmnc(val); + spin_unlock_irqrestore(&pmu_lock, flags); +} + +static inline u32 +xscale2pmu_read_counter(int counter) +{ + u32 val = 0; + + switch (counter) { + case XSCALE_CYCLE_COUNTER: + asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val)); + break; + case XSCALE_COUNTER0: + asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val)); + break; + case XSCALE_COUNTER1: + asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val)); + break; + case XSCALE_COUNTER2: + asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val)); + break; + case XSCALE_COUNTER3: + asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val)); + break; + } + + return val; +} + +static inline void +xscale2pmu_write_counter(int counter, u32 val) +{ + switch (counter) { + case XSCALE_CYCLE_COUNTER: + asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val)); + break; + case XSCALE_COUNTER0: + asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val)); + break; + case XSCALE_COUNTER1: + asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val)); + break; + case XSCALE_COUNTER2: + asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val)); + break; + case XSCALE_COUNTER3: + asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val)); + break; + } +} + +static const struct arm_pmu xscale2pmu = { + .id = ARM_PERF_PMU_ID_XSCALE2, + .handle_irq = xscale2pmu_handle_irq, + .enable = xscale2pmu_enable_event, + .disable = xscale2pmu_disable_event, + .event_map = xscalepmu_event_map, + .raw_event = xscalepmu_raw_event, + .read_counter = xscale2pmu_read_counter, + .write_counter = xscale2pmu_write_counter, + .get_event_idx = xscale2pmu_get_event_idx, + .start = xscale2pmu_start, + .stop = xscale2pmu_stop, + .num_events = 5, + .max_period = (1LLU << 32) - 1, +}; + static int __init init_hw_perf_events(void) { @@ -2115,7 +2912,7 @@ init_hw_perf_events(void) unsigned long implementor = (cpuid & 0xFF000000) >> 24; unsigned long part_number = (cpuid & 0xFFF0); - /* We only support ARM CPUs implemented by ARM at the moment. */ + /* ARM Ltd CPUs. */ if (0x41 == implementor) { switch (part_number) { case 0xB360: /* ARM1136 */ @@ -2157,15 +2954,33 @@ init_hw_perf_events(void) armv7pmu.num_events = armv7_reset_read_pmnc(); perf_max_events = armv7pmu.num_events; break; - default: - pr_info("no hardware support available\n"); - perf_max_events = -1; + } + /* Intel CPUs [xscale]. */ + } else if (0x69 == implementor) { + part_number = (cpuid >> 13) & 0x7; + switch (part_number) { + case 1: + armpmu = &xscale1pmu; + memcpy(armpmu_perf_cache_map, xscale_perf_cache_map, + sizeof(xscale_perf_cache_map)); + perf_max_events = xscale1pmu.num_events; + break; + case 2: + armpmu = &xscale2pmu; + memcpy(armpmu_perf_cache_map, xscale_perf_cache_map, + sizeof(xscale_perf_cache_map)); + perf_max_events = xscale2pmu.num_events; + break; } } - if (armpmu) + if (armpmu) { pr_info("enabled with %s PMU driver, %d counters available\n", - arm_pmu_names[armpmu->id], armpmu->num_events); + arm_pmu_names[armpmu->id], armpmu->num_events); + } else { + pr_info("no hardware support available\n"); + perf_max_events = -1; + } return 0; } -- cgit v1.2.3-59-g8ed1b From 929f5199448a67d41bb249d58815ef77bcd53622 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 30 Apr 2010 11:34:26 +0100 Subject: ARM: 6071/1: perf-events: allow modules to query the number of hardware counters For OProfile to initialise oprofilefs correctly, it needs to know the number of counters it can represent. This patch adds a function to the ARM perf-events backend to return the number of hardware counters available for the current PMU. Cc: Jamie Iles Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/perf_event.h | 3 +++ arch/arm/kernel/perf_event.c | 12 ++++++++++++ 2 files changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index fa4b32625d37..48837e6d8887 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h @@ -42,4 +42,7 @@ enum arm_perf_pmu_ids { extern enum arm_perf_pmu_ids armpmu_get_pmu_id(void); +extern int +armpmu_get_max_events(void); + #endif /* __ARM_PERF_EVENT_H__ */ diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 381f1211233e..c45768614c8a 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -111,6 +111,18 @@ armpmu_get_pmu_id(void) } EXPORT_SYMBOL_GPL(armpmu_get_pmu_id); +int +armpmu_get_max_events(void) +{ + int max_events = 0; + + if (armpmu != NULL) + max_events = armpmu->num_events; + + return max_events; +} +EXPORT_SYMBOL_GPL(armpmu_get_max_events); + #define HW_OP_UNSUPPORTED 0xFFFF #define C(_x) \ -- cgit v1.2.3-59-g8ed1b From 8c1fc96f6fd1f361428ba805103af0d0eee65179 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 30 Apr 2010 11:36:54 +0100 Subject: ARM: 6072/1: oprofile: use perf-events framework as backend There are currently two hardware performance monitoring subsystems in the kernel for ARM: OProfile and perf-events. This creates the following problems: 1.) Duplicate PMU accessor code. Inevitable code drift may lead to bugs in one framework that are fixed in the other. 2.) Locking issues. OProfile doesn't reprogram hardware counters between profiling runs if the events to be monitored have not been changed. This means that other profiling frameworks cannot use the counters if OProfile is in use. 3.) Due to differences in the two frameworks, it may not be possible to compare the results obtained by OProfile with those obtained by perf. This patch removes the OProfile PMU driver code and replaces it with calls to perf, therefore solving the issues mentioned above. The only userspace-visible change is the lack of SCU counter support for 11MPCore. This is currently unsupported by OProfile userspace tools anyway and therefore shouldn't cause any problems. Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Robert Richter Cc: Jamie Iles Cc: Jean Pihet Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/oprofile/common.c | 333 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 281 insertions(+), 52 deletions(-) (limited to 'arch') diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 3fcd752d6146..aad83df89bac 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -2,32 +2,183 @@ * @file common.c * * @remark Copyright 2004 Oprofile Authors + * @remark Copyright 2010 ARM Ltd. * @remark Read the file COPYING * * @author Zwane Mwaikambo + * @author Will Deacon [move to perf] */ +#include +#include #include +#include #include -#include +#include #include #include -#include +#include +#include + +#include +#include -#include "op_counter.h" -#include "op_arm_model.h" +#ifdef CONFIG_HW_PERF_EVENTS +/* + * Per performance monitor configuration as set via oprofilefs. + */ +struct op_counter_config { + unsigned long count; + unsigned long enabled; + unsigned long event; + unsigned long unit_mask; + unsigned long kernel; + unsigned long user; + struct perf_event_attr attr; +}; -static struct op_arm_model_spec *op_arm_model; static int op_arm_enabled; static DEFINE_MUTEX(op_arm_mutex); -struct op_counter_config *counter_config; +static struct op_counter_config *counter_config; +static struct perf_event **perf_events[nr_cpumask_bits]; +static int perf_num_counters; + +/* + * Overflow callback for oprofile. + */ +static void op_overflow_handler(struct perf_event *event, int unused, + struct perf_sample_data *data, struct pt_regs *regs) +{ + int id; + u32 cpu = smp_processor_id(); + + for (id = 0; id < perf_num_counters; ++id) + if (perf_events[cpu][id] == event) + break; + + if (id != perf_num_counters) + oprofile_add_sample(regs, id); + else + pr_warning("oprofile: ignoring spurious overflow " + "on cpu %u\n", cpu); +} + +/* + * Called by op_arm_setup to create perf attributes to mirror the oprofile + * settings in counter_config. Attributes are created as `pinned' events and + * so are permanently scheduled on the PMU. + */ +static void op_perf_setup(void) +{ + int i; + u32 size = sizeof(struct perf_event_attr); + struct perf_event_attr *attr; + + for (i = 0; i < perf_num_counters; ++i) { + attr = &counter_config[i].attr; + memset(attr, 0, size); + attr->type = PERF_TYPE_RAW; + attr->size = size; + attr->config = counter_config[i].event; + attr->sample_period = counter_config[i].count; + attr->pinned = 1; + } +} + +static int op_create_counter(int cpu, int event) +{ + int ret = 0; + struct perf_event *pevent; + + if (!counter_config[event].enabled || (perf_events[cpu][event] != NULL)) + return ret; + + pevent = perf_event_create_kernel_counter(&counter_config[event].attr, + cpu, -1, + op_overflow_handler); + + if (IS_ERR(pevent)) { + ret = PTR_ERR(pevent); + } else if (pevent->state != PERF_EVENT_STATE_ACTIVE) { + pr_warning("oprofile: failed to enable event %d " + "on CPU %d\n", event, cpu); + ret = -EBUSY; + } else { + perf_events[cpu][event] = pevent; + } + + return ret; +} + +static void op_destroy_counter(int cpu, int event) +{ + struct perf_event *pevent = perf_events[cpu][event]; + + if (pevent) { + perf_event_release_kernel(pevent); + perf_events[cpu][event] = NULL; + } +} + +/* + * Called by op_arm_start to create active perf events based on the + * perviously configured attributes. + */ +static int op_perf_start(void) +{ + int cpu, event, ret = 0; + + for_each_online_cpu(cpu) { + for (event = 0; event < perf_num_counters; ++event) { + ret = op_create_counter(cpu, event); + if (ret) + goto out; + } + } + +out: + return ret; +} + +/* + * Called by op_arm_stop at the end of a profiling run. + */ +static void op_perf_stop(void) +{ + int cpu, event; + + for_each_online_cpu(cpu) + for (event = 0; event < perf_num_counters; ++event) + op_destroy_counter(cpu, event); +} + + +static char *op_name_from_perf_id(enum arm_perf_pmu_ids id) +{ + switch (id) { + case ARM_PERF_PMU_ID_XSCALE1: + return "arm/xscale1"; + case ARM_PERF_PMU_ID_XSCALE2: + return "arm/xscale2"; + case ARM_PERF_PMU_ID_V6: + return "arm/armv6"; + case ARM_PERF_PMU_ID_V6MP: + return "arm/mpcore"; + case ARM_PERF_PMU_ID_CA8: + return "arm/armv7"; + case ARM_PERF_PMU_ID_CA9: + return "arm/armv7-ca9"; + default: + return NULL; + } +} static int op_arm_create_files(struct super_block *sb, struct dentry *root) { unsigned int i; - for (i = 0; i < op_arm_model->num_counters; i++) { + for (i = 0; i < perf_num_counters; i++) { struct dentry *dir; char buf[4]; @@ -46,12 +197,10 @@ static int op_arm_create_files(struct super_block *sb, struct dentry *root) static int op_arm_setup(void) { - int ret; - spin_lock(&oprofilefs_lock); - ret = op_arm_model->setup_ctrs(); + op_perf_setup(); spin_unlock(&oprofilefs_lock); - return ret; + return 0; } static int op_arm_start(void) @@ -60,8 +209,9 @@ static int op_arm_start(void) mutex_lock(&op_arm_mutex); if (!op_arm_enabled) { - ret = op_arm_model->start(); - op_arm_enabled = !ret; + ret = 0; + op_perf_start(); + op_arm_enabled = 1; } mutex_unlock(&op_arm_mutex); return ret; @@ -71,7 +221,7 @@ static void op_arm_stop(void) { mutex_lock(&op_arm_mutex); if (op_arm_enabled) - op_arm_model->stop(); + op_perf_stop(); op_arm_enabled = 0; mutex_unlock(&op_arm_mutex); } @@ -81,7 +231,7 @@ static int op_arm_suspend(struct sys_device *dev, pm_message_t state) { mutex_lock(&op_arm_mutex); if (op_arm_enabled) - op_arm_model->stop(); + op_perf_stop(); mutex_unlock(&op_arm_mutex); return 0; } @@ -89,7 +239,7 @@ static int op_arm_suspend(struct sys_device *dev, pm_message_t state) static int op_arm_resume(struct sys_device *dev) { mutex_lock(&op_arm_mutex); - if (op_arm_enabled && op_arm_model->start()) + if (op_arm_enabled && op_perf_start()) op_arm_enabled = 0; mutex_unlock(&op_arm_mutex); return 0; @@ -126,58 +276,137 @@ static void exit_driverfs(void) #define exit_driverfs() do { } while (0) #endif /* CONFIG_PM */ -int __init oprofile_arch_init(struct oprofile_operations *ops) +static int report_trace(struct stackframe *frame, void *d) { - struct op_arm_model_spec *spec = NULL; - int ret = -ENODEV; + unsigned int *depth = d; - ops->backtrace = arm_backtrace; + if (*depth) { + oprofile_add_trace(frame->pc); + (*depth)--; + } -#ifdef CONFIG_CPU_XSCALE - spec = &op_xscale_spec; -#endif + return *depth == 0; +} -#ifdef CONFIG_OPROFILE_ARMV6 - spec = &op_armv6_spec; -#endif +/* + * The registers we're interested in are at the end of the variable + * length saved register structure. The fp points at the end of this + * structure so the address of this struct is: + * (struct frame_tail *)(xxx->fp)-1 + */ +struct frame_tail { + struct frame_tail *fp; + unsigned long sp; + unsigned long lr; +} __attribute__((packed)); -#ifdef CONFIG_OPROFILE_MPCORE - spec = &op_mpcore_spec; -#endif +static struct frame_tail* user_backtrace(struct frame_tail *tail) +{ + struct frame_tail buftail[2]; -#ifdef CONFIG_OPROFILE_ARMV7 - spec = &op_armv7_spec; -#endif + /* Also check accessibility of one struct frame_tail beyond */ + if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) + return NULL; + if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail))) + return NULL; - if (spec) { - ret = spec->init(); - if (ret < 0) - return ret; + oprofile_add_trace(buftail[0].lr); - counter_config = kcalloc(spec->num_counters, sizeof(struct op_counter_config), - GFP_KERNEL); - if (!counter_config) - return -ENOMEM; + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (tail >= buftail[0].fp) + return NULL; + + return buftail[0].fp-1; +} + +static void arm_backtrace(struct pt_regs * const regs, unsigned int depth) +{ + struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1; + + if (!user_mode(regs)) { + struct stackframe frame; + frame.fp = regs->ARM_fp; + frame.sp = regs->ARM_sp; + frame.lr = regs->ARM_lr; + frame.pc = regs->ARM_pc; + walk_stackframe(&frame, report_trace, &depth); + return; + } + + while (depth-- && tail && !((unsigned long) tail & 3)) + tail = user_backtrace(tail); +} + +int __init oprofile_arch_init(struct oprofile_operations *ops) +{ + int cpu, ret = 0; + + perf_num_counters = armpmu_get_max_events(); + + counter_config = kcalloc(perf_num_counters, + sizeof(struct op_counter_config), GFP_KERNEL); - op_arm_model = spec; - init_driverfs(); - ops->create_files = op_arm_create_files; - ops->setup = op_arm_setup; - ops->shutdown = op_arm_stop; - ops->start = op_arm_start; - ops->stop = op_arm_stop; - ops->cpu_type = op_arm_model->name; - printk(KERN_INFO "oprofile: using %s\n", spec->name); + if (!counter_config) { + pr_info("oprofile: failed to allocate %d " + "counters\n", perf_num_counters); + return -ENOMEM; } + for_each_possible_cpu(cpu) { + perf_events[cpu] = kcalloc(perf_num_counters, + sizeof(struct perf_event *), GFP_KERNEL); + if (!perf_events[cpu]) { + pr_info("oprofile: failed to allocate %d perf events " + "for cpu %d\n", perf_num_counters, cpu); + while (--cpu >= 0) + kfree(perf_events[cpu]); + return -ENOMEM; + } + } + + init_driverfs(); + ops->backtrace = arm_backtrace; + ops->create_files = op_arm_create_files; + ops->setup = op_arm_setup; + ops->start = op_arm_start; + ops->stop = op_arm_stop; + ops->shutdown = op_arm_stop; + ops->cpu_type = op_name_from_perf_id(armpmu_get_pmu_id()); + + if (!ops->cpu_type) + ret = -ENODEV; + else + pr_info("oprofile: using %s\n", ops->cpu_type); + return ret; } void oprofile_arch_exit(void) { - if (op_arm_model) { + int cpu, id; + struct perf_event *event; + + if (*perf_events) { exit_driverfs(); - op_arm_model = NULL; + for_each_possible_cpu(cpu) { + for (id = 0; id < perf_num_counters; ++id) { + event = perf_events[cpu][id]; + if (event != NULL) + perf_event_release_kernel(event); + } + kfree(perf_events[cpu]); + } } - kfree(counter_config); + + if (counter_config) + kfree(counter_config); +} +#else +int __init oprofile_arch_init(struct oprofile_operations *ops) +{ + pr_info("oprofile: hardware counters not available\n"); + return -ENODEV; } +void oprofile_arch_exit(void) {} +#endif /* CONFIG_HW_PERF_EVENTS */ -- cgit v1.2.3-59-g8ed1b From fe166148f699cc7865ca07b6754872cfb5ebc312 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 30 Apr 2010 11:37:51 +0100 Subject: ARM: 6073/1: oprofile: remove old files and update KConfig Enable hardware perf-events if CPU_HAS_PMU and select HAVE_OPROFILE if HAVE_PERF_EVENTS. If no hardware support is present, OProfile will fall back to timer mode. This patch also removes the old OProfile drivers in favour of the code implemented by perf. Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/Kconfig | 26 +- arch/arm/oprofile/Makefile | 7 +- arch/arm/oprofile/backtrace.c | 83 ------ arch/arm/oprofile/op_arm_model.h | 35 --- arch/arm/oprofile/op_counter.h | 27 -- arch/arm/oprofile/op_model_arm11_core.c | 162 ------------ arch/arm/oprofile/op_model_arm11_core.h | 45 ---- arch/arm/oprofile/op_model_mpcore.c | 306 ---------------------- arch/arm/oprofile/op_model_mpcore.h | 61 ----- arch/arm/oprofile/op_model_v6.c | 78 ------ arch/arm/oprofile/op_model_v7.c | 415 ----------------------------- arch/arm/oprofile/op_model_v7.h | 103 -------- arch/arm/oprofile/op_model_xscale.c | 444 -------------------------------- 13 files changed, 3 insertions(+), 1789 deletions(-) delete mode 100644 arch/arm/oprofile/backtrace.c delete mode 100644 arch/arm/oprofile/op_arm_model.h delete mode 100644 arch/arm/oprofile/op_counter.h delete mode 100644 arch/arm/oprofile/op_model_arm11_core.c delete mode 100644 arch/arm/oprofile/op_model_arm11_core.h delete mode 100644 arch/arm/oprofile/op_model_mpcore.c delete mode 100644 arch/arm/oprofile/op_model_mpcore.h delete mode 100644 arch/arm/oprofile/op_model_v6.c delete mode 100644 arch/arm/oprofile/op_model_v7.c delete mode 100644 arch/arm/oprofile/op_model_v7.h delete mode 100644 arch/arm/oprofile/op_model_xscale.c (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index daaa4b2b46e1..f7c2a882b54d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -13,7 +13,7 @@ config ARM select RTC_LIB select SYS_SUPPORTS_APM_EMULATION select GENERIC_ATOMIC64 if (!CPU_32v6K) - select HAVE_OPROFILE + select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_ARCH_KGDB select HAVE_KPROBES if (!XIP_KERNEL) select HAVE_KRETPROBES if (HAVE_KPROBES) @@ -181,28 +181,6 @@ config ARM_L1_CACHE_SHIFT_6 help Setting ARM L1 cache line size to 64 Bytes. -if OPROFILE - -config OPROFILE_ARMV6 - def_bool y - depends on CPU_V6 && !SMP - select OPROFILE_ARM11_CORE - -config OPROFILE_MPCORE - def_bool y - depends on CPU_V6 && SMP - select OPROFILE_ARM11_CORE - -config OPROFILE_ARM11_CORE - bool - -config OPROFILE_ARMV7 - def_bool y - depends on CPU_V7 && !SMP - bool - -endif - config VECTORS_BASE hex default 0xffff0000 if MMU || CPU_HIGH_VECTOR @@ -1334,7 +1312,7 @@ config HIGHPTE config HW_PERF_EVENTS bool "Enable hardware performance counter support for perf events" - depends on PERF_EVENTS && CPU_HAS_PMU && (CPU_V6 || CPU_V7) + depends on PERF_EVENTS && CPU_HAS_PMU default y help Enable hardware performance counter support for perf events. If diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile index 88e31f549f50..e666eafed152 100644 --- a/arch/arm/oprofile/Makefile +++ b/arch/arm/oprofile/Makefile @@ -6,9 +6,4 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ oprofilefs.o oprofile_stats.o \ timer_int.o ) -oprofile-y := $(DRIVER_OBJS) common.o backtrace.o -oprofile-$(CONFIG_CPU_XSCALE) += op_model_xscale.o -oprofile-$(CONFIG_OPROFILE_ARM11_CORE) += op_model_arm11_core.o -oprofile-$(CONFIG_OPROFILE_ARMV6) += op_model_v6.o -oprofile-$(CONFIG_OPROFILE_MPCORE) += op_model_mpcore.o -oprofile-$(CONFIG_OPROFILE_ARMV7) += op_model_v7.o +oprofile-y := $(DRIVER_OBJS) common.o diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c deleted file mode 100644 index d805a52b5032..000000000000 --- a/arch/arm/oprofile/backtrace.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Arm specific backtracing code for oprofile - * - * Copyright 2005 Openedhand Ltd. - * - * Author: Richard Purdie - * - * Based on i386 oprofile backtrace code by John Levon, David Smith - * - * 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 -#include -#include -#include -#include -#include - -static int report_trace(struct stackframe *frame, void *d) -{ - unsigned int *depth = d; - - if (*depth) { - oprofile_add_trace(frame->pc); - (*depth)--; - } - - return *depth == 0; -} - -/* - * The registers we're interested in are at the end of the variable - * length saved register structure. The fp points at the end of this - * structure so the address of this struct is: - * (struct frame_tail *)(xxx->fp)-1 - */ -struct frame_tail { - struct frame_tail *fp; - unsigned long sp; - unsigned long lr; -} __attribute__((packed)); - -static struct frame_tail* user_backtrace(struct frame_tail *tail) -{ - struct frame_tail buftail[2]; - - /* Also check accessibility of one struct frame_tail beyond */ - if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) - return NULL; - if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail))) - return NULL; - - oprofile_add_trace(buftail[0].lr); - - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (tail >= buftail[0].fp) - return NULL; - - return buftail[0].fp-1; -} - -void arm_backtrace(struct pt_regs * const regs, unsigned int depth) -{ - struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1; - - if (!user_mode(regs)) { - struct stackframe frame; - frame.fp = regs->ARM_fp; - frame.sp = regs->ARM_sp; - frame.lr = regs->ARM_lr; - frame.pc = regs->ARM_pc; - walk_stackframe(&frame, report_trace, &depth); - return; - } - - while (depth-- && tail && !((unsigned long) tail & 3)) - tail = user_backtrace(tail); -} diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h deleted file mode 100644 index 8c4e4f6a1de3..000000000000 --- a/arch/arm/oprofile/op_arm_model.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file op_arm_model.h - * interface to ARM machine specific operations - * - * @remark Copyright 2004 Oprofile Authors - * @remark Read the file COPYING - * - * @author Zwane Mwaikambo - */ - -#ifndef OP_ARM_MODEL_H -#define OP_ARM_MODEL_H - -struct op_arm_model_spec { - int (*init)(void); - unsigned int num_counters; - int (*setup_ctrs)(void); - int (*start)(void); - void (*stop)(void); - char *name; -}; - -#ifdef CONFIG_CPU_XSCALE -extern struct op_arm_model_spec op_xscale_spec; -#endif - -extern struct op_arm_model_spec op_armv6_spec; -extern struct op_arm_model_spec op_mpcore_spec; -extern struct op_arm_model_spec op_armv7_spec; - -extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth); - -extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); -extern void op_arm_exit(void); -#endif /* OP_ARM_MODEL_H */ diff --git a/arch/arm/oprofile/op_counter.h b/arch/arm/oprofile/op_counter.h deleted file mode 100644 index ca942a63b52f..000000000000 --- a/arch/arm/oprofile/op_counter.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @file op_counter.h - * - * @remark Copyright 2004 Oprofile Authors - * @remark Read the file COPYING - * - * @author Zwane Mwaikambo - */ - -#ifndef OP_COUNTER_H -#define OP_COUNTER_H - -/* Per performance monitor configuration as set via - * oprofilefs. - */ -struct op_counter_config { - unsigned long count; - unsigned long enabled; - unsigned long event; - unsigned long unit_mask; - unsigned long kernel; - unsigned long user; -}; - -extern struct op_counter_config *counter_config; - -#endif /* OP_COUNTER_H */ diff --git a/arch/arm/oprofile/op_model_arm11_core.c b/arch/arm/oprofile/op_model_arm11_core.c deleted file mode 100644 index ef3e2653b90c..000000000000 --- a/arch/arm/oprofile/op_model_arm11_core.c +++ /dev/null @@ -1,162 +0,0 @@ -/** - * @file op_model_arm11_core.c - * ARM11 Event Monitor Driver - * @remark Copyright 2004 ARM SMP Development Team - */ -#include -#include -#include -#include -#include -#include - -#include "op_counter.h" -#include "op_arm_model.h" -#include "op_model_arm11_core.h" - -/* - * ARM11 PMU support - */ -static inline void arm11_write_pmnc(u32 val) -{ - /* upper 4bits and 7, 11 are write-as-0 */ - val &= 0x0ffff77f; - asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r" (val)); -} - -static inline u32 arm11_read_pmnc(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r" (val)); - return val; -} - -static void arm11_reset_counter(unsigned int cnt) -{ - u32 val = -(u32)counter_config[CPU_COUNTER(smp_processor_id(), cnt)].count; - switch (cnt) { - case CCNT: - asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r" (val)); - break; - - case PMN0: - asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r" (val)); - break; - - case PMN1: - asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r" (val)); - break; - } -} - -int arm11_setup_pmu(void) -{ - unsigned int cnt; - u32 pmnc; - - if (arm11_read_pmnc() & PMCR_E) { - printk(KERN_ERR "oprofile: CPU%u PMU still enabled when setup new event counter.\n", smp_processor_id()); - return -EBUSY; - } - - /* initialize PMNC, reset overflow, D bit, C bit and P bit. */ - arm11_write_pmnc(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT | - PMCR_C | PMCR_P); - - for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) { - unsigned long event; - - if (!counter_config[CPU_COUNTER(smp_processor_id(), cnt)].enabled) - continue; - - event = counter_config[CPU_COUNTER(smp_processor_id(), cnt)].event & 255; - - /* - * Set event (if destined for PMNx counters) - */ - if (cnt == PMN0) { - pmnc |= event << 20; - } else if (cnt == PMN1) { - pmnc |= event << 12; - } - - /* - * We don't need to set the event if it's a cycle count - * Enable interrupt for this counter - */ - pmnc |= PMCR_IEN_PMN0 << cnt; - arm11_reset_counter(cnt); - } - arm11_write_pmnc(pmnc); - - return 0; -} - -int arm11_start_pmu(void) -{ - arm11_write_pmnc(arm11_read_pmnc() | PMCR_E); - return 0; -} - -int arm11_stop_pmu(void) -{ - unsigned int cnt; - - arm11_write_pmnc(arm11_read_pmnc() & ~PMCR_E); - - for (cnt = PMN0; cnt <= CCNT; cnt++) - arm11_reset_counter(cnt); - - return 0; -} - -/* - * CPU counters' IRQ handler (one IRQ per CPU) - */ -static irqreturn_t arm11_pmu_interrupt(int irq, void *arg) -{ - struct pt_regs *regs = get_irq_regs(); - unsigned int cnt; - u32 pmnc; - - pmnc = arm11_read_pmnc(); - - for (cnt = PMN0; cnt <= CCNT; cnt++) { - if ((pmnc & (PMCR_OFL_PMN0 << cnt)) && (pmnc & (PMCR_IEN_PMN0 << cnt))) { - arm11_reset_counter(cnt); - oprofile_add_sample(regs, CPU_COUNTER(smp_processor_id(), cnt)); - } - } - /* Clear counter flag(s) */ - arm11_write_pmnc(pmnc); - return IRQ_HANDLED; -} - -int arm11_request_interrupts(const int *irqs, int nr) -{ - unsigned int i; - int ret = 0; - - for(i = 0; i < nr; i++) { - ret = request_irq(irqs[i], arm11_pmu_interrupt, IRQF_DISABLED, "CP15 PMU", NULL); - if (ret != 0) { - printk(KERN_ERR "oprofile: unable to request IRQ%u for MPCORE-EM\n", - irqs[i]); - break; - } - } - - if (i != nr) - while (i-- != 0) - free_irq(irqs[i], NULL); - - return ret; -} - -void arm11_release_interrupts(const int *irqs, int nr) -{ - unsigned int i; - - for (i = 0; i < nr; i++) - free_irq(irqs[i], NULL); -} diff --git a/arch/arm/oprofile/op_model_arm11_core.h b/arch/arm/oprofile/op_model_arm11_core.h deleted file mode 100644 index 1902b99d9dfd..000000000000 --- a/arch/arm/oprofile/op_model_arm11_core.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @file op_model_arm11_core.h - * ARM11 Event Monitor Driver - * @remark Copyright 2004 ARM SMP Development Team - * @remark Copyright 2000-2004 Deepak Saxena - * @remark Copyright 2000-2004 MontaVista Software Inc - * @remark Copyright 2004 Dave Jiang - * @remark Copyright 2004 Intel Corporation - * @remark Copyright 2004 Zwane Mwaikambo - * @remark Copyright 2004 Oprofile Authors - * - * @remark Read the file COPYING - * - * @author Zwane Mwaikambo - */ -#ifndef OP_MODEL_ARM11_CORE_H -#define OP_MODEL_ARM11_CORE_H - -/* - * Per-CPU PMCR - */ -#define PMCR_E (1 << 0) /* Enable */ -#define PMCR_P (1 << 1) /* Count reset */ -#define PMCR_C (1 << 2) /* Cycle counter reset */ -#define PMCR_D (1 << 3) /* Cycle counter counts every 64th cpu cycle */ -#define PMCR_IEN_PMN0 (1 << 4) /* Interrupt enable count reg 0 */ -#define PMCR_IEN_PMN1 (1 << 5) /* Interrupt enable count reg 1 */ -#define PMCR_IEN_CCNT (1 << 6) /* Interrupt enable cycle counter */ -#define PMCR_OFL_PMN0 (1 << 8) /* Count reg 0 overflow */ -#define PMCR_OFL_PMN1 (1 << 9) /* Count reg 1 overflow */ -#define PMCR_OFL_CCNT (1 << 10) /* Cycle counter overflow */ - -#define PMN0 0 -#define PMN1 1 -#define CCNT 2 - -#define CPU_COUNTER(cpu, counter) ((cpu) * 3 + (counter)) - -int arm11_setup_pmu(void); -int arm11_start_pmu(void); -int arm11_stop_pmu(void); -int arm11_request_interrupts(const int *, int); -void arm11_release_interrupts(const int *, int); - -#endif diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c deleted file mode 100644 index f73ce875a395..000000000000 --- a/arch/arm/oprofile/op_model_mpcore.c +++ /dev/null @@ -1,306 +0,0 @@ -/** - * @file op_model_mpcore.c - * MPCORE Event Monitor Driver - * @remark Copyright 2004 ARM SMP Development Team - * @remark Copyright 2000-2004 Deepak Saxena - * @remark Copyright 2000-2004 MontaVista Software Inc - * @remark Copyright 2004 Dave Jiang - * @remark Copyright 2004 Intel Corporation - * @remark Copyright 2004 Zwane Mwaikambo - * @remark Copyright 2004 Oprofile Authors - * - * @remark Read the file COPYING - * - * @author Zwane Mwaikambo - * - * Counters: - * 0: PMN0 on CPU0, per-cpu configurable event counter - * 1: PMN1 on CPU0, per-cpu configurable event counter - * 2: CCNT on CPU0 - * 3: PMN0 on CPU1 - * 4: PMN1 on CPU1 - * 5: CCNT on CPU1 - * 6: PMN0 on CPU1 - * 7: PMN1 on CPU1 - * 8: CCNT on CPU1 - * 9: PMN0 on CPU1 - * 10: PMN1 on CPU1 - * 11: CCNT on CPU1 - * 12-19: configurable SCU event counters - */ - -/* #define DEBUG */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "op_counter.h" -#include "op_arm_model.h" -#include "op_model_arm11_core.h" -#include "op_model_mpcore.h" - -/* - * MPCore SCU event monitor support - */ -#define SCU_EVENTMONITORS_VA_BASE __io_address(REALVIEW_EB11MP_SCU_BASE + 0x10) - -/* - * Bitmask of used SCU counters - */ -static unsigned int scu_em_used; -static const struct pmu_irqs *pmu_irqs; - -/* - * 2 helper fns take a counter number from 0-7 (not the userspace-visible counter number) - */ -static inline void scu_reset_counter(struct eventmonitor __iomem *emc, unsigned int n) -{ - writel(-(u32)counter_config[SCU_COUNTER(n)].count, &emc->MC[n]); -} - -static inline void scu_set_event(struct eventmonitor __iomem *emc, unsigned int n, u32 event) -{ - event &= 0xff; - writeb(event, &emc->MCEB[n]); -} - -/* - * SCU counters' IRQ handler (one IRQ per counter => 2 IRQs per CPU) - */ -static irqreturn_t scu_em_interrupt(int irq, void *arg) -{ - struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE; - unsigned int cnt; - - cnt = irq - IRQ_EB11MP_PMU_SCU0; - oprofile_add_sample(get_irq_regs(), SCU_COUNTER(cnt)); - scu_reset_counter(emc, cnt); - - /* Clear overflow flag for this counter */ - writel(1 << (cnt + 16), &emc->PMCR); - - return IRQ_HANDLED; -} - -/* Configure just the SCU counters that the user has requested */ -static void scu_setup(void) -{ - struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE; - unsigned int i; - - scu_em_used = 0; - - for (i = 0; i < NUM_SCU_COUNTERS; i++) { - if (counter_config[SCU_COUNTER(i)].enabled && - counter_config[SCU_COUNTER(i)].event) { - scu_set_event(emc, i, 0); /* disable counter for now */ - scu_em_used |= 1 << i; - } - } -} - -static int scu_start(void) -{ - struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE; - unsigned int temp, i; - unsigned long event; - int ret = 0; - - /* - * request the SCU counter interrupts that we need - */ - for (i = 0; i < NUM_SCU_COUNTERS; i++) { - if (scu_em_used & (1 << i)) { - ret = request_irq(IRQ_EB11MP_PMU_SCU0 + i, scu_em_interrupt, IRQF_DISABLED, "SCU PMU", NULL); - if (ret) { - printk(KERN_ERR "oprofile: unable to request IRQ%u for SCU Event Monitor\n", - IRQ_EB11MP_PMU_SCU0 + i); - goto err_free_scu; - } - } - } - - /* - * clear overflow and enable interrupt for all used counters - */ - temp = readl(&emc->PMCR); - for (i = 0; i < NUM_SCU_COUNTERS; i++) { - if (scu_em_used & (1 << i)) { - scu_reset_counter(emc, i); - event = counter_config[SCU_COUNTER(i)].event; - scu_set_event(emc, i, event); - - /* clear overflow/interrupt */ - temp |= 1 << (i + 16); - /* enable interrupt*/ - temp |= 1 << (i + 8); - } - } - - /* Enable all 8 counters */ - temp |= PMCR_E; - writel(temp, &emc->PMCR); - - return 0; - - err_free_scu: - while (i--) - free_irq(IRQ_EB11MP_PMU_SCU0 + i, NULL); - return ret; -} - -static void scu_stop(void) -{ - struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE; - unsigned int temp, i; - - /* Disable counter interrupts */ - /* Don't disable all 8 counters (with the E bit) as they may be in use */ - temp = readl(&emc->PMCR); - for (i = 0; i < NUM_SCU_COUNTERS; i++) { - if (scu_em_used & (1 << i)) - temp &= ~(1 << (i + 8)); - } - writel(temp, &emc->PMCR); - - /* Free counter interrupts and reset counters */ - for (i = 0; i < NUM_SCU_COUNTERS; i++) { - if (scu_em_used & (1 << i)) { - scu_reset_counter(emc, i); - free_irq(IRQ_EB11MP_PMU_SCU0 + i, NULL); - } - } -} - -struct em_function_data { - int (*fn)(void); - int ret; -}; - -static void em_func(void *data) -{ - struct em_function_data *d = data; - int ret = d->fn(); - if (ret) - d->ret = ret; -} - -static int em_call_function(int (*fn)(void)) -{ - struct em_function_data data; - - data.fn = fn; - data.ret = 0; - - preempt_disable(); - smp_call_function(em_func, &data, 1); - em_func(&data); - preempt_enable(); - - return data.ret; -} - -/* - * Glue to stick the individual ARM11 PMUs and the SCU - * into the oprofile framework. - */ -static int em_setup_ctrs(void) -{ - int ret; - - /* Configure CPU counters by cross-calling to the other CPUs */ - ret = em_call_function(arm11_setup_pmu); - if (ret == 0) - scu_setup(); - - return 0; -} - -static int em_start(void) -{ - int ret; - - pmu_irqs = reserve_pmu(); - if (IS_ERR(pmu_irqs)) { - ret = PTR_ERR(pmu_irqs); - goto out; - } - - ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs); - if (ret == 0) { - em_call_function(arm11_start_pmu); - - ret = scu_start(); - if (ret) { - arm11_release_interrupts(pmu_irqs->irqs, - pmu_irqs->num_irqs); - } else { - release_pmu(pmu_irqs); - pmu_irqs = NULL; - } - } - -out: - return ret; -} - -static void em_stop(void) -{ - em_call_function(arm11_stop_pmu); - arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs); - scu_stop(); - release_pmu(pmu_irqs); -} - -/* - * Why isn't there a function to route an IRQ to a specific CPU in - * genirq? - */ -static void em_route_irq(int irq, unsigned int cpu) -{ - struct irq_desc *desc = irq_desc + irq; - const struct cpumask *mask = cpumask_of(cpu); - - spin_lock_irq(&desc->lock); - cpumask_copy(desc->affinity, mask); - desc->chip->set_affinity(irq, mask); - spin_unlock_irq(&desc->lock); -} - -static int em_setup(void) -{ - /* - * Send SCU PMU interrupts to the "owner" CPU. - */ - em_route_irq(IRQ_EB11MP_PMU_SCU0, 0); - em_route_irq(IRQ_EB11MP_PMU_SCU1, 0); - em_route_irq(IRQ_EB11MP_PMU_SCU2, 1); - em_route_irq(IRQ_EB11MP_PMU_SCU3, 1); - em_route_irq(IRQ_EB11MP_PMU_SCU4, 2); - em_route_irq(IRQ_EB11MP_PMU_SCU5, 2); - em_route_irq(IRQ_EB11MP_PMU_SCU6, 3); - em_route_irq(IRQ_EB11MP_PMU_SCU7, 3); - - return init_pmu(); -} - -struct op_arm_model_spec op_mpcore_spec = { - .init = em_setup, - .num_counters = MPCORE_NUM_COUNTERS, - .setup_ctrs = em_setup_ctrs, - .start = em_start, - .stop = em_stop, - .name = "arm/mpcore", -}; diff --git a/arch/arm/oprofile/op_model_mpcore.h b/arch/arm/oprofile/op_model_mpcore.h deleted file mode 100644 index 73d811023688..000000000000 --- a/arch/arm/oprofile/op_model_mpcore.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @file op_model_mpcore.c - * MPCORE Event Monitor Driver - * @remark Copyright 2004 ARM SMP Development Team - * @remark Copyright 2000-2004 Deepak Saxena - * @remark Copyright 2000-2004 MontaVista Software Inc - * @remark Copyright 2004 Dave Jiang - * @remark Copyright 2004 Intel Corporation - * @remark Copyright 2004 Zwane Mwaikambo - * @remark Copyright 2004 Oprofile Authors - * - * @remark Read the file COPYING - * - * @author Zwane Mwaikambo - */ -#ifndef OP_MODEL_MPCORE_H -#define OP_MODEL_MPCORE_H - -struct eventmonitor { - unsigned long PMCR; - unsigned char MCEB[8]; - unsigned long MC[8]; -}; - -/* - * List of userspace counter numbers: note that the structure is important. - * The code relies on CPUn's counters being CPU0's counters + 3n - * and on CPU0's counters starting at 0 - */ - -#define COUNTER_CPU0_PMN0 0 -#define COUNTER_CPU0_PMN1 1 -#define COUNTER_CPU0_CCNT 2 - -#define COUNTER_CPU1_PMN0 3 -#define COUNTER_CPU1_PMN1 4 -#define COUNTER_CPU1_CCNT 5 - -#define COUNTER_CPU2_PMN0 6 -#define COUNTER_CPU2_PMN1 7 -#define COUNTER_CPU2_CCNT 8 - -#define COUNTER_CPU3_PMN0 9 -#define COUNTER_CPU3_PMN1 10 -#define COUNTER_CPU3_CCNT 11 - -#define COUNTER_SCU_MN0 12 -#define COUNTER_SCU_MN1 13 -#define COUNTER_SCU_MN2 14 -#define COUNTER_SCU_MN3 15 -#define COUNTER_SCU_MN4 16 -#define COUNTER_SCU_MN5 17 -#define COUNTER_SCU_MN6 18 -#define COUNTER_SCU_MN7 19 -#define NUM_SCU_COUNTERS 8 - -#define SCU_COUNTER(number) ((number) + COUNTER_SCU_MN0) - -#define MPCORE_NUM_COUNTERS SCU_COUNTER(NUM_SCU_COUNTERS) - -#endif diff --git a/arch/arm/oprofile/op_model_v6.c b/arch/arm/oprofile/op_model_v6.c deleted file mode 100644 index a22357a2fd08..000000000000 --- a/arch/arm/oprofile/op_model_v6.c +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file op_model_v6.c - * ARM11 Performance Monitor Driver - * - * Based on op_model_xscale.c - * - * @remark Copyright 2000-2004 Deepak Saxena - * @remark Copyright 2000-2004 MontaVista Software Inc - * @remark Copyright 2004 Dave Jiang - * @remark Copyright 2004 Intel Corporation - * @remark Copyright 2004 Zwane Mwaikambo - * @remark Copyright 2004 OProfile Authors - * - * @remark Read the file COPYING - * - * @author Tony Lindgren - */ - -/* #define DEBUG */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "op_counter.h" -#include "op_arm_model.h" -#include "op_model_arm11_core.h" - -static const struct pmu_irqs *pmu_irqs; - -static void armv6_pmu_stop(void) -{ - arm11_stop_pmu(); - arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs); - release_pmu(pmu_irqs); - pmu_irqs = NULL; -} - -static int armv6_pmu_start(void) -{ - int ret; - - pmu_irqs = reserve_pmu(); - if (IS_ERR(pmu_irqs)) { - ret = PTR_ERR(pmu_irqs); - goto out; - } - - ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs); - if (ret >= 0) { - ret = arm11_start_pmu(); - } else { - release_pmu(pmu_irqs); - pmu_irqs = NULL; - } - -out: - return ret; -} - -static int armv6_detect_pmu(void) -{ - return 0; -} - -struct op_arm_model_spec op_armv6_spec = { - .init = armv6_detect_pmu, - .num_counters = 3, - .setup_ctrs = arm11_setup_pmu, - .start = armv6_pmu_start, - .stop = armv6_pmu_stop, - .name = "arm/armv6", -}; diff --git a/arch/arm/oprofile/op_model_v7.c b/arch/arm/oprofile/op_model_v7.c deleted file mode 100644 index 8642d0891ae1..000000000000 --- a/arch/arm/oprofile/op_model_v7.c +++ /dev/null @@ -1,415 +0,0 @@ -/** - * op_model_v7.c - * ARM V7 (Cortex A8) Event Monitor Driver - * - * Copyright 2008 Jean Pihet - * Copyright 2004 ARM SMP Development Team - * - * 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 -#include -#include -#include -#include -#include -#include - -#include - -#include "op_counter.h" -#include "op_arm_model.h" -#include "op_model_v7.h" - -/* #define DEBUG */ - - -/* - * ARM V7 PMNC support - */ - -static u32 cnt_en[CNTMAX]; - -static inline void armv7_pmnc_write(u32 val) -{ - val &= PMNC_MASK; - asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (val)); -} - -static inline u32 armv7_pmnc_read(void) -{ - u32 val; - - asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val)); - return val; -} - -static inline u32 armv7_pmnc_enable_counter(unsigned int cnt) -{ - u32 val; - - if (cnt >= CNTMAX) { - printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter" - " %d\n", smp_processor_id(), cnt); - return -1; - } - - if (cnt == CCNT) - val = CNTENS_C; - else - val = (1 << (cnt - CNT0)); - - val &= CNTENS_MASK; - asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val)); - - return cnt; -} - -static inline u32 armv7_pmnc_disable_counter(unsigned int cnt) -{ - u32 val; - - if (cnt >= CNTMAX) { - printk(KERN_ERR "oprofile: CPU%u disabling wrong PMNC counter" - " %d\n", smp_processor_id(), cnt); - return -1; - } - - if (cnt == CCNT) - val = CNTENC_C; - else - val = (1 << (cnt - CNT0)); - - val &= CNTENC_MASK; - asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val)); - - return cnt; -} - -static inline u32 armv7_pmnc_enable_intens(unsigned int cnt) -{ - u32 val; - - if (cnt >= CNTMAX) { - printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter" - " interrupt enable %d\n", smp_processor_id(), cnt); - return -1; - } - - if (cnt == CCNT) - val = INTENS_C; - else - val = (1 << (cnt - CNT0)); - - val &= INTENS_MASK; - asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val)); - - return cnt; -} - -static inline u32 armv7_pmnc_getreset_flags(void) -{ - u32 val; - - /* Read */ - asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val)); - - /* Write to clear flags */ - val &= FLAG_MASK; - asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val)); - - return val; -} - -static inline int armv7_pmnc_select_counter(unsigned int cnt) -{ - u32 val; - - if ((cnt == CCNT) || (cnt >= CNTMAX)) { - printk(KERN_ERR "oprofile: CPU%u selecting wrong PMNC counteri" - " %d\n", smp_processor_id(), cnt); - return -1; - } - - val = (cnt - CNT0) & SELECT_MASK; - asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); - - return cnt; -} - -static inline void armv7_pmnc_write_evtsel(unsigned int cnt, u32 val) -{ - if (armv7_pmnc_select_counter(cnt) == cnt) { - val &= EVTSEL_MASK; - asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val)); - } -} - -static void armv7_pmnc_reset_counter(unsigned int cnt) -{ - u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt); - u32 val = -(u32)counter_config[cpu_cnt].count; - - switch (cnt) { - case CCNT: - armv7_pmnc_disable_counter(cnt); - - asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (val)); - - if (cnt_en[cnt] != 0) - armv7_pmnc_enable_counter(cnt); - - break; - - case CNT0: - case CNT1: - case CNT2: - case CNT3: - armv7_pmnc_disable_counter(cnt); - - if (armv7_pmnc_select_counter(cnt) == cnt) - asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val)); - - if (cnt_en[cnt] != 0) - armv7_pmnc_enable_counter(cnt); - - break; - - default: - printk(KERN_ERR "oprofile: CPU%u resetting wrong PMNC counter" - " %d\n", smp_processor_id(), cnt); - break; - } -} - -int armv7_setup_pmnc(void) -{ - unsigned int cnt; - - if (armv7_pmnc_read() & PMNC_E) { - printk(KERN_ERR "oprofile: CPU%u PMNC still enabled when setup" - " new event counter.\n", smp_processor_id()); - return -EBUSY; - } - - /* Initialize & Reset PMNC: C bit and P bit */ - armv7_pmnc_write(PMNC_P | PMNC_C); - - - for (cnt = CCNT; cnt < CNTMAX; cnt++) { - unsigned long event; - u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt); - - /* - * Disable counter - */ - armv7_pmnc_disable_counter(cnt); - cnt_en[cnt] = 0; - - if (!counter_config[cpu_cnt].enabled) - continue; - - event = counter_config[cpu_cnt].event & 255; - - /* - * Set event (if destined for PMNx counters) - * We don't need to set the event if it's a cycle count - */ - if (cnt != CCNT) - armv7_pmnc_write_evtsel(cnt, event); - - /* - * Enable interrupt for this counter - */ - armv7_pmnc_enable_intens(cnt); - - /* - * Reset counter - */ - armv7_pmnc_reset_counter(cnt); - - /* - * Enable counter - */ - armv7_pmnc_enable_counter(cnt); - cnt_en[cnt] = 1; - } - - return 0; -} - -static inline void armv7_start_pmnc(void) -{ - armv7_pmnc_write(armv7_pmnc_read() | PMNC_E); -} - -static inline void armv7_stop_pmnc(void) -{ - armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E); -} - -/* - * CPU counters' IRQ handler (one IRQ per CPU) - */ -static irqreturn_t armv7_pmnc_interrupt(int irq, void *arg) -{ - struct pt_regs *regs = get_irq_regs(); - unsigned int cnt; - u32 flags; - - - /* - * Stop IRQ generation - */ - armv7_stop_pmnc(); - - /* - * Get and reset overflow status flags - */ - flags = armv7_pmnc_getreset_flags(); - - /* - * Cycle counter - */ - if (flags & FLAG_C) { - u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), CCNT); - armv7_pmnc_reset_counter(CCNT); - oprofile_add_sample(regs, cpu_cnt); - } - - /* - * PMNC counters 0:3 - */ - for (cnt = CNT0; cnt < CNTMAX; cnt++) { - if (flags & (1 << (cnt - CNT0))) { - u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt); - armv7_pmnc_reset_counter(cnt); - oprofile_add_sample(regs, cpu_cnt); - } - } - - /* - * Allow IRQ generation - */ - armv7_start_pmnc(); - - return IRQ_HANDLED; -} - -int armv7_request_interrupts(const int *irqs, int nr) -{ - unsigned int i; - int ret = 0; - - for (i = 0; i < nr; i++) { - ret = request_irq(irqs[i], armv7_pmnc_interrupt, - IRQF_DISABLED, "CP15 PMNC", NULL); - if (ret != 0) { - printk(KERN_ERR "oprofile: unable to request IRQ%u" - " for ARMv7\n", - irqs[i]); - break; - } - } - - if (i != nr) - while (i-- != 0) - free_irq(irqs[i], NULL); - - return ret; -} - -void armv7_release_interrupts(const int *irqs, int nr) -{ - unsigned int i; - - for (i = 0; i < nr; i++) - free_irq(irqs[i], NULL); -} - -#ifdef DEBUG -static void armv7_pmnc_dump_regs(void) -{ - u32 val; - unsigned int cnt; - - printk(KERN_INFO "PMNC registers dump:\n"); - - asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val)); - printk(KERN_INFO "PMNC =0x%08x\n", val); - - asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val)); - printk(KERN_INFO "CNTENS=0x%08x\n", val); - - asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val)); - printk(KERN_INFO "INTENS=0x%08x\n", val); - - asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val)); - printk(KERN_INFO "FLAGS =0x%08x\n", val); - - asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val)); - printk(KERN_INFO "SELECT=0x%08x\n", val); - - asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); - printk(KERN_INFO "CCNT =0x%08x\n", val); - - for (cnt = CNT0; cnt < CNTMAX; cnt++) { - armv7_pmnc_select_counter(cnt); - asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val)); - printk(KERN_INFO "CNT[%d] count =0x%08x\n", cnt-CNT0, val); - asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val)); - printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", cnt-CNT0, val); - } -} -#endif - -static const struct pmu_irqs *pmu_irqs; - -static void armv7_pmnc_stop(void) -{ -#ifdef DEBUG - armv7_pmnc_dump_regs(); -#endif - armv7_stop_pmnc(); - armv7_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs); - release_pmu(pmu_irqs); - pmu_irqs = NULL; -} - -static int armv7_pmnc_start(void) -{ - int ret; - - pmu_irqs = reserve_pmu(); - if (IS_ERR(pmu_irqs)) - return PTR_ERR(pmu_irqs); - -#ifdef DEBUG - armv7_pmnc_dump_regs(); -#endif - ret = armv7_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs); - if (ret >= 0) { - armv7_start_pmnc(); - } else { - release_pmu(pmu_irqs); - pmu_irqs = NULL; - } - - return ret; -} - -static int armv7_detect_pmnc(void) -{ - return 0; -} - -struct op_arm_model_spec op_armv7_spec = { - .init = armv7_detect_pmnc, - .num_counters = 5, - .setup_ctrs = armv7_setup_pmnc, - .start = armv7_pmnc_start, - .stop = armv7_pmnc_stop, - .name = "arm/armv7", -}; diff --git a/arch/arm/oprofile/op_model_v7.h b/arch/arm/oprofile/op_model_v7.h deleted file mode 100644 index 9ca334b39c75..000000000000 --- a/arch/arm/oprofile/op_model_v7.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * op_model_v7.h - * ARM v7 (Cortex A8) Event Monitor Driver - * - * Copyright 2008 Jean Pihet - * Copyright 2004 ARM SMP Development Team - * Copyright 2000-2004 Deepak Saxena - * Copyright 2000-2004 MontaVista Software Inc - * Copyright 2004 Dave Jiang - * Copyright 2004 Intel Corporation - * Copyright 2004 Zwane Mwaikambo - * Copyright 2004 Oprofile Authors - * - * Read the file COPYING - * - * 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. - */ -#ifndef OP_MODEL_V7_H -#define OP_MODEL_V7_H - -/* - * Per-CPU PMNC: config reg - */ -#define PMNC_E (1 << 0) /* Enable all counters */ -#define PMNC_P (1 << 1) /* Reset all counters */ -#define PMNC_C (1 << 2) /* Cycle counter reset */ -#define PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */ -#define PMNC_X (1 << 4) /* Export to ETM */ -#define PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ -#define PMNC_MASK 0x3f /* Mask for writable bits */ - -/* - * Available counters - */ -#define CCNT 0 -#define CNT0 1 -#define CNT1 2 -#define CNT2 3 -#define CNT3 4 -#define CNTMAX 5 - -#define CPU_COUNTER(cpu, counter) ((cpu) * CNTMAX + (counter)) - -/* - * CNTENS: counters enable reg - */ -#define CNTENS_P0 (1 << 0) -#define CNTENS_P1 (1 << 1) -#define CNTENS_P2 (1 << 2) -#define CNTENS_P3 (1 << 3) -#define CNTENS_C (1 << 31) -#define CNTENS_MASK 0x8000000f /* Mask for writable bits */ - -/* - * CNTENC: counters disable reg - */ -#define CNTENC_P0 (1 << 0) -#define CNTENC_P1 (1 << 1) -#define CNTENC_P2 (1 << 2) -#define CNTENC_P3 (1 << 3) -#define CNTENC_C (1 << 31) -#define CNTENC_MASK 0x8000000f /* Mask for writable bits */ - -/* - * INTENS: counters overflow interrupt enable reg - */ -#define INTENS_P0 (1 << 0) -#define INTENS_P1 (1 << 1) -#define INTENS_P2 (1 << 2) -#define INTENS_P3 (1 << 3) -#define INTENS_C (1 << 31) -#define INTENS_MASK 0x8000000f /* Mask for writable bits */ - -/* - * EVTSEL: Event selection reg - */ -#define EVTSEL_MASK 0x7f /* Mask for writable bits */ - -/* - * SELECT: Counter selection reg - */ -#define SELECT_MASK 0x1f /* Mask for writable bits */ - -/* - * FLAG: counters overflow flag status reg - */ -#define FLAG_P0 (1 << 0) -#define FLAG_P1 (1 << 1) -#define FLAG_P2 (1 << 2) -#define FLAG_P3 (1 << 3) -#define FLAG_C (1 << 31) -#define FLAG_MASK 0x8000000f /* Mask for writable bits */ - - -int armv7_setup_pmu(void); -int armv7_start_pmu(void); -int armv7_stop_pmu(void); -int armv7_request_interrupts(const int *, int); -void armv7_release_interrupts(const int *, int); - -#endif diff --git a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c deleted file mode 100644 index 1d34a02048bd..000000000000 --- a/arch/arm/oprofile/op_model_xscale.c +++ /dev/null @@ -1,444 +0,0 @@ -/** - * @file op_model_xscale.c - * XScale Performance Monitor Driver - * - * @remark Copyright 2000-2004 Deepak Saxena - * @remark Copyright 2000-2004 MontaVista Software Inc - * @remark Copyright 2004 Dave Jiang - * @remark Copyright 2004 Intel Corporation - * @remark Copyright 2004 Zwane Mwaikambo - * @remark Copyright 2004 OProfile Authors - * - * @remark Read the file COPYING - * - * @author Zwane Mwaikambo - */ - -/* #define DEBUG */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "op_counter.h" -#include "op_arm_model.h" - -#define PMU_ENABLE 0x001 /* Enable counters */ -#define PMN_RESET 0x002 /* Reset event counters */ -#define CCNT_RESET 0x004 /* Reset clock counter */ -#define PMU_RESET (CCNT_RESET | PMN_RESET) -#define PMU_CNT64 0x008 /* Make CCNT count every 64th cycle */ - -/* - * Different types of events that can be counted by the XScale PMU - * as used by Oprofile userspace. Here primarily for documentation - * purposes. - */ - -#define EVT_ICACHE_MISS 0x00 -#define EVT_ICACHE_NO_DELIVER 0x01 -#define EVT_DATA_STALL 0x02 -#define EVT_ITLB_MISS 0x03 -#define EVT_DTLB_MISS 0x04 -#define EVT_BRANCH 0x05 -#define EVT_BRANCH_MISS 0x06 -#define EVT_INSTRUCTION 0x07 -#define EVT_DCACHE_FULL_STALL 0x08 -#define EVT_DCACHE_FULL_STALL_CONTIG 0x09 -#define EVT_DCACHE_ACCESS 0x0A -#define EVT_DCACHE_MISS 0x0B -#define EVT_DCACE_WRITE_BACK 0x0C -#define EVT_PC_CHANGED 0x0D -#define EVT_BCU_REQUEST 0x10 -#define EVT_BCU_FULL 0x11 -#define EVT_BCU_DRAIN 0x12 -#define EVT_BCU_ECC_NO_ELOG 0x14 -#define EVT_BCU_1_BIT_ERR 0x15 -#define EVT_RMW 0x16 -/* EVT_CCNT is not hardware defined */ -#define EVT_CCNT 0xFE -#define EVT_UNUSED 0xFF - -struct pmu_counter { - volatile unsigned long ovf; - unsigned long reset_counter; -}; - -enum { CCNT, PMN0, PMN1, PMN2, PMN3, MAX_COUNTERS }; - -static struct pmu_counter results[MAX_COUNTERS]; - -/* - * There are two versions of the PMU in current XScale processors - * with differing register layouts and number of performance counters. - * e.g. IOP32x is xsc1 whilst IOP33x is xsc2. - * We detect which register layout to use in xscale_detect_pmu() - */ -enum { PMU_XSC1, PMU_XSC2 }; - -struct pmu_type { - int id; - char *name; - int num_counters; - unsigned int int_enable; - unsigned int cnt_ovf[MAX_COUNTERS]; - unsigned int int_mask[MAX_COUNTERS]; -}; - -static struct pmu_type pmu_parms[] = { - { - .id = PMU_XSC1, - .name = "arm/xscale1", - .num_counters = 3, - .int_mask = { [PMN0] = 0x10, [PMN1] = 0x20, - [CCNT] = 0x40 }, - .cnt_ovf = { [CCNT] = 0x400, [PMN0] = 0x100, - [PMN1] = 0x200}, - }, - { - .id = PMU_XSC2, - .name = "arm/xscale2", - .num_counters = 5, - .int_mask = { [CCNT] = 0x01, [PMN0] = 0x02, - [PMN1] = 0x04, [PMN2] = 0x08, - [PMN3] = 0x10 }, - .cnt_ovf = { [CCNT] = 0x01, [PMN0] = 0x02, - [PMN1] = 0x04, [PMN2] = 0x08, - [PMN3] = 0x10 }, - }, -}; - -static struct pmu_type *pmu; - -static void write_pmnc(u32 val) -{ - if (pmu->id == PMU_XSC1) { - /* upper 4bits and 7, 11 are write-as-0 */ - val &= 0xffff77f; - __asm__ __volatile__ ("mcr p14, 0, %0, c0, c0, 0" : : "r" (val)); - } else { - /* bits 4-23 are write-as-0, 24-31 are write ignored */ - val &= 0xf; - __asm__ __volatile__ ("mcr p14, 0, %0, c0, c1, 0" : : "r" (val)); - } -} - -static u32 read_pmnc(void) -{ - u32 val; - - if (pmu->id == PMU_XSC1) - __asm__ __volatile__ ("mrc p14, 0, %0, c0, c0, 0" : "=r" (val)); - else { - __asm__ __volatile__ ("mrc p14, 0, %0, c0, c1, 0" : "=r" (val)); - /* bits 1-2 and 4-23 are read-unpredictable */ - val &= 0xff000009; - } - - return val; -} - -static u32 __xsc1_read_counter(int counter) -{ - u32 val = 0; - - switch (counter) { - case CCNT: - __asm__ __volatile__ ("mrc p14, 0, %0, c1, c0, 0" : "=r" (val)); - break; - case PMN0: - __asm__ __volatile__ ("mrc p14, 0, %0, c2, c0, 0" : "=r" (val)); - break; - case PMN1: - __asm__ __volatile__ ("mrc p14, 0, %0, c3, c0, 0" : "=r" (val)); - break; - } - return val; -} - -static u32 __xsc2_read_counter(int counter) -{ - u32 val = 0; - - switch (counter) { - case CCNT: - __asm__ __volatile__ ("mrc p14, 0, %0, c1, c1, 0" : "=r" (val)); - break; - case PMN0: - __asm__ __volatile__ ("mrc p14, 0, %0, c0, c2, 0" : "=r" (val)); - break; - case PMN1: - __asm__ __volatile__ ("mrc p14, 0, %0, c1, c2, 0" : "=r" (val)); - break; - case PMN2: - __asm__ __volatile__ ("mrc p14, 0, %0, c2, c2, 0" : "=r" (val)); - break; - case PMN3: - __asm__ __volatile__ ("mrc p14, 0, %0, c3, c2, 0" : "=r" (val)); - break; - } - return val; -} - -static u32 read_counter(int counter) -{ - u32 val; - - if (pmu->id == PMU_XSC1) - val = __xsc1_read_counter(counter); - else - val = __xsc2_read_counter(counter); - - return val; -} - -static void __xsc1_write_counter(int counter, u32 val) -{ - switch (counter) { - case CCNT: - __asm__ __volatile__ ("mcr p14, 0, %0, c1, c0, 0" : : "r" (val)); - break; - case PMN0: - __asm__ __volatile__ ("mcr p14, 0, %0, c2, c0, 0" : : "r" (val)); - break; - case PMN1: - __asm__ __volatile__ ("mcr p14, 0, %0, c3, c0, 0" : : "r" (val)); - break; - } -} - -static void __xsc2_write_counter(int counter, u32 val) -{ - switch (counter) { - case CCNT: - __asm__ __volatile__ ("mcr p14, 0, %0, c1, c1, 0" : : "r" (val)); - break; - case PMN0: - __asm__ __volatile__ ("mcr p14, 0, %0, c0, c2, 0" : : "r" (val)); - break; - case PMN1: - __asm__ __volatile__ ("mcr p14, 0, %0, c1, c2, 0" : : "r" (val)); - break; - case PMN2: - __asm__ __volatile__ ("mcr p14, 0, %0, c2, c2, 0" : : "r" (val)); - break; - case PMN3: - __asm__ __volatile__ ("mcr p14, 0, %0, c3, c2, 0" : : "r" (val)); - break; - } -} - -static void write_counter(int counter, u32 val) -{ - if (pmu->id == PMU_XSC1) - __xsc1_write_counter(counter, val); - else - __xsc2_write_counter(counter, val); -} - -static int xscale_setup_ctrs(void) -{ - u32 evtsel, pmnc; - int i; - - for (i = CCNT; i < MAX_COUNTERS; i++) { - if (counter_config[i].enabled) - continue; - - counter_config[i].event = EVT_UNUSED; - } - - switch (pmu->id) { - case PMU_XSC1: - pmnc = (counter_config[PMN1].event << 20) | (counter_config[PMN0].event << 12); - pr_debug("xscale_setup_ctrs: pmnc: %#08x\n", pmnc); - write_pmnc(pmnc); - break; - - case PMU_XSC2: - evtsel = counter_config[PMN0].event | (counter_config[PMN1].event << 8) | - (counter_config[PMN2].event << 16) | (counter_config[PMN3].event << 24); - - pr_debug("xscale_setup_ctrs: evtsel %#08x\n", evtsel); - __asm__ __volatile__ ("mcr p14, 0, %0, c8, c1, 0" : : "r" (evtsel)); - break; - } - - for (i = CCNT; i < MAX_COUNTERS; i++) { - if (counter_config[i].event == EVT_UNUSED) { - counter_config[i].event = 0; - pmu->int_enable &= ~pmu->int_mask[i]; - continue; - } - - results[i].reset_counter = counter_config[i].count; - write_counter(i, -(u32)counter_config[i].count); - pmu->int_enable |= pmu->int_mask[i]; - pr_debug("xscale_setup_ctrs: counter%d %#08x from %#08lx\n", i, - read_counter(i), counter_config[i].count); - } - - return 0; -} - -static void inline __xsc1_check_ctrs(void) -{ - int i; - u32 pmnc = read_pmnc(); - - /* NOTE: there's an A stepping errata that states if an overflow */ - /* bit already exists and another occurs, the previous */ - /* Overflow bit gets cleared. There's no workaround. */ - /* Fixed in B stepping or later */ - - /* Write the value back to clear the overflow flags. Overflow */ - /* flags remain in pmnc for use below */ - write_pmnc(pmnc & ~PMU_ENABLE); - - for (i = CCNT; i <= PMN1; i++) { - if (!(pmu->int_mask[i] & pmu->int_enable)) - continue; - - if (pmnc & pmu->cnt_ovf[i]) - results[i].ovf++; - } -} - -static void inline __xsc2_check_ctrs(void) -{ - int i; - u32 flag = 0, pmnc = read_pmnc(); - - pmnc &= ~PMU_ENABLE; - write_pmnc(pmnc); - - /* read overflow flag register */ - __asm__ __volatile__ ("mrc p14, 0, %0, c5, c1, 0" : "=r" (flag)); - - for (i = CCNT; i <= PMN3; i++) { - if (!(pmu->int_mask[i] & pmu->int_enable)) - continue; - - if (flag & pmu->cnt_ovf[i]) - results[i].ovf++; - } - - /* writeback clears overflow bits */ - __asm__ __volatile__ ("mcr p14, 0, %0, c5, c1, 0" : : "r" (flag)); -} - -static irqreturn_t xscale_pmu_interrupt(int irq, void *arg) -{ - int i; - u32 pmnc; - - if (pmu->id == PMU_XSC1) - __xsc1_check_ctrs(); - else - __xsc2_check_ctrs(); - - for (i = CCNT; i < MAX_COUNTERS; i++) { - if (!results[i].ovf) - continue; - - write_counter(i, -(u32)results[i].reset_counter); - oprofile_add_sample(get_irq_regs(), i); - results[i].ovf--; - } - - pmnc = read_pmnc() | PMU_ENABLE; - write_pmnc(pmnc); - - return IRQ_HANDLED; -} - -static const struct pmu_irqs *pmu_irqs; - -static void xscale_pmu_stop(void) -{ - u32 pmnc = read_pmnc(); - - pmnc &= ~PMU_ENABLE; - write_pmnc(pmnc); - - free_irq(pmu_irqs->irqs[0], results); - release_pmu(pmu_irqs); - pmu_irqs = NULL; -} - -static int xscale_pmu_start(void) -{ - int ret; - u32 pmnc; - - pmu_irqs = reserve_pmu(); - if (IS_ERR(pmu_irqs)) - return PTR_ERR(pmu_irqs); - - pmnc = read_pmnc(); - - ret = request_irq(pmu_irqs->irqs[0], xscale_pmu_interrupt, - IRQF_DISABLED, "XScale PMU", (void *)results); - - if (ret < 0) { - printk(KERN_ERR "oprofile: unable to request IRQ%d for XScale PMU\n", - pmu_irqs->irqs[0]); - release_pmu(pmu_irqs); - pmu_irqs = NULL; - return ret; - } - - if (pmu->id == PMU_XSC1) - pmnc |= pmu->int_enable; - else { - __asm__ __volatile__ ("mcr p14, 0, %0, c4, c1, 0" : : "r" (pmu->int_enable)); - pmnc &= ~PMU_CNT64; - } - - pmnc |= PMU_ENABLE; - write_pmnc(pmnc); - pr_debug("xscale_pmu_start: pmnc: %#08x mask: %08x\n", pmnc, pmu->int_enable); - return 0; -} - -static int xscale_detect_pmu(void) -{ - int ret = 0; - u32 id; - - id = (read_cpuid(CPUID_ID) >> 13) & 0x7; - - switch (id) { - case 1: - pmu = &pmu_parms[PMU_XSC1]; - break; - case 2: - pmu = &pmu_parms[PMU_XSC2]; - break; - default: - ret = -ENODEV; - break; - } - - if (!ret) { - op_xscale_spec.name = pmu->name; - op_xscale_spec.num_counters = pmu->num_counters; - pr_debug("xscale_detect_pmu: detected %s PMU\n", pmu->name); - } - - return ret; -} - -struct op_arm_model_spec op_xscale_spec = { - .init = xscale_detect_pmu, - .setup_ctrs = xscale_setup_ctrs, - .start = xscale_pmu_start, - .stop = xscale_pmu_stop, -}; - -- cgit v1.2.3-59-g8ed1b From d1e86d64bc48dedd0d68d182d0ce6951d8b4fd0d Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 30 Apr 2010 11:38:39 +0100 Subject: ARM: 6074/1: oprofile: convert from sysdev to platform device This is a reworking of an original patch posted by Aaro Koskinen: oprofile does not work with PM, because sysdev_suspend() is done with interrupts disabled and oprofile needs a mutex. Implementing oprofile as a platform device solves this problem. Cc: Aaro Koskinen Signed-off-by: Will Deacon Signed-off-by: Aaro Koskinen Signed-off-by: Russell King --- arch/arm/oprofile/common.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index aad83df89bac..0691176899ff 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -10,13 +10,14 @@ */ #include +#include #include #include #include #include #include +#include #include -#include #include #include @@ -227,7 +228,7 @@ static void op_arm_stop(void) } #ifdef CONFIG_PM -static int op_arm_suspend(struct sys_device *dev, pm_message_t state) +static int op_arm_suspend(struct platform_device *dev, pm_message_t state) { mutex_lock(&op_arm_mutex); if (op_arm_enabled) @@ -236,7 +237,7 @@ static int op_arm_suspend(struct sys_device *dev, pm_message_t state) return 0; } -static int op_arm_resume(struct sys_device *dev) +static int op_arm_resume(struct platform_device *dev) { mutex_lock(&op_arm_mutex); if (op_arm_enabled && op_perf_start()) @@ -245,34 +246,42 @@ static int op_arm_resume(struct sys_device *dev) return 0; } -static struct sysdev_class oprofile_sysclass = { - .name = "oprofile", +static struct platform_driver oprofile_driver = { + .driver = { + .name = "arm-oprofile", + }, .resume = op_arm_resume, .suspend = op_arm_suspend, }; -static struct sys_device device_oprofile = { - .id = 0, - .cls = &oprofile_sysclass, -}; +static struct platform_device *oprofile_pdev; static int __init init_driverfs(void) { int ret; - if (!(ret = sysdev_class_register(&oprofile_sysclass))) - ret = sysdev_register(&device_oprofile); + ret = platform_driver_register(&oprofile_driver); + if (ret) + goto out; + + oprofile_pdev = platform_device_register_simple( + oprofile_driver.driver.name, 0, NULL, 0); + if (IS_ERR(oprofile_pdev)) { + ret = PTR_ERR(oprofile_pdev); + platform_driver_unregister(&oprofile_driver); + } +out: return ret; } static void exit_driverfs(void) { - sysdev_unregister(&device_oprofile); - sysdev_class_unregister(&oprofile_sysclass); + platform_device_unregister(oprofile_pdev); + platform_driver_unregister(&oprofile_driver); } #else -#define init_driverfs() do { } while (0) +static int __init init_driverfs(void) { return 0; } #define exit_driverfs() do { } while (0) #endif /* CONFIG_PM */ @@ -353,6 +362,12 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) return -ENOMEM; } + ret = init_driverfs(); + if (ret) { + kfree(counter_config); + return ret; + } + for_each_possible_cpu(cpu) { perf_events[cpu] = kcalloc(perf_num_counters, sizeof(struct perf_event *), GFP_KERNEL); @@ -365,7 +380,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) } } - init_driverfs(); ops->backtrace = arm_backtrace; ops->create_files = op_arm_create_files; ops->setup = op_arm_setup; -- cgit v1.2.3-59-g8ed1b From f3d46f9d3194e0329216002a8724d4c0957abc79 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 17 May 2010 14:33:53 +1000 Subject: atomic_t: Cast to volatile when accessing atomic variables In preparation for removing volatile from the atomic_t definition, this patch adds a volatile cast to all the atomic read functions. Signed-off-by: Anton Blanchard Signed-off-by: Linus Torvalds --- arch/alpha/include/asm/atomic.h | 4 ++-- arch/arm/include/asm/atomic.h | 2 +- arch/avr32/include/asm/atomic.h | 2 +- arch/cris/include/asm/atomic.h | 2 +- arch/frv/include/asm/atomic.h | 2 +- arch/h8300/include/asm/atomic.h | 2 +- arch/ia64/include/asm/atomic.h | 4 ++-- arch/m32r/include/asm/atomic.h | 2 +- arch/m68k/include/asm/atomic_mm.h | 2 +- arch/m68k/include/asm/atomic_no.h | 2 +- arch/mips/include/asm/atomic.h | 4 ++-- arch/mn10300/include/asm/atomic.h | 2 +- arch/parisc/include/asm/atomic.h | 4 ++-- arch/sh/include/asm/atomic.h | 2 +- arch/sparc/include/asm/atomic_32.h | 2 +- arch/sparc/include/asm/atomic_64.h | 4 ++-- arch/x86/include/asm/atomic.h | 2 +- arch/x86/include/asm/atomic64_64.h | 2 +- arch/xtensa/include/asm/atomic.h | 2 +- include/asm-generic/atomic.h | 2 +- 20 files changed, 25 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h index 610dff44d94b..e756d04b6cd5 100644 --- a/arch/alpha/include/asm/atomic.h +++ b/arch/alpha/include/asm/atomic.h @@ -17,8 +17,8 @@ #define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) #define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } ) -#define atomic_read(v) ((v)->counter + 0) -#define atomic64_read(v) ((v)->counter + 0) +#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic64_read(v) (*(volatile long *)&(v)->counter) #define atomic_set(v,i) ((v)->counter = (i)) #define atomic64_set(v,i) ((v)->counter = (i)) diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index e8ddec2cb158..a0162fa94564 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -24,7 +24,7 @@ * strex/ldrex monitor on some implementations. The reason we can use it for * atomic_set() is the clrex or dummy strex done on every exception return. */ -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) #if __LINUX_ARM_ARCH__ >= 6 diff --git a/arch/avr32/include/asm/atomic.h b/arch/avr32/include/asm/atomic.h index b131c27ddf57..bbce6a1c6bb6 100644 --- a/arch/avr32/include/asm/atomic.h +++ b/arch/avr32/include/asm/atomic.h @@ -19,7 +19,7 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v, i) (((v)->counter) = i) /* diff --git a/arch/cris/include/asm/atomic.h b/arch/cris/include/asm/atomic.h index a6aca819e9f3..88dc9b9c4ba0 100644 --- a/arch/cris/include/asm/atomic.h +++ b/arch/cris/include/asm/atomic.h @@ -15,7 +15,7 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) /* These should be written in asm but we do it in C for now. */ diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h index 00a57af79afc..fae32c7fdcb6 100644 --- a/arch/frv/include/asm/atomic.h +++ b/arch/frv/include/asm/atomic.h @@ -36,7 +36,7 @@ #define smp_mb__after_atomic_inc() barrier() #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v, i) (((v)->counter) = (i)) #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS diff --git a/arch/h8300/include/asm/atomic.h b/arch/h8300/include/asm/atomic.h index 33c8c0fa9583..e936804b7508 100644 --- a/arch/h8300/include/asm/atomic.h +++ b/arch/h8300/include/asm/atomic.h @@ -10,7 +10,7 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v, i) (((v)->counter) = i) #include diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h index 88405cb0832a..4e1948447a00 100644 --- a/arch/ia64/include/asm/atomic.h +++ b/arch/ia64/include/asm/atomic.h @@ -21,8 +21,8 @@ #define ATOMIC_INIT(i) ((atomic_t) { (i) }) #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) -#define atomic_read(v) ((v)->counter) -#define atomic64_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic64_read(v) (*(volatile long *)&(v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) #define atomic64_set(v,i) (((v)->counter) = (i)) diff --git a/arch/m32r/include/asm/atomic.h b/arch/m32r/include/asm/atomic.h index 63f0cf0f50dd..d44a51e5271b 100644 --- a/arch/m32r/include/asm/atomic.h +++ b/arch/m32r/include/asm/atomic.h @@ -26,7 +26,7 @@ * * Atomically reads the value of @v. */ -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) /** * atomic_set - set atomic variable diff --git a/arch/m68k/include/asm/atomic_mm.h b/arch/m68k/include/asm/atomic_mm.h index d9d2ed647435..6a223b3f7e74 100644 --- a/arch/m68k/include/asm/atomic_mm.h +++ b/arch/m68k/include/asm/atomic_mm.h @@ -15,7 +15,7 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v, i) (((v)->counter) = i) static inline void atomic_add(int i, atomic_t *v) diff --git a/arch/m68k/include/asm/atomic_no.h b/arch/m68k/include/asm/atomic_no.h index 5674cb9449bd..289310c63a8a 100644 --- a/arch/m68k/include/asm/atomic_no.h +++ b/arch/m68k/include/asm/atomic_no.h @@ -15,7 +15,7 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v, i) (((v)->counter) = i) static __inline__ void atomic_add(int i, atomic_t *v) diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 519197ede089..59dc0c7ef733 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -29,7 +29,7 @@ * * Atomically reads the value of @v. */ -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) /* * atomic_set - set atomic variable @@ -410,7 +410,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) * @v: pointer of type atomic64_t * */ -#define atomic64_read(v) ((v)->counter) +#define atomic64_read(v) (*(volatile long *)&(v)->counter) /* * atomic64_set - set atomic variable diff --git a/arch/mn10300/include/asm/atomic.h b/arch/mn10300/include/asm/atomic.h index 5bf5be9566de..e41222d6c2fd 100644 --- a/arch/mn10300/include/asm/atomic.h +++ b/arch/mn10300/include/asm/atomic.h @@ -31,7 +31,7 @@ * Atomically reads the value of @v. Note that the guaranteed * useful range of an atomic_t is only 24 bits. */ -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) /** * atomic_set - set atomic variable diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 716634d1f546..f81955934aeb 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -189,7 +189,7 @@ static __inline__ void atomic_set(atomic_t *v, int i) static __inline__ int atomic_read(const atomic_t *v) { - return v->counter; + return (*(volatile int *)&(v)->counter); } /* exported interface */ @@ -286,7 +286,7 @@ atomic64_set(atomic64_t *v, s64 i) static __inline__ s64 atomic64_read(const atomic64_t *v) { - return v->counter; + return (*(volatile long *)&(v)->counter); } #define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)(i)),(v)))) diff --git a/arch/sh/include/asm/atomic.h b/arch/sh/include/asm/atomic.h index 275a448ae8c2..c7983124d99d 100644 --- a/arch/sh/include/asm/atomic.h +++ b/arch/sh/include/asm/atomic.h @@ -13,7 +13,7 @@ #define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v,i) ((v)->counter = (i)) #if defined(CONFIG_GUSA_RB) diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h index f0d343c3b956..7ae128b19d3f 100644 --- a/arch/sparc/include/asm/atomic_32.h +++ b/arch/sparc/include/asm/atomic_32.h @@ -25,7 +25,7 @@ extern int atomic_cmpxchg(atomic_t *, int, int); extern int atomic_add_unless(atomic_t *, int, int); extern void atomic_set(atomic_t *, int); -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v))) #define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v))) diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index f2e48009989e..2050ca02c423 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h @@ -13,8 +13,8 @@ #define ATOMIC_INIT(i) { (i) } #define ATOMIC64_INIT(i) { (i) } -#define atomic_read(v) ((v)->counter) -#define atomic64_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic64_read(v) (*(volatile long *)&(v)->counter) #define atomic_set(v, i) (((v)->counter) = i) #define atomic64_set(v, i) (((v)->counter) = i) diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index 8f8217b9bdac..37b39d27abe0 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -22,7 +22,7 @@ */ static inline int atomic_read(const atomic_t *v) { - return v->counter; + return (*(volatile int *)&(v)->counter); } /** diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h index 51c5b4056929..b014e235ea8d 100644 --- a/arch/x86/include/asm/atomic64_64.h +++ b/arch/x86/include/asm/atomic64_64.h @@ -18,7 +18,7 @@ */ static inline long atomic64_read(const atomic64_t *v) { - return v->counter; + return (*(volatile long *)&(v)->counter); } /** diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index 22d6dde42619..a96a0619d0b7 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h @@ -46,7 +46,7 @@ * * Atomically reads the value of @v. */ -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) /** * atomic_set - set atomic variable diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h index c99c64dc5f3d..c33749f95b32 100644 --- a/include/asm-generic/atomic.h +++ b/include/asm-generic/atomic.h @@ -33,7 +33,7 @@ * Atomically reads the value of @v. Note that the guaranteed * useful range of an atomic_t is only 24 bits. */ -#define atomic_read(v) ((v)->counter) +#define atomic_read(v) (*(volatile int *)&(v)->counter) /** * atomic_set - set atomic variable -- cgit v1.2.3-59-g8ed1b From 345e5c8a1cc30ebd527bcc122d9540538942f1ba Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Thu, 7 Jan 2010 17:57:46 +0100 Subject: powerpc: Add interrupt support to mpc8xxx_gpio Signed-off-by: Peter Korsgaard Acked-by: Anton Vorontsov Signed-off-by: Kumar Gala --- .../powerpc/dts-bindings/fsl/8xxx_gpio.txt | 22 ++- arch/powerpc/sysdev/mpc8xxx_gpio.c | 147 +++++++++++++++++++++ 2 files changed, 168 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt b/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt index d015dcec4011..b0019eb5330e 100644 --- a/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt +++ b/Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt @@ -11,7 +11,7 @@ Required properties: 83xx, "fsl,mpc8572-gpio" for 85xx and "fsl,mpc8610-gpio" for 86xx. - #gpio-cells : Should be two. The first cell is the pin number and the second cell is used to specify optional parameters (currently unused). - - interrupts : Interrupt mapping for GPIO IRQ (currently unused). + - interrupts : Interrupt mapping for GPIO IRQ. - interrupt-parent : Phandle for the interrupt controller that services interrupts for this device. - gpio-controller : Marks the port as GPIO controller. @@ -38,3 +38,23 @@ Example of gpio-controller nodes for a MPC8347 SoC: See booting-without-of.txt for details of how to specify GPIO information for devices. + +To use GPIO pins as interrupt sources for peripherals, specify the +GPIO controller as the interrupt parent and define GPIO number + +trigger mode using the interrupts property, which is defined like +this: + +interrupts = , where: + - number: GPIO pin (0..31) + - trigger: trigger mode: + 2 = trigger on falling edge + 3 = trigger on both edges + +Example of device using this is: + + funkyfpga@0 { + compatible = "funky-fpga"; + ... + interrupts = <4 3>; + interrupt-parent = <&gpio1>; + }; diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index 6478eb10691a..83f519655fac 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c @@ -16,6 +16,7 @@ #include #include #include +#include #define MPC8XXX_GPIO_PINS 32 @@ -35,6 +36,7 @@ struct mpc8xxx_gpio_chip { * open drain mode safely */ u32 data; + struct irq_host *irq; }; static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) @@ -128,12 +130,136 @@ static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val return 0; } +static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) +{ + struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); + struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); + + if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS) + return irq_create_mapping(mpc8xxx_gc->irq, offset); + else + return -ENXIO; +} + +static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc) +{ + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_desc_data(desc); + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; + unsigned int mask; + + mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR); + if (mask) + generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, + 32 - ffs(mask))); +} + +static void mpc8xxx_irq_unmask(unsigned int virq) +{ + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; + unsigned long flags; + + spin_lock_irqsave(&mpc8xxx_gc->lock, flags); + + setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq))); + + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); +} + +static void mpc8xxx_irq_mask(unsigned int virq) +{ + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; + unsigned long flags; + + spin_lock_irqsave(&mpc8xxx_gc->lock, flags); + + clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq))); + + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); +} + +static void mpc8xxx_irq_ack(unsigned int virq) +{ + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; + + out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(virq_to_hw(virq))); +} + +static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type) +{ + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; + unsigned long flags; + + switch (flow_type) { + case IRQ_TYPE_EDGE_FALLING: + spin_lock_irqsave(&mpc8xxx_gc->lock, flags); + setbits32(mm->regs + GPIO_ICR, + mpc8xxx_gpio2mask(virq_to_hw(virq))); + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); + break; + + case IRQ_TYPE_EDGE_BOTH: + spin_lock_irqsave(&mpc8xxx_gc->lock, flags); + clrbits32(mm->regs + GPIO_ICR, + mpc8xxx_gpio2mask(virq_to_hw(virq))); + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); + break; + + default: + return -EINVAL; + } + + return 0; +} + +static struct irq_chip mpc8xxx_irq_chip = { + .name = "mpc8xxx-gpio", + .unmask = mpc8xxx_irq_unmask, + .mask = mpc8xxx_irq_mask, + .ack = mpc8xxx_irq_ack, + .set_type = mpc8xxx_irq_set_type, +}; + +static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + set_irq_chip_data(virq, h->host_data); + set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); + set_irq_type(virq, IRQ_TYPE_NONE); + + return 0; +} + +static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, + unsigned int *out_flags) + +{ + /* interrupt sense values coming from the device tree equal either + * EDGE_FALLING or EDGE_BOTH + */ + *out_hwirq = intspec[0]; + *out_flags = intspec[1]; + + return 0; +} + +static struct irq_host_ops mpc8xxx_gpio_irq_ops = { + .map = mpc8xxx_gpio_irq_map, + .xlate = mpc8xxx_gpio_irq_xlate, +}; + static void __init mpc8xxx_add_controller(struct device_node *np) { struct mpc8xxx_gpio_chip *mpc8xxx_gc; struct of_mm_gpio_chip *mm_gc; struct of_gpio_chip *of_gc; struct gpio_chip *gc; + unsigned hwirq; int ret; mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL); @@ -158,11 +284,32 @@ static void __init mpc8xxx_add_controller(struct device_node *np) else gc->get = mpc8xxx_gpio_get; gc->set = mpc8xxx_gpio_set; + gc->to_irq = mpc8xxx_gpio_to_irq; ret = of_mm_gpiochip_add(np, mm_gc); if (ret) goto err; + hwirq = irq_of_parse_and_map(np, 0); + if (hwirq == NO_IRQ) + goto skip_irq; + + mpc8xxx_gc->irq = + irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS, + &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS); + if (!mpc8xxx_gc->irq) + goto skip_irq; + + mpc8xxx_gc->irq->host_data = mpc8xxx_gc; + + /* ack and mask all irqs */ + out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); + out_be32(mm_gc->regs + GPIO_IMR, 0); + + set_irq_data(hwirq, mpc8xxx_gc); + set_irq_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade); + +skip_irq: return; err: -- cgit v1.2.3-59-g8ed1b From 18f397c838e50bb2b8d581dcfc73f3d35ee5b1e2 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Thu, 22 Apr 2010 19:25:13 -0500 Subject: powerpc: remove tls_ssl_stream descriptor type capability in sec3.3 node Technically, whilst SEC v3.3 h/w honours the tls_ssl_stream descriptor type, it lacks the ARC4 algorithm execution unit required to be able to execute anything meaningful with it. Change the node to agree with the documentation that declares that the sec3.3 really doesn't have such a descriptor type. Reported-by: Haiying Wang Signed-off-by: Kim Phillips Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8315erdb.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 8a3a4f3ef831..508b770d3dd6 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -292,7 +292,7 @@ fsl,num-channels = <4>; fsl,channel-fifo-len = <24>; fsl,exec-units-mask = <0x97c>; - fsl,descriptor-types-mask = <0x3ab0abf>; + fsl,descriptor-types-mask = <0x3a30abf>; }; sata@18000 { -- cgit v1.2.3-59-g8ed1b From 7541ef78c3b83e906b580f005207000545cf770a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 15 Apr 2010 22:36:31 +0400 Subject: powerpc/85xx: Add eTSEC 2.0 support for P1020RDB boards This patch adds support for eTSEC 2.0 as found in P1020. The changes include introduction of the group nodes for the etsec nodes. Signed-off-by: Sandeep Gopalpet Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/p1020rdb.dts | 119 +++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/boot/dts/p1020rdb.dts b/arch/powerpc/boot/dts/p1020rdb.dts index df5269093af8..49848c545d86 100644 --- a/arch/powerpc/boot/dts/p1020rdb.dts +++ b/arch/powerpc/boot/dts/p1020rdb.dts @@ -19,6 +19,9 @@ aliases { serial0 = &serial0; serial1 = &serial1; + ethernet0 = &enet0; + ethernet1 = &enet1; + ethernet2 = &enet2; pci0 = &pci0; pci1 = &pci1; }; @@ -346,6 +349,122 @@ }; }; + mdio@24000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,etsec2-mdio"; + reg = <0x24000 0x1000 0xb0030 0x4>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <3 1>; + reg = <0x0>; + }; + + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <2 1>; + reg = <0x1>; + }; + }; + + mdio@25000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,etsec2-tbi"; + reg = <0x25000 0x1000 0xb1030 0x4>; + + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@b0000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "network"; + model = "eTSEC"; + compatible = "fsl,etsec2"; + fsl,num_rx_queues = <0x8>; + fsl,num_tx_queues = <0x8>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupt-parent = <&mpic>; + fixed-link = <1 1 1000 0 0>; + phy-connection-type = "rgmii-id"; + + queue-group@0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xb0000 0x1000>; + interrupts = <29 2 30 2 34 2>; + }; + + queue-group@1 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xb4000 0x1000>; + interrupts = <17 2 18 2 24 2>; + }; + }; + + enet1: ethernet@b1000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "network"; + model = "eTSEC"; + compatible = "fsl,etsec2"; + fsl,num_rx_queues = <0x8>; + fsl,num_tx_queues = <0x8>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupt-parent = <&mpic>; + phy-handle = <&phy0>; + tbi-handle = <&tbi0>; + phy-connection-type = "sgmii"; + + queue-group@0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xb1000 0x1000>; + interrupts = <35 2 36 2 40 2>; + }; + + queue-group@1 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xb5000 0x1000>; + interrupts = <51 2 52 2 67 2>; + }; + }; + + enet2: ethernet@b2000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "network"; + model = "eTSEC"; + compatible = "fsl,etsec2"; + fsl,num_rx_queues = <0x8>; + fsl,num_tx_queues = <0x8>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupt-parent = <&mpic>; + phy-handle = <&phy1>; + phy-connection-type = "rgmii-id"; + + queue-group@0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xb2000 0x1000>; + interrupts = <31 2 32 2 33 2>; + }; + + queue-group@1 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xb6000 0x1000>; + interrupts = <25 2 26 2 27 2>; + }; + }; + usb@22000 { #address-cells = <1>; #size-cells = <0>; -- cgit v1.2.3-59-g8ed1b From 0aedc0085146131da5b04476aab21834b1403b31 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 22 Apr 2010 19:44:47 +0400 Subject: powerpc/85xx: Fix P1020RDB boot hang due USB2 Since USB2 is shared with local bus, either local bus or USB2 should be disabled. By default U-Boot enables local bus, so we have to disable USB2, otherwise kernel hangs: ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver fsl-ehci fsl-ehci.0: Freescale On-Chip EHCI Host Controller fsl-ehci fsl-ehci.0: new USB bus registered, assigned bus number 1 fsl-ehci fsl-ehci.0: irq 28, io base 0xffe22000 fsl-ehci fsl-ehci.0: USB 2.0 started, EHCI 1.00 hub 1-0:1.0: USB hub found hub 1-0:1.0: 1 port detected fsl-ehci fsl-ehci.1: Freescale On-Chip EHCI Host Controller fsl-ehci fsl-ehci.1: new USB bus registered, assigned bus number 2 Note that U-Boot doesn't clear 'status' property when it enables USB2, so we have to comment out the whole node. To enable USB2, one can issue 'setenv hwconfig usb2:dr_mode=' command at the U-Boot prompt. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/p1020rdb.dts | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/boot/dts/p1020rdb.dts b/arch/powerpc/boot/dts/p1020rdb.dts index 49848c545d86..22f64b62d7f6 100644 --- a/arch/powerpc/boot/dts/p1020rdb.dts +++ b/arch/powerpc/boot/dts/p1020rdb.dts @@ -475,6 +475,11 @@ phy_type = "ulpi"; }; + /* USB2 is shared with localbus, so it must be disabled + by default. We can't put 'status = "disabled";' here + since U-Boot doesn't clear the status property when + it enables USB2. OTOH, U-Boot does create a new node + when there isn't any. So, just comment it out. usb@23000 { #address-cells = <1>; #size-cells = <0>; @@ -484,6 +489,7 @@ interrupts = <46 0x2>; phy_type = "ulpi"; }; + */ sdhci@2e000 { compatible = "fsl,p1020-esdhc", "fsl,esdhc"; -- cgit v1.2.3-59-g8ed1b From 6971df4f5b0e5b6955c03e8d51bad5d50463f98f Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sun, 2 May 2010 21:27:05 +0400 Subject: powerpc/83xx: Add MCU LEDs support for MPC837xRDB and MPC8315RDB boards There are two front-panel LEDs on MPC837xRDB and MPC8315RDB boards: PWR and HDD. After adding appropriate nodes we can program these LEDs from kernel and user space. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8315erdb.dts | 14 ++++++++++++++ arch/powerpc/boot/dts/mpc8377_rdb.dts | 14 ++++++++++++++ arch/powerpc/boot/dts/mpc8378_rdb.dts | 14 ++++++++++++++ arch/powerpc/boot/dts/mpc8379_rdb.dts | 14 ++++++++++++++ arch/powerpc/platforms/83xx/mpc831x_rdb.c | 1 + arch/powerpc/platforms/83xx/mpc837x_rdb.c | 1 + 6 files changed, 58 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 508b770d3dd6..4dd08c322979 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -463,4 +463,18 @@ 0 0x00800000>; }; }; + + leds { + compatible = "gpio-leds"; + + pwr { + gpios = <&mcu_pio 0 0>; + default-state = "on"; + }; + + hdd { + gpios = <&mcu_pio 1 0>; + linux,default-trigger = "ide-disk"; + }; + }; }; diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index 9e2264b10008..dbc1b988b29d 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -486,4 +486,18 @@ 0 0x00800000>; }; }; + + leds { + compatible = "gpio-leds"; + + pwr { + gpios = <&mcu_pio 0 0>; + default-state = "on"; + }; + + hdd { + gpios = <&mcu_pio 1 0>; + linux,default-trigger = "ide-disk"; + }; + }; }; diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts index 4e6a1a407bbd..3447eb9f6e88 100644 --- a/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -470,4 +470,18 @@ 0 0x00800000>; }; }; + + leds { + compatible = "gpio-leds"; + + pwr { + gpios = <&mcu_pio 0 0>; + default-state = "on"; + }; + + hdd { + gpios = <&mcu_pio 1 0>; + linux,default-trigger = "ide-disk"; + }; + }; }; diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts index 72336d504528..15560c619b04 100644 --- a/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -436,4 +436,18 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; + + leds { + compatible = "gpio-leds"; + + pwr { + gpios = <&mcu_pio 0 0>; + default-state = "on"; + }; + + hdd { + gpios = <&mcu_pio 1 0>; + linux,default-trigger = "ide-disk"; + }; + }; }; diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c index 0b4f883b20eb..ae525e4745d2 100644 --- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c @@ -74,6 +74,7 @@ static int __init mpc831x_rdb_probe(void) static struct of_device_id __initdata of_bus_ids[] = { { .compatible = "simple-bus" }, { .compatible = "gianfar" }, + { .compatible = "gpio-leds", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c index a1908d261240..e00801c42540 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c @@ -72,6 +72,7 @@ static struct of_device_id mpc837x_ids[] = { { .compatible = "soc", }, { .compatible = "simple-bus", }, { .compatible = "gianfar", }, + { .compatible = "gpio-leds", }, {}, }; -- cgit v1.2.3-59-g8ed1b From 4c5ddd52695f7bac6362ad13fd3dc878212d1368 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Mon, 3 May 2010 16:54:15 -0500 Subject: powerpc/8610: add probing for individual DMA channels, not just DMA controllers A future version of the MPC8610 HPCD's ASoC DMA driver will probe on individual DMA channel nodes, so the DMA controller nodes' compatible string must be listed in mpc8610_ids[] for the probe to work. Also remove the "gianfar" compatible from mpc8610_ids[], since there is no gianfar (or any other networking device) on the 8610. Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/platforms/86xx/mpc8610_hpcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index 5abe137f6309..018cc67be426 100644 --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -83,7 +83,8 @@ static struct of_device_id __initdata mpc8610_ids[] = { { .compatible = "fsl,mpc8610-immr", }, { .compatible = "fsl,mpc8610-guts", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, + /* So that the DMA channel nodes can be probed individually: */ + { .compatible = "fsl,eloplus-dma", }, {} }; -- cgit v1.2.3-59-g8ed1b From 78e2e68a2b79f394b7cd61e07987a8a89af907f7 Mon Sep 17 00:00:00 2001 From: Li Yang Date: Fri, 7 May 2010 16:38:34 +0800 Subject: powerpc/fsl-booke: Fix InstructionTLBError execute permission check In CONFIG_PTE_64BIT the PTE format has unique permission bits for user and supervisor execute. However on !CONFIG_PTE_64BIT we overload the supervisor bit to imply user execute with _PAGE_USER set. This allows us to use the same permission check mask for user or supervisor code on !CONFIG_PTE_64BIT. However, on CONFIG_PTE_64BIT we map _PAGE_EXEC to _PAGE_BAP_UX so we need a different permission mask based on the fault coming from a kernel address or user space. Without unique permission masks we see issues like the following with modules: Unable to handle kernel paging request for instruction fetch Faulting instruction address: 0xf938d040 Oops: Kernel access of bad area, sig: 11 [#1] Signed-off-by: Li Yang Signed-off-by: Jin Qing Signed-off-by: Kumar Gala --- arch/powerpc/kernel/head_fsl_booke.S | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 725526547994..edd4a57fd29e 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -639,6 +639,13 @@ interrupt_base: rlwinm r12,r12,0,16,1 mtspr SPRN_MAS1,r12 + /* Make up the required permissions for kernel code */ +#ifdef CONFIG_PTE_64BIT + li r13,_PAGE_PRESENT | _PAGE_BAP_SX + oris r13,r13,_PAGE_ACCESSED@h +#else + li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC +#endif b 4f /* Get the PGD for the current thread */ @@ -646,15 +653,15 @@ interrupt_base: mfspr r11,SPRN_SPRG_THREAD lwz r11,PGDIR(r11) -4: - /* Make up the required permissions */ + /* Make up the required permissions for user code */ #ifdef CONFIG_PTE_64BIT - li r13,_PAGE_PRESENT | _PAGE_EXEC + li r13,_PAGE_PRESENT | _PAGE_BAP_UX oris r13,r13,_PAGE_ACCESSED@h #else li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC #endif +4: FIND_PTE andc. r13,r13,r11 /* Check permission */ -- cgit v1.2.3-59-g8ed1b From 78f622377f7d31d988db350a43c5689dd5f31876 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 13 May 2010 14:38:21 -0500 Subject: powerpc/fsl-booke: Move loadcam_entry back to asm code to fix SMP ftrace When we build with ftrace enabled its possible that loadcam_entry would have used the stack pointer (even though the code doesn't need it). We call loadcam_entry in __secondary_start before the stack is setup. To ensure that loadcam_entry doesn't use the stack pointer the easiest solution is to just have it in asm code. Signed-off-by: Kumar Gala --- arch/powerpc/kernel/asm-offsets.c | 8 ++++++++ arch/powerpc/mm/fsl_booke_mmu.c | 25 +++---------------------- arch/powerpc/mm/mmu_decl.h | 10 +++++++++- arch/powerpc/mm/tlb_nohash_low.S | 28 ++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 957ceb7059c5..0271b58ec31e 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -448,6 +448,14 @@ int main(void) DEFINE(PGD_T_LOG2, PGD_T_LOG2); DEFINE(PTE_T_LOG2, PTE_T_LOG2); #endif +#ifdef CONFIG_FSL_BOOKE + DEFINE(TLBCAM_SIZE, sizeof(struct tlbcam)); + DEFINE(TLBCAM_MAS0, offsetof(struct tlbcam, MAS0)); + DEFINE(TLBCAM_MAS1, offsetof(struct tlbcam, MAS1)); + DEFINE(TLBCAM_MAS2, offsetof(struct tlbcam, MAS2)); + DEFINE(TLBCAM_MAS3, offsetof(struct tlbcam, MAS3)); + DEFINE(TLBCAM_MAS7, offsetof(struct tlbcam, MAS7)); +#endif #ifdef CONFIG_KVM_EXIT_TIMING DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu, diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index 1ed6b52f3031..cdc7526e9c93 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -2,7 +2,7 @@ * Modifications by Kumar Gala (galak@kernel.crashing.org) to support * E500 Book E processors. * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright 2004,2010 Freescale Semiconductor, Inc. * * This file contains the routines for initializing the MMU * on the 4xx series of chips. @@ -56,19 +56,13 @@ unsigned int tlbcam_index; -#define NUM_TLBCAMS (64) #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS) #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS" #endif -struct tlbcam { - u32 MAS0; - u32 MAS1; - unsigned long MAS2; - u32 MAS3; - u32 MAS7; -} TLBCAM[NUM_TLBCAMS]; +#define NUM_TLBCAMS (64) +struct tlbcam TLBCAM[NUM_TLBCAMS]; struct tlbcamrange { unsigned long start; @@ -109,19 +103,6 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) return 0; } -void loadcam_entry(int idx) -{ - mtspr(SPRN_MAS0, TLBCAM[idx].MAS0); - mtspr(SPRN_MAS1, TLBCAM[idx].MAS1); - mtspr(SPRN_MAS2, TLBCAM[idx].MAS2); - mtspr(SPRN_MAS3, TLBCAM[idx].MAS3); - - if (mmu_has_feature(MMU_FTR_BIG_PHYS)) - mtspr(SPRN_MAS7, TLBCAM[idx].MAS7); - - asm volatile("isync;tlbwe;isync" : : : "memory"); -} - /* * Set up one of the I/D BAT (block address translation) register pairs. * The parameters are not checked; in particular size must be a power diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index eb11d5d2aa94..63b84a0d3b10 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -144,7 +144,15 @@ extern unsigned long mmu_mapin_ram(unsigned long top); extern void MMU_init_hw(void); extern unsigned long mmu_mapin_ram(unsigned long top); extern void adjust_total_lowmem(void); - +extern void loadcam_entry(unsigned int index); + +struct tlbcam { + u32 MAS0; + u32 MAS1; + unsigned long MAS2; + u32 MAS3; + u32 MAS7; +}; #elif defined(CONFIG_PPC32) /* anything 32-bit except 4xx or 8xx */ extern void MMU_init_hw(void); diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index e925cb58afd9..cfa768203d08 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S @@ -365,3 +365,31 @@ _GLOBAL(set_context) #else #error Unsupported processor type ! #endif + +#if defined(CONFIG_FSL_BOOKE) +/* + * extern void loadcam_entry(unsigned int index) + * + * Load TLBCAM[index] entry in to the L2 CAM MMU + */ +_GLOBAL(loadcam_entry) + LOAD_REG_ADDR(r4, TLBCAM) + mulli r5,r3,TLBCAM_SIZE + add r3,r5,r4 + lwz r4,TLBCAM_MAS0(r3) + mtspr SPRN_MAS0,r4 + lwz r4,TLBCAM_MAS1(r3) + mtspr SPRN_MAS1,r4 + PPC_LL r4,TLBCAM_MAS2(r3) + mtspr SPRN_MAS2,r4 + lwz r4,TLBCAM_MAS3(r3) + mtspr SPRN_MAS3,r4 +BEGIN_MMU_FTR_SECTION + lwz r4,TLBCAM_MAS7(r3) + mtspr SPRN_MAS7,r4 +END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) + isync + tlbwe + isync + blr +#endif -- cgit v1.2.3-59-g8ed1b From 9a58a3333923c7fef4ba6ac9afd817429e63a1fe Mon Sep 17 00:00:00 2001 From: Sreedhara DS Date: Mon, 26 Apr 2010 18:13:05 +0100 Subject: IPC driver for Intel Mobile Internet Device (MID) platforms The IPC (inter processor communications) is used to provide the communications between kernel and system control units on some embedded Intel x86 platforms. (Various bits of clean up and restructuring by Alan Cox) Signed-off-by: Sreedhara DS Signed-off-by: Alan Cox --- arch/x86/include/asm/intel_scu_ipc.h | 55 +++ drivers/platform/x86/Kconfig | 8 + drivers/platform/x86/Makefile | 1 + drivers/platform/x86/intel_scu_ipc.c | 829 +++++++++++++++++++++++++++++++++++ 4 files changed, 893 insertions(+) create mode 100644 arch/x86/include/asm/intel_scu_ipc.h create mode 100644 drivers/platform/x86/intel_scu_ipc.c (limited to 'arch') diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h new file mode 100644 index 000000000000..4470c9ad4a3e --- /dev/null +++ b/arch/x86/include/asm/intel_scu_ipc.h @@ -0,0 +1,55 @@ +#ifndef _ASM_X86_INTEL_SCU_IPC_H_ +#define _ASM_X86_INTEL_SCU_IPC_H_ + +/* Read single register */ +int intel_scu_ipc_ioread8(u16 addr, u8 *data); + +/* Read two sequential registers */ +int intel_scu_ipc_ioread16(u16 addr, u16 *data); + +/* Read four sequential registers */ +int intel_scu_ipc_ioread32(u16 addr, u32 *data); + +/* Read a vector */ +int intel_scu_ipc_readv(u16 *addr, u8 *data, int len); + +/* Write single register */ +int intel_scu_ipc_iowrite8(u16 addr, u8 data); + +/* Write two sequential registers */ +int intel_scu_ipc_iowrite16(u16 addr, u16 data); + +/* Write four sequential registers */ +int intel_scu_ipc_iowrite32(u16 addr, u32 data); + +/* Write a vector */ +int intel_scu_ipc_writev(u16 *addr, u8 *data, int len); + +/* Update single register based on the mask */ +int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask); + +/* + * Indirect register read + * Can be used when SCCB(System Controller Configuration Block) register + * HRIM(Honor Restricted IPC Messages) is set (bit 23) + */ +int intel_scu_ipc_register_read(u32 addr, u32 *data); + +/* + * Indirect register write + * Can be used when SCCB(System Controller Configuration Block) register + * HRIM(Honor Restricted IPC Messages) is set (bit 23) + */ +int intel_scu_ipc_register_write(u32 addr, u32 data); + +/* Issue commands to the SCU with or without data */ +int intel_scu_ipc_simple_command(int cmd, int sub); +int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, + u32 *out, int outlen); +/* I2C control api */ +int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data); + +/* Update FW version */ +int intel_scu_ipc_fw_update(u8 *buffer, u32 length); + +#endif diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 6c3320d75055..619134151ca6 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -527,4 +527,12 @@ config ACPI_CMPC keys as input device, backlight device, tablet and accelerometer devices. +config INTEL_SCU_IPC + bool "Intel SCU IPC Support" + depends on X86_MRST + default y + ---help--- + IPC is used to bridge the communications between kernel and SCU on + some embedded Intel x86 platforms. + endif # X86_PLATFORM_DEVICES diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index a906490e3530..8770bfe71431 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -25,3 +25,4 @@ obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o +obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c new file mode 100644 index 000000000000..576c3ed92435 --- /dev/null +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -0,0 +1,829 @@ +/* + * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism + * + * (C) Copyright 2008-2010 Intel Corporation + * Author: Sreedhara DS (sreedhara.ds@intel.com) + * + * 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; version 2 + * of the License. + * + * SCU runing in ARC processor communicates with other entity running in IA + * core through IPC mechanism which in turn messaging between IA core ad SCU. + * SCU has two IPC mechanism IPC-1 and IPC-2. IPC-1 is used between IA32 and + * SCU where IPC-2 is used between P-Unit and SCU. This driver delas with + * IPC-1 Driver provides an API for power control unit registers (e.g. MSIC) + * along with other APIs. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* IPC defines the following message types */ +#define IPCMSG_WATCHDOG_TIMER 0xF8 /* Set Kernel Watchdog Threshold */ +#define IPCMSG_BATTERY 0xEF /* Coulomb Counter Accumulator */ +#define IPCMSG_FW_UPDATE 0xFE /* Firmware update */ +#define IPCMSG_PCNTRL 0xFF /* Power controller unit read/write */ +#define IPCMSG_FW_REVISION 0xF4 /* Get firmware revision */ + +/* Command id associated with message IPCMSG_PCNTRL */ +#define IPC_CMD_PCNTRL_W 0 /* Register write */ +#define IPC_CMD_PCNTRL_R 1 /* Register read */ +#define IPC_CMD_PCNTRL_M 2 /* Register read-modify-write */ + +/* Miscelaneous Command ids */ +#define IPC_CMD_INDIRECT_RD 2 /* 32bit indirect read */ +#define IPC_CMD_INDIRECT_WR 5 /* 32bit indirect write */ + +/* + * IPC register summary + * + * IPC register blocks are memory mapped at fixed address of 0xFF11C000 + * To read or write information to the SCU, driver writes to IPC-1 memory + * mapped registers (base address 0xFF11C000). The following is the IPC + * mechanism + * + * 1. IA core cDMI interface claims this transaction and converts it to a + * Transaction Layer Packet (TLP) message which is sent across the cDMI. + * + * 2. South Complex cDMI block receives this message and writes it to + * the IPC-1 register block, causing an interrupt to the SCU + * + * 3. SCU firmware decodes this interrupt and IPC message and the appropriate + * message handler is called within firmware. + */ + +#define IPC_BASE_ADDR 0xFF11C000 /* IPC1 base register address */ +#define IPC_MAX_ADDR 0x100 /* Maximum IPC regisers */ +#define IPC_WWBUF_SIZE 16 /* IPC Write buffer Size */ +#define IPC_RWBUF_SIZE 16 /* IPC Read buffer Size */ +#define IPC_I2C_BASE 0xFF12B000 /* I2C control register base address */ +#define IPC_I2C_MAX_ADDR 0x10 /* Maximum I2C regisers */ + +static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id); +static void ipc_remove(struct pci_dev *pdev); + +struct intel_scu_ipc_dev { + struct pci_dev *pdev; + void __iomem *ipc_base; + void __iomem *i2c_base; +}; + +static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ + +static int platform = 1; +module_param(platform, int, 0); +MODULE_PARM_DESC(platform, "1 for moorestown platform"); + + + + +/* + * IPC Read Buffer (Read Only): + * 16 byte buffer for receiving data from SCU, if IPC command + * processing results in response data + */ +#define IPC_READ_BUFFER 0x90 + +#define IPC_I2C_CNTRL_ADDR 0 +#define I2C_DATA_ADDR 0x04 + +static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */ + +/* + * Command Register (Write Only): + * A write to this register results in an interrupt to the SCU core processor + * Format: + * |rfu2(8) | size(8) | command id(4) | rfu1(3) | ioc(1) | command(8)| + */ +static inline void ipc_command(u32 cmd) /* Send ipc command */ +{ + writel(cmd, ipcdev.ipc_base); +} + +/* + * IPC Write Buffer (Write Only): + * 16-byte buffer for sending data associated with IPC command to + * SCU. Size of the data is specified in the IPC_COMMAND_REG register + */ +static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */ +{ + writel(data, ipcdev.ipc_base + 0x80 + offset); +} + +/* + * IPC destination Pointer (Write Only): + * Use content as pointer for destination write + */ +static inline void ipc_write_dptr(u32 data) /* Write dptr data */ +{ + writel(data, ipcdev.ipc_base + 0x0C); +} + +/* + * IPC Source Pointer (Write Only): + * Use content as pointer for read location +*/ +static inline void ipc_write_sptr(u32 data) /* Write dptr data */ +{ + writel(data, ipcdev.ipc_base + 0x08); +} + +/* + * Status Register (Read Only): + * Driver will read this register to get the ready/busy status of the IPC + * block and error status of the IPC command that was just processed by SCU + * Format: + * |rfu3(8)|error code(8)|initiator id(8)|cmd id(4)|rfu1(2)|error(1)|busy(1)| + */ + +static inline u8 ipc_read_status(void) +{ + return __raw_readl(ipcdev.ipc_base + 0x04); +} + +static inline u8 ipc_data_readb(u32 offset) /* Read ipc byte data */ +{ + return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset); +} + +static inline u8 ipc_data_readl(u32 offset) /* Read ipc u32 data */ +{ + return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); +} + +static inline int busy_loop(void) /* Wait till scu status is busy */ +{ + u32 status = 0; + u32 loop_count = 0; + + status = ipc_read_status(); + while (status & 1) { + udelay(1); /* scu processing time is in few u secods */ + status = ipc_read_status(); + loop_count++; + /* break if scu doesn't reset busy bit after huge retry */ + if (loop_count > 100000) { + dev_err(&ipcdev.pdev->dev, "IPC timed out"); + return -ETIMEDOUT; + } + } + return (status >> 1) & 1; +} + +/* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ +static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) +{ + int nc; + u32 offset = 0; + u32 err = 0; + u8 cbuf[IPC_WWBUF_SIZE] = { '\0' }; + u32 *wbuf = (u32 *)&cbuf; + + mutex_lock(&ipclock); + if (ipcdev.pdev == NULL) { + mutex_unlock(&ipclock); + return -ENODEV; + } + + if (platform == 1) { + /* Entry is 4 bytes for read/write, 5 bytes for read modify */ + for (nc = 0; nc < count; nc++) { + cbuf[offset] = addr[nc]; + cbuf[offset + 1] = addr[nc] >> 8; + if (id != IPC_CMD_PCNTRL_R) + cbuf[offset + 2] = data[nc]; + if (id == IPC_CMD_PCNTRL_M) { + cbuf[offset + 3] = data[nc + 1]; + offset += 1; + } + offset += 3; + } + for (nc = 0, offset = 0; nc < count; nc++, offset += 4) + ipc_data_writel(wbuf[nc], offset); /* Write wbuff */ + + } else { + for (nc = 0, offset = 0; nc < count; nc++, offset += 2) + ipc_data_writel(addr[nc], offset); /* Write addresses */ + if (id != IPC_CMD_PCNTRL_R) { + for (nc = 0; nc < count; nc++, offset++) + ipc_data_writel(data[nc], offset); /* Write data */ + if (id == IPC_CMD_PCNTRL_M) + ipc_data_writel(data[nc + 1], offset); /* Mask value*/ + } + } + + if (id != IPC_CMD_PCNTRL_M) + ipc_command((count * 3) << 16 | id << 12 | 0 << 8 | op); + else + ipc_command((count * 4) << 16 | id << 12 | 0 << 8 | op); + + err = busy_loop(); + + if (id == IPC_CMD_PCNTRL_R) { /* Read rbuf */ + /* Workaround: values are read as 0 without memcpy_fromio */ + memcpy_fromio(cbuf, ipcdev.ipc_base + IPC_READ_BUFFER, 16); + if (platform == 1) { + for (nc = 0, offset = 2; nc < count; nc++, offset += 3) + data[nc] = ipc_data_readb(offset); + } else { + for (nc = 0; nc < count; nc++) + data[nc] = ipc_data_readb(nc); + } + } + mutex_unlock(&ipclock); + return err; +} + +/** + * intel_scu_ipc_ioread8 - read a word via the SCU + * @addr: register on SCU + * @data: return pointer for read byte + * + * Read a single register. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_ioread8(u16 addr, u8 *data) +{ + return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); +} +EXPORT_SYMBOL(intel_scu_ipc_ioread8); + +/** + * intel_scu_ipc_ioread16 - read a word via the SCU + * @addr: register on SCU + * @data: return pointer for read word + * + * Read a register pair. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_ioread16(u16 addr, u16 *data) +{ + u16 x[2] = {addr, addr + 1 }; + return pwr_reg_rdwr(x, (u8 *)data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); +} +EXPORT_SYMBOL(intel_scu_ipc_ioread16); + +/** + * intel_scu_ipc_ioread32 - read a dword via the SCU + * @addr: register on SCU + * @data: return pointer for read dword + * + * Read four registers. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_ioread32(u16 addr, u32 *data) +{ + u16 x[4] = {addr, addr + 1, addr + 2, addr + 3}; + return pwr_reg_rdwr(x, (u8 *)data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); +} +EXPORT_SYMBOL(intel_scu_ipc_ioread32); + +/** + * intel_scu_ipc_iowrite8 - write a byte via the SCU + * @addr: register on SCU + * @data: byte to write + * + * Write a single register. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_iowrite8(u16 addr, u8 data) +{ + return pwr_reg_rdwr(&addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); +} +EXPORT_SYMBOL(intel_scu_ipc_iowrite8); + +/** + * intel_scu_ipc_iowrite16 - write a word via the SCU + * @addr: register on SCU + * @data: word to write + * + * Write two registers. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_iowrite16(u16 addr, u16 data) +{ + u16 x[2] = {addr, addr + 1 }; + return pwr_reg_rdwr(x, (u8 *)&data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); +} +EXPORT_SYMBOL(intel_scu_ipc_iowrite16); + +/** + * intel_scu_ipc_iowrite32 - write a dword via the SCU + * @addr: register on SCU + * @data: dword to write + * + * Write four registers. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_iowrite32(u16 addr, u32 data) +{ + u16 x[4] = {addr, addr + 1, addr + 2, addr + 3}; + return pwr_reg_rdwr(x, (u8 *)&data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); +} +EXPORT_SYMBOL(intel_scu_ipc_iowrite32); + +/** + * intel_scu_ipc_readvv - read a set of registers + * @addr: register list + * @data: bytes to return + * @len: length of array + * + * Read registers. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * The largest array length permitted by the hardware is 5 items. + * + * This function may sleep. + */ +int intel_scu_ipc_readv(u16 *addr, u8 *data, int len) +{ + return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); +} +EXPORT_SYMBOL(intel_scu_ipc_readv); + +/** + * intel_scu_ipc_writev - write a set of registers + * @addr: register list + * @data: bytes to write + * @len: length of array + * + * Write registers. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * The largest array length permitted by the hardware is 5 items. + * + * This function may sleep. + * + */ +int intel_scu_ipc_writev(u16 *addr, u8 *data, int len) +{ + return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); +} +EXPORT_SYMBOL(intel_scu_ipc_writev); + + +/** + * intel_scu_ipc_update_register - r/m/w a register + * @addr: register address + * @bits: bits to update + * @mask: mask of bits to update + * + * Read-modify-write power control unit register. The first data argument + * must be register value and second is mask value + * mask is a bitmap that indicates which bits to update. + * 0 = masked. Don't modify this bit, 1 = modify this bit. + * returns 0 on success or an error code. + * + * This function may sleep. Locking between SCU accesses is handled + * for the caller. + */ +int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask) +{ + u8 data[2] = { bits, mask }; + return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M); +} +EXPORT_SYMBOL(intel_scu_ipc_update_register); + +/** + * intel_scu_ipc_register_read - 32bit indirect read + * @addr: register address + * @value: 32bit value return + * + * Performs IA 32 bit indirect read, returns 0 on success, or an + * error code. + * + * Can be used when SCCB(System Controller Configuration Block) register + * HRIM(Honor Restricted IPC Messages) is set (bit 23) + * + * This function may sleep. Locking for SCU accesses is handled for + * the caller. + */ +int intel_scu_ipc_register_read(u32 addr, u32 *value) +{ + u32 err = 0; + + mutex_lock(&ipclock); + if (ipcdev.pdev == NULL) { + mutex_unlock(&ipclock); + return -ENODEV; + } + ipc_write_sptr(addr); + ipc_command(4 << 16 | IPC_CMD_INDIRECT_RD); + err = busy_loop(); + *value = ipc_data_readl(0); + mutex_unlock(&ipclock); + return err; +} +EXPORT_SYMBOL(intel_scu_ipc_register_read); + +/** + * intel_scu_ipc_register_write - 32bit indirect write + * @addr: register address + * @value: 32bit value to write + * + * Performs IA 32 bit indirect write, returns 0 on success, or an + * error code. + * + * Can be used when SCCB(System Controller Configuration Block) register + * HRIM(Honor Restricted IPC Messages) is set (bit 23) + * + * This function may sleep. Locking for SCU accesses is handled for + * the caller. + */ +int intel_scu_ipc_register_write(u32 addr, u32 value) +{ + u32 err = 0; + + mutex_lock(&ipclock); + if (ipcdev.pdev == NULL) { + mutex_unlock(&ipclock); + return -ENODEV; + } + ipc_write_dptr(addr); + ipc_data_writel(value, 0); + ipc_command(4 << 16 | IPC_CMD_INDIRECT_WR); + err = busy_loop(); + mutex_unlock(&ipclock); + return err; +} +EXPORT_SYMBOL(intel_scu_ipc_register_write); + +/** + * intel_scu_ipc_simple_command - send a simple command + * @cmd: command + * @sub: sub type + * + * Issue a simple command to the SCU. Do not use this interface if + * you must then access data as any data values may be overwritten + * by another SCU access by the time this function returns. + * + * This function may sleep. Locking for SCU accesses is handled for + * the caller. + */ +int intel_scu_ipc_simple_command(int cmd, int sub) +{ + u32 err = 0; + + mutex_lock(&ipclock); + if (ipcdev.pdev == NULL) { + mutex_unlock(&ipclock); + return -ENODEV; + } + ipc_command(cmd << 12 | sub); + err = busy_loop(); + mutex_unlock(&ipclock); + return err; +} +EXPORT_SYMBOL(intel_scu_ipc_simple_command); + +/** + * intel_scu_ipc_command - command with data + * @cmd: command + * @sub: sub type + * @in: input data + * @inlen: input length + * @out: output data + * @outlein: output length + * + * Issue a command to the SCU which involves data transfers. Do the + * data copies under the lock but leave it for the caller to interpret + */ + +int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, + u32 *out, int outlen) +{ + u32 err = 0; + int i = 0; + + mutex_lock(&ipclock); + if (ipcdev.pdev == NULL) { + mutex_unlock(&ipclock); + return -ENODEV; + } + + for (i = 0; i < inlen; i++) + ipc_data_writel(*in++, 4 * i); + + ipc_command(cmd << 12 | sub); + err = busy_loop(); + + for (i = 0; i < outlen; i++) + *out++ = ipc_data_readl(4 * i); + + mutex_unlock(&ipclock); + return err; +} +EXPORT_SYMBOL(intel_scu_ipc_command); + +/*I2C commands */ +#define IPC_I2C_WRITE 1 /* I2C Write command */ +#define IPC_I2C_READ 2 /* I2C Read command */ + +/** + * intel_scu_ipc_i2c_cntrl - I2C read/write operations + * @addr: I2C address + command bits + * @data: data to read/write + * + * Perform an an I2C read/write operation via the SCU. All locking is + * handled for the caller. This function may sleep. + * + * Returns an error code or 0 on success. + * + * This has to be in the IPC driver for the locking. + */ +int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data) +{ + u32 cmd = 0; + + mutex_lock(&ipclock); + cmd = (addr >> 24) & 0xFF; + if (cmd == IPC_I2C_READ) { + writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); + /* Write not getting updated without delay */ + mdelay(1); + *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); + } else if (cmd == IPC_I2C_WRITE) { + writel(addr, ipcdev.i2c_base + I2C_DATA_ADDR); + mdelay(1); + writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); + } else { + dev_err(&ipcdev.pdev->dev, + "intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd); + + mutex_unlock(&ipclock); + return -1; + } + mutex_unlock(&ipclock); + return 0; +} +EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl); + +#define IPC_FW_LOAD_ADDR 0xFFFC0000 /* Storage location for FW image */ +#define IPC_FW_UPDATE_MBOX_ADDR 0xFFFFDFF4 /* Mailbox between ipc and scu */ +#define IPC_MAX_FW_SIZE 262144 /* 256K storage size for loading the FW image */ +#define IPC_FW_MIP_HEADER_SIZE 2048 /* Firmware MIP header size */ +/* IPC inform SCU to get ready for update process */ +#define IPC_CMD_FW_UPDATE_READY 0x10FE +/* IPC inform SCU to go for update process */ +#define IPC_CMD_FW_UPDATE_GO 0x20FE +/* Status code for fw update */ +#define IPC_FW_UPDATE_SUCCESS 0x444f4e45 /* Status code 'DONE' */ +#define IPC_FW_UPDATE_BADN 0x4241444E /* Status code 'BADN' */ +#define IPC_FW_TXHIGH 0x54784849 /* Status code 'IPC_FW_TXHIGH' */ +#define IPC_FW_TXLOW 0x54784c4f /* Status code 'IPC_FW_TXLOW' */ + +struct fw_update_mailbox { + u32 status; + u32 scu_flag; + u32 driver_flag; +}; + + +/** + * intel_scu_ipc_fw_update - Firmware update utility + * @buffer: firmware buffer + * @length: size of firmware buffer + * + * This function provides an interface to load the firmware into + * the SCU. Returns 0 on success or -1 on failure + */ +int intel_scu_ipc_fw_update(u8 *buffer, u32 length) +{ + void __iomem *fw_update_base; + struct fw_update_mailbox __iomem *mailbox = NULL; + int retry_cnt = 0; + u32 status; + + mutex_lock(&ipclock); + fw_update_base = ioremap_nocache(IPC_FW_LOAD_ADDR, (128*1024)); + if (fw_update_base == NULL) { + mutex_unlock(&ipclock); + return -ENOMEM; + } + mailbox = ioremap_nocache(IPC_FW_UPDATE_MBOX_ADDR, + sizeof(struct fw_update_mailbox)); + if (mailbox == NULL) { + iounmap(fw_update_base); + mutex_unlock(&ipclock); + return -ENOMEM; + } + + ipc_command(IPC_CMD_FW_UPDATE_READY); + + /* Intitialize mailbox */ + writel(0, &mailbox->status); + writel(0, &mailbox->scu_flag); + writel(0, &mailbox->driver_flag); + + /* Driver copies the 2KB MIP header to SRAM at 0xFFFC0000*/ + memcpy_toio(fw_update_base, buffer, 0x800); + + /* Driver sends "FW Update" IPC command (CMD_ID 0xFE; MSG_ID 0x02). + * Upon receiving this command, SCU will write the 2K MIP header + * from 0xFFFC0000 into NAND. + * SCU will write a status code into the Mailbox, and then set scu_flag. + */ + + ipc_command(IPC_CMD_FW_UPDATE_GO); + + /*Driver stalls until scu_flag is set */ + while (readl(&mailbox->scu_flag) != 1) { + rmb(); + mdelay(1); + } + + /* Driver checks Mailbox status. + * If the status is 'BADN', then abort (bad NAND). + * If the status is 'IPC_FW_TXLOW', then continue. + */ + while (readl(&mailbox->status) != IPC_FW_TXLOW) { + rmb(); + mdelay(10); + } + mdelay(10); + +update_retry: + if (retry_cnt > 5) + goto update_end; + + if (readl(&mailbox->status) != IPC_FW_TXLOW) + goto update_end; + buffer = buffer + 0x800; + memcpy_toio(fw_update_base, buffer, 0x20000); + writel(1, &mailbox->driver_flag); + while (readl(&mailbox->scu_flag) == 1) { + rmb(); + mdelay(1); + } + + /* check for 'BADN' */ + if (readl(&mailbox->status) == IPC_FW_UPDATE_BADN) + goto update_end; + + while (readl(&mailbox->status) != IPC_FW_TXHIGH) { + rmb(); + mdelay(10); + } + mdelay(10); + + if (readl(&mailbox->status) != IPC_FW_TXHIGH) + goto update_end; + + buffer = buffer + 0x20000; + memcpy_toio(fw_update_base, buffer, 0x20000); + writel(0, &mailbox->driver_flag); + + while (mailbox->scu_flag == 0) { + rmb(); + mdelay(1); + } + + /* check for 'BADN' */ + if (readl(&mailbox->status) == IPC_FW_UPDATE_BADN) + goto update_end; + + if (readl(&mailbox->status) == IPC_FW_TXLOW) { + ++retry_cnt; + goto update_retry; + } + +update_end: + status = readl(&mailbox->status); + + iounmap(fw_update_base); + iounmap(mailbox); + mutex_unlock(&ipclock); + + if (status == IPC_FW_UPDATE_SUCCESS) + return 0; + return -1; +} +EXPORT_SYMBOL(intel_scu_ipc_fw_update); + +/* + * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1 + * When ioc bit is set to 1, caller api must wait for interrupt handler called + * which in turn unlocks the caller api. Currently this is not used + * + * This is edge triggered so we need take no action to clear anything + */ +static irqreturn_t ioc(int irq, void *dev_id) +{ + return IRQ_HANDLED; +} + +/** + * ipc_probe - probe an Intel SCU IPC + * @dev: the PCI device matching + * @id: entry in the match table + * + * Enable and install an intel SCU IPC. This appears in the PCI space + * but uses some hard coded addresses as well. + */ +static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int err; + resource_size_t pci_resource; + + if (ipcdev.pdev) /* We support only one SCU */ + return -EBUSY; + + ipcdev.pdev = pci_dev_get(dev); + + err = pci_enable_device(dev); + if (err) + return err; + + err = pci_request_regions(dev, "intel_scu_ipc"); + if (err) + return err; + + pci_resource = pci_resource_start(dev, 0); + if (!pci_resource) + return -ENOMEM; + + if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev)) + return -EBUSY; + + ipcdev.ipc_base = ioremap_nocache(IPC_BASE_ADDR, IPC_MAX_ADDR); + if (!ipcdev.ipc_base) + return -ENOMEM; + + ipcdev.i2c_base = ioremap_nocache(IPC_I2C_BASE, IPC_I2C_MAX_ADDR); + if (!ipcdev.i2c_base) { + iounmap(ipcdev.ipc_base); + return -ENOMEM; + } + return 0; +} + +/** + * ipc_remove - remove a bound IPC device + * @pdev: PCI device + * + * In practice the SCU is not removable but this function is also + * called for each device on a module unload or cleanup which is the + * path that will get used. + * + * Free up the mappings and release the PCI resources + */ +static void ipc_remove(struct pci_dev *pdev) +{ + free_irq(pdev->irq, &ipcdev); + pci_release_regions(pdev); + pci_dev_put(ipcdev.pdev); + iounmap(ipcdev.ipc_base); + iounmap(ipcdev.i2c_base); + ipcdev.pdev = NULL; +} + +static const struct pci_device_id pci_ids[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080e)}, + { 0,} +}; +MODULE_DEVICE_TABLE(pci, pci_ids); + +static struct pci_driver ipc_driver = { + .name = "intel_scu_ipc", + .id_table = pci_ids, + .probe = ipc_probe, + .remove = ipc_remove, +}; + + +static int __init intel_scu_ipc_init(void) +{ + return pci_register_driver(&ipc_driver); +} + +static void __exit intel_scu_ipc_exit(void) +{ + pci_unregister_driver(&ipc_driver); +} + +MODULE_AUTHOR("Sreedhara DS "); +MODULE_DESCRIPTION("Intel SCU IPC driver"); +MODULE_LICENSE("GPL"); + +module_init(intel_scu_ipc_init); +module_exit(intel_scu_ipc_exit); -- cgit v1.2.3-59-g8ed1b From 98830bc9967b18d6f9a614a1f354f5580196ef85 Mon Sep 17 00:00:00 2001 From: Hartley Sweeten Date: Mon, 17 May 2010 17:18:10 +0100 Subject: ARM: 6136/1: ARCH_REQUIRE_GPIOLIB selects GENERIC_GPIO The ARCH_REQUIRE_GPIOLIB config option will select GPIOLIB which in turn will select GENERIC_GPIO. Because of this, there is no reason to do the select GENERIC_GPIO in arch/arm/Kconfig for the architectures that have ARCH_REQUIRE_GPIOLIB. Signed-off-by: H Hartley Sweeten Signed-off-by: Russell King --- arch/arm/Kconfig | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index daaa4b2b46e1..9e938a79a3b2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -296,7 +296,6 @@ config ARCH_VEXPRESS config ARCH_AT91 bool "Atmel AT91" - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select HAVE_CLK select ARCH_USES_GETTIMEOFFSET @@ -326,7 +325,6 @@ config ARCH_CLPS711X config ARCH_GEMINI bool "Cortina Systems Gemini" select CPU_FA526 - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select ARCH_USES_GETTIMEOFFSET help @@ -349,7 +347,6 @@ config ARCH_EP93XX select CPU_ARM920T select ARM_AMBA select ARM_VIC - select GENERIC_GPIO select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_HOLES_MEMORYMODEL @@ -382,7 +379,6 @@ config ARCH_STMP3XXX select ARCH_REQUIRE_GPIOLIB select GENERIC_TIME select GENERIC_CLOCKEVENTS - select GENERIC_GPIO select USB_ARCH_HAS_EHCI help Support for systems based on the Freescale 3xxx CPUs. @@ -421,7 +417,6 @@ config ARCH_IOP32X select CPU_XSCALE select PLAT_IOP select PCI - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB help Support for Intel's 80219 and IOP32X (XScale) family of @@ -433,7 +428,6 @@ config ARCH_IOP33X select CPU_XSCALE select PLAT_IOP select PCI - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB help Support for Intel's IOP33X (XScale) family of processors. @@ -485,7 +479,6 @@ config ARCH_L7200 config ARCH_DOVE bool "Marvell Dove" select PCI - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -497,7 +490,6 @@ config ARCH_KIRKWOOD bool "Marvell Kirkwood" select CPU_FEROCEON select PCI - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -519,7 +511,6 @@ config ARCH_MV78XX0 bool "Marvell MV78xx0" select CPU_FEROCEON select PCI - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -533,7 +524,6 @@ config ARCH_ORION5X depends on MMU select CPU_FEROCEON select PCI - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -546,7 +536,6 @@ config ARCH_ORION5X config ARCH_MMP bool "Marvell PXA168/910/MMP2" depends on MMU - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select COMMON_CLKDEV select GENERIC_TIME @@ -559,8 +548,7 @@ config ARCH_MMP config ARCH_KS8695 bool "Micrel/Kendin KS8695" select CPU_ARM922T - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB + select ARCH_REQUIRE_GPIOLIB select ARCH_USES_GETTIMEOFFSET help Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based @@ -583,7 +571,6 @@ config ARCH_W90X900 bool "Nuvoton W90X900 CPU" select CPU_ARM926T select ARCH_REQUIRE_GPIOLIB - select GENERIC_GPIO select COMMON_CLKDEV select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -617,7 +604,6 @@ config ARCH_PXA depends on MMU select ARCH_MTD_XIP select ARCH_HAS_CPUFREQ - select GENERIC_GPIO select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select GENERIC_TIME @@ -666,7 +652,6 @@ config ARCH_SA1100 select ARCH_MTD_XIP select ARCH_HAS_CPUFREQ select CPU_FREQ - select GENERIC_GPIO select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_CLK @@ -690,7 +675,6 @@ config ARCH_S3C64XX bool "Samsung S3C64XX" select PLAT_SAMSUNG select CPU_V6 - select GENERIC_GPIO select ARM_VIC select HAVE_CLK select NO_IOPORT @@ -801,7 +785,6 @@ config ARCH_NOMADIK select COMMON_CLKDEV select GENERIC_TIME select GENERIC_CLOCKEVENTS - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB help Support for the Nomadik platform by ST-Ericsson @@ -811,7 +794,6 @@ config ARCH_DAVINCI select CPU_ARM926T select GENERIC_TIME select GENERIC_CLOCKEVENTS - select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select ZONE_DMA select HAVE_IDE @@ -823,7 +805,6 @@ config ARCH_DAVINCI config ARCH_OMAP bool "TI OMAP" - select GENERIC_GPIO select HAVE_CLK select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_CPUFREQ @@ -839,7 +820,6 @@ config PLAT_SPEAR select ARCH_REQUIRE_GPIOLIB select COMMON_CLKDEV select GENERIC_CLOCKEVENTS - select GENERIC_GPIO select GENERIC_TIME select HAVE_CLK help -- cgit v1.2.3-59-g8ed1b From fec84e330719c20d2146c8dbdc9ff50b3a1d7039 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 17 May 2010 18:43:24 +0200 Subject: x86, hpet: Add reference to chipset erratum documentation for disable-hpet-msi-quirk (At the moment the "SB700 Family Product Errata" document is available at http://support.amd.com/us/Embedded_TechDocs/46837.pdf) Signed-off-by: Andreas Herrmann LKML-Reference: <20100517164324.GB10254@alberich.amd.com> Signed-off-by: H. Peter Anvin --- arch/x86/kernel/quirks.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index cd2c336c8d09..e72d3fc6547d 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -495,6 +495,9 @@ void force_hpet_resume(void) /* * HPET MSI on some boards (ATI SB700/SB800) has side effect on * floppy DMA. Disable HPET MSI on such platforms. + * See erratum #27 (Misinterpreted MSI Requests May Result in + * Corrupted LPC DMA Data) in AMD Publication #46837, + * "SB700 Family Product Errata", Rev. 1.0, March 2010. * * Also force the read back of the CMP register in hpet_next_event() * to work around the problem that the CMP register write seems to be -- cgit v1.2.3-59-g8ed1b From b1f3bb494e8acddeb972331c2ac642b3c7bceeb9 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 15 Oct 2009 08:42:21 +0000 Subject: m68k: Remove BKL from rtc implementations m68k does not support SMP. The access to the rtc is already serialized with local_irq_save/restore which is sufficient on UP. The open() protection in arch/m68k/mvme16x/rtc.c is not pretty but sufficient on UP and safe w/o the BKL. open() in arch/m68k/bvme6000/rtc.c can do with the same atomic logic as arch/m68k/mvme16x/rtc.c Signed-off-by: Thomas Gleixner Signed-off-by: Geert Uytterhoeven --- arch/m68k/bvme6000/rtc.c | 29 +++++++++-------------------- arch/m68k/mvme16x/rtc.c | 19 +++++-------------- 2 files changed, 14 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c index b46ea1714a89..cb8617bb194b 100644 --- a/arch/m68k/bvme6000/rtc.c +++ b/arch/m68k/bvme6000/rtc.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -35,10 +34,9 @@ static unsigned char days_in_mo[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -static char rtc_status; +static atomic_t rtc_status = ATOMIC_INIT(1); -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE; unsigned char msr; @@ -132,29 +130,20 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } /* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. + * We enforce only one user at a time here with the open/close. */ - static int rtc_open(struct inode *inode, struct file *file) { - lock_kernel(); - if(rtc_status) { - unlock_kernel(); + if (!atomic_dec_and_test(&rtc_status)) { + atomic_inc(&rtc_status); return -EBUSY; } - - rtc_status = 1; - unlock_kernel(); return 0; } static int rtc_release(struct inode *inode, struct file *file) { - lock_kernel(); - rtc_status = 0; - unlock_kernel(); + atomic_inc(&rtc_status); return 0; } @@ -163,9 +152,9 @@ static int rtc_release(struct inode *inode, struct file *file) */ static const struct file_operations rtc_fops = { - .ioctl = rtc_ioctl, - .open = rtc_open, - .release = rtc_release, + .unlocked_ioctl = rtc_ioctl, + .open = rtc_open, + .release = rtc_release, }; static struct miscdevice rtc_dev = { diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c index 8da9c250d3e1..11ac6f63967a 100644 --- a/arch/m68k/mvme16x/rtc.c +++ b/arch/m68k/mvme16x/rtc.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -36,8 +35,7 @@ static const unsigned char days_in_mo[] = static atomic_t rtc_ready = ATOMIC_INIT(1); -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { volatile MK48T08ptr_t rtc = (MK48T08ptr_t)MVME_RTC_BASE; unsigned long flags; @@ -120,22 +118,15 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } /* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. + * We enforce only one user at a time here with the open/close. */ - static int rtc_open(struct inode *inode, struct file *file) { - lock_kernel(); if( !atomic_dec_and_test(&rtc_ready) ) { atomic_inc( &rtc_ready ); - unlock_kernel(); return -EBUSY; } - unlock_kernel(); - return 0; } @@ -150,9 +141,9 @@ static int rtc_release(struct inode *inode, struct file *file) */ static const struct file_operations rtc_fops = { - .ioctl = rtc_ioctl, - .open = rtc_open, - .release = rtc_release, + .unlocked_ioctl = rtc_ioctl, + .open = rtc_open, + .release = rtc_release, }; static struct miscdevice rtc_dev= -- cgit v1.2.3-59-g8ed1b From 291d7e9553fef2e18825b1ef1345fbd316dff98f Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 31 Dec 2009 15:35:44 -0500 Subject: m68k: Simplify param.h by using Signed-off-by: Robert P. J. Day Signed-off-by: Geert Uytterhoeven --- arch/m68k/include/asm/param.h | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/m68k/include/asm/param.h b/arch/m68k/include/asm/param.h index 85c41b75aa78..36265ccf5c7b 100644 --- a/arch/m68k/include/asm/param.h +++ b/arch/m68k/include/asm/param.h @@ -1,26 +1,12 @@ #ifndef _M68K_PARAM_H #define _M68K_PARAM_H -#ifdef __KERNEL__ -# define HZ CONFIG_HZ /* Internal kernel timer frequency */ -# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ -# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ -#endif - -#ifndef HZ -#define HZ 100 -#endif - #ifdef __uClinux__ #define EXEC_PAGESIZE 4096 #else #define EXEC_PAGESIZE 8192 #endif -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ +#include #endif /* _M68K_PARAM_H */ -- cgit v1.2.3-59-g8ed1b From b9b0d8b430ebd61d32e2a9544e75a3c4b10cddcd Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Sat, 6 Feb 2010 18:47:11 +0100 Subject: m68k: Remove trailing spaces in messages Signed-off-by: Frans Pop Signed-off-by: Geert Uytterhoeven --- arch/m68k/kernel/traps.c | 2 +- arch/m68k/mac/config.c | 10 +++++----- arch/m68k/q40/config.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index aacd6d17b833..ada4f4cca811 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -455,7 +455,7 @@ static inline void access_error040(struct frame *fp) if (do_page_fault(&fp->ptregs, addr, errorcode)) { #ifdef DEBUG - printk("do_page_fault() !=0 \n"); + printk("do_page_fault() !=0\n"); #endif if (user_mode(&fp->ptregs)){ /* delay writebacks after signal delivery */ diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index 0356da9bf763..1c16b1baf8db 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -148,7 +148,7 @@ static void mac_cache_card_flush(int writeback) void __init config_mac(void) { if (!MACH_IS_MAC) - printk(KERN_ERR "ERROR: no Mac, but config_mac() called!! \n"); + printk(KERN_ERR "ERROR: no Mac, but config_mac() called!!\n"); mach_sched_init = mac_sched_init; mach_init_IRQ = mac_init_IRQ; @@ -867,7 +867,7 @@ static void __init mac_identify(void) */ iop_preinit(); - printk(KERN_INFO "Detected Macintosh model: %d \n", model); + printk(KERN_INFO "Detected Macintosh model: %d\n", model); /* * Report booter data: @@ -878,12 +878,12 @@ static void __init mac_identify(void) mac_bi_data.videoaddr, mac_bi_data.videorow, mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF, mac_bi_data.dimensions >> 16); - printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n", + printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx\n", mac_bi_data.videological, mac_orig_videoaddr, mac_bi_data.sccbase); - printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx \n", + printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx\n", mac_bi_data.boottime, mac_bi_data.gmtbias); - printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n", + printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx\n", mac_bi_data.id, mac_bi_data.cpuid, mac_bi_data.memsize); iop_init(); diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 31ab3f08bbda..ad10fecec2fe 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -126,7 +126,7 @@ static void q40_reset(void) { halted = 1; printk("\n\n*******************************************\n" - "Called q40_reset : press the RESET button!! \n" + "Called q40_reset : press the RESET button!!\n" "*******************************************\n"); Q40_LED_ON(); while (1) -- cgit v1.2.3-59-g8ed1b From 9881bbb269e8f287d0e55ae3384e48b26f1872f7 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 27 Feb 2010 17:51:33 +0100 Subject: m68k: hp300 - Checkpatch cleanup arch/m68k/hp300/time.h:2: WARNING: space prohibited between function name and open parenthesis '(' Signed-off-by: Andrea Gelmini Signed-off-by: Geert Uytterhoeven --- arch/m68k/hp300/time.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/m68k/hp300/time.h b/arch/m68k/hp300/time.h index f5b3d098b0f5..7b98242960de 100644 --- a/arch/m68k/hp300/time.h +++ b/arch/m68k/hp300/time.h @@ -1,4 +1,2 @@ extern void hp300_sched_init(irq_handler_t vector); -extern unsigned long hp300_gettimeoffset (void); - - +extern unsigned long hp300_gettimeoffset(void); -- cgit v1.2.3-59-g8ed1b From b52dd0077cde89111c00efc73a8db07f50ebb3e8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 28 Feb 2010 13:06:27 +0100 Subject: m68k: Implement generic_find_next_{zero_,}le_bit() linux-next: fs/udf/balloc.c: In function 'udf_bitmap_new_block': fs/udf/balloc.c:274: error: implicit declaration of function 'generic_find_next_le_bit' Convert ext2_find_next_{zero_,}bit() into generic_find_next_{zero_,}le_bit(), and wrap the ext2_find_next_{zero_,}bit() around the latter. Signed-off-by: Geert Uytterhoeven --- arch/m68k/include/asm/bitops_mm.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/m68k/include/asm/bitops_mm.h b/arch/m68k/include/asm/bitops_mm.h index 9bde784e7bad..b4ecdaada520 100644 --- a/arch/m68k/include/asm/bitops_mm.h +++ b/arch/m68k/include/asm/bitops_mm.h @@ -365,6 +365,10 @@ static inline int minix_test_bit(int nr, const void *vaddr) #define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 24, (unsigned long *)(addr)) #define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr)) #define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr)) +#define ext2_find_next_zero_bit(addr, size, offset) \ + generic_find_next_zero_le_bit((unsigned long *)addr, size, offset) +#define ext2_find_next_bit(addr, size, offset) \ + generic_find_next_le_bit((unsigned long *)addr, size, offset) static inline int ext2_test_bit(int nr, const void *vaddr) { @@ -394,10 +398,9 @@ static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size) return (p - addr) * 32 + res; } -static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size, - unsigned offset) +static inline unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, + unsigned long size, unsigned long offset) { - const unsigned long *addr = vaddr; const unsigned long *p = addr + (offset >> 5); int bit = offset & 31UL, res; @@ -437,10 +440,9 @@ static inline int ext2_find_first_bit(const void *vaddr, unsigned size) return (p - addr) * 32 + res; } -static inline int ext2_find_next_bit(const void *vaddr, unsigned size, - unsigned offset) +static inline unsigned long generic_find_next_le_bit(const unsigned long *addr, + unsigned long size, unsigned long offset) { - const unsigned long *addr = vaddr; const unsigned long *p = addr + (offset >> 5); int bit = offset & 31UL, res; -- cgit v1.2.3-59-g8ed1b From adbf6e6952e80ae42a403442dcae21438cae94b3 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 23 Apr 2010 02:06:20 +1000 Subject: m68k: invoke oom-killer from page fault As explained in commit 1c0fe6e3bd, we want to call the architecture independent oom killer when getting an unexplained OOM from handle_mm_fault, rather than simply killing current. Cc: linux-m68k@lists.linux-m68k.org Cc: Geert Uytterhoeven Cc: linux-arch@vger.kernel.org Signed-off-by: Nick Piggin Acked-by: David Rientjes [Geert] Kill 2 introduced compiler warnings Signed-off-by: Geert Uytterhoeven --- arch/m68k/mm/fault.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index d0e35cf99fc6..a96394a0333d 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c @@ -154,7 +154,6 @@ good_area: * the fault. */ - survive: fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); #ifdef DEBUG printk("handle_mm_fault returns %d\n",fault); @@ -180,15 +179,10 @@ good_area: */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { - yield(); - down_read(&mm->mmap_sem); - goto survive; - } - - printk("VM: killing process %s\n", current->comm); - if (user_mode(regs)) - do_group_exit(SIGKILL); + if (!user_mode(regs)) + goto no_context; + pagefault_out_of_memory(); + return 0; no_context: current->thread.signo = SIGBUS; -- cgit v1.2.3-59-g8ed1b From 0d305464aefff342c85b4db8b3d7a4345246e5a1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 5 Apr 2009 12:40:41 +0200 Subject: m68k: amiga - Zorro host bridge platform device conversion Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/Makefile | 2 +- arch/m68k/amiga/platform.c | 58 +++++++++++ drivers/zorro/proc.c | 6 +- drivers/zorro/zorro.c | 243 ++++++++++++++++++++++++--------------------- include/linux/zorro.h | 9 -- 5 files changed, 190 insertions(+), 128 deletions(-) create mode 100644 arch/m68k/amiga/platform.c (limited to 'arch') diff --git a/arch/m68k/amiga/Makefile b/arch/m68k/amiga/Makefile index 6a0d7650f980..11dd30b16b3b 100644 --- a/arch/m68k/amiga/Makefile +++ b/arch/m68k/amiga/Makefile @@ -2,6 +2,6 @@ # Makefile for Linux arch/m68k/amiga source directory # -obj-y := config.o amiints.o cia.o chipram.o amisound.o +obj-y := config.o amiints.o cia.o chipram.o amisound.o platform.o obj-$(CONFIG_AMIGA_PCMCIA) += pcmcia.o diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c new file mode 100644 index 000000000000..33a7669b4415 --- /dev/null +++ b/arch/m68k/amiga/platform.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007-2009 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include + +#include + + +#ifdef CONFIG_ZORRO + +static const struct resource zorro_resources[] __initconst = { + /* Zorro II regions (on Zorro II/III) */ + { + .name = "Zorro II exp", + .start = 0x00e80000, + .end = 0x00efffff, + .flags = IORESOURCE_MEM, + }, { + .name = "Zorro II mem", + .start = 0x00200000, + .end = 0x009fffff, + .flags = IORESOURCE_MEM, + }, + /* Zorro III regions (on Zorro III only) */ + { + .name = "Zorro III exp", + .start = 0xff000000, + .end = 0xffffffff, + .flags = IORESOURCE_MEM, + }, { + .name = "Zorro III cfg", + .start = 0x40000000, + .end = 0x7fffffff, + .flags = IORESOURCE_MEM, + } +}; + + +static int __init amiga_init_bus(void) +{ + if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) + return -ENODEV; + + platform_device_register_simple("amiga-zorro", -1, zorro_resources, + AMIGAHW_PRESENT(ZORRO3) ? 4 : 2); + return 0; +} + +subsys_initcall(amiga_init_bus); + +#endif /* CONFIG_ZORRO */ diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c index d47c47fc048f..3c7046d79654 100644 --- a/drivers/zorro/proc.c +++ b/drivers/zorro/proc.c @@ -97,7 +97,7 @@ static void zorro_seq_stop(struct seq_file *m, void *v) static int zorro_seq_show(struct seq_file *m, void *v) { - u_int slot = *(loff_t *)v; + unsigned int slot = *(loff_t *)v; struct zorro_dev *z = &zorro_autocon[slot]; seq_printf(m, "%02x\t%08x\t%08lx\t%08lx\t%02x\n", slot, z->id, @@ -129,7 +129,7 @@ static const struct file_operations zorro_devices_proc_fops = { static struct proc_dir_entry *proc_bus_zorro_dir; -static int __init zorro_proc_attach_device(u_int slot) +static int __init zorro_proc_attach_device(unsigned int slot) { struct proc_dir_entry *entry; char name[4]; @@ -146,7 +146,7 @@ static int __init zorro_proc_attach_device(u_int slot) static int __init zorro_proc_init(void) { - u_int slot; + unsigned int slot; if (MACH_IS_AMIGA && AMIGAHW_PRESENT(ZORRO)) { proc_bus_zorro_dir = proc_mkdir("bus/zorro", NULL); diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c index d45fb34e2d23..6455f3a244c5 100644 --- a/drivers/zorro/zorro.c +++ b/drivers/zorro/zorro.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -26,24 +28,17 @@ * Zorro Expansion Devices */ -u_int zorro_num_autocon = 0; +unsigned int zorro_num_autocon; struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO]; /* - * Single Zorro bus + * Zorro bus */ -struct zorro_bus zorro_bus = {\ - .resources = { - /* Zorro II regions (on Zorro II/III) */ - { .name = "Zorro II exp", .start = 0x00e80000, .end = 0x00efffff }, - { .name = "Zorro II mem", .start = 0x00200000, .end = 0x009fffff }, - /* Zorro III regions (on Zorro III only) */ - { .name = "Zorro III exp", .start = 0xff000000, .end = 0xffffffff }, - { .name = "Zorro III cfg", .start = 0x40000000, .end = 0x7fffffff } - }, - .name = "Zorro bus" +struct zorro_bus { + struct list_head devices; /* list of devices on this bus */ + struct device dev; }; @@ -53,18 +48,19 @@ struct zorro_bus zorro_bus = {\ struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from) { - struct zorro_dev *z; + struct zorro_dev *z; - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) - return NULL; + if (!zorro_num_autocon) + return NULL; - for (z = from ? from+1 : &zorro_autocon[0]; - z < zorro_autocon+zorro_num_autocon; - z++) - if (id == ZORRO_WILDCARD || id == z->id) - return z; - return NULL; + for (z = from ? from+1 : &zorro_autocon[0]; + z < zorro_autocon+zorro_num_autocon; + z++) + if (id == ZORRO_WILDCARD || id == z->id) + return z; + return NULL; } +EXPORT_SYMBOL(zorro_find_device); /* @@ -83,121 +79,138 @@ struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from) */ DECLARE_BITMAP(zorro_unused_z2ram, 128); +EXPORT_SYMBOL(zorro_unused_z2ram); static void __init mark_region(unsigned long start, unsigned long end, int flag) { - if (flag) - start += Z2RAM_CHUNKMASK; - else - end += Z2RAM_CHUNKMASK; - start &= ~Z2RAM_CHUNKMASK; - end &= ~Z2RAM_CHUNKMASK; - - if (end <= Z2RAM_START || start >= Z2RAM_END) - return; - start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START; - end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START; - while (start < end) { - u32 chunk = start>>Z2RAM_CHUNKSHIFT; if (flag) - set_bit(chunk, zorro_unused_z2ram); + start += Z2RAM_CHUNKMASK; else - clear_bit(chunk, zorro_unused_z2ram); - start += Z2RAM_CHUNKSIZE; - } + end += Z2RAM_CHUNKMASK; + start &= ~Z2RAM_CHUNKMASK; + end &= ~Z2RAM_CHUNKMASK; + + if (end <= Z2RAM_START || start >= Z2RAM_END) + return; + start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START; + end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START; + while (start < end) { + u32 chunk = start>>Z2RAM_CHUNKSHIFT; + if (flag) + set_bit(chunk, zorro_unused_z2ram); + else + clear_bit(chunk, zorro_unused_z2ram); + start += Z2RAM_CHUNKSIZE; + } } -static struct resource __init *zorro_find_parent_resource(struct zorro_dev *z) +static struct resource __init *zorro_find_parent_resource( + struct platform_device *bridge, struct zorro_dev *z) { - int i; + int i; - for (i = 0; i < zorro_bus.num_resources; i++) - if (zorro_resource_start(z) >= zorro_bus.resources[i].start && - zorro_resource_end(z) <= zorro_bus.resources[i].end) - return &zorro_bus.resources[i]; - return &iomem_resource; + for (i = 0; i < bridge->num_resources; i++) { + struct resource *r = &bridge->resource[i]; + if (zorro_resource_start(z) >= r->start && + zorro_resource_end(z) <= r->end) + return r; + } + return &iomem_resource; } - /* - * Initialization - */ -static int __init zorro_init(void) +static int __init amiga_zorro_probe(struct platform_device *pdev) { - struct zorro_dev *z; - unsigned int i; - int error; - - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) - return 0; - - pr_info("Zorro: Probing AutoConfig expansion devices: %d device%s\n", - zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); - - /* Initialize the Zorro bus */ - INIT_LIST_HEAD(&zorro_bus.devices); - dev_set_name(&zorro_bus.dev, "zorro"); - error = device_register(&zorro_bus.dev); - if (error) { - pr_err("Zorro: Error registering zorro_bus\n"); - return error; - } - - /* Request the resources */ - zorro_bus.num_resources = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2; - for (i = 0; i < zorro_bus.num_resources; i++) - request_resource(&iomem_resource, &zorro_bus.resources[i]); - - /* Register all devices */ - for (i = 0; i < zorro_num_autocon; i++) { - z = &zorro_autocon[i]; - z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8); - if (z->id == ZORRO_PROD_GVP_EPC_BASE) { - /* GVP quirk */ - unsigned long magic = zorro_resource_start(z)+0x8000; - z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK; - } - sprintf(z->name, "Zorro device %08x", z->id); - zorro_name_device(z); - z->resource.name = z->name; - if (request_resource(zorro_find_parent_resource(z), &z->resource)) - pr_err("Zorro: Address space collision on device %s %pR\n", - z->name, &z->resource); - dev_set_name(&z->dev, "%02x", i); - z->dev.parent = &zorro_bus.dev; - z->dev.bus = &zorro_bus_type; - error = device_register(&z->dev); + struct zorro_bus *bus; + struct zorro_dev *z; + struct resource *r; + unsigned int i; + int error; + + /* Initialize the Zorro bus */ + bus = kzalloc(sizeof(*bus), GFP_KERNEL); + if (!bus) + return -ENOMEM; + + INIT_LIST_HEAD(&bus->devices); + bus->dev.parent = &pdev->dev; + dev_set_name(&bus->dev, "zorro"); + error = device_register(&bus->dev); if (error) { - pr_err("Zorro: Error registering device %s\n", z->name); - continue; + pr_err("Zorro: Error registering zorro_bus\n"); + kfree(bus); + return error; } - error = zorro_create_sysfs_dev_files(z); - if (error) - dev_err(&z->dev, "Error creating sysfs files\n"); - } - - /* Mark all available Zorro II memory */ - zorro_for_each_dev(z) { - if (z->rom.er_Type & ERTF_MEMLIST) - mark_region(zorro_resource_start(z), zorro_resource_end(z)+1, 1); - } - - /* Unmark all used Zorro II memory */ - for (i = 0; i < m68k_num_memory; i++) - if (m68k_memory[i].addr < 16*1024*1024) - mark_region(m68k_memory[i].addr, - m68k_memory[i].addr+m68k_memory[i].size, 0); - - return 0; + platform_set_drvdata(pdev, bus); + + /* Register all devices */ + pr_info("Zorro: Probing AutoConfig expansion devices: %u device%s\n", + zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); + + for (i = 0; i < zorro_num_autocon; i++) { + z = &zorro_autocon[i]; + z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8); + if (z->id == ZORRO_PROD_GVP_EPC_BASE) { + /* GVP quirk */ + unsigned long magic = zorro_resource_start(z)+0x8000; + z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK; + } + sprintf(z->name, "Zorro device %08x", z->id); + zorro_name_device(z); + z->resource.name = z->name; + r = zorro_find_parent_resource(pdev, z); + error = request_resource(r, &z->resource); + if (error) + dev_err(&bus->dev, + "Address space collision on device %s %pR\n", + z->name, &z->resource); + dev_set_name(&z->dev, "%02x", i); + z->dev.parent = &bus->dev; + z->dev.bus = &zorro_bus_type; + error = device_register(&z->dev); + if (error) { + dev_err(&bus->dev, "Error registering device %s\n", + z->name); + continue; + } + error = zorro_create_sysfs_dev_files(z); + if (error) + dev_err(&z->dev, "Error creating sysfs files\n"); + } + + /* Mark all available Zorro II memory */ + zorro_for_each_dev(z) { + if (z->rom.er_Type & ERTF_MEMLIST) + mark_region(zorro_resource_start(z), + zorro_resource_end(z)+1, 1); + } + + /* Unmark all used Zorro II memory */ + for (i = 0; i < m68k_num_memory; i++) + if (m68k_memory[i].addr < 16*1024*1024) + mark_region(m68k_memory[i].addr, + m68k_memory[i].addr+m68k_memory[i].size, + 0); + + return 0; } -subsys_initcall(zorro_init); +static struct platform_driver amiga_zorro_driver = { + .driver = { + .name = "amiga-zorro", + .owner = THIS_MODULE, + }, +}; -EXPORT_SYMBOL(zorro_find_device); -EXPORT_SYMBOL(zorro_unused_z2ram); +static int __init amiga_zorro_init(void) +{ + return platform_driver_probe(&amiga_zorro_driver, amiga_zorro_probe); +} + +module_init(amiga_zorro_init); MODULE_LICENSE("GPL"); diff --git a/include/linux/zorro.h b/include/linux/zorro.h index 908db1b36d6c..7bf9db525e9e 100644 --- a/include/linux/zorro.h +++ b/include/linux/zorro.h @@ -141,15 +141,6 @@ struct zorro_dev { * Zorro bus */ -struct zorro_bus { - struct list_head devices; /* list of devices on this bus */ - unsigned int num_resources; /* number of resources */ - struct resource resources[4]; /* address space routed to this bus */ - struct device dev; - char name[10]; -}; - -extern struct zorro_bus zorro_bus; /* single Zorro bus */ extern struct bus_type zorro_bus_type; -- cgit v1.2.3-59-g8ed1b From fa6688e1c7e7341fb7d1ca5878a3641762e60dec Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 5 Apr 2009 12:45:56 +0200 Subject: m68k: amiga - Frame buffer platform device conversion Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/platform.c | 15 ++++++++++++++ drivers/video/amifb.c | 49 +++++++++++++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 33a7669b4415..7fa929cf9a3a 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -56,3 +56,18 @@ static int __init amiga_init_bus(void) subsys_initcall(amiga_init_bus); #endif /* CONFIG_ZORRO */ + + +static int __init amiga_init_devices(void) +{ + if (!MACH_IS_AMIGA) + return -ENODEV; + + /* video hardware */ + if (AMIGAHW_PRESENT(AMI_VIDEO)) + platform_device_register_simple("amiga-video", -1, NULL, 0); + + return 0; +} + +device_initcall(amiga_init_devices); diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c index dca48df98444..e5d6b56d4447 100644 --- a/drivers/video/amifb.c +++ b/drivers/video/amifb.c @@ -50,8 +50,9 @@ #include #include #include - +#include #include + #include #include #include @@ -1135,7 +1136,7 @@ static int amifb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg * Interface to the low level console driver */ -static void amifb_deinit(void); +static void amifb_deinit(struct platform_device *pdev); /* * Internal routines @@ -2246,7 +2247,7 @@ static inline void chipfree(void) * Initialisation */ -static int __init amifb_init(void) +static int __init amifb_probe(struct platform_device *pdev) { int tag, i, err = 0; u_long chipptr; @@ -2261,16 +2262,6 @@ static int __init amifb_init(void) } amifb_setup(option); #endif - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_VIDEO)) - return -ENODEV; - - /* - * We request all registers starting from bplpt[0] - */ - if (!request_mem_region(CUSTOM_PHYSADDR+0xe0, 0x120, - "amifb [Denise/Lisa]")) - return -EBUSY; - custom.dmacon = DMAF_ALL | DMAF_MASTER; switch (amiga_chipset) { @@ -2377,6 +2368,7 @@ default_chipset: fb_info.fbops = &amifb_ops; fb_info.par = ¤tpar; fb_info.flags = FBINFO_DEFAULT; + fb_info.device = &pdev->dev; if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, ami_modedb, NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) { @@ -2451,18 +2443,18 @@ default_chipset: return 0; amifb_error: - amifb_deinit(); + amifb_deinit(pdev); return err; } -static void amifb_deinit(void) +static void amifb_deinit(struct platform_device *pdev) { if (fb_info.cmap.len) fb_dealloc_cmap(&fb_info.cmap); + fb_dealloc_cmap(&fb_info.cmap); chipfree(); if (videomemory) iounmap((void*)videomemory); - release_mem_region(CUSTOM_PHYSADDR+0xe0, 0x120); custom.dmacon = DMAF_ALL | DMAF_MASTER; } @@ -3794,14 +3786,35 @@ static void ami_rebuild_copper(void) } } -static void __exit amifb_exit(void) +static int __exit amifb_remove(struct platform_device *pdev) { unregister_framebuffer(&fb_info); - amifb_deinit(); + amifb_deinit(pdev); amifb_video_off(); + return 0; +} + +static struct platform_driver amifb_driver = { + .remove = __exit_p(amifb_remove), + .driver = { + .name = "amiga-video", + .owner = THIS_MODULE, + }, +}; + +static int __init amifb_init(void) +{ + return platform_driver_probe(&amifb_driver, amifb_probe); } module_init(amifb_init); + +static void __exit amifb_exit(void) +{ + platform_driver_unregister(&amifb_driver); +} + module_exit(amifb_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:amiga-video"); -- cgit v1.2.3-59-g8ed1b From ff2db7c5ab78817eb3c5d15dd87f18e9be726f1a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 5 Apr 2009 12:59:54 +0200 Subject: m68k: amiga - Sound platform device conversion Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/platform.c | 5 ++++ sound/oss/dmasound/dmasound_paula.c | 51 ++++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 7fa929cf9a3a..2e308e7a0949 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -67,6 +67,11 @@ static int __init amiga_init_devices(void) if (AMIGAHW_PRESENT(AMI_VIDEO)) platform_device_register_simple("amiga-video", -1, NULL, 0); + + /* sound hardware */ + if (AMIGAHW_PRESENT(AMI_AUDIO)) + platform_device_register_simple("amiga-audio", -1, NULL, 0); + return 0; } diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c index bb14e4c67e89..87910e992133 100644 --- a/sound/oss/dmasound/dmasound_paula.c +++ b/sound/oss/dmasound/dmasound_paula.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -710,31 +711,41 @@ static MACHINE machAmiga = { /*** Config & Setup **********************************************************/ -static int __init dmasound_paula_init(void) +static int __init amiga_audio_probe(struct platform_device *pdev) { - int err; - - if (MACH_IS_AMIGA && AMIGAHW_PRESENT(AMI_AUDIO)) { - if (!request_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40, - "dmasound [Paula]")) - return -EBUSY; - dmasound.mach = machAmiga; - dmasound.mach.default_hard = def_hard ; - dmasound.mach.default_soft = def_soft ; - err = dmasound_init(); - if (err) - release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40); - return err; - } else - return -ENODEV; + dmasound.mach = machAmiga; + dmasound.mach.default_hard = def_hard ; + dmasound.mach.default_soft = def_soft ; + return dmasound_init(); } -static void __exit dmasound_paula_cleanup(void) +static int __exit amiga_audio_remove(struct platform_device *pdev) { dmasound_deinit(); - release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40); + return 0; +} + +static struct platform_driver amiga_audio_driver = { + .remove = __exit_p(amiga_audio_remove), + .driver = { + .name = "amiga-audio", + .owner = THIS_MODULE, + }, +}; + +static int __init amiga_audio_init(void) +{ + return platform_driver_probe(&amiga_audio_driver, amiga_audio_probe); } -module_init(dmasound_paula_init); -module_exit(dmasound_paula_cleanup); +module_init(amiga_audio_init); + +static void __exit amiga_audio_exit(void) +{ + platform_driver_unregister(&amiga_audio_driver); +} + +module_exit(amiga_audio_exit); + MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:amiga-audio"); -- cgit v1.2.3-59-g8ed1b From 92183b346f02773dae09182c65f16b013f295d80 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 5 Apr 2009 13:02:13 +0200 Subject: m68k: amiga - Floppy platform device conversion Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/platform.c | 5 +++++ drivers/block/amiflop.c | 47 +++++++++++++++++++++------------------------- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 2e308e7a0949..38f18bf14737 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -72,6 +72,11 @@ static int __init amiga_init_devices(void) if (AMIGAHW_PRESENT(AMI_AUDIO)) platform_device_register_simple("amiga-audio", -1, NULL, 0); + + /* storage interfaces */ + if (AMIGAHW_PRESENT(AMI_FLOPPY)) + platform_device_register_simple("amiga-floppy", -1, NULL, 0); + return 0; } diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 0182a22c423a..832798aa14f6 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -1696,34 +1697,18 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) return get_disk(unit[drive].gendisk); } -static int __init amiga_floppy_init(void) +static int __init amiga_floppy_probe(struct platform_device *pdev) { int i, ret; - if (!MACH_IS_AMIGA) - return -ENODEV; - - if (!AMIGAHW_PRESENT(AMI_FLOPPY)) - return -ENODEV; - if (register_blkdev(FLOPPY_MAJOR,"fd")) return -EBUSY; - /* - * We request DSKPTR, DSKLEN and DSKDATA only, because the other - * floppy registers are too spreaded over the custom register space - */ - ret = -EBUSY; - if (!request_mem_region(CUSTOM_PHYSADDR+0x20, 8, "amiflop [Paula]")) { - printk("fd: cannot get floppy registers\n"); - goto out_blkdev; - } - ret = -ENOMEM; if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) == NULL) { printk("fd: cannot get chip mem buffer\n"); - goto out_memregion; + goto out_blkdev; } ret = -EBUSY; @@ -1792,18 +1777,13 @@ out_irq2: free_irq(IRQ_AMIGA_DSKBLK, NULL); out_irq: amiga_chip_free(raw_buf); -out_memregion: - release_mem_region(CUSTOM_PHYSADDR+0x20, 8); out_blkdev: unregister_blkdev(FLOPPY_MAJOR,"fd"); return ret; } -module_init(amiga_floppy_init); -#ifdef MODULE - #if 0 /* not safe to unload */ -void cleanup_module(void) +static int __exit amiga_floppy_remove(struct platform_device *pdev) { int i; @@ -1820,12 +1800,25 @@ void cleanup_module(void) custom.dmacon = DMAF_DISK; /* disable DMA */ amiga_chip_free(raw_buf); blk_cleanup_queue(floppy_queue); - release_mem_region(CUSTOM_PHYSADDR+0x20, 8); unregister_blkdev(FLOPPY_MAJOR, "fd"); } #endif -#else +static struct platform_driver amiga_floppy_driver = { + .driver = { + .name = "amiga-floppy", + .owner = THIS_MODULE, + }, +}; + +static int __init amiga_floppy_init(void) +{ + return platform_driver_probe(&amiga_floppy_driver, amiga_floppy_probe); +} + +module_init(amiga_floppy_init); + +#ifndef MODULE static int __init amiga_floppy_setup (char *str) { int n; @@ -1840,3 +1833,5 @@ static int __init amiga_floppy_setup (char *str) __setup("floppy=", amiga_floppy_setup); #endif + +MODULE_ALIAS("platform:amiga-floppy"); -- cgit v1.2.3-59-g8ed1b From c59bd5688299cddb71183e156e7a3c1409b90df2 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 17 May 2010 15:13:23 -0700 Subject: x86, hweight: Use a 32-bit popcnt for __arch_hweight32() Use a 32-bit popcnt instruction for __arch_hweight32(), even on x86-64. Even though the input register will *usually* be zero-extended due to the standard operation of the hardware, it isn't necessarily so if the input value was the result of truncating a 64-bit operation. Note: the POPCNT32 variant used on x86-64 has a technically unnecessary REX prefix to make it five bytes long, the same as a CALL instruction, therefore avoiding an unnecessary NOP. Reported-by: Linus Torvalds Signed-off-by: H. Peter Anvin Cc: Borislav Petkov LKML-Reference: --- arch/x86/include/asm/arch_hweight.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h index d1fc3c219ae6..9686c3d9ff73 100644 --- a/arch/x86/include/asm/arch_hweight.h +++ b/arch/x86/include/asm/arch_hweight.h @@ -2,13 +2,15 @@ #define _ASM_X86_HWEIGHT_H #ifdef CONFIG_64BIT +/* popcnt %edi, %eax -- redundant REX prefix for alignment */ +#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7" /* popcnt %rdi, %rax */ -#define POPCNT ".byte 0xf3,0x48,0x0f,0xb8,0xc7" +#define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7" #define REG_IN "D" #define REG_OUT "a" #else /* popcnt %eax, %eax */ -#define POPCNT ".byte 0xf3,0x0f,0xb8,0xc0" +#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc0" #define REG_IN "a" #define REG_OUT "a" #endif @@ -23,7 +25,7 @@ static inline unsigned int __arch_hweight32(unsigned int w) { unsigned int res = 0; - asm (ALTERNATIVE("call __sw_hweight32", POPCNT, X86_FEATURE_POPCNT) + asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT) : "="REG_OUT (res) : REG_IN (w)); @@ -48,7 +50,7 @@ static inline unsigned long __arch_hweight64(__u64 w) return __arch_hweight32((u32)w) + __arch_hweight32((u32)(w >> 32)); #else - asm (ALTERNATIVE("call __sw_hweight64", POPCNT, X86_FEATURE_POPCNT) + asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT) : "="REG_OUT (res) : REG_IN (w)); #endif /* CONFIG_X86_32 */ -- cgit v1.2.3-59-g8ed1b From 26be1b7b317f1d6e9226ba3f450476b0a6d423a3 Mon Sep 17 00:00:00 2001 From: Mike Solovyev Date: Wed, 12 May 2010 15:38:00 +0400 Subject: ARM: h1940: framebuffer configuration fix Seems like a typo, wrong setup leads to broken image on ipaq screen. Signed-off-by: Mike Solovyev Signed-off-by: Arnaud Patard Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-h1940.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index b212561d2c57..03028b98f362 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -162,8 +162,8 @@ static struct s3c2410fb_display h1940_lcd __initdata = { .xres = 240, .yres = 320, .bpp = 16, - .left_margin = 20, - .right_margin = 8, + .left_margin = 8, + .right_margin = 20, .hsync_len = 4, .upper_margin = 8, .lower_margin = 7, -- cgit v1.2.3-59-g8ed1b From 4f7cdc38c000deba82479205f4c99f4c1e7c6d1f Mon Sep 17 00:00:00 2001 From: Naveen Krishna Date: Thu, 13 May 2010 22:06:36 +0900 Subject: ARM: SAMSUNG: Moving ADC device definition to plat-samsung. This patch moves ADC device definition to plat-samsung. Because that is generic to the S3C64XX and S5P Series SoCs. Signed-off-by: Naveen Krishna Ch Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/Kconfig | 1 + arch/arm/mach-s3c64xx/Makefile | 1 - arch/arm/mach-s3c64xx/dev-adc.c | 46 -------------------------------- arch/arm/mach-s3c64xx/include/mach/map.h | 1 + arch/arm/mach-s3c64xx/s3c6410.c | 2 ++ arch/arm/plat-samsung/Kconfig | 5 ++++ arch/arm/plat-samsung/Makefile | 1 + arch/arm/plat-samsung/dev-adc.c | 46 ++++++++++++++++++++++++++++++++ 8 files changed, 56 insertions(+), 47 deletions(-) delete mode 100644 arch/arm/mach-s3c64xx/dev-adc.c create mode 100644 arch/arm/plat-samsung/dev-adc.c (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 959df3840de5..69e9fbfea917 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -85,6 +85,7 @@ config MACH_ANW6410 config MACH_SMDK6410 bool "SMDK6410" select CPU_S3C6410 + select SAMSUNG_DEV_ADC select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_I2C1 diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 3758e15086be..da662783493a 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -58,5 +58,4 @@ obj-$(CONFIG_MACH_HMT) += mach-hmt.o obj-y += dev-uart.o obj-y += dev-rtc.o obj-y += dev-audio.o -obj-$(CONFIG_S3C_ADC) += dev-adc.o obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o diff --git a/arch/arm/mach-s3c64xx/dev-adc.c b/arch/arm/mach-s3c64xx/dev-adc.c deleted file mode 100644 index fafef9b6bcfa..000000000000 --- a/arch/arm/mach-s3c64xx/dev-adc.c +++ /dev/null @@ -1,46 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/dev-adc.c - * - * Copyright 2010 Maurus Cuelenaere - * - * S3C64xx series device definition for ADC device - * - * 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 -#include -#include - -#include -#include - -#include -#include -#include - -static struct resource s3c_adc_resource[] = { - [0] = { - .start = S3C64XX_PA_ADC, - .end = S3C64XX_PA_ADC + SZ_256 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TC, - .end = IRQ_TC, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = IRQ_ADC, - .end = IRQ_ADC, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_adc = { - .name = "s3c64xx-adc", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_adc_resource), - .resource = s3c_adc_resource, -}; diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h index 801c1c0f3a95..869c8e025127 100644 --- a/arch/arm/mach-s3c64xx/include/mach/map.h +++ b/arch/arm/mach-s3c64xx/include/mach/map.h @@ -103,5 +103,6 @@ #define S3C_PA_USBHOST S3C64XX_PA_USBHOST #define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG #define S3C_VA_USB_HSPHY S3C64XX_VA_USB_HSPHY +#define SAMSUNG_PA_ADC S3C64XX_PA_ADC #endif /* __ASM_ARCH_6400_MAP_H */ diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c index 59635d19466a..3ab695c691ee 100644 --- a/arch/arm/mach-s3c64xx/s3c6410.c +++ b/arch/arm/mach-s3c64xx/s3c6410.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -52,6 +53,7 @@ void __init s3c6410_map_io(void) s3c_i2c0_setname("s3c2440-i2c"); s3c_i2c1_setname("s3c2440-i2c"); + s3c_device_adc.name = "s3c64xx-adc"; s3c_device_nand.name = "s3c6400-nand"; } diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index d552c65fa1b0..641649fde388 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -185,6 +185,11 @@ config S3C_DEV_NAND help Compile in platform device definition for NAND controller +config SAMSUNG_DEV_ADC + bool + help + Compile in platform device definition for ADC controller + config S3C64XX_DEV_SPI bool help diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 22c89d08f6e5..3cf30a4b0883 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -40,6 +40,7 @@ obj-y += dev-uart.o obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o +obj-$(CONFIG_SAMSUNG_DEV_ADC) += dev-adc.o # DMA support diff --git a/arch/arm/plat-samsung/dev-adc.c b/arch/arm/plat-samsung/dev-adc.c new file mode 100644 index 000000000000..9d903d4095ed --- /dev/null +++ b/arch/arm/plat-samsung/dev-adc.c @@ -0,0 +1,46 @@ +/* linux/arch/arm/plat-samsung/dev-adc.c + * + * Copyright 2010 Maurus Cuelenaere + * + * S3C64xx series device definition for ADC device + * + * 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 +#include +#include + +#include +#include + +#include +#include +#include + +static struct resource s3c_adc_resource[] = { + [0] = { + .start = SAMSUNG_PA_ADC, + .end = SAMSUNG_PA_ADC + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TC, + .end = IRQ_TC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_ADC, + .end = IRQ_ADC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_adc = { + .name = "samsung-adc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_adc_resource), + .resource = s3c_adc_resource, +}; -- cgit v1.2.3-59-g8ed1b From 56e6943b902562e09d3e74126d8d8256b5ea17fb Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Mon, 17 May 2010 22:39:48 -0700 Subject: can: sja1000 platform data fixes The member "clock" of struct "sja1000_platform_data" is documented as "CAN bus oscillator frequency in Hz" but it's actually used as the CAN clock frequency, which is half of it. To avoid further confusion, this patch fixes it by renaming the member to "osc_freq". That way, also non mainline users will notice the change. The platform code for the relevant boards is updated accordingly. Furthermore, pre-defined values are now used for the members "ocr" and "cdr". Signed-off-by: Wolfgang Grandegger Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- arch/arm/mach-mx2/pcm970-baseboard.c | 6 +++--- arch/arm/mach-mx3/mach-pcm037.c | 6 +++--- drivers/net/can/sja1000/sja1000_platform.c | 3 ++- include/linux/can/platform/sja1000.h | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c index 4aafd5b8b85b..f490a406d57e 100644 --- a/arch/arm/mach-mx2/pcm970-baseboard.c +++ b/arch/arm/mach-mx2/pcm970-baseboard.c @@ -201,9 +201,9 @@ static struct resource pcm970_sja1000_resources[] = { }; struct sja1000_platform_data pcm970_sja1000_platform_data = { - .clock = 16000000 / 2, - .ocr = 0x40 | 0x18, - .cdr = 0x40, + .osc_freq = 16000000, + .ocr = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL, + .cdr = CDR_CBP, }; static struct platform_device pcm970_sja1000 = { diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c index 2df1ec55a97e..78ecd751549b 100644 --- a/arch/arm/mach-mx3/mach-pcm037.c +++ b/arch/arm/mach-mx3/mach-pcm037.c @@ -530,9 +530,9 @@ static struct resource pcm970_sja1000_resources[] = { }; struct sja1000_platform_data pcm970_sja1000_platform_data = { - .clock = 16000000 / 2, - .ocr = 0x40 | 0x18, - .cdr = 0x40, + .osc_freq = 16000000, + .ocr = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL, + .cdr = CDR_CBP, }; static struct platform_device pcm970_sja1000 = { diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c index b65cabb361ab..d9fadc489b32 100644 --- a/drivers/net/can/sja1000/sja1000_platform.c +++ b/drivers/net/can/sja1000/sja1000_platform.c @@ -111,7 +111,8 @@ static int sp_probe(struct platform_device *pdev) dev->irq = res_irq->start; priv->irq_flags = res_irq->flags & (IRQF_TRIGGER_MASK | IRQF_SHARED); priv->reg_base = addr; - priv->can.clock.freq = pdata->clock; + /* The CAN clock frequency is half the oscillator clock frequency */ + priv->can.clock.freq = pdata->osc_freq / 2; priv->ocr = pdata->ocr; priv->cdr = pdata->cdr; diff --git a/include/linux/can/platform/sja1000.h b/include/linux/can/platform/sja1000.h index 01ee2aeb048d..96f8fcc78d78 100644 --- a/include/linux/can/platform/sja1000.h +++ b/include/linux/can/platform/sja1000.h @@ -26,7 +26,7 @@ #define OCR_TX_SHIFT 2 struct sja1000_platform_data { - u32 clock; /* CAN bus oscillator frequency in Hz */ + u32 osc_freq; /* CAN bus oscillator frequency in Hz */ u8 ocr; /* output control register */ u8 cdr; /* clock divider register */ -- cgit v1.2.3-59-g8ed1b From c77b29db74a0ea4fdce0564a63b8876798625d64 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 18 May 2010 14:53:23 +0900 Subject: sh: fix up CONFIG_KEXEC=n build. The reserve_crashkernel() definition is in asm/kexec.h which is only dragged in via linux/kexec.h if CONFIG_KEXEC is set. Just switch over to asm/kexec.h unconditionally to fix up the build. Signed-off-by: Paul Mundt --- arch/sh/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 7f3cb5254abb..46f84de62469 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -17,10 +17,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From dd2fdd264eaa616fab4cf80e89f83f4a2fc26288 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 18 May 2010 15:23:48 +0900 Subject: sh64: provide a stub per_cpu_trap_init() definition. This is needed to fix up the build at the moment. Gradually this will be reworked to follow the 32-bit initialization path and deal with delayed VBR initialization. Signed-off-by: Paul Mundt --- arch/sh/kernel/traps_64.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index e3f92eb05ffd..e67e140bf1f6 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -944,3 +944,8 @@ asmlinkage void do_debug_interrupt(unsigned long code, struct pt_regs *regs) /* Clear all DEBUGINT causes */ poke_real_address_q(DM_EXP_CAUSE_PHY, 0x0); } + +void __cpuinit per_cpu_trap_init(void) +{ + /* Nothing to do for now, VBR initialization later. */ +} -- cgit v1.2.3-59-g8ed1b From 717e7c2672e37253a4d3aa70e4716b5b0a658761 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 18 May 2010 08:17:56 +0100 Subject: ARM: remove 'select GENERIC_TIME' GENERIC_TIME is now enabled by default, so 'select GENERIC_TIME' is redundant. Remove them. Signed-off-by: Russell King --- arch/arm/Kconfig | 28 ---------------------------- arch/arm/mach-at91/Kconfig | 10 ---------- arch/arm/mach-shmobile/Kconfig | 3 --- 3 files changed, 41 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 492f81344900..a07b6c47a6b8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -225,7 +225,6 @@ config ARCH_INTEGRATOR select ARCH_HAS_CPUFREQ select COMMON_CLKDEV select ICST - select GENERIC_TIME select GENERIC_CLOCKEVENTS select PLAT_VERSATILE help @@ -236,7 +235,6 @@ config ARCH_REALVIEW select ARM_AMBA select COMMON_CLKDEV select ICST - select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB select PLAT_VERSATILE @@ -251,7 +249,6 @@ config ARCH_VERSATILE select ARM_VIC select COMMON_CLKDEV select ICST - select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB select PLAT_VERSATILE @@ -266,7 +263,6 @@ config ARCH_VEXPRESS select ARM_TIMER_SP804 select COMMON_CLKDEV select GENERIC_CLOCKEVENTS - select GENERIC_TIME select HAVE_CLK select ICST select PLAT_VERSATILE @@ -288,7 +284,6 @@ config ARCH_BCMRING select CPU_V6 select ARM_AMBA select COMMON_CLKDEV - select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB help @@ -304,7 +299,6 @@ config ARCH_CLPS711X config ARCH_CNS3XXX bool "Cavium Networks CNS3XXX family" select CPU_V6 - select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARM_GIC help @@ -353,7 +347,6 @@ config ARCH_FOOTBRIDGE config ARCH_MXC bool "Freescale MXC/iMX-based" - select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB select COMMON_CLKDEV @@ -365,7 +358,6 @@ config ARCH_STMP3XXX select CPU_ARM926T select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB - select GENERIC_TIME select GENERIC_CLOCKEVENTS select USB_ARCH_HAS_EHCI help @@ -376,7 +368,6 @@ config ARCH_NETX select CPU_ARM926T select ARM_VIC select GENERIC_CLOCKEVENTS - select GENERIC_TIME help This enables support for systems based on the Hilscher NetX Soc @@ -443,7 +434,6 @@ config ARCH_IXP4XX depends on MMU select CPU_XSCALE select GENERIC_GPIO - select GENERIC_TIME select GENERIC_CLOCKEVENTS select DMABOUNCE if PCI help @@ -468,7 +458,6 @@ config ARCH_DOVE bool "Marvell Dove" select PCI select ARCH_REQUIRE_GPIOLIB - select GENERIC_TIME select GENERIC_CLOCKEVENTS select PLAT_ORION help @@ -479,7 +468,6 @@ config ARCH_KIRKWOOD select CPU_FEROCEON select PCI select ARCH_REQUIRE_GPIOLIB - select GENERIC_TIME select GENERIC_CLOCKEVENTS select PLAT_ORION help @@ -489,7 +477,6 @@ config ARCH_KIRKWOOD config ARCH_LOKI bool "Marvell Loki (88RC8480)" select CPU_FEROCEON - select GENERIC_TIME select GENERIC_CLOCKEVENTS select PLAT_ORION help @@ -500,7 +487,6 @@ config ARCH_MV78XX0 select CPU_FEROCEON select PCI select ARCH_REQUIRE_GPIOLIB - select GENERIC_TIME select GENERIC_CLOCKEVENTS select PLAT_ORION help @@ -513,7 +499,6 @@ config ARCH_ORION5X select CPU_FEROCEON select PCI select ARCH_REQUIRE_GPIOLIB - select GENERIC_TIME select GENERIC_CLOCKEVENTS select PLAT_ORION help @@ -526,7 +511,6 @@ config ARCH_MMP depends on MMU select ARCH_REQUIRE_GPIOLIB select COMMON_CLKDEV - select GENERIC_TIME select GENERIC_CLOCKEVENTS select TICK_ONESHOT select PLAT_PXA @@ -546,7 +530,6 @@ config ARCH_NS9XXX bool "NetSilicon NS9xxx" select CPU_ARM926T select GENERIC_GPIO - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_CLK help @@ -560,7 +543,6 @@ config ARCH_W90X900 select CPU_ARM926T select ARCH_REQUIRE_GPIOLIB select COMMON_CLKDEV - select GENERIC_TIME select GENERIC_CLOCKEVENTS help Support for Nuvoton (Winbond logic dept.) ARM9 processor, @@ -594,7 +576,6 @@ config ARCH_PXA select ARCH_HAS_CPUFREQ select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB - select GENERIC_TIME select GENERIC_CLOCKEVENTS select TICK_ONESHOT select PLAT_PXA @@ -604,7 +585,6 @@ config ARCH_PXA config ARCH_MSM bool "Qualcomm MSM" select HAVE_CLK - select GENERIC_TIME select GENERIC_CLOCKEVENTS help Support for Qualcomm MSM/QSD based systems. This runs on the @@ -641,7 +621,6 @@ config ARCH_SA1100 select ARCH_MTD_XIP select ARCH_HAS_CPUFREQ select CPU_FREQ - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_CLK select TICK_ONESHOT @@ -752,7 +731,6 @@ config ARCH_U300 select HAVE_TCM select ARM_AMBA select ARM_VIC - select GENERIC_TIME select GENERIC_CLOCKEVENTS select COMMON_CLKDEV select GENERIC_GPIO @@ -763,7 +741,6 @@ config ARCH_U8500 bool "ST-Ericsson U8500 Series" select CPU_V7 select ARM_AMBA - select GENERIC_TIME select GENERIC_CLOCKEVENTS select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB @@ -776,7 +753,6 @@ config ARCH_NOMADIK select ARM_VIC select CPU_ARM926T select COMMON_CLKDEV - select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB help @@ -785,7 +761,6 @@ config ARCH_NOMADIK config ARCH_DAVINCI bool "TI DaVinci" select CPU_ARM926T - select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB select ZONE_DMA @@ -801,7 +776,6 @@ config ARCH_OMAP select HAVE_CLK select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_CPUFREQ - select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_HAS_HOLES_MEMORYMODEL help @@ -813,7 +787,6 @@ config PLAT_SPEAR select ARCH_REQUIRE_GPIOLIB select COMMON_CLKDEV select GENERIC_CLOCKEVENTS - select GENERIC_TIME select HAVE_CLK help Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx). @@ -951,7 +924,6 @@ config ARCH_ACORN config PLAT_IOP bool select GENERIC_CLOCKEVENTS - select GENERIC_TIME config PLAT_ORION bool diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 103976411a67..841eaf8f27e2 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -23,14 +23,12 @@ choice config ARCH_AT91RM9200 bool "AT91RM9200" select CPU_ARM920T - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_AT91_USART3 config ARCH_AT91SAM9260 bool "AT91SAM9260 or AT91SAM9XE" select CPU_ARM926T - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_AT91_USART3 select HAVE_AT91_USART4 @@ -39,28 +37,24 @@ config ARCH_AT91SAM9260 config ARCH_AT91SAM9261 bool "AT91SAM9261" select CPU_ARM926T - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL config ARCH_AT91SAM9G10 bool "AT91SAM9G10" select CPU_ARM926T - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL config ARCH_AT91SAM9263 bool "AT91SAM9263" select CPU_ARM926T - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL config ARCH_AT91SAM9RL bool "AT91SAM9RL" select CPU_ARM926T - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_AT91_USART3 select HAVE_FB_ATMEL @@ -68,7 +62,6 @@ config ARCH_AT91SAM9RL config ARCH_AT91SAM9G20 bool "AT91SAM9G20" select CPU_ARM926T - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_AT91_USART3 select HAVE_AT91_USART4 @@ -77,7 +70,6 @@ config ARCH_AT91SAM9G20 config ARCH_AT91SAM9G45 bool "AT91SAM9G45" select CPU_ARM926T - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_AT91_USART3 select HAVE_FB_ATMEL @@ -85,14 +77,12 @@ config ARCH_AT91SAM9G45 config ARCH_AT91CAP9 bool "AT91CAP9" select CPU_ARM926T - select GENERIC_TIME select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL config ARCH_AT572D940HF bool "AT572D940HF" select CPU_ARM926T - select GENERIC_TIME select GENERIC_CLOCKEVENTS config ARCH_AT91X40 diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index aeceb9b92aeb..f2b88c5fe142 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -7,7 +7,6 @@ config ARCH_SH7367 select CPU_V6 select HAVE_CLK select COMMON_CLKDEV - select GENERIC_TIME select GENERIC_CLOCKEVENTS config ARCH_SH7377 @@ -15,7 +14,6 @@ config ARCH_SH7377 select CPU_V7 select HAVE_CLK select COMMON_CLKDEV - select GENERIC_TIME select GENERIC_CLOCKEVENTS config ARCH_SH7372 @@ -23,7 +21,6 @@ config ARCH_SH7372 select CPU_V7 select HAVE_CLK select COMMON_CLKDEV - select GENERIC_TIME select GENERIC_CLOCKEVENTS comment "SH-Mobile Board Type" -- cgit v1.2.3-59-g8ed1b From adc0950c08e1f433f6933759f4facf9b2cf8d29d Mon Sep 17 00:00:00 2001 From: Atul Dahiya Date: Tue, 18 May 2010 14:58:56 +0900 Subject: ARM: SAMSUNG: Move RTC device definitions in plat-samsung This patch moves RTC device definitions from mach-s3c64xx to plat-samsung, to enable the other SoCs to use same device definition. Signed-off-by: Atul Dahiya Signed-off-by: Sangbeom Kim Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/Makefile | 1 - arch/arm/mach-s3c64xx/dev-rtc.c | 43 -------------------------------- arch/arm/mach-s3c64xx/include/mach/map.h | 1 + arch/arm/plat-samsung/Kconfig | 5 ++++ arch/arm/plat-samsung/Makefile | 1 + arch/arm/plat-samsung/dev-rtc.c | 43 ++++++++++++++++++++++++++++++++ 6 files changed, 50 insertions(+), 44 deletions(-) delete mode 100644 arch/arm/mach-s3c64xx/dev-rtc.c create mode 100644 arch/arm/plat-samsung/dev-rtc.c (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 3758e15086be..56ef97286b31 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -56,7 +56,6 @@ obj-$(CONFIG_MACH_HMT) += mach-hmt.o # device support obj-y += dev-uart.o -obj-y += dev-rtc.o obj-y += dev-audio.o obj-$(CONFIG_S3C_ADC) += dev-adc.o obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o diff --git a/arch/arm/mach-s3c64xx/dev-rtc.c b/arch/arm/mach-s3c64xx/dev-rtc.c deleted file mode 100644 index b9e7a05f0129..000000000000 --- a/arch/arm/mach-s3c64xx/dev-rtc.c +++ /dev/null @@ -1,43 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/dev-rtc.c - * - * Copyright 2009 by Maurus Cuelenaere - * - * 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 -#include -#include - -#include -#include - -#include - -static struct resource s3c_rtc_resource[] = { - [0] = { - .start = S3C64XX_PA_RTC, - .end = S3C64XX_PA_RTC + 0xff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_RTC_ALARM, - .end = IRQ_RTC_ALARM, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = IRQ_RTC_TIC, - .end = IRQ_RTC_TIC, - .flags = IORESOURCE_IRQ - } -}; - -struct platform_device s3c_device_rtc = { - .name = "s3c64xx-rtc", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_rtc_resource), - .resource = s3c_rtc_resource, -}; -EXPORT_SYMBOL(s3c_device_rtc); diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h index 801c1c0f3a95..cce28a968164 100644 --- a/arch/arm/mach-s3c64xx/include/mach/map.h +++ b/arch/arm/mach-s3c64xx/include/mach/map.h @@ -103,5 +103,6 @@ #define S3C_PA_USBHOST S3C64XX_PA_USBHOST #define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG #define S3C_VA_USB_HSPHY S3C64XX_VA_USB_HSPHY +#define S3C_PA_RTC S3C64XX_PA_RTC #endif /* __ASM_ARCH_6400_MAP_H */ diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index d552c65fa1b0..f4a017df29a1 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -185,6 +185,11 @@ config S3C_DEV_NAND help Compile in platform device definition for NAND controller +config S3C_DEV_RTC + bool + help + Complie in platform device definition for RTC + config S3C64XX_DEV_SPI bool help diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 22c89d08f6e5..4326c1be4936 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -40,6 +40,7 @@ obj-y += dev-uart.o obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o +obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o # DMA support diff --git a/arch/arm/plat-samsung/dev-rtc.c b/arch/arm/plat-samsung/dev-rtc.c new file mode 100644 index 000000000000..bf4e2267333c --- /dev/null +++ b/arch/arm/plat-samsung/dev-rtc.c @@ -0,0 +1,43 @@ +/* linux/arch/arm/plat-samsung/dev-rtc.c + * + * Copyright 2009 by Maurus Cuelenaere + * + * 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 +#include +#include + +#include +#include + +#include + +static struct resource s3c_rtc_resource[] = { + [0] = { + .start = S3C_PA_RTC, + .end = S3C_PA_RTC + 0xff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_RTC_ALARM, + .end = IRQ_RTC_ALARM, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_RTC_TIC, + .end = IRQ_RTC_TIC, + .flags = IORESOURCE_IRQ + } +}; + +struct platform_device s3c_device_rtc = { + .name = "s3c64xx-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_rtc_resource), + .resource = s3c_rtc_resource, +}; +EXPORT_SYMBOL(s3c_device_rtc); -- cgit v1.2.3-59-g8ed1b From d800edebe33cac300ab1ff3b95e8a74d53e842d2 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 11:59:06 +0900 Subject: S3C: DMA: Add api driver for PL330 Latest Samsung SoCs have one or more PL330 as their DMACs. This patch implements the S3C DMA API for PL330 core driver. The design has been kept as generic as possible while keeping effort to add support for new SoCs to the minimum possible level. Some of the salient features of this driver are:- o Automatic scheduling of client requests onto DMAC if more than one DMAC can reach the peripheral. Factors, such as current load and number of exclusive but inactive peripherals that are supported by the DMAC, are used to decide suitability of a DMAC for a particular client. o CIRCULAR buffer option is supported. o The driver scales transparently with the number of DMACs and total peripherals in the platform, since all peripherals are added to the peripheral pool and DMACs to the controller pool. For most conservative use of memory, smallest driver size and best performance, we don't employ legacy data structures of the S3C DMA API. That should not have any affect since those data structures are completely invisible to the DMA clients. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/plat-samsung/Kconfig | 6 + arch/arm/plat-samsung/Makefile | 2 + arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h | 78 ++ .../plat-samsung/include/plat/s3c-pl330-pdata.h | 32 + arch/arm/plat-samsung/s3c-pl330.c | 1224 ++++++++++++++++++++ 5 files changed, 1342 insertions(+) create mode 100644 arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h create mode 100644 arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h create mode 100644 arch/arm/plat-samsung/s3c-pl330.c (limited to 'arch') diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index d552c65fa1b0..78b8b89b4620 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -198,6 +198,12 @@ config S3C_DMA help Internal configuration for S3C DMA core +config S3C_PL330_DMA + bool + select PL330 + help + S3C DMA API Driver for PL330 DMAC. + comment "Power management" config SAMSUNG_PM_DEBUG diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 22c89d08f6e5..05718a36d746 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -45,6 +45,8 @@ obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o obj-$(CONFIG_S3C_DMA) += dma.o +obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o + # PM support obj-$(CONFIG_PM) += pm.o diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h new file mode 100644 index 000000000000..5fe6721b57f7 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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. + */ + +#ifndef __S3C_DMA_PL330_H_ +#define __S3C_DMA_PL330_H_ + +#define S3C2410_DMAF_AUTOSTART (1 << 0) +#define S3C2410_DMAF_CIRCULAR (1 << 1) + +/* + * PL330 can assign any channel to communicate with + * any of the peripherals attched to the DMAC. + * For the sake of consistency across client drivers, + * We keep the channel names unchanged and only add + * missing peripherals are added. + * Order is not important since S3C PL330 API driver + * use these just as IDs. + */ +enum dma_ch { + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_IRDA, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S0S_TX, + DMACH_I2S1_RX, + DMACH_I2S1_TX, + DMACH_I2S2_RX, + DMACH_I2S2_TX, + DMACH_SPI0_RX, + DMACH_SPI0_TX, + DMACH_SPI1_RX, + DMACH_SPI1_TX, + DMACH_SPI2_RX, + DMACH_SPI2_TX, + DMACH_AC97_MICIN, + DMACH_AC97_PCMIN, + DMACH_AC97_PCMOUT, + DMACH_EXTERNAL, + DMACH_PWM, + DMACH_SPDIF, + DMACH_HSI_RX, + DMACH_HSI_TX, + DMACH_PCM0_TX, + DMACH_PCM0_RX, + DMACH_PCM1_TX, + DMACH_PCM1_RX, + DMACH_PCM2_TX, + DMACH_PCM2_RX, + DMACH_MSM_REQ3, + DMACH_MSM_REQ2, + DMACH_MSM_REQ1, + DMACH_MSM_REQ0, + /* END Marker, also used to denote a reserved channel */ + DMACH_MAX, +}; + +static inline bool s3c_dma_has_circular(void) +{ + return true; +} + +#include + +#endif /* __S3C_DMA_PL330_H_ */ diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h new file mode 100644 index 000000000000..bf5e2a9d408d --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h @@ -0,0 +1,32 @@ +/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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. + */ + +#ifndef __S3C_PL330_PDATA_H +#define __S3C_PL330_PDATA_H + +#include + +/* + * Every PL330 DMAC has max 32 peripheral interfaces, + * of which some may be not be really used in your + * DMAC's configuration. + * Populate this array of 32 peri i/fs with relevant + * channel IDs for used peri i/f and DMACH_MAX for + * those unused. + * + * The platforms just need to provide this info + * to the S3C DMA API driver for PL330. + */ +struct s3c_pl330_platdata { + enum dma_ch peri[32]; +}; + +#endif /* __S3C_PL330_PDATA_H */ diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c new file mode 100644 index 000000000000..a91305a60aed --- /dev/null +++ b/arch/arm/plat-samsung/s3c-pl330.c @@ -0,0 +1,1224 @@ +/* linux/arch/arm/plat-samsung/s3c-pl330.c + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +/** + * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC. + * @busy_chan: Number of channels currently busy. + * @peri: List of IDs of peripherals this DMAC can work with. + * @node: To attach to the global list of DMACs. + * @pi: PL330 configuration info for the DMAC. + * @kmcache: Pool to quickly allocate xfers for all channels in the dmac. + */ +struct s3c_pl330_dmac { + unsigned busy_chan; + enum dma_ch *peri; + struct list_head node; + struct pl330_info *pi; + struct kmem_cache *kmcache; +}; + +/** + * struct s3c_pl330_xfer - A request submitted by S3C DMA clients. + * @token: Xfer ID provided by the client. + * @node: To attach to the list of xfers on a channel. + * @px: Xfer for PL330 core. + * @chan: Owner channel of this xfer. + */ +struct s3c_pl330_xfer { + void *token; + struct list_head node; + struct pl330_xfer px; + struct s3c_pl330_chan *chan; +}; + +/** + * struct s3c_pl330_chan - Logical channel to communicate with + * a Physical peripheral. + * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC. + * NULL if the channel is available to be acquired. + * @id: ID of the peripheral that this channel can communicate with. + * @options: Options specified by the client. + * @sdaddr: Address provided via s3c2410_dma_devconfig. + * @node: To attach to the global list of channels. + * @lrq: Pointer to the last submitted pl330_req to PL330 core. + * @xfer_list: To manage list of xfers enqueued. + * @req: Two requests to communicate with the PL330 engine. + * @callback_fn: Callback function to the client. + * @rqcfg: Channel configuration for the xfers. + * @xfer_head: Pointer to the xfer to be next excecuted. + * @dmac: Pointer to the DMAC that manages this channel, NULL if the + * channel is available to be acquired. + * @client: Client of this channel. NULL if the + * channel is available to be acquired. + */ +struct s3c_pl330_chan { + void *pl330_chan_id; + enum dma_ch id; + unsigned int options; + unsigned long sdaddr; + struct list_head node; + struct pl330_req *lrq; + struct list_head xfer_list; + struct pl330_req req[2]; + s3c2410_dma_cbfn_t callback_fn; + struct pl330_reqcfg rqcfg; + struct s3c_pl330_xfer *xfer_head; + struct s3c_pl330_dmac *dmac; + struct s3c2410_dma_client *client; +}; + +/* All DMACs in the platform */ +static LIST_HEAD(dmac_list); + +/* All channels to peripherals in the platform */ +static LIST_HEAD(chan_list); + +/* + * Since we add resources(DMACs and Channels) to the global pool, + * we need to guard access to the resources using a global lock + */ +static DEFINE_SPINLOCK(res_lock); + +/* Returns the channel with ID 'id' in the chan_list */ +static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id) +{ + struct s3c_pl330_chan *ch; + + list_for_each_entry(ch, &chan_list, node) + if (ch->id == id) + return ch; + + return NULL; +} + +/* Allocate a new channel with ID 'id' and add to chan_list */ +static void chan_add(const enum dma_ch id) +{ + struct s3c_pl330_chan *ch = id_to_chan(id); + + /* Return if the channel already exists */ + if (ch) + return; + + ch = kmalloc(sizeof(*ch), GFP_KERNEL); + /* Return silently to work with other channels */ + if (!ch) + return; + + ch->id = id; + ch->dmac = NULL; + + list_add_tail(&ch->node, &chan_list); +} + +/* If the channel is not yet acquired by any client */ +static bool chan_free(struct s3c_pl330_chan *ch) +{ + if (!ch) + return false; + + /* Channel points to some DMAC only when it's acquired */ + return ch->dmac ? false : true; +} + +/* + * Returns 0 is peripheral i/f is invalid or not present on the dmac. + * Index + 1, otherwise. + */ +static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id) +{ + enum dma_ch *id = dmac->peri; + int i; + + /* Discount invalid markers */ + if (ch_id == DMACH_MAX) + return 0; + + for (i = 0; i < PL330_MAX_PERI; i++) + if (id[i] == ch_id) + return i + 1; + + return 0; +} + +/* If all channel threads of the DMAC are busy */ +static inline bool dmac_busy(struct s3c_pl330_dmac *dmac) +{ + struct pl330_info *pi = dmac->pi; + + return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true; +} + +/* + * Returns the number of free channels that + * can be handled by this dmac only. + */ +static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac) +{ + enum dma_ch *id = dmac->peri; + struct s3c_pl330_dmac *d; + struct s3c_pl330_chan *ch; + unsigned found, count = 0; + enum dma_ch p; + int i; + + for (i = 0; i < PL330_MAX_PERI; i++) { + p = id[i]; + ch = id_to_chan(p); + + if (p == DMACH_MAX || !chan_free(ch)) + continue; + + found = 0; + list_for_each_entry(d, &dmac_list, node) { + if (d != dmac && iface_of_dmac(d, ch->id)) { + found = 1; + break; + } + } + if (!found) + count++; + } + + return count; +} + +/* + * Measure of suitability of 'dmac' handling 'ch' + * + * 0 indicates 'dmac' can not handle 'ch' either + * because it is not supported by the hardware or + * because all dmac channels are currently busy. + * + * >0 vlaue indicates 'dmac' has the capability. + * The bigger the value the more suitable the dmac. + */ +#define MAX_SUIT UINT_MAX +#define MIN_SUIT 0 + +static unsigned suitablility(struct s3c_pl330_dmac *dmac, + struct s3c_pl330_chan *ch) +{ + struct pl330_info *pi = dmac->pi; + enum dma_ch *id = dmac->peri; + struct s3c_pl330_dmac *d; + unsigned s; + int i; + + s = MIN_SUIT; + /* If all the DMAC channel threads are busy */ + if (dmac_busy(dmac)) + return s; + + for (i = 0; i < PL330_MAX_PERI; i++) + if (id[i] == ch->id) + break; + + /* If the 'dmac' can't talk to 'ch' */ + if (i == PL330_MAX_PERI) + return s; + + s = MAX_SUIT; + list_for_each_entry(d, &dmac_list, node) { + /* + * If some other dmac can talk to this + * peri and has some channel free. + */ + if (d != dmac && iface_of_dmac(d, ch->id) && !dmac_busy(d)) { + s = 0; + break; + } + } + if (s) + return s; + + s = 100; + + /* Good if free chans are more, bad otherwise */ + s += (pi->pcfg.num_chan - dmac->busy_chan) - ch_onlyby_dmac(dmac); + + return s; +} + +/* More than one DMAC may have capability to transfer data with the + * peripheral. This function assigns most suitable DMAC to manage the + * channel and hence communicate with the peripheral. + */ +static struct s3c_pl330_dmac *map_chan_to_dmac(struct s3c_pl330_chan *ch) +{ + struct s3c_pl330_dmac *d, *dmac = NULL; + unsigned sn, sl = MIN_SUIT; + + list_for_each_entry(d, &dmac_list, node) { + sn = suitablility(d, ch); + + if (sn == MAX_SUIT) + return d; + + if (sn > sl) + dmac = d; + } + + return dmac; +} + +/* Acquire the channel for peripheral 'id' */ +static struct s3c_pl330_chan *chan_acquire(const enum dma_ch id) +{ + struct s3c_pl330_chan *ch = id_to_chan(id); + struct s3c_pl330_dmac *dmac; + + /* If the channel doesn't exist or is already acquired */ + if (!ch || !chan_free(ch)) { + ch = NULL; + goto acq_exit; + } + + dmac = map_chan_to_dmac(ch); + /* If couldn't map */ + if (!dmac) { + ch = NULL; + goto acq_exit; + } + + dmac->busy_chan++; + ch->dmac = dmac; + +acq_exit: + return ch; +} + +/* Delete xfer from the queue */ +static inline void del_from_queue(struct s3c_pl330_xfer *xfer) +{ + struct s3c_pl330_xfer *t; + struct s3c_pl330_chan *ch; + int found; + + if (!xfer) + return; + + ch = xfer->chan; + + /* Make sure xfer is in the queue */ + found = 0; + list_for_each_entry(t, &ch->xfer_list, node) + if (t == xfer) { + found = 1; + break; + } + + if (!found) + return; + + /* If xfer is last entry in the queue */ + if (xfer->node.next == &ch->xfer_list) + t = list_entry(ch->xfer_list.next, + struct s3c_pl330_xfer, node); + else + t = list_entry(xfer->node.next, + struct s3c_pl330_xfer, node); + + /* If there was only one node left */ + if (t == xfer) + ch->xfer_head = NULL; + else if (ch->xfer_head == xfer) + ch->xfer_head = t; + + list_del(&xfer->node); +} + +/* Provides pointer to the next xfer in the queue. + * If CIRCULAR option is set, the list is left intact, + * otherwise the xfer is removed from the list. + * Forced delete 'pluck' can be set to override the CIRCULAR option. + */ +static struct s3c_pl330_xfer *get_from_queue(struct s3c_pl330_chan *ch, + int pluck) +{ + struct s3c_pl330_xfer *xfer = ch->xfer_head; + + if (!xfer) + return NULL; + + /* If xfer is last entry in the queue */ + if (xfer->node.next == &ch->xfer_list) + ch->xfer_head = list_entry(ch->xfer_list.next, + struct s3c_pl330_xfer, node); + else + ch->xfer_head = list_entry(xfer->node.next, + struct s3c_pl330_xfer, node); + + if (pluck || !(ch->options & S3C2410_DMAF_CIRCULAR)) + del_from_queue(xfer); + + return xfer; +} + +static inline void add_to_queue(struct s3c_pl330_chan *ch, + struct s3c_pl330_xfer *xfer, int front) +{ + struct pl330_xfer *xt; + + /* If queue empty */ + if (ch->xfer_head == NULL) + ch->xfer_head = xfer; + + xt = &ch->xfer_head->px; + /* If the head already submitted (CIRCULAR head) */ + if (ch->options & S3C2410_DMAF_CIRCULAR && + (xt == ch->req[0].x || xt == ch->req[1].x)) + ch->xfer_head = xfer; + + /* If this is a resubmission, it should go at the head */ + if (front) { + ch->xfer_head = xfer; + list_add(&xfer->node, &ch->xfer_list); + } else { + list_add_tail(&xfer->node, &ch->xfer_list); + } +} + +static inline void _finish_off(struct s3c_pl330_xfer *xfer, + enum s3c2410_dma_buffresult res, int ffree) +{ + struct s3c_pl330_chan *ch; + + if (!xfer) + return; + + ch = xfer->chan; + + /* Do callback */ + if (ch->callback_fn) + ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res); + + /* Force Free or if buffer is not needed anymore */ + if (ffree || !(ch->options & S3C2410_DMAF_CIRCULAR)) + kmem_cache_free(ch->dmac->kmcache, xfer); +} + +static inline int s3c_pl330_submit(struct s3c_pl330_chan *ch, + struct pl330_req *r) +{ + struct s3c_pl330_xfer *xfer; + int ret = 0; + + /* If already submitted */ + if (r->x) + return 0; + + xfer = get_from_queue(ch, 0); + if (xfer) { + r->x = &xfer->px; + + /* Use max bandwidth for M<->M xfers */ + if (r->rqtype == MEMTOMEM) { + struct pl330_info *pi = xfer->chan->dmac->pi; + int burst = 1 << ch->rqcfg.brst_size; + u32 bytes = r->x->bytes; + int bl; + + bl = pi->pcfg.data_bus_width / 8; + bl *= pi->pcfg.data_buf_dep; + bl /= burst; + + /* src/dst_burst_len can't be more than 16 */ + if (bl > 16) + bl = 16; + + while (bl > 1) { + if (!(bytes % (bl * burst))) + break; + bl--; + } + + ch->rqcfg.brst_len = bl; + } else { + ch->rqcfg.brst_len = 1; + } + + ret = pl330_submit_req(ch->pl330_chan_id, r); + + /* If submission was successful */ + if (!ret) { + ch->lrq = r; /* latest submitted req */ + return 0; + } + + r->x = NULL; + + /* If both of the PL330 ping-pong buffers filled */ + if (ret == -EAGAIN) { + dev_err(ch->dmac->pi->dev, "%s:%d!\n", + __func__, __LINE__); + /* Queue back again */ + add_to_queue(ch, xfer, 1); + ret = 0; + } else { + dev_err(ch->dmac->pi->dev, "%s:%d!\n", + __func__, __LINE__); + _finish_off(xfer, S3C2410_RES_ERR, 0); + } + } + + return ret; +} + +static void s3c_pl330_rq(struct s3c_pl330_chan *ch, + struct pl330_req *r, enum pl330_op_err err) +{ + unsigned long flags; + struct s3c_pl330_xfer *xfer; + struct pl330_xfer *xl = r->x; + enum s3c2410_dma_buffresult res; + + spin_lock_irqsave(&res_lock, flags); + + r->x = NULL; + + s3c_pl330_submit(ch, r); + + spin_unlock_irqrestore(&res_lock, flags); + + /* Map result to S3C DMA API */ + if (err == PL330_ERR_NONE) + res = S3C2410_RES_OK; + else if (err == PL330_ERR_ABORT) + res = S3C2410_RES_ABORT; + else + res = S3C2410_RES_ERR; + + /* If last request had some xfer */ + if (xl) { + xfer = container_of(xl, struct s3c_pl330_xfer, px); + _finish_off(xfer, res, 0); + } else { + dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n", + __func__, __LINE__); + } +} + +static void s3c_pl330_rq0(void *token, enum pl330_op_err err) +{ + struct pl330_req *r = token; + struct s3c_pl330_chan *ch = container_of(r, + struct s3c_pl330_chan, req[0]); + s3c_pl330_rq(ch, r, err); +} + +static void s3c_pl330_rq1(void *token, enum pl330_op_err err) +{ + struct pl330_req *r = token; + struct s3c_pl330_chan *ch = container_of(r, + struct s3c_pl330_chan, req[1]); + s3c_pl330_rq(ch, r, err); +} + +/* Release an acquired channel */ +static void chan_release(struct s3c_pl330_chan *ch) +{ + struct s3c_pl330_dmac *dmac; + + if (chan_free(ch)) + return; + + dmac = ch->dmac; + ch->dmac = NULL; + dmac->busy_chan--; +} + +int s3c2410_dma_ctrl(enum dma_ch id, enum s3c2410_chan_op op) +{ + struct s3c_pl330_xfer *xfer; + enum pl330_chan_op pl330op; + struct s3c_pl330_chan *ch; + unsigned long flags; + int idx, ret; + + spin_lock_irqsave(&res_lock, flags); + + ch = id_to_chan(id); + + if (!ch || chan_free(ch)) { + ret = -EINVAL; + goto ctrl_exit; + } + + switch (op) { + case S3C2410_DMAOP_START: + /* Make sure both reqs are enqueued */ + idx = (ch->lrq == &ch->req[0]) ? 1 : 0; + s3c_pl330_submit(ch, &ch->req[idx]); + s3c_pl330_submit(ch, &ch->req[1 - idx]); + pl330op = PL330_OP_START; + break; + + case S3C2410_DMAOP_STOP: + pl330op = PL330_OP_ABORT; + break; + + case S3C2410_DMAOP_FLUSH: + pl330op = PL330_OP_FLUSH; + break; + + case S3C2410_DMAOP_PAUSE: + case S3C2410_DMAOP_RESUME: + case S3C2410_DMAOP_TIMEOUT: + case S3C2410_DMAOP_STARTED: + spin_unlock_irqrestore(&res_lock, flags); + return 0; + + default: + spin_unlock_irqrestore(&res_lock, flags); + return -EINVAL; + } + + ret = pl330_chan_ctrl(ch->pl330_chan_id, pl330op); + + if (pl330op == PL330_OP_START) { + spin_unlock_irqrestore(&res_lock, flags); + return ret; + } + + idx = (ch->lrq == &ch->req[0]) ? 1 : 0; + + /* Abort the current xfer */ + if (ch->req[idx].x) { + xfer = container_of(ch->req[idx].x, + struct s3c_pl330_xfer, px); + + /* Drop xfer during FLUSH */ + if (pl330op == PL330_OP_FLUSH) + del_from_queue(xfer); + + ch->req[idx].x = NULL; + + spin_unlock_irqrestore(&res_lock, flags); + _finish_off(xfer, S3C2410_RES_ABORT, + pl330op == PL330_OP_FLUSH ? 1 : 0); + spin_lock_irqsave(&res_lock, flags); + } + + /* Flush the whole queue */ + if (pl330op == PL330_OP_FLUSH) { + + if (ch->req[1 - idx].x) { + xfer = container_of(ch->req[1 - idx].x, + struct s3c_pl330_xfer, px); + + del_from_queue(xfer); + + ch->req[1 - idx].x = NULL; + + spin_unlock_irqrestore(&res_lock, flags); + _finish_off(xfer, S3C2410_RES_ABORT, 1); + spin_lock_irqsave(&res_lock, flags); + } + + /* Finish off the remaining in the queue */ + xfer = ch->xfer_head; + while (xfer) { + + del_from_queue(xfer); + + spin_unlock_irqrestore(&res_lock, flags); + _finish_off(xfer, S3C2410_RES_ABORT, 1); + spin_lock_irqsave(&res_lock, flags); + + xfer = ch->xfer_head; + } + } + +ctrl_exit: + spin_unlock_irqrestore(&res_lock, flags); + + return ret; +} +EXPORT_SYMBOL(s3c2410_dma_ctrl); + +int s3c2410_dma_enqueue(enum dma_ch id, void *token, + dma_addr_t addr, int size) +{ + struct s3c_pl330_chan *ch; + struct s3c_pl330_xfer *xfer; + unsigned long flags; + int idx, ret = 0; + + spin_lock_irqsave(&res_lock, flags); + + ch = id_to_chan(id); + + /* Error if invalid or free channel */ + if (!ch || chan_free(ch)) { + ret = -EINVAL; + goto enq_exit; + } + + /* Error if size is unaligned */ + if (ch->rqcfg.brst_size && size % (1 << ch->rqcfg.brst_size)) { + ret = -EINVAL; + goto enq_exit; + } + + xfer = kmem_cache_alloc(ch->dmac->kmcache, GFP_ATOMIC); + if (!xfer) { + ret = -ENOMEM; + goto enq_exit; + } + + xfer->token = token; + xfer->chan = ch; + xfer->px.bytes = size; + xfer->px.next = NULL; /* Single request */ + + /* For S3C DMA API, direction is always fixed for all xfers */ + if (ch->req[0].rqtype == MEMTODEV) { + xfer->px.src_addr = addr; + xfer->px.dst_addr = ch->sdaddr; + } else { + xfer->px.src_addr = ch->sdaddr; + xfer->px.dst_addr = addr; + } + + add_to_queue(ch, xfer, 0); + + /* Try submitting on either request */ + idx = (ch->lrq == &ch->req[0]) ? 1 : 0; + + if (!ch->req[idx].x) + s3c_pl330_submit(ch, &ch->req[idx]); + else + s3c_pl330_submit(ch, &ch->req[1 - idx]); + + spin_unlock_irqrestore(&res_lock, flags); + + if (ch->options & S3C2410_DMAF_AUTOSTART) + s3c2410_dma_ctrl(id, S3C2410_DMAOP_START); + + return 0; + +enq_exit: + spin_unlock_irqrestore(&res_lock, flags); + + return ret; +} +EXPORT_SYMBOL(s3c2410_dma_enqueue); + +int s3c2410_dma_request(enum dma_ch id, + struct s3c2410_dma_client *client, + void *dev) +{ + struct s3c_pl330_dmac *dmac; + struct s3c_pl330_chan *ch; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&res_lock, flags); + + ch = chan_acquire(id); + if (!ch) { + ret = -EBUSY; + goto req_exit; + } + + dmac = ch->dmac; + + ch->pl330_chan_id = pl330_request_channel(dmac->pi); + if (!ch->pl330_chan_id) { + chan_release(ch); + ret = -EBUSY; + goto req_exit; + } + + ch->client = client; + ch->options = 0; /* Clear any option */ + ch->callback_fn = NULL; /* Clear any callback */ + ch->lrq = NULL; + + ch->rqcfg.brst_size = 2; /* Default word size */ + ch->rqcfg.swap = SWAP_NO; + ch->rqcfg.scctl = SCCTRL0; /* Noncacheable and nonbufferable */ + ch->rqcfg.dcctl = DCCTRL0; /* Noncacheable and nonbufferable */ + ch->rqcfg.privileged = 0; + ch->rqcfg.insnaccess = 0; + + /* Set invalid direction */ + ch->req[0].rqtype = DEVTODEV; + ch->req[1].rqtype = ch->req[0].rqtype; + + ch->req[0].cfg = &ch->rqcfg; + ch->req[1].cfg = ch->req[0].cfg; + + ch->req[0].peri = iface_of_dmac(dmac, id) - 1; /* Original index */ + ch->req[1].peri = ch->req[0].peri; + + ch->req[0].token = &ch->req[0]; + ch->req[0].xfer_cb = s3c_pl330_rq0; + ch->req[1].token = &ch->req[1]; + ch->req[1].xfer_cb = s3c_pl330_rq1; + + ch->req[0].x = NULL; + ch->req[1].x = NULL; + + /* Reset xfer list */ + INIT_LIST_HEAD(&ch->xfer_list); + ch->xfer_head = NULL; + +req_exit: + spin_unlock_irqrestore(&res_lock, flags); + + return ret; +} +EXPORT_SYMBOL(s3c2410_dma_request); + +int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client) +{ + struct s3c_pl330_chan *ch; + struct s3c_pl330_xfer *xfer; + unsigned long flags; + int ret = 0; + unsigned idx; + + spin_lock_irqsave(&res_lock, flags); + + ch = id_to_chan(id); + + if (!ch || chan_free(ch)) + goto free_exit; + + /* Refuse if someone else wanted to free the channel */ + if (ch->client != client) { + ret = -EBUSY; + goto free_exit; + } + + /* Stop any active xfer, Flushe the queue and do callbacks */ + pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH); + + /* Abort the submitted requests */ + idx = (ch->lrq == &ch->req[0]) ? 1 : 0; + + if (ch->req[idx].x) { + xfer = container_of(ch->req[idx].x, + struct s3c_pl330_xfer, px); + + ch->req[idx].x = NULL; + del_from_queue(xfer); + + spin_unlock_irqrestore(&res_lock, flags); + _finish_off(xfer, S3C2410_RES_ABORT, 1); + spin_lock_irqsave(&res_lock, flags); + } + + if (ch->req[1 - idx].x) { + xfer = container_of(ch->req[1 - idx].x, + struct s3c_pl330_xfer, px); + + ch->req[1 - idx].x = NULL; + del_from_queue(xfer); + + spin_unlock_irqrestore(&res_lock, flags); + _finish_off(xfer, S3C2410_RES_ABORT, 1); + spin_lock_irqsave(&res_lock, flags); + } + + /* Pluck and Abort the queued requests in order */ + do { + xfer = get_from_queue(ch, 1); + + spin_unlock_irqrestore(&res_lock, flags); + _finish_off(xfer, S3C2410_RES_ABORT, 1); + spin_lock_irqsave(&res_lock, flags); + } while (xfer); + + ch->client = NULL; + + pl330_release_channel(ch->pl330_chan_id); + + ch->pl330_chan_id = NULL; + + chan_release(ch); + +free_exit: + spin_unlock_irqrestore(&res_lock, flags); + + return ret; +} +EXPORT_SYMBOL(s3c2410_dma_free); + +int s3c2410_dma_config(enum dma_ch id, int xferunit) +{ + struct s3c_pl330_chan *ch; + struct pl330_info *pi; + unsigned long flags; + int i, dbwidth, ret = 0; + + spin_lock_irqsave(&res_lock, flags); + + ch = id_to_chan(id); + + if (!ch || chan_free(ch)) { + ret = -EINVAL; + goto cfg_exit; + } + + pi = ch->dmac->pi; + dbwidth = pi->pcfg.data_bus_width / 8; + + /* Max size of xfer can be pcfg.data_bus_width */ + if (xferunit > dbwidth) { + ret = -EINVAL; + goto cfg_exit; + } + + i = 0; + while (xferunit != (1 << i)) + i++; + + /* If valid value */ + if (xferunit == (1 << i)) + ch->rqcfg.brst_size = i; + else + ret = -EINVAL; + +cfg_exit: + spin_unlock_irqrestore(&res_lock, flags); + + return ret; +} +EXPORT_SYMBOL(s3c2410_dma_config); + +/* Options that are supported by this driver */ +#define S3C_PL330_FLAGS (S3C2410_DMAF_CIRCULAR | S3C2410_DMAF_AUTOSTART) + +int s3c2410_dma_setflags(enum dma_ch id, unsigned int options) +{ + struct s3c_pl330_chan *ch; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&res_lock, flags); + + ch = id_to_chan(id); + + if (!ch || chan_free(ch) || options & ~(S3C_PL330_FLAGS)) + ret = -EINVAL; + else + ch->options = options; + + spin_unlock_irqrestore(&res_lock, flags); + + return 0; +} +EXPORT_SYMBOL(s3c2410_dma_setflags); + +int s3c2410_dma_set_buffdone_fn(enum dma_ch id, s3c2410_dma_cbfn_t rtn) +{ + struct s3c_pl330_chan *ch; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&res_lock, flags); + + ch = id_to_chan(id); + + if (!ch || chan_free(ch)) + ret = -EINVAL; + else + ch->callback_fn = rtn; + + spin_unlock_irqrestore(&res_lock, flags); + + return ret; +} +EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); + +int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source, + unsigned long address) +{ + struct s3c_pl330_chan *ch; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&res_lock, flags); + + ch = id_to_chan(id); + + if (!ch || chan_free(ch)) { + ret = -EINVAL; + goto devcfg_exit; + } + + switch (source) { + case S3C2410_DMASRC_HW: /* P->M */ + ch->req[0].rqtype = DEVTOMEM; + ch->req[1].rqtype = DEVTOMEM; + ch->rqcfg.src_inc = 0; + ch->rqcfg.dst_inc = 1; + break; + case S3C2410_DMASRC_MEM: /* M->P */ + ch->req[0].rqtype = MEMTODEV; + ch->req[1].rqtype = MEMTODEV; + ch->rqcfg.src_inc = 1; + ch->rqcfg.dst_inc = 0; + break; + default: + ret = -EINVAL; + goto devcfg_exit; + } + + ch->sdaddr = address; + +devcfg_exit: + spin_unlock_irqrestore(&res_lock, flags); + + return ret; +} +EXPORT_SYMBOL(s3c2410_dma_devconfig); + +int s3c2410_dma_getposition(enum dma_ch id, dma_addr_t *src, dma_addr_t *dst) +{ + struct s3c_pl330_chan *ch = id_to_chan(id); + struct pl330_chanstatus status; + int ret; + + if (!ch || chan_free(ch)) + return -EINVAL; + + ret = pl330_chan_status(ch->pl330_chan_id, &status); + if (ret < 0) + return ret; + + *src = status.src_addr; + *dst = status.dst_addr; + + return 0; +} +EXPORT_SYMBOL(s3c2410_dma_getposition); + +static irqreturn_t pl330_irq_handler(int irq, void *data) +{ + if (pl330_update(data)) + return IRQ_HANDLED; + else + return IRQ_NONE; +} + +static int pl330_probe(struct platform_device *pdev) +{ + struct s3c_pl330_dmac *s3c_pl330_dmac; + struct s3c_pl330_platdata *pl330pd; + struct pl330_info *pl330_info; + struct resource *res; + int i, ret, irq; + + pl330pd = pdev->dev.platform_data; + + /* Can't do without the list of _32_ peripherals */ + if (!pl330pd || !pl330pd->peri) { + dev_err(&pdev->dev, "platform data missing!\n"); + return -ENODEV; + } + + pl330_info = kzalloc(sizeof(*pl330_info), GFP_KERNEL); + if (!pl330_info) + return -ENOMEM; + + pl330_info->pl330_data = NULL; + pl330_info->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + goto probe_err1; + } + + request_mem_region(res->start, resource_size(res), pdev->name); + + pl330_info->base = ioremap(res->start, resource_size(res)); + if (!pl330_info->base) { + ret = -ENXIO; + goto probe_err2; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + ret = irq; + goto probe_err3; + } + + ret = request_irq(irq, pl330_irq_handler, 0, + dev_name(&pdev->dev), pl330_info); + if (ret) + goto probe_err4; + + ret = pl330_add(pl330_info); + if (ret) + goto probe_err5; + + /* Allocate a new DMAC */ + s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL); + if (!s3c_pl330_dmac) { + ret = -ENOMEM; + goto probe_err6; + } + + /* Hook the info */ + s3c_pl330_dmac->pi = pl330_info; + + /* No busy channels */ + s3c_pl330_dmac->busy_chan = 0; + + s3c_pl330_dmac->kmcache = kmem_cache_create(dev_name(&pdev->dev), + sizeof(struct s3c_pl330_xfer), 0, 0, NULL); + + if (!s3c_pl330_dmac->kmcache) { + ret = -ENOMEM; + goto probe_err7; + } + + /* Get the list of peripherals */ + s3c_pl330_dmac->peri = pl330pd->peri; + + /* Attach to the list of DMACs */ + list_add_tail(&s3c_pl330_dmac->node, &dmac_list); + + /* Create a channel for each peripheral in the DMAC + * that is, if it doesn't already exist + */ + for (i = 0; i < PL330_MAX_PERI; i++) + if (s3c_pl330_dmac->peri[i] != DMACH_MAX) + chan_add(s3c_pl330_dmac->peri[i]); + + printk(KERN_INFO + "Loaded driver for PL330 DMAC-%d %s\n", pdev->id, pdev->name); + printk(KERN_INFO + "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", + pl330_info->pcfg.data_buf_dep, + pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan, + pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events); + + return 0; + +probe_err7: + kfree(s3c_pl330_dmac); +probe_err6: + pl330_del(pl330_info); +probe_err5: + free_irq(irq, pl330_info); +probe_err4: +probe_err3: + iounmap(pl330_info->base); +probe_err2: + release_mem_region(res->start, resource_size(res)); +probe_err1: + kfree(pl330_info); + + return ret; +} + +static int pl330_remove(struct platform_device *pdev) +{ + struct s3c_pl330_dmac *dmac, *d; + struct s3c_pl330_chan *ch; + unsigned long flags; + int del, found; + + if (!pdev->dev.platform_data) + return -EINVAL; + + spin_lock_irqsave(&res_lock, flags); + + found = 0; + list_for_each_entry(d, &dmac_list, node) + if (d->pi->dev == &pdev->dev) { + found = 1; + break; + } + + if (!found) { + spin_unlock_irqrestore(&res_lock, flags); + return 0; + } + + dmac = d; + + /* Remove all Channels that are managed only by this DMAC */ + list_for_each_entry(ch, &chan_list, node) { + + /* Only channels that are handled by this DMAC */ + if (iface_of_dmac(dmac, ch->id)) + del = 1; + else + continue; + + /* Don't remove if some other DMAC has it too */ + list_for_each_entry(d, &dmac_list, node) + if (d != dmac && iface_of_dmac(d, ch->id)) { + del = 0; + break; + } + + if (del) { + spin_unlock_irqrestore(&res_lock, flags); + s3c2410_dma_free(ch->id, ch->client); + spin_lock_irqsave(&res_lock, flags); + list_del(&ch->node); + kfree(ch); + } + } + + /* Remove the DMAC */ + list_del(&dmac->node); + kfree(dmac); + + spin_unlock_irqrestore(&res_lock, flags); + + return 0; +} + +static struct platform_driver pl330_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "s3c-pl330", + }, + .probe = pl330_probe, + .remove = pl330_remove, +}; + +static int __init pl330_init(void) +{ + return platform_driver_register(&pl330_driver); +} +module_init(pl330_init); + +static void __exit pl330_exit(void) +{ + platform_driver_unregister(&pl330_driver); + return; +} +module_exit(pl330_exit); + +MODULE_AUTHOR("Jaswinder Singh "); +MODULE_DESCRIPTION("Driver for PL330 DMA Controller"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From d8b5065b75e87e87c2cbba984b3050e869b4b910 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 11:59:20 +0900 Subject: S5P6440: DMA: Add platform devices for PL330 DMACs Samsung's Soc S5P6440 has one PL330 DMAC. Define and add the PL330 DMAC as platform device on the S5P6440 platform. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/Kconfig | 1 + arch/arm/mach-s5p6440/Makefile | 2 +- arch/arm/mach-s5p6440/dma.c | 105 +++++++++++++++++++++++++++++++ arch/arm/mach-s5p6440/include/mach/dma.h | 26 ++++++++ arch/arm/mach-s5p6440/include/mach/map.h | 2 + 5 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-s5p6440/dma.c create mode 100644 arch/arm/mach-s5p6440/include/mach/dma.h (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/Kconfig b/arch/arm/mach-s5p6440/Kconfig index 4c29ff8b07de..77aeffd17330 100644 --- a/arch/arm/mach-s5p6440/Kconfig +++ b/arch/arm/mach-s5p6440/Kconfig @@ -9,6 +9,7 @@ if ARCH_S5P6440 config CPU_S5P6440 bool + select S3C_PL330_DMA help Enable S5P6440 CPU support diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile index 1ad894b1d3ab..3f243dd1ad14 100644 --- a/arch/arm/mach-s5p6440/Makefile +++ b/arch/arm/mach-s5p6440/Makefile @@ -12,7 +12,7 @@ obj- := # Core support for S5P6440 system -obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o +obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o dma.o # machine support diff --git a/arch/arm/mach-s5p6440/dma.c b/arch/arm/mach-s5p6440/dma.c new file mode 100644 index 000000000000..07606ad57519 --- /dev/null +++ b/arch/arm/mach-s5p6440/dma.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include +#include + +#include +#include + +#include + +static u64 dma_dmamask = DMA_BIT_MASK(32); + +static struct resource s5p6440_pdma_resource[] = { + [0] = { + .start = S5P6440_PA_PDMA, + .end = S5P6440_PA_PDMA + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DMA0, + .end = IRQ_DMA0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_pl330_platdata s5p6440_pdma_pdata = { + .peri = { + [0] = DMACH_UART0_RX, + [1] = DMACH_UART0_TX, + [2] = DMACH_UART1_RX, + [3] = DMACH_UART1_TX, + [4] = DMACH_UART2_RX, + [5] = DMACH_UART2_TX, + [6] = DMACH_UART3_RX, + [7] = DMACH_UART3_TX, + [8] = DMACH_MAX, + [9] = DMACH_MAX, + [10] = DMACH_PCM0_TX, + [11] = DMACH_PCM0_RX, + [12] = DMACH_I2S0_TX, + [13] = DMACH_I2S0_RX, + [14] = DMACH_SPI0_TX, + [15] = DMACH_SPI0_RX, + [16] = DMACH_MAX, + [17] = DMACH_MAX, + [18] = DMACH_MAX, + [19] = DMACH_MAX, + [20] = DMACH_SPI1_TX, + [21] = DMACH_SPI1_RX, + [22] = DMACH_MAX, + [23] = DMACH_MAX, + [24] = DMACH_MAX, + [25] = DMACH_MAX, + [26] = DMACH_MAX, + [27] = DMACH_MAX, + [28] = DMACH_MAX, + [29] = DMACH_PWM, + [30] = DMACH_MAX, + [31] = DMACH_MAX, + }, +}; + +static struct platform_device s5p6440_device_pdma = { + .name = "s3c-pl330", + .id = 1, + .num_resources = ARRAY_SIZE(s5p6440_pdma_resource), + .resource = s5p6440_pdma_resource, + .dev = { + .dma_mask = &dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s5p6440_pdma_pdata, + }, +}; + +static struct platform_device *s5p6440_dmacs[] __initdata = { + &s5p6440_device_pdma, +}; + +static int __init s5p6440_dma_init(void) +{ + platform_add_devices(s5p6440_dmacs, ARRAY_SIZE(s5p6440_dmacs)); + + return 0; +} +arch_initcall(s5p6440_dma_init); diff --git a/arch/arm/mach-s5p6440/include/mach/dma.h b/arch/arm/mach-s5p6440/include/mach/dma.h new file mode 100644 index 000000000000..81209eb1409b --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/dma.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MACH_DMA_H +#define __MACH_DMA_H + +/* This platform uses the common S3C DMA API driver for PL330 */ +#include + +#endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h index 8924e5a4d6a6..0275784eb22f 100644 --- a/arch/arm/mach-s5p6440/include/mach/map.h +++ b/arch/arm/mach-s5p6440/include/mach/map.h @@ -29,6 +29,8 @@ #define S5P6440_PA_VIC0 (0xE4000000) #define S5P_PA_VIC0 S5P6440_PA_VIC0 +#define S5P6440_PA_PDMA 0xE9000000 + #define S5P6440_PA_VIC1 (0xE4100000) #define S5P_PA_VIC1 S5P6440_PA_VIC1 -- cgit v1.2.3-59-g8ed1b From d460f5b035c3b1d192d7ba1dbca50cb441fef08e Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 11:59:27 +0900 Subject: S5P6442: DMA: Add platform devices for PL330 DMACs Samsung's Soc S5P6442 has two PL330 DMACs. First is dedicated for Memory->Memory data transfer while the second is meant for data transfer with peripherals. Define and add the peripheral PL330 DMAC as platform device on the S5P6442 platform. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6442/Kconfig | 1 + arch/arm/mach-s5p6442/Makefile | 2 +- arch/arm/mach-s5p6442/dma.c | 105 +++++++++++++++++++++++++++++++ arch/arm/mach-s5p6442/include/mach/dma.h | 26 ++++++++ arch/arm/mach-s5p6442/include/mach/map.h | 3 + 5 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-s5p6442/dma.c create mode 100644 arch/arm/mach-s5p6442/include/mach/dma.h (limited to 'arch') diff --git a/arch/arm/mach-s5p6442/Kconfig b/arch/arm/mach-s5p6442/Kconfig index 4f3f6de6a013..0fd41b447915 100644 --- a/arch/arm/mach-s5p6442/Kconfig +++ b/arch/arm/mach-s5p6442/Kconfig @@ -12,6 +12,7 @@ if ARCH_S5P6442 config CPU_S5P6442 bool select PLAT_S5P + select S3C_PL330_DMA help Enable S5P6442 CPU support diff --git a/arch/arm/mach-s5p6442/Makefile b/arch/arm/mach-s5p6442/Makefile index dde39a6ce6bc..17bd22ee107d 100644 --- a/arch/arm/mach-s5p6442/Makefile +++ b/arch/arm/mach-s5p6442/Makefile @@ -12,7 +12,7 @@ obj- := # Core support for S5P6442 system -obj-$(CONFIG_CPU_S5P6442) += cpu.o init.o clock.o +obj-$(CONFIG_CPU_S5P6442) += cpu.o init.o clock.o dma.o # machine support diff --git a/arch/arm/mach-s5p6442/dma.c b/arch/arm/mach-s5p6442/dma.c new file mode 100644 index 000000000000..ad4f8704b93d --- /dev/null +++ b/arch/arm/mach-s5p6442/dma.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include +#include + +#include +#include + +#include + +static u64 dma_dmamask = DMA_BIT_MASK(32); + +static struct resource s5p6442_pdma_resource[] = { + [0] = { + .start = S5P6442_PA_PDMA, + .end = S5P6442_PA_PDMA + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PDMA, + .end = IRQ_PDMA, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_pl330_platdata s5p6442_pdma_pdata = { + .peri = { + [0] = DMACH_UART0_RX, + [1] = DMACH_UART0_TX, + [2] = DMACH_UART1_RX, + [3] = DMACH_UART1_TX, + [4] = DMACH_UART2_RX, + [5] = DMACH_UART2_TX, + [6] = DMACH_MAX, + [7] = DMACH_MAX, + [8] = DMACH_MAX, + [9] = DMACH_I2S0_RX, + [10] = DMACH_I2S0_TX, + [11] = DMACH_I2S0S_TX, + [12] = DMACH_I2S1_RX, + [13] = DMACH_I2S1_TX, + [14] = DMACH_MAX, + [15] = DMACH_MAX, + [16] = DMACH_SPI0_RX, + [17] = DMACH_SPI0_TX, + [18] = DMACH_MAX, + [19] = DMACH_MAX, + [20] = DMACH_PCM0_RX, + [21] = DMACH_PCM0_TX, + [22] = DMACH_PCM1_RX, + [23] = DMACH_PCM1_TX, + [24] = DMACH_MAX, + [25] = DMACH_MAX, + [26] = DMACH_MAX, + [27] = DMACH_MSM_REQ0, + [28] = DMACH_MSM_REQ1, + [29] = DMACH_MSM_REQ2, + [30] = DMACH_MSM_REQ3, + [31] = DMACH_MAX, + }, +}; + +static struct platform_device s5p6442_device_pdma = { + .name = "s3c-pl330", + .id = 1, + .num_resources = ARRAY_SIZE(s5p6442_pdma_resource), + .resource = s5p6442_pdma_resource, + .dev = { + .dma_mask = &dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s5p6442_pdma_pdata, + }, +}; + +static struct platform_device *s5p6442_dmacs[] __initdata = { + &s5p6442_device_pdma, +}; + +static int __init s5p6442_dma_init(void) +{ + platform_add_devices(s5p6442_dmacs, ARRAY_SIZE(s5p6442_dmacs)); + + return 0; +} +arch_initcall(s5p6442_dma_init); diff --git a/arch/arm/mach-s5p6442/include/mach/dma.h b/arch/arm/mach-s5p6442/include/mach/dma.h new file mode 100644 index 000000000000..81209eb1409b --- /dev/null +++ b/arch/arm/mach-s5p6442/include/mach/dma.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MACH_DMA_H +#define __MACH_DMA_H + +/* This platform uses the common S3C DMA API driver for PL330 */ +#include + +#endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h index 685277d792fb..a263d77f6968 100644 --- a/arch/arm/mach-s5p6442/include/mach/map.h +++ b/arch/arm/mach-s5p6442/include/mach/map.h @@ -34,6 +34,9 @@ #define S5P6442_PA_VIC2 (0xE4200000) #define S5P_PA_VIC2 S5P6442_PA_VIC2 +#define S5P6442_PA_MDMA 0xE8000000 +#define S5P6442_PA_PDMA 0xE9000000 + #define S5P6442_PA_TIMER (0xEA000000) #define S5P_PA_TIMER S5P6442_PA_TIMER -- cgit v1.2.3-59-g8ed1b From 7d1a2077a7e519fc0c68617526abea3f72632e60 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 11:59:34 +0900 Subject: S5PV210: DMA: Add platform devices for PL330 DMACs Samsung's Soc S5PV210 has three PL330 DMACs. First is dedicated for Memory->Memory data transfer while the other two meant for data transfer with peripherals. Define and add latter two PL330 DMACs as platform devices on the S5PV210 platform. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/Kconfig | 1 + arch/arm/mach-s5pv210/Makefile | 2 +- arch/arm/mach-s5pv210/dma.c | 168 +++++++++++++++++++++++++++++++ arch/arm/mach-s5pv210/include/mach/dma.h | 26 +++++ arch/arm/mach-s5pv210/include/mach/map.h | 4 + 5 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-s5pv210/dma.c create mode 100644 arch/arm/mach-s5pv210/include/mach/dma.h (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index af33a1a89b72..7601c28e240b 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -12,6 +12,7 @@ if ARCH_S5PV210 config CPU_S5PV210 bool select PLAT_S5P + select S3C_PL330_DMA help Enable S5PV210 CPU support diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 8ebf51c52a01..f7f1cdce6fea 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -12,7 +12,7 @@ obj- := # Core support for S5PV210 system -obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o +obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o # machine support diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c new file mode 100644 index 000000000000..778ad5fe231a --- /dev/null +++ b/arch/arm/mach-s5pv210/dma.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include +#include + +#include +#include + +#include + +static u64 dma_dmamask = DMA_BIT_MASK(32); + +static struct resource s5pv210_pdma0_resource[] = { + [0] = { + .start = S5PV210_PA_PDMA0, + .end = S5PV210_PA_PDMA0 + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PDMA0, + .end = IRQ_PDMA0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_pl330_platdata s5pv210_pdma0_pdata = { + .peri = { + [0] = DMACH_UART0_RX, + [1] = DMACH_UART0_TX, + [2] = DMACH_UART1_RX, + [3] = DMACH_UART1_TX, + [4] = DMACH_UART2_RX, + [5] = DMACH_UART2_TX, + [6] = DMACH_UART3_RX, + [7] = DMACH_UART3_TX, + [8] = DMACH_MAX, + [9] = DMACH_I2S0_RX, + [10] = DMACH_I2S0_TX, + [11] = DMACH_I2S0S_TX, + [12] = DMACH_I2S1_RX, + [13] = DMACH_I2S1_TX, + [14] = DMACH_MAX, + [15] = DMACH_MAX, + [16] = DMACH_SPI0_RX, + [17] = DMACH_SPI0_TX, + [18] = DMACH_SPI1_RX, + [19] = DMACH_SPI1_TX, + [20] = DMACH_MAX, + [21] = DMACH_MAX, + [22] = DMACH_AC97_MICIN, + [23] = DMACH_AC97_PCMIN, + [24] = DMACH_AC97_PCMOUT, + [25] = DMACH_MAX, + [26] = DMACH_PWM, + [27] = DMACH_SPDIF, + [28] = DMACH_MAX, + [29] = DMACH_MAX, + [30] = DMACH_MAX, + [31] = DMACH_MAX, + }, +}; + +static struct platform_device s5pv210_device_pdma0 = { + .name = "s3c-pl330", + .id = 1, + .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource), + .resource = s5pv210_pdma0_resource, + .dev = { + .dma_mask = &dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s5pv210_pdma0_pdata, + }, +}; + +static struct resource s5pv210_pdma1_resource[] = { + [0] = { + .start = S5PV210_PA_PDMA1, + .end = S5PV210_PA_PDMA1 + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PDMA1, + .end = IRQ_PDMA1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_pl330_platdata s5pv210_pdma1_pdata = { + .peri = { + [0] = DMACH_UART0_RX, + [1] = DMACH_UART0_TX, + [2] = DMACH_UART1_RX, + [3] = DMACH_UART1_TX, + [4] = DMACH_UART2_RX, + [5] = DMACH_UART2_TX, + [6] = DMACH_UART3_RX, + [7] = DMACH_UART3_TX, + [8] = DMACH_MAX, + [9] = DMACH_I2S0_RX, + [10] = DMACH_I2S0_TX, + [11] = DMACH_I2S0S_TX, + [12] = DMACH_I2S1_RX, + [13] = DMACH_I2S1_TX, + [14] = DMACH_I2S2_RX, + [15] = DMACH_I2S2_TX, + [16] = DMACH_SPI0_RX, + [17] = DMACH_SPI0_TX, + [18] = DMACH_SPI1_RX, + [19] = DMACH_SPI1_TX, + [20] = DMACH_MAX, + [21] = DMACH_MAX, + [22] = DMACH_PCM0_RX, + [23] = DMACH_PCM0_TX, + [24] = DMACH_PCM1_RX, + [25] = DMACH_PCM1_TX, + [26] = DMACH_MSM_REQ0, + [27] = DMACH_MSM_REQ1, + [28] = DMACH_MSM_REQ2, + [29] = DMACH_MSM_REQ3, + [30] = DMACH_PCM2_RX, + [31] = DMACH_PCM2_TX, + }, +}; + +static struct platform_device s5pv210_device_pdma1 = { + .name = "s3c-pl330", + .id = 2, + .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource), + .resource = s5pv210_pdma1_resource, + .dev = { + .dma_mask = &dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s5pv210_pdma1_pdata, + }, +}; + +static struct platform_device *s5pv210_dmacs[] __initdata = { + &s5pv210_device_pdma0, + &s5pv210_device_pdma1, +}; + +static int __init s5pv210_dma_init(void) +{ + platform_add_devices(s5pv210_dmacs, ARRAY_SIZE(s5pv210_dmacs)); + + return 0; +} +arch_initcall(s5pv210_dma_init); diff --git a/arch/arm/mach-s5pv210/include/mach/dma.h b/arch/arm/mach-s5pv210/include/mach/dma.h new file mode 100644 index 000000000000..81209eb1409b --- /dev/null +++ b/arch/arm/mach-s5pv210/include/mach/dma.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MACH_DMA_H +#define __MACH_DMA_H + +/* This platform uses the common S3C DMA API driver for PL330 */ +#include + +#endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index c22694c8231f..c038585080c0 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -43,6 +43,10 @@ #define S5PV210_PA_SROMC (0xE8000000) +#define S5PV210_PA_MDMA 0xFA200000 +#define S5PV210_PA_PDMA0 0xE0900000 +#define S5PV210_PA_PDMA1 0xE0A00000 + #define S5PV210_PA_VIC0 (0xF2000000) #define S5P_PA_VIC0 S5PV210_PA_VIC0 -- cgit v1.2.3-59-g8ed1b From 06225c08ec2ad0f0dec063df7f08773a8358db12 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 18 May 2010 18:15:44 +0900 Subject: sh: Fix up the NUMA build for recent LMB changes. Now that the node 0 initialization code has been overhauled, kill off the now obsolete setup_memory() bits. Signed-off-by: Paul Mundt --- arch/sh/mm/numa.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'arch') diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c index 961b34085e3b..a2e645f64a37 100644 --- a/arch/sh/mm/numa.c +++ b/arch/sh/mm/numa.c @@ -24,44 +24,6 @@ EXPORT_SYMBOL_GPL(node_data); * latency. Each node's pgdat is node-local at the beginning of the node, * immediately followed by the node mem map. */ -void __init setup_memory(void) -{ - unsigned long free_pfn = PFN_UP(__pa(_end)); - u64 base = min_low_pfn << PAGE_SHIFT; - u64 size = (max_low_pfn << PAGE_SHIFT) - base; - - lmb_add(base, size); - - /* Reserve the LMB regions used by the kernel, initrd, etc.. */ - lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET, - (PFN_PHYS(free_pfn) + PAGE_SIZE - 1) - - (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET)); - - /* - * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET. - */ - if (CONFIG_ZERO_PAGE_OFFSET != 0) - lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET); - - lmb_analyze(); - lmb_dump_all(); - - /* - * Node 0 sets up its pgdat at the first available pfn, - * and bumps it up before setting up the bootmem allocator. - */ - NODE_DATA(0) = pfn_to_kaddr(free_pfn); - memset(NODE_DATA(0), 0, sizeof(struct pglist_data)); - free_pfn += PFN_UP(sizeof(struct pglist_data)); - NODE_DATA(0)->bdata = &bootmem_node_data[0]; - - /* Set up node 0 */ - setup_bootmem_allocator(free_pfn); - - /* Give the platforms a chance to hook up their nodes */ - plat_mem_setup(); -} - void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) { unsigned long bootmap_pages; -- cgit v1.2.3-59-g8ed1b From 4d0956b8f597aac10208ca763f8fe641fde16aab Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 18 May 2010 18:18:28 +0900 Subject: sh: update defconfigs. Signed-off-by: Paul Mundt --- arch/sh/configs/ap325rxa_defconfig | 56 ++++++++++---------- arch/sh/configs/cayman_defconfig | 46 +++++++++------- arch/sh/configs/dreamcast_defconfig | 29 ++++++---- arch/sh/configs/ecovec24-romimage_defconfig | 54 ++++++++++--------- arch/sh/configs/ecovec24_defconfig | 7 ++- arch/sh/configs/edosk7705_defconfig | 21 +++++--- arch/sh/configs/edosk7760_defconfig | 38 +++++++------ arch/sh/configs/espt_defconfig | 42 +++++++-------- arch/sh/configs/hp6xx_defconfig | 24 +++++---- arch/sh/configs/kfr2r09-romimage_defconfig | 50 ++++++++++-------- arch/sh/configs/kfr2r09_defconfig | 57 ++++++++++---------- arch/sh/configs/landisk_defconfig | 45 +++++++++++----- arch/sh/configs/lboxre2_defconfig | 35 ++++++++---- arch/sh/configs/magicpanelr2_defconfig | 28 +++++++--- arch/sh/configs/microdev_defconfig | 23 +++++--- arch/sh/configs/migor_defconfig | 60 +++++++++++---------- arch/sh/configs/polaris_defconfig | 31 ++++++----- arch/sh/configs/r7780mp_defconfig | 72 +++++++++++++------------ arch/sh/configs/r7785rp_defconfig | 76 +++++++++++++++----------- arch/sh/configs/rsk7201_defconfig | 31 +++++------ arch/sh/configs/rsk7203_defconfig | 49 ++++++++++------- arch/sh/configs/rts7751r2d1_defconfig | 54 +++++++++++-------- arch/sh/configs/rts7751r2dplus_defconfig | 54 +++++++++++-------- arch/sh/configs/sdk7780_defconfig | 53 +++++++++++-------- arch/sh/configs/sdk7786_defconfig | 14 ++--- arch/sh/configs/se7206_defconfig | 38 ++++++------- arch/sh/configs/se7343_defconfig | 53 +++++++++++-------- arch/sh/configs/se7619_defconfig | 22 +++++--- arch/sh/configs/se7705_defconfig | 25 +++++---- arch/sh/configs/se7712_defconfig | 28 ++++++---- arch/sh/configs/se7721_defconfig | 40 ++++++++------ arch/sh/configs/se7722_defconfig | 29 ++++++---- arch/sh/configs/se7724_defconfig | 78 +++++++++++++++++---------- arch/sh/configs/se7750_defconfig | 24 +++++---- arch/sh/configs/se7751_defconfig | 25 +++++---- arch/sh/configs/se7780_defconfig | 39 ++++++++++---- arch/sh/configs/sh03_defconfig | 43 ++++++++------- arch/sh/configs/sh7710voipgw_defconfig | 29 +++++----- arch/sh/configs/sh7724_generic_defconfig | 58 ++++++++------------ arch/sh/configs/sh7763rdp_defconfig | 45 +++++++--------- arch/sh/configs/sh7770_generic_defconfig | 54 ++++++++----------- arch/sh/configs/sh7785lcr_32bit_defconfig | 75 ++++++++++++++------------ arch/sh/configs/sh7785lcr_defconfig | 62 +++++++++++++--------- arch/sh/configs/shmin_defconfig | 23 +++++--- arch/sh/configs/shx3_defconfig | 67 +++++++++++------------ arch/sh/configs/snapgear_defconfig | 31 +++++++---- arch/sh/configs/systemh_defconfig | 23 +++++--- arch/sh/configs/titan_defconfig | 49 +++++++++++------ arch/sh/configs/ul2_defconfig | 38 +++++++------ arch/sh/configs/urquell_defconfig | 82 ++++++++++++++++++----------- 50 files changed, 1237 insertions(+), 892 deletions(-) (limited to 'arch') diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig index 8931a60e37a4..7fefa2b9e28c 100644 --- a/arch/sh/configs/ap325rxa_defconfig +++ b/arch/sh/configs/ap325rxa_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:10:59 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:04:35 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -47,9 +48,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -71,11 +74,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -107,7 +105,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -116,13 +114,13 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -237,8 +235,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set -# CONFIG_X2TLB is not set +# CONFIG_PMB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -246,6 +244,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -261,7 +261,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -335,7 +335,7 @@ CONFIG_SECCOMP=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -371,6 +371,7 @@ CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_HIBERNATION is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y # CONFIG_CPU_IDLE is not set CONFIG_NET=y @@ -378,7 +379,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -594,6 +594,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_DS1682 is not set # CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set @@ -613,6 +614,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -774,6 +776,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -802,6 +805,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_SH_MOBILE=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -814,15 +818,9 @@ CONFIG_I2C_SH_MOBILE=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y CONFIG_SPI_MASTER=y @@ -853,13 +851,16 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -891,22 +892,25 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_AB4500_CORE is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -1041,10 +1045,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_AT91 is not set -# CONFIG_MMC_ATMELMCI is not set CONFIG_MMC_SPI=y -# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1120,8 +1121,6 @@ CONFIG_RTC_DRV_PCF8563=y CONFIG_UIO=y # CONFIG_UIO_PDRV is not set CONFIG_UIO_PDRV_GENIRQ=y -# CONFIG_UIO_SMX is not set -# CONFIG_UIO_SERCOS3 is not set # # TI VLYNQ @@ -1206,6 +1205,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_UBIFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1234,6 +1234,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1426,6 +1427,7 @@ CONFIG_CRYPTO_CBC=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig index 92589a950d07..edae0a6830da 100644 --- a/arch/sh/configs/cayman_defconfig +++ b/arch/sh/configs/cayman_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:14:50 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 18:01:02 2010 # CONFIG_SUPERH=y # CONFIG_SUPERH32 is not set @@ -13,7 +13,6 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y @@ -32,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -47,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y # CONFIG_SYSVIPC is not set CONFIG_POSIX_MQUEUE=y @@ -70,7 +72,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -114,7 +115,6 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y @@ -204,6 +204,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_IOREMAP_FIXED=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -225,7 +226,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -294,7 +295,6 @@ CONFIG_HZ=250 # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -309,9 +309,9 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -337,7 +337,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -463,6 +462,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set # CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_DS1682 is not set # CONFIG_C2PORT is not set @@ -480,6 +480,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -569,7 +570,7 @@ CONFIG_SCSI_LOWLEVEL=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -638,6 +639,8 @@ CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +CONFIG_CHELSIO_T4_DEPENDS=y +# CONFIG_CHELSIO_T4 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set @@ -650,6 +653,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set @@ -732,6 +736,7 @@ CONFIG_DEVKMEM=y # # CONFIG_SERIAL_SH_SCI is not set # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -779,6 +784,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -791,15 +797,9 @@ CONFIG_I2C_HELPER_AUTO=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -823,10 +823,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_I5K_AMB is not set @@ -863,6 +864,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_TMP421 is not set @@ -909,9 +911,9 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set -# CONFIG_AB3100_CORE is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -919,6 +921,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=y @@ -1125,6 +1128,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1153,6 +1157,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1208,6 +1213,7 @@ CONFIG_SCHEDSTATS=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -1234,6 +1240,7 @@ CONFIG_FRAME_POINTER=y # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set @@ -1361,6 +1368,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig index 55f652be954b..b96bf3d2cd01 100644 --- a/arch/sh/configs/dreamcast_defconfig +++ b/arch/sh/configs/dreamcast_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:17:35 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:11:55 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -72,7 +75,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -124,6 +126,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -242,6 +245,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -263,7 +267,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -360,7 +364,6 @@ CONFIG_SECCOMP=y CONFIG_PREEMPT=y CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -377,9 +380,9 @@ CONFIG_CMDLINE="console=ttySC1,115200 panic=3" # CONFIG_MAPLE=y CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set @@ -404,7 +407,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -532,6 +534,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -549,7 +552,7 @@ CONFIG_HAVE_IDE=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -589,6 +592,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -717,6 +721,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -771,6 +776,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -778,6 +784,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m @@ -918,7 +925,6 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -976,6 +982,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -990,6 +997,7 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1135,6 +1143,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/ecovec24-romimage_defconfig b/arch/sh/configs/ecovec24-romimage_defconfig index 662c1ad20494..58aec9dd5630 100644 --- a/arch/sh/configs/ecovec24-romimage_defconfig +++ b/arch/sh/configs/ecovec24-romimage_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:18:17 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:14:56 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -71,11 +74,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -86,6 +84,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -111,7 +110,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -120,13 +119,13 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -237,8 +236,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x10000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set -# CONFIG_X2TLB is not set +# CONFIG_PMB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -246,6 +245,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -261,7 +262,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -336,7 +337,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -370,6 +371,7 @@ CONFIG_PM=y # CONFIG_SUSPEND is not set # CONFIG_HIBERNATION is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y # CONFIG_CPU_IDLE is not set CONFIG_NET=y @@ -377,7 +379,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -485,6 +486,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -585,6 +587,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -650,6 +653,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -678,6 +682,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_SH_MOBILE=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -690,15 +695,9 @@ CONFIG_I2C_SH_MOBILE=y # Other I2C/SMBus bus drivers # # CONFIG_I2C_PCA_PLATFORM is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -712,13 +711,16 @@ CONFIG_GPIO_SYSFS=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -747,20 +749,23 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -868,7 +873,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -880,7 +884,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -911,7 +914,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1027,6 +1029,7 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y @@ -1056,6 +1059,7 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index 6041c66dd10e..67c665671c6c 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.34-rc2 -# Mon Mar 29 02:21:58 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:17:28 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -336,6 +336,7 @@ CONFIG_SECCOMP=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -762,6 +763,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -1755,6 +1757,7 @@ CONFIG_CRYPTO_CBC=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig index 72f8718dd738..0883d873ea64 100644 --- a/arch/sh/configs/edosk7705_defconfig +++ b/arch/sh/configs/edosk7705_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:24:26 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:21:52 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -12,8 +12,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -29,6 +29,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -43,9 +44,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SYSVIPC is not set # CONFIG_BSD_PROCESS_ACCT is not set @@ -61,11 +64,11 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 -# CONFIG_CGROUPS is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_UID16 is not set # CONFIG_KALLSYMS is not set @@ -87,7 +90,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set # CONFIG_VM_EVENT_COUNTERS is not set # CONFIG_COMPAT_BRK is not set @@ -103,6 +106,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -202,6 +206,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -217,7 +222,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -330,6 +335,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_PHONE is not set @@ -361,6 +367,7 @@ CONFIG_HAVE_IDE=y # Non-8250 serial port support # # CONFIG_SERIAL_SH_SCI is not set +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set @@ -440,6 +447,7 @@ CONFIG_INOTIFY_USER=y # # Caches # +# CONFIG_FSCACHE is not set # # Pseudo filesystems @@ -491,6 +499,7 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig index 0932e6d656eb..8257f5776374 100644 --- a/arch/sh/configs/edosk7760_defconfig +++ b/arch/sh/configs/edosk7760_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:24:44 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:23:10 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -72,7 +75,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -83,6 +85,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -110,8 +113,9 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y CONFIG_COMPAT_BRK=y @@ -128,6 +132,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -246,6 +251,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -261,7 +267,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -342,7 +348,6 @@ CONFIG_SCHED_HRTICK=y CONFIG_PREEMPT=y CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -379,7 +384,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -579,6 +583,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -685,6 +690,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -713,6 +719,7 @@ CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_SH7760=y # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -725,15 +732,9 @@ CONFIG_I2C_SH7760=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set CONFIG_I2C_DEBUG_CORE=y CONFIG_I2C_DEBUG_ALGO=y CONFIG_I2C_DEBUG_BUS=y -CONFIG_I2C_DEBUG_CHIP=y # CONFIG_SPI is not set # @@ -756,6 +757,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set @@ -763,12 +765,13 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -947,6 +950,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -969,6 +973,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1048,6 +1053,7 @@ CONFIG_TIMER_STATS=y # CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -1096,6 +1102,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1214,6 +1221,7 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig index f899e5613f86..8acdc374d033 100644 --- a/arch/sh/configs/espt_defconfig +++ b/arch/sh/configs/espt_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:26:55 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:27:14 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -69,11 +72,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -112,7 +110,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -120,7 +117,6 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -131,6 +127,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -243,7 +240,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set +# CONFIG_PMB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -253,6 +250,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -269,7 +267,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -344,7 +342,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -381,7 +379,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -444,7 +441,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -584,6 +580,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -688,6 +685,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -753,6 +751,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -944,7 +943,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -956,7 +954,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1052,6 +1049,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1078,6 +1076,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1144,13 +1143,12 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_STACKTRACE=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1158,10 +1156,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # CONFIG_DYNAMIC_DEBUG is not set @@ -1269,7 +1264,8 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig index 06644908631e..f894bdc97a65 100644 --- a/arch/sh/configs/hp6xx_defconfig +++ b/arch/sh/configs/hp6xx_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:30:31 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:30:50 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y # CONFIG_SYSVIPC is not set CONFIG_BSD_PROCESS_ACCT=y @@ -66,7 +69,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -99,7 +101,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -115,6 +117,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -228,6 +231,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -243,7 +247,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -326,7 +330,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -344,7 +347,6 @@ CONFIG_ENTRY_OFFSET=0x00001000 CONFIG_PCCARD=y CONFIG_PCMCIA=y CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y # # PC-card bridges @@ -369,6 +371,7 @@ CONFIG_SUSPEND_FREEZER=y # CONFIG_HIBERNATION is not set CONFIG_APM_EMULATION=y # CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y # CONFIG_CPU_IDLE is not set # CONFIG_NET is not set @@ -412,6 +415,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -544,6 +548,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -722,7 +727,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -780,6 +784,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -977,6 +982,7 @@ CONFIG_CRYPTO_MD5=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/kfr2r09-romimage_defconfig b/arch/sh/configs/kfr2r09-romimage_defconfig index 3d834e59e8f9..8c54e1620e95 100644 --- a/arch/sh/configs/kfr2r09-romimage_defconfig +++ b/arch/sh/configs/kfr2r09-romimage_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:31:09 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:33:23 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set @@ -70,11 +73,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -85,6 +83,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -110,7 +109,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -119,13 +118,13 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -222,8 +221,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set -# CONFIG_X2TLB is not set +# CONFIG_PMB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -231,6 +230,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -246,7 +247,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -321,7 +322,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -354,6 +355,7 @@ CONFIG_PM=y # CONFIG_PM_DEBUG is not set # CONFIG_SUSPEND is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y # CONFIG_CPU_IDLE is not set CONFIG_NET=y @@ -361,7 +363,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -449,6 +450,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_NETDEVICES is not set @@ -511,6 +513,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -538,6 +541,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_SH_MOBILE=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -549,15 +553,9 @@ CONFIG_I2C_SH_MOBILE=y # Other I2C/SMBus bus drivers # # CONFIG_I2C_PCA_PLATFORM is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -571,13 +569,16 @@ CONFIG_GPIO_SYSFS=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -606,20 +607,23 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -690,6 +694,7 @@ CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set CONFIG_USB_CDC_COMPOSITE=y +# CONFIG_USB_G_NOKIA is not set # CONFIG_USB_G_MULTI is not set # @@ -794,6 +799,7 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig index f22be494ed99..2e74b08ca14d 100644 --- a/arch/sh/configs/kfr2r09_defconfig +++ b/arch/sh/configs/kfr2r09_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:32:55 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:35:20 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -47,9 +48,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -72,11 +75,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -87,6 +85,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -112,7 +111,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -121,13 +120,13 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -243,8 +242,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set -# CONFIG_X2TLB is not set +# CONFIG_PMB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -252,6 +251,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -267,7 +268,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -343,7 +344,7 @@ CONFIG_KEXEC=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -377,6 +378,7 @@ CONFIG_PM=y # CONFIG_SUSPEND is not set # CONFIG_HIBERNATION is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y @@ -386,7 +388,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -580,6 +581,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -659,6 +661,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -687,6 +690,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_SH_MOBILE=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -699,15 +703,9 @@ CONFIG_I2C_SH_MOBILE=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -721,13 +719,16 @@ CONFIG_GPIO_SYSFS=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -756,20 +757,23 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -889,6 +893,7 @@ CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set CONFIG_USB_CDC_COMPOSITE=m +# CONFIG_USB_G_NOKIA is not set # CONFIG_USB_G_MULTI is not set # @@ -912,9 +917,6 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_AT91 is not set -# CONFIG_MMC_ATMELMCI is not set -# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -982,8 +984,6 @@ CONFIG_RTC_DRV_SH=y CONFIG_UIO=y # CONFIG_UIO_PDRV is not set CONFIG_UIO_PDRV_GENIRQ=y -# CONFIG_UIO_SMX is not set -# CONFIG_UIO_SERCOS3 is not set # # TI VLYNQ @@ -996,7 +996,6 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1074,6 +1073,7 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y @@ -1103,6 +1103,7 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index 2a42d4977fe4..87789345d47f 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:35:31 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:38:08 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -69,7 +72,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -102,7 +104,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y @@ -120,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -238,6 +241,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -253,7 +257,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -333,7 +337,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -348,15 +351,14 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set CONFIG_PCCARD=y CONFIG_PCMCIA=y CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y CONFIG_CARDBUS=y # @@ -392,7 +394,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -612,6 +613,7 @@ CONFIG_BLK_DEV_IDEDMA=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -711,7 +713,7 @@ CONFIG_MD_RAID1=m # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -751,6 +753,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -798,6 +801,8 @@ CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +CONFIG_CHELSIO_T4_DEPENDS=y +# CONFIG_CHELSIO_T4 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set @@ -810,6 +815,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set @@ -835,6 +841,7 @@ CONFIG_WLAN=y CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_NET_PCMCIA is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set @@ -910,6 +917,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -977,6 +985,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -984,6 +993,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1025,6 +1035,7 @@ CONFIG_USB_HID=m # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=m CONFIG_HID_APPLE=m CONFIG_HID_BELKIN=m @@ -1040,14 +1051,19 @@ CONFIG_HID_GYRATION=m CONFIG_HID_LOGITECH=m # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=m +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=m # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=m # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=m +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=m CONFIG_HID_SONY=m +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=m # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1169,6 +1185,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m # CONFIG_USB_SERIAL_NAVMAN is not set CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set # CONFIG_USB_SERIAL_QUALCOMM is not set # CONFIG_USB_SERIAL_SPCP8X5 is not set # CONFIG_USB_SERIAL_HP4X is not set @@ -1182,6 +1199,7 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_SERIAL_OPTION is not set # CONFIG_USB_SERIAL_OMNINET is not set # CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set # CONFIG_USB_SERIAL_DEBUG is not set # @@ -1194,7 +1212,6 @@ CONFIG_USB_EMI26=m # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1208,7 +1225,6 @@ CONFIG_USB_SISUSBVGA_CON=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1313,6 +1329,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1347,6 +1364,7 @@ CONFIG_SUNRPC=m # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1531,6 +1549,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig index f2f1f8c73b2f..6088a76bd21c 100644 --- a/arch/sh/configs/lboxre2_defconfig +++ b/arch/sh/configs/lboxre2_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:37:01 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:42:57 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -69,7 +72,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -102,7 +104,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y @@ -120,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -238,6 +241,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -253,7 +257,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -333,7 +337,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -349,15 +352,14 @@ CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set CONFIG_PCCARD=y CONFIG_PCMCIA=y CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y CONFIG_CARDBUS=y # @@ -392,7 +394,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -552,6 +553,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -670,6 +672,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -707,7 +710,7 @@ CONFIG_PATA_PLATFORM=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -747,6 +750,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -798,6 +802,8 @@ CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +CONFIG_CHELSIO_T4_DEPENDS=y +# CONFIG_CHELSIO_T4 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set @@ -810,6 +816,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set @@ -908,6 +915,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -975,6 +983,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -982,6 +991,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1155,6 +1165,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1173,6 +1184,7 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1357,6 +1369,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig index a7a16ce357ad..28c104da0ba1 100644 --- a/arch/sh/configs/magicpanelr2_defconfig +++ b/arch/sh/configs/magicpanelr2_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:37:42 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:44:00 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -45,9 +46,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -71,7 +74,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -82,6 +84,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -109,8 +112,9 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -126,6 +130,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -244,6 +249,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -259,7 +265,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -344,7 +350,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -380,7 +385,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -586,6 +590,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -741,6 +746,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -765,6 +771,7 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: @@ -953,6 +960,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -977,6 +985,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1051,6 +1060,7 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -1097,6 +1107,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1125,6 +1136,7 @@ CONFIG_DUMP_CODE=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig index 7d43fabdc073..41cefa490ec1 100644 --- a/arch/sh/configs/microdev_defconfig +++ b/arch/sh/configs/microdev_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:40:41 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:48:22 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y # CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set @@ -69,7 +72,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -80,6 +82,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -106,7 +109,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -122,6 +125,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -235,6 +239,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -256,7 +261,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -334,7 +339,6 @@ CONFIG_HZ=250 CONFIG_PREEMPT=y CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -515,6 +519,7 @@ CONFIG_IDE_PROC_FS=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -596,6 +601,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -774,6 +780,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -800,6 +807,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -992,6 +1000,7 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig index d2b183117771..1c889b74cd57 100644 --- a/arch/sh/configs/migor_defconfig +++ b/arch/sh/configs/migor_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:41:41 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 18:01:29 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -47,9 +48,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -71,7 +74,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -82,6 +84,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -109,7 +112,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -117,17 +119,16 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -243,7 +244,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y -# CONFIG_X2TLB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_NUMA=y CONFIG_NODES_SHIFT=1 @@ -254,6 +255,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -271,7 +274,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_MIGRATION is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -348,7 +351,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -384,6 +387,7 @@ CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_HIBERNATION is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y # CONFIG_CPU_IDLE is not set CONFIG_NET=y @@ -391,7 +395,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -454,7 +457,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -564,6 +566,7 @@ CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set CONFIG_MTD_NAND_PLATFORM=y +# CONFIG_MTD_NAND_SH_FLCTL is not set # CONFIG_MTD_ONENAND is not set # @@ -596,6 +599,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_DS1682 is not set # CONFIG_C2PORT is not set @@ -612,6 +616,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -764,6 +769,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -792,6 +798,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_SH_MOBILE=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -804,15 +811,9 @@ CONFIG_I2C_SH_MOBILE=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -826,13 +827,16 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -861,20 +865,23 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -1054,6 +1061,7 @@ CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set # CONFIG_USB_G_MULTI is not set # @@ -1129,8 +1137,6 @@ CONFIG_RTC_DRV_SH=y CONFIG_UIO=y # CONFIG_UIO_PDRV is not set CONFIG_UIO_PDRV_GENIRQ=y -# CONFIG_UIO_SMX is not set -# CONFIG_UIO_SERCOS3 is not set # # TI VLYNQ @@ -1143,7 +1149,6 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1202,6 +1207,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1224,6 +1230,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1251,13 +1258,12 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_STACKTRACE=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1265,10 +1271,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # CONFIG_DYNAMIC_DEBUG is not set @@ -1383,7 +1386,8 @@ CONFIG_CRYPTO_WORKQUEUE=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig index d50c0314281e..826b1198959f 100644 --- a/arch/sh/configs/polaris_defconfig +++ b/arch/sh/configs/polaris_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:45:25 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:53:51 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -45,9 +46,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -71,11 +74,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -109,8 +107,9 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -126,6 +125,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -244,6 +244,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -259,7 +260,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=999999 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -340,7 +341,6 @@ CONFIG_SCHED_HRTICK=y CONFIG_PREEMPT=y CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -377,7 +377,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -583,6 +582,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -712,6 +712,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -829,7 +830,6 @@ CONFIG_RTC_DRV_SH=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -896,6 +896,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -919,6 +920,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -958,6 +960,7 @@ CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set CONFIG_DEBUG_PREEMPT=y CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_PI_LIST=y @@ -1010,6 +1013,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1038,6 +1042,7 @@ CONFIG_DUMP_CODE=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig index efda63d4070a..4b751bd37e20 100644 --- a/arch/sh/configs/r7780mp_defconfig +++ b/arch/sh/configs/r7780mp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:16:13 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 15:58:09 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -33,6 +33,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_IO_TRAPPED=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -73,11 +76,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -112,7 +110,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y @@ -122,7 +119,6 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -133,6 +129,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -245,11 +242,8 @@ CONFIG_PAGE_OFFSET=0x80000000 CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 -# CONFIG_29BIT is not set -CONFIG_32BIT=y -CONFIG_PMB_ENABLE=y +CONFIG_29BIT=y # CONFIG_PMB is not set -CONFIG_PMB_FIXED=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -257,6 +251,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -278,7 +273,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -358,7 +353,7 @@ CONFIG_KEXEC=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -374,9 +369,9 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -402,7 +397,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -452,6 +446,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ATM is not set CONFIG_STP=m CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y # CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set @@ -472,7 +467,6 @@ CONFIG_LLC=m # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -621,6 +615,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set # CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_DS1682 is not set # CONFIG_C2PORT is not set @@ -638,6 +633,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -755,6 +751,7 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -791,7 +788,7 @@ CONFIG_PATA_PLATFORM=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -832,6 +829,7 @@ CONFIG_NET_PCI=y CONFIG_PCNET32=m # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -884,6 +882,8 @@ CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +CONFIG_CHELSIO_T4_DEPENDS=y +# CONFIG_CHELSIO_T4 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set @@ -896,6 +896,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set @@ -995,6 +996,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -1043,6 +1045,7 @@ CONFIG_I2C_HIGHLANDER=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -1055,15 +1058,9 @@ CONFIG_I2C_HIGHLANDER=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -1087,10 +1084,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_I5K_AMB is not set @@ -1127,6 +1125,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_TMP421 is not set @@ -1156,6 +1155,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set @@ -1163,12 +1163,14 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1176,6 +1178,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1372,6 +1375,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1402,6 +1406,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1480,6 +1485,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_PREEMPT is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -1490,7 +1496,6 @@ CONFIG_SCHED_DEBUG=y # CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y @@ -1507,11 +1512,11 @@ CONFIG_DEBUG_INFO=y # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1519,10 +1524,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y # CONFIG_FUNCTION_TRACER is not set @@ -1535,6 +1537,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1662,7 +1665,8 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig index f4b00451dcee..f5e3819469e9 100644 --- a/arch/sh/configs/r7785rp_defconfig +++ b/arch/sh/configs/r7785rp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:19:35 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:03:27 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -34,6 +34,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_IO_TRAPPED=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -49,9 +50,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -77,7 +80,6 @@ CONFIG_TREE_RCU_TRACE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -112,7 +114,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y @@ -122,18 +123,17 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y CONFIG_KRETPROBES=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -247,12 +247,9 @@ CONFIG_PAGE_OFFSET=0x80000000 CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 -# CONFIG_29BIT is not set -CONFIG_32BIT=y -CONFIG_PMB_ENABLE=y +CONFIG_29BIT=y # CONFIG_PMB is not set -CONFIG_PMB_FIXED=y -# CONFIG_X2TLB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y # CONFIG_NUMA is not set CONFIG_ARCH_FLATMEM_ENABLE=y @@ -263,6 +260,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -285,7 +284,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=999999 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -303,6 +302,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y CONFIG_SH_STORE_QUEUES=y +# CONFIG_SPECULATIVE_EXECUTION is not set CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_FPU=y @@ -377,7 +377,7 @@ CONFIG_KEXEC=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -393,9 +393,9 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCI_LEGACY is not set # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -421,7 +421,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -471,6 +470,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ATM is not set CONFIG_STP=m CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y # CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set @@ -492,7 +492,6 @@ CONFIG_LLC=m # # CONFIG_NET_PKTGEN is not set # CONFIG_NET_TCPPROBE is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -557,6 +556,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set # CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_DS1682 is not set # CONFIG_C2PORT is not set @@ -574,6 +574,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -691,6 +692,7 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -727,7 +729,7 @@ CONFIG_PATA_PLATFORM=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -797,6 +799,8 @@ CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +CONFIG_CHELSIO_T4_DEPENDS=y +# CONFIG_CHELSIO_T4 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set @@ -809,6 +813,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set @@ -910,6 +915,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -959,6 +965,7 @@ CONFIG_I2C_HIGHLANDER=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -971,15 +978,9 @@ CONFIG_I2C_HIGHLANDER=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -994,13 +995,17 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_SCH is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -1033,10 +1038,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_I5K_AMB is not set @@ -1074,6 +1080,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_TMP421 is not set @@ -1102,20 +1109,25 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set +# CONFIG_MFD_TIMBERDALE is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1123,6 +1135,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1371,6 +1384,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1401,6 +1415,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1475,6 +1490,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_PREEMPT is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -1510,7 +1526,6 @@ CONFIG_FRAME_POINTER=y # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1518,10 +1533,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y # CONFIG_FUNCTION_TRACER is not set @@ -1534,6 +1546,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1661,7 +1674,8 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig index 2fc635a5a8c5..80e7b41ca620 100644 --- a/arch/sh/configs/rsk7201_defconfig +++ b/arch/sh/configs/rsk7201_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:23:12 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:09:18 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -44,9 +45,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y @@ -65,7 +68,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y # CONFIG_IKCONFIG_PROC is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -79,6 +81,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -105,7 +108,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -114,7 +116,6 @@ CONFIG_COMPAT_BRK=y CONFIG_SLOB=y # CONFIG_MMAP_ALLOW_UNINITIALIZED is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -124,6 +125,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -240,6 +242,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -255,7 +258,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1 # @@ -326,7 +329,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -485,6 +487,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -545,6 +548,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=8 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set @@ -657,7 +661,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -720,6 +723,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -756,13 +760,12 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_STACKTRACE=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -770,10 +773,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # CONFIG_DYNAMIC_DEBUG is not set @@ -795,7 +795,8 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig index 0169e60e0947..66eb7d7dad44 100644 --- a/arch/sh/configs/rsk7203_defconfig +++ b/arch/sh/configs/rsk7203_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:23:54 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:11:37 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -45,9 +46,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y @@ -70,7 +73,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y # CONFIG_IKCONFIG_PROC is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -85,6 +87,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -112,7 +115,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y @@ -122,7 +124,6 @@ CONFIG_COMPAT_BRK=y CONFIG_SLOB=y # CONFIG_MMAP_ALLOW_UNINITIALIZED is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -132,6 +133,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -248,6 +250,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -263,7 +266,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1 # @@ -350,7 +353,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -448,7 +450,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -592,6 +593,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -662,6 +664,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -723,6 +726,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=4 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set @@ -745,6 +749,7 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: @@ -783,6 +788,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_TMIO is not set CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set # CONFIG_REGULATOR_FIXED_VOLTAGE is not set # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set @@ -816,6 +822,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -831,14 +838,19 @@ CONFIG_HID_GYRATION=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=y # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=y # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -859,7 +871,6 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_DEVICEFS=y CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set @@ -916,7 +927,6 @@ CONFIG_USB_R8A66597_HCD=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -928,7 +938,6 @@ CONFIG_USB_R8A66597_HCD=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -948,11 +957,11 @@ CONFIG_LEDS_GPIO=y CONFIG_LEDS_GPIO_PLATFORM=y # CONFIG_LEDS_REGULATOR is not set # CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y # # LED Triggers # -CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_BACKLIGHT=y @@ -1018,7 +1027,6 @@ CONFIG_RTC_DRV_SH=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1072,6 +1080,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1098,6 +1107,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1180,6 +1190,7 @@ CONFIG_DEBUG_OBJECTS=y # CONFIG_DEBUG_OBJECTS_TIMERS is not set # CONFIG_DEBUG_OBJECTS_WORK is not set CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 +# CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -1189,7 +1200,6 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_LOCK_STAT is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y @@ -1207,11 +1217,11 @@ CONFIG_FRAME_POINTER=y # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_PAGE_POISONING is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1219,10 +1229,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y # CONFIG_FUNCTION_TRACER is not set @@ -1234,6 +1241,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1263,7 +1271,8 @@ CONFIG_DUMP_CODE=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig index dba024d72a89..6bd3d95d1518 100644 --- a/arch/sh/configs/rts7751r2d1_defconfig +++ b/arch/sh/configs/rts7751r2d1_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:25:36 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:15:07 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -33,6 +33,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_IO_TRAPPED=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -47,9 +48,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -70,7 +73,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -104,7 +106,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y @@ -113,7 +114,6 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -124,6 +124,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -242,6 +243,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -257,7 +259,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -343,7 +345,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -359,9 +360,9 @@ CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set @@ -389,7 +390,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -449,7 +449,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -525,6 +524,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -642,6 +642,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -678,7 +679,7 @@ CONFIG_PATA_PLATFORM=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -719,6 +720,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -771,6 +773,8 @@ CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +CONFIG_CHELSIO_T4_DEPENDS=y +# CONFIG_CHELSIO_T4 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set @@ -783,6 +787,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set @@ -805,6 +810,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -882,6 +888,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -964,6 +971,7 @@ CONFIG_MFD_SM501=y # CONFIG_MFD_MC13783 is not set # CONFIG_EZX_PCAP is not set # CONFIG_AB4500_CORE is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -971,6 +979,7 @@ CONFIG_MFD_SM501=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m @@ -1152,6 +1161,7 @@ CONFIG_SND_SPI=y CONFIG_SND_SUPERH=y CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set # CONFIG_SND_USB_CAIAQ is not set # CONFIG_SND_SOC is not set CONFIG_SOUND_PRIME=m @@ -1170,6 +1180,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -1185,14 +1196,19 @@ CONFIG_HID_GYRATION=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=y # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=y # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1291,7 +1307,6 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1303,7 +1318,6 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1381,7 +1395,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1442,6 +1455,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1456,6 +1470,7 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1522,13 +1537,12 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_STACKTRACE=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1536,10 +1550,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # CONFIG_DYNAMIC_DEBUG is not set @@ -1648,7 +1659,8 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig index 6d511d06cbf6..487abcc4d4e7 100644 --- a/arch/sh/configs/rts7751r2dplus_defconfig +++ b/arch/sh/configs/rts7751r2dplus_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:26:39 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:20:00 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -33,6 +33,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_IO_TRAPPED=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -47,9 +48,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -70,7 +73,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -104,7 +106,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y @@ -113,7 +114,6 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -124,6 +124,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -242,6 +243,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -257,7 +259,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -343,7 +345,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -359,9 +360,9 @@ CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set @@ -389,7 +390,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -449,7 +449,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -611,6 +610,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -728,6 +728,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -764,7 +765,7 @@ CONFIG_PATA_PLATFORM=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -805,6 +806,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -857,6 +859,8 @@ CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +CONFIG_CHELSIO_T4_DEPENDS=y +# CONFIG_CHELSIO_T4 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set @@ -869,6 +873,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set @@ -891,6 +896,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -968,6 +974,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -1050,6 +1057,7 @@ CONFIG_MFD_SM501=y # CONFIG_MFD_MC13783 is not set # CONFIG_EZX_PCAP is not set # CONFIG_AB4500_CORE is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1057,6 +1065,7 @@ CONFIG_MFD_SM501=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m @@ -1238,6 +1247,7 @@ CONFIG_SND_SPI=y CONFIG_SND_SUPERH=y CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set # CONFIG_SND_USB_CAIAQ is not set # CONFIG_SND_SOC is not set CONFIG_SOUND_PRIME=m @@ -1256,6 +1266,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -1271,14 +1282,19 @@ CONFIG_HID_GYRATION=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=y # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=y # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1377,7 +1393,6 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1389,7 +1404,6 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1467,7 +1481,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1529,6 +1542,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1543,6 +1557,7 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1609,13 +1624,12 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_STACKTRACE=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1623,10 +1637,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # CONFIG_DYNAMIC_DEBUG is not set @@ -1735,7 +1746,8 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig index 1859ba099945..fe923142c2cc 100644 --- a/arch/sh/configs/sdk7780_defconfig +++ b/arch/sh/configs/sdk7780_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:27:20 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:21:00 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -47,9 +48,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -73,7 +76,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=18 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -107,8 +109,9 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y CONFIG_SLUB_DEBUG=y @@ -126,6 +129,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -237,11 +241,8 @@ CONFIG_PAGE_OFFSET=0x80000000 CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 -# CONFIG_29BIT is not set -CONFIG_32BIT=y -CONFIG_PMB_ENABLE=y +CONFIG_29BIT=y # CONFIG_PMB is not set -CONFIG_PMB_FIXED=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -249,6 +250,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -270,7 +272,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -353,7 +355,7 @@ CONFIG_SCHED_HRTICK=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -369,16 +371,15 @@ CONFIG_CMDLINE="mem=128M console=tty0 console=ttySC0,115200 ip=bootp root=/dev/n # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCI_LEGACY is not set CONFIG_PCI_DEBUG=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set CONFIG_PCCARD=y CONFIG_PCMCIA=y CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y CONFIG_CARDBUS=y # @@ -417,7 +418,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -659,6 +659,7 @@ CONFIG_BLK_DEV_GENERIC=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -777,6 +778,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -824,7 +826,7 @@ CONFIG_BLK_DEV_DM=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -890,6 +892,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_NET_PCMCIA is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set @@ -995,6 +998,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -1057,6 +1061,7 @@ CONFIG_SSB_DRIVER_PCICORE=y # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1064,6 +1069,7 @@ CONFIG_SSB_DRIVER_PCICORE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1167,6 +1173,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -1182,14 +1189,19 @@ CONFIG_HID_GYRATION=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=y # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=y # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1288,7 +1300,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1301,7 +1312,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1317,10 +1327,6 @@ CONFIG_LEDS_CLASS=y # # LED drivers # - -# -# LED Triggers -# # CONFIG_LEDS_TRIGGERS is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set @@ -1416,6 +1422,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1444,6 +1451,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1523,6 +1531,7 @@ CONFIG_TIMER_STATS=y # CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -1571,6 +1580,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1690,6 +1700,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index 740ada659441..269824598520 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.34-rc5 -# Mon Apr 26 16:52:58 2010 +# Tue May 18 18:03:37 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -29,6 +29,7 @@ CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_NO_VIRT_TO_BUS=y @@ -277,7 +278,7 @@ CONFIG_QUICKLIST=y CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_MEMORY_START=0x60000000 +CONFIG_MEMORY_START=0x40000000 CONFIG_MEMORY_SIZE=0x20000000 # CONFIG_29BIT is not set CONFIG_32BIT=y @@ -410,10 +411,10 @@ CONFIG_HZ_1000=y CONFIG_HZ=1000 CONFIG_SCHED_HRTICK=y CONFIG_KEXEC=y -# CONFIG_CRASH_DUMP is not set CONFIG_SECCOMP=y CONFIG_SMP=y CONFIG_NR_CPUS=2 +CONFIG_HOTPLUG_CPU=y # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y @@ -1101,7 +1102,6 @@ CONFIG_I2C_HELPER_AUTO=y # # CONFIG_I2C_DESIGNWARE is not set # CONFIG_I2C_OCORES is not set -CONFIG_I2C_SDK7786=y # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_XILINX is not set @@ -1775,8 +1775,8 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set CONFIG_DEBUG_PREEMPT=y @@ -1810,6 +1810,7 @@ CONFIG_RCU_CPU_STALL_DETECTOR=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set +CONFIG_LATENCYTOP=y CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_PAGE_POISONING is not set CONFIG_NOP_TRACER=y @@ -1974,6 +1975,7 @@ CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_VIRTUALIZATION is not set CONFIG_BINARY_PRINTF=y # diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index 43e6780a89d1..910eaec934c9 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:30:00 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:34:06 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y @@ -72,7 +75,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_TREE_RCU_TRACE=y # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set CONFIG_CGROUPS=y CONFIG_CGROUP_DEBUG=y CONFIG_CGROUP_NS=y @@ -82,6 +84,7 @@ CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y CONFIG_CGROUP_MEM_RES_CTLR=y +# CONFIG_CGROUP_SCHED is not set CONFIG_MM_OWNER=y # CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y @@ -96,6 +99,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -123,7 +127,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y @@ -133,7 +136,6 @@ CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLOB=y # CONFIG_MMAP_ALLOW_UNINITIALIZED is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -143,6 +145,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -162,7 +165,6 @@ CONFIG_BLOCK=y CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_CGROUP is not set # # IO Schedulers @@ -261,6 +263,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -276,7 +279,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1 # @@ -361,7 +364,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -400,7 +402,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -463,7 +464,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -607,6 +607,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -688,6 +689,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=4 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set @@ -799,7 +801,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -853,6 +854,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -881,6 +883,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -919,6 +922,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_KMEMLEAK is not set CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -929,7 +933,6 @@ CONFIG_DEBUG_PREEMPT=y # CONFIG_LOCK_STAT is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set @@ -947,11 +950,11 @@ CONFIG_FRAME_POINTER=y # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -959,10 +962,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y # CONFIG_FUNCTION_TRACER is not set @@ -975,6 +975,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1094,7 +1095,8 @@ CONFIG_CRYPTO_LZO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig index ec494e32fa2e..586cb1e02be0 100644 --- a/arch/sh/configs/se7343_defconfig +++ b/arch/sh/configs/se7343_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:30:41 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:37:31 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -70,11 +73,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -107,7 +105,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -124,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -245,6 +244,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -260,7 +260,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -335,7 +335,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -370,6 +370,7 @@ CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y # CONFIG_CPU_IDLE is not set CONFIG_NET=y @@ -377,7 +378,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -569,6 +569,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -635,6 +636,7 @@ CONFIG_USB_USBNET=y CONFIG_USB_NET_CDCETHER=y # CONFIG_USB_NET_CDC_EEM is not set CONFIG_USB_NET_DM9601=y +# CONFIG_USB_NET_SMSC75XX is not set # CONFIG_USB_NET_SMSC95XX is not set # CONFIG_USB_NET_GL620A is not set # CONFIG_USB_NET_NET1080 is not set @@ -644,6 +646,7 @@ CONFIG_USB_NET_DM9601=y # CONFIG_USB_NET_CDC_SUBSET is not set # CONFIG_USB_NET_ZAURUS is not set # CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -713,6 +716,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=4 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_UNIX98_PTYS is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -739,6 +743,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_SH_MOBILE=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -752,15 +757,9 @@ CONFIG_I2C_SH_MOBILE=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -783,6 +782,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set @@ -790,12 +790,13 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -878,6 +879,7 @@ CONFIG_SND_DRIVERS=y CONFIG_SND_SUPERH=y CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set # CONFIG_SND_USB_CAIAQ is not set # CONFIG_SND_SOC is not set # CONFIG_SOUND_PRIME is not set @@ -895,6 +897,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -910,14 +913,19 @@ CONFIG_HID_GYRATION=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=y # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=y # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -997,7 +1005,6 @@ CONFIG_USB_ISP116X_HCD=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1009,7 +1016,6 @@ CONFIG_USB_ISP116X_HCD=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1027,8 +1033,6 @@ CONFIG_RTC_LIB=y CONFIG_UIO=y # CONFIG_UIO_PDRV is not set # CONFIG_UIO_PDRV_GENIRQ is not set -# CONFIG_UIO_SMX is not set -# CONFIG_UIO_SERCOS3 is not set # # TI VLYNQ @@ -1115,6 +1119,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1141,6 +1146,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1324,6 +1330,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig index ee87e2b2168f..acb3e02a7123 100644 --- a/arch/sh/configs/se7619_defconfig +++ b/arch/sh/configs/se7619_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:34:15 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:41:13 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -44,9 +45,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SYSVIPC is not set # CONFIG_BSD_PROCESS_ACCT is not set @@ -62,7 +65,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set @@ -91,7 +93,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set # CONFIG_VM_EVENT_COUNTERS is not set CONFIG_COMPAT_BRK=y @@ -107,6 +109,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -217,6 +220,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -232,7 +236,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1 # @@ -301,7 +305,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -453,6 +456,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -513,6 +517,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set @@ -612,7 +617,6 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -664,6 +668,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -729,6 +734,7 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig index 03f4219f2086..084fec9e9050 100644 --- a/arch/sh/configs/se7705_defconfig +++ b/arch/sh/configs/se7705_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:34:37 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:42:43 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SWAP is not set # CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set @@ -67,7 +70,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set @@ -76,6 +78,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -101,7 +104,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -117,6 +120,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -234,6 +238,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -249,7 +254,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -327,7 +332,6 @@ CONFIG_HZ=250 CONFIG_PREEMPT=y CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -362,7 +366,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -562,6 +565,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -679,6 +683,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -798,7 +803,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -863,6 +867,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -885,6 +890,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1026,6 +1032,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig index cfa58199a368..4487a230466f 100644 --- a/arch/sh/configs/se7712_defconfig +++ b/arch/sh/configs/se7712_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:44:56 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 18:05:15 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -12,8 +12,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -29,6 +29,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -43,9 +44,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -68,7 +71,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -102,8 +104,9 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -119,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -236,6 +240,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -251,7 +256,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -329,7 +334,6 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -366,7 +370,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -614,6 +617,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -754,6 +758,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -834,11 +839,11 @@ CONFIG_LEDS_CLASS=y # # LED drivers # +CONFIG_LEDS_TRIGGERS=y # # LED Triggers # -CONFIG_LEDS_TRIGGERS=y # CONFIG_LEDS_TRIGGER_TIMER is not set # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set @@ -940,6 +945,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -962,6 +968,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -997,6 +1004,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -1042,6 +1050,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1167,6 +1176,7 @@ CONFIG_CRYPTO_DEFLATE=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig index 201283c829a1..7c06b5c0b49b 100644 --- a/arch/sh/configs/se7721_defconfig +++ b/arch/sh/configs/se7721_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:46:58 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 18:06:03 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -12,8 +12,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -44,9 +45,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -69,11 +72,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -107,8 +105,9 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -124,6 +123,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -241,6 +241,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -256,7 +257,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -334,7 +335,6 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -371,7 +371,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -620,6 +619,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -687,6 +687,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -764,6 +765,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -829,6 +831,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -844,14 +847,19 @@ CONFIG_HID_GYRATION=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=y # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=y # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -946,7 +954,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -958,7 +965,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -973,11 +979,11 @@ CONFIG_LEDS_CLASS=y # # LED drivers # +CONFIG_LEDS_TRIGGERS=y # # LED Triggers # -CONFIG_LEDS_TRIGGERS=y # CONFIG_LEDS_TRIGGER_TIMER is not set # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set @@ -1082,6 +1088,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1163,6 +1170,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -1208,6 +1216,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1333,6 +1342,7 @@ CONFIG_CRYPTO_DEFLATE=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig index 4a4efd261d03..42782e7ff8ba 100644 --- a/arch/sh/configs/se7722_defconfig +++ b/arch/sh/configs/se7722_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 13:49:15 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 18:07:07 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -73,7 +76,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -84,6 +86,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -122,13 +125,13 @@ CONFIG_PROFILING=y # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -245,7 +248,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y -# CONFIG_X2TLB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_NUMA=y CONFIG_NODES_SHIFT=1 @@ -256,6 +259,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -279,7 +284,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -356,7 +361,7 @@ CONFIG_KEXEC=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -391,6 +396,7 @@ CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_HIBERNATION is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y # CONFIG_CPU_IDLE is not set CONFIG_NET=y @@ -398,7 +404,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -519,6 +524,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -676,6 +682,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -898,6 +905,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -912,6 +920,7 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -944,6 +953,7 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y @@ -1059,6 +1069,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig index ab371afe3595..ebb4ac4a7d8f 100644 --- a/arch/sh/configs/se7724_defconfig +++ b/arch/sh/configs/se7724_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 14:36:56 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 16:55:41 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -47,9 +48,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -71,11 +74,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -107,7 +105,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -116,13 +114,13 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -237,8 +235,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set -# CONFIG_X2TLB is not set +# CONFIG_PMB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -246,6 +244,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -261,7 +261,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -340,7 +340,7 @@ CONFIG_SECCOMP=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -376,6 +376,7 @@ CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_HIBERNATION is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y # CONFIG_CPU_IDLE is not set CONFIG_NET=y @@ -383,7 +384,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -559,6 +559,7 @@ CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_NAND_SH_FLCTL is not set # CONFIG_MTD_ONENAND is not set # @@ -600,6 +601,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_DS1682 is not set # CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set @@ -619,6 +621,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -726,6 +729,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -805,6 +809,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -833,6 +838,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_SH_MOBILE=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -846,15 +852,9 @@ CONFIG_I2C_SH_MOBILE=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y CONFIG_SPI_MASTER=y @@ -885,13 +885,16 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -923,22 +926,25 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_AB4500_CORE is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -1001,7 +1007,9 @@ CONFIG_USB_GSPCA=m # CONFIG_USB_M5602 is not set # CONFIG_USB_STV06XX is not set # CONFIG_USB_GL860 is not set +# CONFIG_USB_GSPCA_BENQ is not set # CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_CPIA1 is not set # CONFIG_USB_GSPCA_ETOMS is not set # CONFIG_USB_GSPCA_FINEPIX is not set # CONFIG_USB_GSPCA_JEILINJ is not set @@ -1009,9 +1017,11 @@ CONFIG_USB_GSPCA=m # CONFIG_USB_GSPCA_MR97310A is not set # CONFIG_USB_GSPCA_OV519 is not set # CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_OV534_9 is not set # CONFIG_USB_GSPCA_PAC207 is not set # CONFIG_USB_GSPCA_PAC7302 is not set # CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SN9C2028 is not set # CONFIG_USB_GSPCA_SN9C20X is not set # CONFIG_USB_GSPCA_SONIXB is not set # CONFIG_USB_GSPCA_SONIXJ is not set @@ -1033,6 +1043,7 @@ CONFIG_USB_GSPCA=m # CONFIG_VIDEO_PVRUSB2 is not set # CONFIG_VIDEO_HDPVR is not set # CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_TLG2300 is not set # CONFIG_VIDEO_CX231XX is not set # CONFIG_VIDEO_USBVISION is not set # CONFIG_USB_ET61X251 is not set @@ -1147,6 +1158,7 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_SUPERH is not set CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set # CONFIG_SND_USB_CAIAQ is not set CONFIG_SND_SOC=m @@ -1155,6 +1167,7 @@ CONFIG_SND_SOC=m # CONFIG_SND_SOC_SH4_FSI=m CONFIG_SND_FSI_AK4642=y +# CONFIG_SND_FSI_DA7210 is not set CONFIG_SND_SOC_I2C_AND_SPI=m CONFIG_SND_SOC_ALL_CODECS=m CONFIG_SND_SOC_WM_HUBS=m @@ -1167,6 +1180,7 @@ CONFIG_SND_SOC_AK4535=m CONFIG_SND_SOC_AK4642=m CONFIG_SND_SOC_AK4671=m CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_DA7210=m CONFIG_SND_SOC_L3=m CONFIG_SND_SOC_PCM3008=m CONFIG_SND_SOC_SPDIF=m @@ -1189,17 +1203,21 @@ CONFIG_SND_SOC_WM8753=m CONFIG_SND_SOC_WM8776=m CONFIG_SND_SOC_WM8900=m CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8904=m CONFIG_SND_SOC_WM8940=m +CONFIG_SND_SOC_WM8955=m CONFIG_SND_SOC_WM8960=m CONFIG_SND_SOC_WM8961=m CONFIG_SND_SOC_WM8971=m CONFIG_SND_SOC_WM8974=m +CONFIG_SND_SOC_WM8978=m CONFIG_SND_SOC_WM8988=m CONFIG_SND_SOC_WM8990=m CONFIG_SND_SOC_WM8993=m CONFIG_SND_SOC_WM9081=m CONFIG_SND_SOC_MAX9877=m CONFIG_SND_SOC_TPA6130A2=m +CONFIG_SND_SOC_WM2000=m # CONFIG_SOUND_PRIME is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y @@ -1215,6 +1233,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set # CONFIG_HID_A4TECH is not set # CONFIG_HID_APPLE is not set # CONFIG_HID_BELKIN is not set @@ -1229,12 +1248,16 @@ CONFIG_USB_HID=y # CONFIG_HID_KENSINGTON is not set # CONFIG_HID_LOGITECH is not set # CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MOSART is not set # CONFIG_HID_MONTEREY is not set # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set # CONFIG_HID_PANTHERLORD is not set # CONFIG_HID_PETALYNX is not set +# CONFIG_HID_QUANTA is not set # CONFIG_HID_SAMSUNG is not set # CONFIG_HID_SONY is not set +# CONFIG_HID_STANTUM is not set # CONFIG_HID_SUNPLUS is not set # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1327,7 +1350,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1339,7 +1361,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG_FILES is not set CONFIG_USB_GADGET_VBUS_DRAW=2 @@ -1378,6 +1399,7 @@ CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set # CONFIG_USB_G_MULTI is not set # @@ -1401,10 +1423,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_AT91 is not set -# CONFIG_MMC_ATMELMCI is not set CONFIG_MMC_SPI=y -# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1480,8 +1499,6 @@ CONFIG_RTC_DRV_PCF8563=y CONFIG_UIO=y # CONFIG_UIO_PDRV is not set CONFIG_UIO_PDRV_GENIRQ=y -# CONFIG_UIO_SMX is not set -# CONFIG_UIO_SERCOS3 is not set # # TI VLYNQ @@ -1566,6 +1583,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_UBIFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1594,6 +1612,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1786,6 +1805,7 @@ CONFIG_CRYPTO_CBC=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig index b15a44e2ec43..e096c3e7e18c 100644 --- a/arch/sh/configs/se7750_defconfig +++ b/arch/sh/configs/se7750_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 14:39:10 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:00:16 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -70,7 +73,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -103,7 +105,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -120,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -237,6 +240,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -252,7 +256,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -329,7 +333,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -364,7 +367,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -580,6 +582,7 @@ CONFIG_IDE_PROC_FS=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -698,6 +701,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -816,7 +820,6 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -885,6 +888,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -907,6 +911,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1063,6 +1068,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig index d1effdeaa416..84d3facf6a30 100644 --- a/arch/sh/configs/se7751_defconfig +++ b/arch/sh/configs/se7751_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 14:39:56 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:03:26 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -69,7 +72,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -80,6 +82,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -106,7 +109,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -123,6 +126,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -240,6 +244,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -255,7 +260,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -333,7 +338,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -369,7 +373,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -589,6 +592,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -666,6 +670,7 @@ CONFIG_DEVKMEM=y # Non-8250 serial port support # # CONFIG_SERIAL_SH_SCI is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -785,7 +790,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -854,6 +858,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -868,6 +873,7 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1012,6 +1018,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig index 58533d50f06e..f0d7e679e75f 100644 --- a/arch/sh/configs/se7780_defconfig +++ b/arch/sh/configs/se7780_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 14:40:32 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:06:12 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -100,7 +103,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y @@ -117,6 +120,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -238,6 +242,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -253,7 +258,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -328,6 +333,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -343,9 +349,9 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -362,7 +368,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -571,6 +576,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -714,7 +720,7 @@ CONFIG_SATA_SIL=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -772,6 +778,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -807,6 +814,7 @@ CONFIG_WLAN=y # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_PPP is not set @@ -878,6 +886,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -928,6 +937,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -935,6 +945,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1032,6 +1043,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -1047,14 +1059,19 @@ CONFIG_HID_GYRATION=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=y # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=y # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1148,7 +1165,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1161,7 +1177,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1192,7 +1207,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -1211,6 +1225,7 @@ CONFIG_INOTIFY_USER=y # # Caches # +# CONFIG_FSCACHE is not set # # CD-ROM/DVD Filesystems @@ -1332,6 +1347,7 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y @@ -1442,6 +1458,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig index 666fde110b27..562147d333e3 100644 --- a/arch/sh/configs/sh03_defconfig +++ b/arch/sh/configs/sh03_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 14:41:25 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:10:00 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -73,7 +76,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -84,6 +86,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -111,7 +114,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y @@ -120,7 +122,6 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -131,6 +132,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -250,6 +252,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -265,7 +268,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -342,7 +345,6 @@ CONFIG_HZ=250 CONFIG_PREEMPT=y CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -358,9 +360,9 @@ CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs" # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set @@ -388,7 +390,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -453,7 +454,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -574,6 +574,7 @@ CONFIG_IDE_PROC_FS=y # # SCSI device support # +CONFIG_SCSI_MOD=m # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=m CONFIG_SCSI_DMA=y @@ -664,7 +665,7 @@ CONFIG_SCSI_LOWLEVEL=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -704,6 +705,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -751,6 +753,8 @@ CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +CONFIG_CHELSIO_T4_DEPENDS=y +# CONFIG_CHELSIO_T4 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set @@ -763,6 +767,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set @@ -853,6 +858,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -927,6 +933,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -934,6 +941,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1075,6 +1083,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1105,6 +1114,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1187,13 +1197,12 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_STACKTRACE=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1201,10 +1210,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # CONFIG_DYNAMIC_DEBUG is not set @@ -1323,7 +1329,8 @@ CONFIG_CRYPTO_DEFLATE=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig index 35a3beeba182..98485ca46390 100644 --- a/arch/sh/configs/sh7710voipgw_defconfig +++ b/arch/sh/configs/sh7710voipgw_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 14:43:04 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:14:59 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -44,9 +45,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -68,11 +71,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -105,7 +103,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -122,6 +120,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -240,6 +239,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -255,7 +255,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -331,7 +331,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -367,7 +366,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -620,6 +618,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -723,6 +722,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_UNIX98_PTYS is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -824,7 +824,6 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -890,6 +889,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -904,6 +904,7 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -934,6 +935,7 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set CONFIG_HAVE_FUNCTION_TRACER=y @@ -1049,6 +1051,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/sh7724_generic_defconfig b/arch/sh/configs/sh7724_generic_defconfig index a3056b69d2ba..a6a9e6887ef8 100644 --- a/arch/sh/configs/sh7724_generic_defconfig +++ b/arch/sh/configs/sh7724_generic_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:03:45 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:17:36 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -65,11 +68,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set # CONFIG_CGROUP_NS is not set @@ -78,6 +76,7 @@ CONFIG_CGROUPS=y # CONFIG_CPUSETS is not set # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set +# CONFIG_CGROUP_SCHED is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set @@ -106,7 +105,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y # CONFIG_COMPAT_BRK is not set @@ -114,21 +112,19 @@ CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling # -# CONFIG_GCOV_KERNEL is not set # CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_RT_MUTEXES=y @@ -138,7 +134,6 @@ CONFIG_BLOCK=y CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_CGROUP is not set # # IO Schedulers @@ -235,8 +230,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set -# CONFIG_X2TLB is not set +# CONFIG_PMB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -246,6 +241,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -262,7 +259,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -353,7 +350,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -390,6 +387,7 @@ CONFIG_HIBERNATION_NVS=y CONFIG_HIBERNATION=y CONFIG_PM_STD_PARTITION="" CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y @@ -428,6 +426,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -467,6 +466,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set @@ -491,6 +491,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_SH_MOBILE=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -502,15 +503,9 @@ CONFIG_I2C_SH_MOBILE=y # Other I2C/SMBus bus drivers # # CONFIG_I2C_PCA_PLATFORM is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -533,6 +528,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set @@ -540,12 +536,13 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -629,8 +626,6 @@ CONFIG_RTC_DRV_SH=y CONFIG_UIO=y # CONFIG_UIO_PDRV is not set CONFIG_UIO_PDRV_GENIRQ=y -# CONFIG_UIO_SMX is not set -# CONFIG_UIO_SERCOS3 is not set # # TI VLYNQ @@ -643,7 +638,6 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -707,15 +701,12 @@ CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set # CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_STACKTRACE=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -723,13 +714,9 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set -# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y @@ -747,7 +734,8 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig index 04b841b29427..6f308b71f81a 100644 --- a/arch/sh/configs/sh7763rdp_defconfig +++ b/arch/sh/configs/sh7763rdp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:05:29 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:19:21 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -69,11 +72,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -112,7 +110,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -120,7 +117,6 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -131,6 +127,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -243,7 +240,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set +# CONFIG_PMB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -253,6 +250,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -269,7 +267,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -344,7 +342,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -381,7 +379,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -444,7 +441,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -585,6 +581,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -689,6 +686,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -754,6 +752,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -945,7 +944,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -957,7 +955,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -980,9 +977,6 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_AT91 is not set -# CONFIG_MMC_ATMELMCI is not set -# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1074,6 +1068,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1096,6 +1091,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1162,13 +1158,12 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_STACKTRACE=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1176,10 +1171,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # CONFIG_DYNAMIC_DEBUG is not set @@ -1287,7 +1279,8 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/sh7770_generic_defconfig b/arch/sh/configs/sh7770_generic_defconfig index 7b247053ece6..4327f898baa8 100644 --- a/arch/sh/configs/sh7770_generic_defconfig +++ b/arch/sh/configs/sh7770_generic_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:06:28 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:20:25 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -45,9 +46,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -64,11 +67,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set # CONFIG_CGROUP_NS is not set @@ -77,6 +75,7 @@ CONFIG_CGROUPS=y # CONFIG_CPUSETS is not set # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set +# CONFIG_CGROUP_SCHED is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set @@ -105,7 +104,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y # CONFIG_COMPAT_BRK is not set @@ -113,7 +111,6 @@ CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_IOREMAP_PROT=y @@ -123,11 +120,11 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling # -# CONFIG_GCOV_KERNEL is not set # CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_RT_MUTEXES=y @@ -137,7 +134,6 @@ CONFIG_BLOCK=y CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_CGROUP is not set # # IO Schedulers @@ -232,7 +228,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set +# CONFIG_PMB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -242,6 +238,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -258,7 +255,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -347,7 +344,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -382,6 +379,7 @@ CONFIG_HIBERNATION_NVS=y CONFIG_HIBERNATION=y CONFIG_PM_STD_PARTITION="" # CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y @@ -420,6 +418,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -459,6 +458,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set @@ -483,6 +483,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_SH_MOBILE=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -494,15 +495,9 @@ CONFIG_I2C_SH_MOBILE=y # Other I2C/SMBus bus drivers # # CONFIG_I2C_PCA_PLATFORM is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -525,6 +520,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set @@ -532,12 +528,13 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -621,8 +618,6 @@ CONFIG_RTC_DRV_SH=y CONFIG_UIO=y # CONFIG_UIO_PDRV is not set CONFIG_UIO_PDRV_GENIRQ=y -# CONFIG_UIO_SMX is not set -# CONFIG_UIO_SERCOS3 is not set # # TI VLYNQ @@ -635,7 +630,6 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -699,15 +693,12 @@ CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set # CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_STACKTRACE=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -715,13 +706,9 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set -# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y @@ -739,7 +726,8 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig index 8330813b0c1d..e9af616b2160 100644 --- a/arch/sh/configs/sh7785lcr_32bit_defconfig +++ b/arch/sh/configs/sh7785lcr_32bit_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:07:40 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:22:09 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -74,11 +77,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -112,7 +110,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y CONFIG_PERF_COUNTERS=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y @@ -126,13 +123,13 @@ CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y CONFIG_KRETPROBES=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -246,12 +243,9 @@ CONFIG_PAGE_OFFSET=0x80000000 CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x40000000 CONFIG_MEMORY_SIZE=0x20000000 -# CONFIG_29BIT is not set -CONFIG_32BIT=y -CONFIG_PMB_ENABLE=y +CONFIG_29BIT=y # CONFIG_PMB is not set -CONFIG_PMB_FIXED=y -# CONFIG_X2TLB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y # CONFIG_NUMA is not set CONFIG_ARCH_FLATMEM_ENABLE=y @@ -262,6 +256,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -284,7 +280,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -302,6 +298,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y CONFIG_SH_STORE_QUEUES=y +# CONFIG_SPECULATIVE_EXECUTION is not set CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_FPU=y @@ -311,7 +308,7 @@ CONFIG_CPU_HAS_FPU=y # # CONFIG_SH_HIGHLANDER is not set CONFIG_SH_SH7785LCR=y -# CONFIG_SH_SH7785LCR_PT is not set +CONFIG_SH_SH7785LCR_29BIT_PHYSMAPS=y # # Timer and clock configuration @@ -374,7 +371,7 @@ CONFIG_SECCOMP=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -CONFIG_SPARSE_IRQ=y +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -389,9 +386,9 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCI_LEGACY is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set @@ -421,7 +418,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -633,6 +629,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -706,6 +703,7 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -742,7 +740,7 @@ CONFIG_SATA_SIL=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -797,6 +795,7 @@ CONFIG_R8169=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -901,6 +900,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_LEGACY_PTYS is not set @@ -947,6 +947,7 @@ CONFIG_I2C_ALGOPCA=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -960,15 +961,9 @@ CONFIG_I2C_ALGOPCA=y # CONFIG_I2C_PCA_PLATFORM=y # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -1011,6 +1006,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set CONFIG_MFD_SM501=y # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set @@ -1018,12 +1014,14 @@ CONFIG_MFD_SM501=y # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1209,6 +1207,7 @@ CONFIG_SND_CMIPCI=y # CONFIG_SND_SUPERH is not set CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set # CONFIG_SND_USB_CAIAQ is not set # CONFIG_SND_SOC is not set # CONFIG_SOUND_PRIME is not set @@ -1226,6 +1225,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=m CONFIG_HID_APPLE=m CONFIG_HID_BELKIN=m @@ -1242,14 +1242,19 @@ CONFIG_HID_KENSINGTON=m CONFIG_HID_LOGITECH=m # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=m +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=m CONFIG_HID_NTRIG=m +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=m # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=m +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=m CONFIG_HID_SONY=m +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=m CONFIG_HID_GREENASIA=m # CONFIG_GREENASIA_FF is not set @@ -1273,7 +1278,6 @@ CONFIG_USB=y # CONFIG_USB_DEVICEFS is not set CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set @@ -1351,7 +1355,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1364,7 +1367,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1390,10 +1392,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y CONFIG_MMC_SDHCI=m # CONFIG_MMC_SDHCI_PCI is not set CONFIG_MMC_SDHCI_PLTFM=m -# CONFIG_MMC_AT91 is not set -# CONFIG_MMC_ATMELMCI is not set # CONFIG_MMC_TIFM_SD is not set -# CONFIG_MMC_TMIO is not set # CONFIG_MMC_CB710 is not set # CONFIG_MMC_VIA_SDMMC is not set # CONFIG_MEMSTICK is not set @@ -1460,6 +1459,7 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_SH is not set # CONFIG_RTC_DRV_GENERIC is not set CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set # # DMA Devices @@ -1469,10 +1469,10 @@ CONFIG_UIO=m # CONFIG_UIO_CIF is not set # CONFIG_UIO_PDRV is not set # CONFIG_UIO_PDRV_GENIRQ is not set -# CONFIG_UIO_SMX is not set # CONFIG_UIO_AEC is not set # CONFIG_UIO_SERCOS3 is not set # CONFIG_UIO_PCI_GENERIC is not set +# CONFIG_UIO_NETX is not set # # TI VLYNQ @@ -1556,6 +1556,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1586,6 +1587,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1660,6 +1662,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set CONFIG_FRAME_POINTER=y # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set CONFIG_LATENCYTOP=y CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_NOP_TRACER=y @@ -1690,6 +1693,7 @@ CONFIG_SCHED_TRACER=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set CONFIG_STACK_TRACER=y CONFIG_KMEMTRACE=y CONFIG_WORKQUEUE_TRACER=y @@ -1815,6 +1819,7 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +# CONFIG_VIRTUALIZATION is not set CONFIG_BINARY_PRINTF=y # diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig index f196e87c7665..30f38c2767bf 100644 --- a/arch/sh/configs/sh7785lcr_defconfig +++ b/arch/sh/configs/sh7785lcr_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:09:09 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:27:53 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -73,11 +76,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -124,13 +122,13 @@ CONFIG_PROFILING=y # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -244,8 +242,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set -# CONFIG_X2TLB is not set +# CONFIG_PMB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y # CONFIG_NUMA is not set CONFIG_ARCH_FLATMEM_ENABLE=y @@ -254,6 +252,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -269,7 +269,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -287,6 +287,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y CONFIG_SH_STORE_QUEUES=y +# CONFIG_SPECULATIVE_EXECUTION is not set CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_FPU=y @@ -344,7 +345,7 @@ CONFIG_KEXEC=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -359,9 +360,9 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -387,7 +388,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -598,6 +598,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -671,6 +672,7 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -707,7 +709,7 @@ CONFIG_SATA_SIL=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -766,6 +768,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -851,6 +854,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -899,6 +903,7 @@ CONFIG_I2C_ALGOPCA=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -912,15 +917,9 @@ CONFIG_I2C_ALGOPCA=y # CONFIG_I2C_PCA_PLATFORM=y # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -943,6 +942,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set CONFIG_MFD_SM501=y # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set @@ -950,12 +950,14 @@ CONFIG_MFD_SM501=y # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -963,6 +965,7 @@ CONFIG_MFD_SM501=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1059,6 +1062,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -1074,14 +1078,19 @@ CONFIG_HID_GYRATION=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=y # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=y # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1182,7 +1191,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1195,7 +1203,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set CONFIG_USB_TEST=m # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1353,6 +1360,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1383,6 +1391,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1461,6 +1470,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -1509,6 +1519,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1633,6 +1644,7 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig index 45441c0ab30c..4ba2705c7a4a 100644 --- a/arch/sh/configs/shmin_defconfig +++ b/arch/sh/configs/shmin_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:10:09 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:32:23 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -12,8 +12,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -29,6 +29,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -43,9 +44,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SWAP is not set # CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set @@ -65,7 +68,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set @@ -95,7 +97,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -111,6 +113,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -222,6 +225,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -237,7 +241,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -312,7 +316,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -544,6 +547,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -625,6 +629,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -719,7 +724,6 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -773,6 +777,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -797,6 +802,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -936,6 +942,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index ecf50cda4cbc..42f6bd34440d 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:10:45 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 18:08:45 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -28,6 +28,7 @@ CONFIG_SYS_SUPPORTS_NUMA=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_NO_VIRT_TO_BUS=y @@ -35,6 +36,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_COHERENT=y # CONFIG_DMA_NONCOHERENT is not set +# CONFIG_NEED_DMA_MAP_STATE is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -49,9 +51,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -73,15 +77,11 @@ CONFIG_TREE_RCU=y CONFIG_RCU_TRACE=y CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set CONFIG_TREE_RCU_TRACE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set CONFIG_CGROUP_NS=y @@ -92,6 +92,7 @@ CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y CONFIG_CGROUP_MEM_RES_CTLR=y # CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set +# CONFIG_CGROUP_SCHED is not set CONFIG_MM_OWNER=y CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -131,7 +132,6 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y @@ -140,12 +140,10 @@ CONFIG_COMPAT_BRK=y # CONFIG_SLUB is not set CONFIG_SLOB=y CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y CONFIG_KRETPROBES=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y @@ -153,6 +151,7 @@ CONFIG_HAVE_DMA_ATTRS=y CONFIG_USE_GENERIC_SMP_HELPERS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -173,7 +172,6 @@ CONFIG_BLOCK=y CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_CGROUP is not set # # IO Schedulers @@ -269,8 +267,8 @@ CONFIG_FORCE_MAX_ZONEORDER=7 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set -# CONFIG_X2TLB is not set +# CONFIG_PMB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_NUMA=y CONFIG_NODES_SHIFT=3 @@ -282,6 +280,8 @@ CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y # CONFIG_PAGE_SIZE_4KB is not set # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -307,7 +307,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_SCHED_MC=y @@ -392,14 +392,14 @@ CONFIG_HZ_250=y CONFIG_HZ=250 CONFIG_SCHED_HRTICK=y CONFIG_KEXEC=y -# CONFIG_CRASH_DUMP is not set CONFIG_SECCOMP=y CONFIG_SMP=y CONFIG_NR_CPUS=4 +# CONFIG_HOTPLUG_CPU is not set # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -518,7 +518,6 @@ CONFIG_IPV6_NDISC_NODETYPE=y # # CONFIG_NET_PKTGEN is not set # CONFIG_NET_TCPPROBE is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set CONFIG_CAN=m CONFIG_CAN_RAW=m @@ -583,6 +582,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_DS1682 is not set # CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set @@ -601,6 +601,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -693,6 +694,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -734,6 +736,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -760,6 +763,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -773,15 +777,9 @@ CONFIG_I2C_HELPER_AUTO=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -838,10 +836,9 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_MC13783 is not set -# CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set # CONFIG_AB4500_CORE is not set # CONFIG_REGULATOR is not set @@ -933,7 +930,6 @@ CONFIG_USB_R8A66597_HCD=m # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -945,7 +941,6 @@ CONFIG_USB_R8A66597_HCD=m # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set @@ -983,6 +978,7 @@ CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set # CONFIG_USB_G_MULTI is not set # @@ -1065,8 +1061,6 @@ CONFIG_RTC_DRV_SH=y CONFIG_UIO=m # CONFIG_UIO_PDRV is not set # CONFIG_UIO_PDRV_GENIRQ is not set -# CONFIG_UIO_SMX is not set -# CONFIG_UIO_SERCOS3 is not set # # TI VLYNQ @@ -1145,6 +1139,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1159,6 +1154,7 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1246,7 +1242,6 @@ CONFIG_DEBUG_PREEMPT=y # CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set @@ -1266,9 +1261,9 @@ CONFIG_FRAME_POINTER=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y @@ -1276,10 +1271,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y # CONFIG_FUNCTION_TRACER is not set @@ -1292,6 +1284,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1329,6 +1322,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set # CONFIG_CRYPTO_CRYPTD is not set # CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_TEST is not set @@ -1407,7 +1401,8 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y -CONFIG_BINARY_PRINTF=y +# CONFIG_VIRTUALIZATION is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig index 98352d757851..513834d2b8ab 100644 --- a/arch/sh/configs/snapgear_defconfig +++ b/arch/sh/configs/snapgear_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:14:18 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:36:53 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set # CONFIG_SWAP is not set # CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set @@ -68,7 +71,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -79,6 +81,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -105,7 +108,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y @@ -122,6 +125,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -235,6 +239,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -250,7 +255,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -335,7 +340,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -350,9 +354,9 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -569,6 +573,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -586,7 +591,7 @@ CONFIG_HAVE_IDE=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -626,6 +631,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -726,6 +732,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -764,6 +771,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -771,6 +779,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -848,7 +857,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -907,6 +915,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -925,6 +934,7 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -983,6 +993,7 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig index 72982e360e3f..14e69a229c0a 100644 --- a/arch/sh/configs/systemh_defconfig +++ b/arch/sh/configs/systemh_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:14:50 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:39:19 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y # CONFIG_SYSVIPC is not set # CONFIG_BSD_PROCESS_ACCT is not set @@ -65,7 +68,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -76,6 +78,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -102,7 +105,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -119,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -237,6 +241,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -252,7 +257,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -332,7 +337,6 @@ CONFIG_HZ=250 CONFIG_PREEMPT=y CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -402,6 +406,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -442,6 +447,7 @@ CONFIG_DEVKMEM=y # Non-8250 serial port support # # CONFIG_SERIAL_SH_SCI is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -552,7 +558,6 @@ CONFIG_RTC_LIB=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4_FS is not set -CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set @@ -609,6 +614,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -676,6 +682,7 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig index 78c257053c79..79196b4dfdb1 100644 --- a/arch/sh/configs/titan_defconfig +++ b/arch/sh/configs/titan_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:17:20 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 17:41:12 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -46,9 +47,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -71,7 +74,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -82,6 +84,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -109,8 +112,9 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y CONFIG_COMPAT_BRK=y @@ -127,6 +131,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -245,6 +250,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -260,7 +266,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -345,7 +351,6 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_GUSA=y # CONFIG_GUSA_RB is not set -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -361,9 +366,9 @@ CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw" # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -392,7 +397,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -561,6 +565,7 @@ CONFIG_IP6_NF_RAW=m # CONFIG_ATM is not set CONFIG_STP=y CONFIG_BRIDGE=y +CONFIG_BRIDGE_IGMP_SNOOPING=y # CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=y # CONFIG_VLAN_8021Q_GVRP is not set @@ -749,6 +754,7 @@ CONFIG_MTD_NAND_IDS=m # CONFIG_MTD_NAND_CAFE is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_NAND_SH_FLCTL is not set # CONFIG_MTD_ONENAND is not set # @@ -768,10 +774,6 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m - -# -# DRBD disabled because PROC_FS, INET or CONNECTOR not selected -# # CONFIG_BLK_DEV_DRBD is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set @@ -802,6 +804,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -892,7 +895,7 @@ CONFIG_SCSI_LOWLEVEL=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -951,6 +954,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -1002,6 +1006,8 @@ CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +CONFIG_CHELSIO_T4_DEPENDS=y +# CONFIG_CHELSIO_T4 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set @@ -1014,6 +1020,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set @@ -1040,6 +1047,7 @@ CONFIG_USB_NET_AX8817X=m CONFIG_USB_NET_CDCETHER=m # CONFIG_USB_NET_CDC_EEM is not set # CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set # CONFIG_USB_NET_SMSC95XX is not set # CONFIG_USB_NET_GL620A is not set CONFIG_USB_NET_NET1080=m @@ -1049,6 +1057,7 @@ CONFIG_USB_NET_PLUSB=m # CONFIG_USB_NET_CDC_SUBSET is not set CONFIG_USB_NET_ZAURUS=m # CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -1136,6 +1145,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -1215,6 +1225,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1222,6 +1233,7 @@ CONFIG_SSB_POSSIBLE=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1372,6 +1384,7 @@ CONFIG_USB_SERIAL_ARK3116=m # CONFIG_USB_SERIAL_NAVMAN is not set CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set # CONFIG_USB_SERIAL_QUALCOMM is not set # CONFIG_USB_SERIAL_SPCP8X5 is not set # CONFIG_USB_SERIAL_HP4X is not set @@ -1385,6 +1398,7 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_SERIAL_OPTION is not set # CONFIG_USB_SERIAL_OMNINET is not set # CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set # CONFIG_USB_SERIAL_DEBUG is not set # @@ -1397,7 +1411,6 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1410,7 +1423,6 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1552,6 +1564,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1585,6 +1598,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CEPH_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set CONFIG_CIFS_WEAK_PW_HASH=y @@ -1680,6 +1694,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -1726,6 +1741,7 @@ CONFIG_FTRACE=y CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KSYM_TRACER is not set # CONFIG_STACK_TRACER is not set # CONFIG_KMEMTRACE is not set # CONFIG_WORKQUEUE_TRACER is not set @@ -1853,6 +1869,7 @@ CONFIG_CRYPTO_DEFLATE=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig index 4fa03bf086dd..17b7258dcde5 100644 --- a/arch/sh/configs/ul2_defconfig +++ b/arch/sh/configs/ul2_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:18:53 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 18:10:50 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -73,7 +76,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -84,6 +86,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -122,13 +125,13 @@ CONFIG_PROFILING=y # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -244,7 +247,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x01f00000 CONFIG_29BIT=y -# CONFIG_X2TLB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_NUMA=y CONFIG_NODES_SHIFT=1 @@ -255,6 +258,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -278,7 +283,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_MIGRATION is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -352,7 +357,7 @@ CONFIG_KEXEC=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -388,6 +393,7 @@ CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_HIBERNATION is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y # CONFIG_CPU_IDLE is not set CONFIG_NET=y @@ -395,7 +401,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -473,7 +478,7 @@ CONFIG_CFG80211=y # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set # CONFIG_CFG80211_REG_DEBUG is not set CONFIG_CFG80211_DEFAULT_PS=y -# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set CONFIG_CFG80211_WEXT=y CONFIG_WIRELESS_EXT_SYSFS=y CONFIG_LIB80211=m @@ -619,6 +624,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -709,6 +715,7 @@ CONFIG_LIBERTAS=m # CONFIG_LIBERTAS_USB is not set CONFIG_LIBERTAS_SDIO=m CONFIG_LIBERTAS_DEBUG=y +# CONFIG_LIBERTAS_MESH is not set # CONFIG_P54_COMMON is not set # CONFIG_RT2X00 is not set # CONFIG_WL12XX is not set @@ -730,6 +737,7 @@ CONFIG_USB_NET_AX8817X=y CONFIG_USB_NET_CDCETHER=y # CONFIG_USB_NET_CDC_EEM is not set # CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set # CONFIG_USB_NET_SMSC95XX is not set # CONFIG_USB_NET_GL620A is not set # CONFIG_USB_NET_NET1080 is not set @@ -739,6 +747,7 @@ CONFIG_USB_NET_CDCETHER=y # CONFIG_USB_NET_CDC_SUBSET is not set # CONFIG_USB_NET_ZAURUS is not set # CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -800,6 +809,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=1 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set @@ -952,7 +962,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -964,7 +973,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -987,9 +995,6 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_AT91 is not set -# CONFIG_MMC_ATMELMCI is not set -# CONFIG_MMC_TMIO is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1079,6 +1084,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1104,6 +1110,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1299,6 +1306,7 @@ CONFIG_CRYPTO_ARC4=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig index 23bda1916f4d..28bb19d2cbe9 100644 --- a/arch/sh/configs/urquell_defconfig +++ b/arch/sh/configs/urquell_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 15:27:53 2010 +# Linux kernel version: 2.6.34-rc5 +# Tue May 18 18:13:10 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -35,6 +35,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_COHERENT=y # CONFIG_DMA_NONCOHERENT is not set +# CONFIG_NEED_DMA_MAP_STATE is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -49,9 +50,11 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -77,11 +80,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -# CONFIG_USER_SCHED is not set -CONFIG_CGROUP_SCHED=y CONFIG_CGROUPS=y CONFIG_CGROUP_DEBUG=y CONFIG_CGROUP_NS=y @@ -93,6 +91,9 @@ CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y CONFIG_CGROUP_MEM_RES_CTLR=y CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y CONFIG_MM_OWNER=y # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -102,6 +103,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -142,13 +144,13 @@ CONFIG_PROFILING=y # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -169,7 +171,6 @@ CONFIG_BLOCK=y CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_CGROUP is not set # # IO Schedulers @@ -265,8 +266,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set -# CONFIG_X2TLB is not set +# CONFIG_PMB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y # CONFIG_NUMA is not set CONFIG_ARCH_FLATMEM_ENABLE=y @@ -277,6 +278,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -299,7 +302,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -317,6 +320,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y CONFIG_SH_STORE_QUEUES=y +# CONFIG_SPECULATIVE_EXECUTION is not set CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEAEX=y @@ -325,15 +329,14 @@ CONFIG_CPU_HAS_FPU=y # # Board support # +# CONFIG_SH_SDK7786 is not set CONFIG_SH_URQUELL=y # # Timer and clock configuration # CONFIG_SH_TIMER_TMU=y -CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_CPG=y -CONFIG_SH_CLK_CPG_LEGACY=y CONFIG_TICK_ONESHOT=y # CONFIG_NO_HZ is not set CONFIG_HIGH_RES_TIMERS=y @@ -376,7 +379,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_GUSA=y -CONFIG_SPARSE_IRQ=y +# CONFIG_INTC_USERIMASK is not set # # Boot options @@ -391,6 +394,7 @@ CONFIG_ENTRY_OFFSET=0x00001000 # Bus options # CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y CONFIG_PCIEPORTBUS=y CONFIG_PCIEAER=y # CONFIG_PCIE_ECRC is not set @@ -398,7 +402,6 @@ CONFIG_PCIEAER=y CONFIG_PCIEASPM=y CONFIG_PCIEASPM_DEBUG=y # CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCI_LEGACY is not set CONFIG_PCI_DEBUG=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -428,7 +431,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -639,6 +641,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -712,6 +715,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -748,7 +752,7 @@ CONFIG_ATA_SFF=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -807,6 +811,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_E100 is not set @@ -871,6 +876,7 @@ CONFIG_WLAN=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -958,6 +964,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -1007,6 +1014,7 @@ CONFIG_I2C_ALGOPCA=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -1020,15 +1028,9 @@ CONFIG_I2C_ALGOPCA=y # CONFIG_I2C_PCA_PLATFORM=y # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # @@ -1043,13 +1045,17 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_SCH is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -1082,10 +1088,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_I5K_AMB is not set @@ -1123,6 +1130,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_TMP421 is not set @@ -1151,21 +1159,26 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set CONFIG_MFD_SM501=y # CONFIG_MFD_SM501_GPIO is not set # CONFIG_MFD_SH_MOBILE_SDHI is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set +# CONFIG_MFD_TIMBERDALE is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -1187,6 +1200,7 @@ CONFIG_VIDEO_IR=y # Graphics support # CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1283,6 +1297,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -1298,14 +1313,19 @@ CONFIG_HID_GYRATION=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set CONFIG_HID_MONTEREY=y # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y +# CONFIG_HID_QUANTA is not set CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set CONFIG_HID_SUNPLUS=y # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1326,7 +1346,6 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_DEVICEFS=y CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set @@ -1405,7 +1424,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1417,7 +1435,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1584,6 +1601,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1610,6 +1628,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1688,6 +1707,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -1713,6 +1733,7 @@ CONFIG_FRAME_POINTER=y # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y @@ -1846,6 +1867,7 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +# CONFIG_VIRTUALIZATION is not set # CONFIG_BINARY_PRINTF is not set # -- cgit v1.2.3-59-g8ed1b From 05e021f095ffe9c7c1a695a3e2835f39243c6270 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Mon, 17 May 2010 20:17:42 +0200 Subject: ARM: S3C64XX: Add USB external clock definition This adds the xusbxti clock to S3C64XX platform. Signed-off-by: Maurus Cuelenaere Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/clock.c | 7 +++++++ arch/arm/plat-samsung/include/plat/clock.h | 1 + 2 files changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index da8359589019..7a4138beb665 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -88,6 +88,12 @@ struct clk clk_48m = { .enable = clk_48m_ctrl, }; +struct clk clk_xusbxti = { + .name = "xusbxti", + .id = -1, + .rate = 48000000, +}; + static int inline s3c64xx_gate(void __iomem *reg, struct clk *clk, int enable) @@ -791,6 +797,7 @@ static struct clk *clks[] __initdata = { &clk_27m, &clk_48m, &clk_h2, + &clk_xusbxti, }; /** diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h index 60b62692ac7a..efbc984640c3 100644 --- a/arch/arm/plat-samsung/include/plat/clock.h +++ b/arch/arm/plat-samsung/include/plat/clock.h @@ -74,6 +74,7 @@ extern struct clk clk_ext; extern struct clk clk_h2; extern struct clk clk_27m; extern struct clk clk_48m; +extern struct clk clk_xusbxti; extern int clk_default_setrate(struct clk *clk, unsigned long rate); extern struct clk_ops clk_ops_def_setrate; -- cgit v1.2.3-59-g8ed1b From fbd6fe73514cf31a07c7b16518930ea84c644463 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 30 Apr 2010 19:08:38 +0900 Subject: ARM: S3C2443: Add initial defines for framebuffer support Add the necessary defines to get the s3c-fb device to compile for s3c2443. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/irqs.h | 3 +++ arch/arm/mach-s3c2410/include/mach/map.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h index 877c15e1b154..11bb0f08fe6a 100644 --- a/arch/arm/mach-s3c2410/include/mach/irqs.h +++ b/arch/arm/mach-s3c2410/include/mach/irqs.h @@ -187,6 +187,9 @@ #define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3 #define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3 +#define IRQ_LCD_VSYNC IRQ_S3C2443_LCD3 +#define IRQ_LCD_SYSTEM IRQ_S3C2443_LCD2 + #ifdef CONFIG_CPU_S3C2440 #define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97 #else diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h index f07d68066d7e..091c98a639d9 100644 --- a/arch/arm/mach-s3c2410/include/mach/map.h +++ b/arch/arm/mach-s3c2410/include/mach/map.h @@ -67,6 +67,8 @@ #define S3C2443_PA_HSMMC (0x4A800000) #define S3C2416_PA_HSMMC0 (0x4AC00000) +#define S3C2443_PA_FB (0x4C800000) + /* S3C2412 memory and IO controls */ #define S3C2412_PA_SSMC (0x4F000000) #define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000) @@ -106,6 +108,7 @@ #define S3C24XX_PA_SDI S3C2410_PA_SDI #define S3C24XX_PA_NAND S3C2410_PA_NAND +#define S3C_PA_FB S3C2443_PA_FB #define S3C_PA_IIC S3C2410_PA_IIC #define S3C_PA_UART S3C24XX_PA_UART #define S3C_PA_USBHOST S3C2410_PA_USBHOST -- cgit v1.2.3-59-g8ed1b From dc5d2e8236e2eec461e8c34d302635142e93ab49 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 30 Apr 2010 19:34:25 +0900 Subject: ARM: S3C2443: Fix definition of LCD clock bit Fix the definition of the LCD clock bit, it is the TFT display controller on bit 9, not the older STN on bit 10. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h index d87ebe0cb625..08ab9dfb6ae6 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h @@ -83,8 +83,7 @@ #define S3C2443_HCLKCON_DMA4 (1<<4) #define S3C2443_HCLKCON_DMA5 (1<<5) #define S3C2443_HCLKCON_CAMIF (1<<8) -#define S3C2443_HCLKCON_DISP (1<<9) -#define S3C2443_HCLKCON_LCDC (1<<10) +#define S3C2443_HCLKCON_LCDC (1<<9) #define S3C2443_HCLKCON_USBH (1<<11) #define S3C2443_HCLKCON_USBD (1<<12) #define S3C2443_HCLKCON_HSMMC (1<<16) -- cgit v1.2.3-59-g8ed1b From f077f3fc055b329787783a1ab0efb9a8f8ecc874 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 13 May 2010 14:44:50 +0900 Subject: ARM: SAMSUNG: Set S3C_FB_MAX_WIN in Move the S3C_FB_MAX_WIN to the platform data to avoid having to include the registers with the platform data. Set S3C_FB_MAX_WIN to 5, which is the maximum that any of the current hardware can do and the cost of having it set to this for all is minimal (at least for the platform data case), then always leave this as the maximum for the systems supported. Also remove the inclusion of from the device definition in arch/arm/plat-samsung Signed-off-by: Ben Dooks --- arch/arm/plat-samsung/dev-fb.c | 1 - arch/arm/plat-samsung/include/plat/fb.h | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c index 002a15f313f3..bf60204c6297 100644 --- a/arch/arm/plat-samsung/dev-fb.c +++ b/arch/arm/plat-samsung/dev-fb.c @@ -19,7 +19,6 @@ #include #include -#include #include #include diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h index ffc01a76b7ce..1f85649d8c18 100644 --- a/arch/arm/plat-samsung/include/plat/fb.h +++ b/arch/arm/plat-samsung/include/plat/fb.h @@ -15,6 +15,13 @@ #ifndef __PLAT_S3C_FB_H #define __PLAT_S3C_FB_H __FILE__ +/* S3C_FB_MAX_WIN + * Set to the maximum number of windows that any of the supported hardware + * can use. Since the platform data uses this for an array size, having it + * set to the maximum of any version of the hardware can do is safe. + */ +#define S3C_FB_MAX_WIN (5) + /** * struct s3c_fb_pd_win - per window setup data * @win_mode: The display parameters to initialise (not for window 0) -- cgit v1.2.3-59-g8ed1b From f64bea4318a73e833d0a9b8400cc0f6cee957da3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 3 May 2010 15:29:44 +0900 Subject: ARM: SMDK2416: Add support for framebuffer device and ensure correct setup Add support for the LCD display on the SMDJK2416, and correctly name the framebuffer device. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2416/Kconfig | 1 + arch/arm/mach-s3c2416/mach-smdk2416.c | 62 +++++++++++++++++++++++++++++++++-- arch/arm/mach-s3c2416/s3c2416.c | 2 ++ 3 files changed, 62 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index 29103a6047de..657e4fe17f39 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig @@ -30,6 +30,7 @@ menu "S3C2416 Machines" config MACH_SMDK2416 bool "SMDK2416" select CPU_S3C2416 + select S3C_DEV_FB select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 help diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c index 99d24c44f30f..5fc3f67ef265 100644 --- a/arch/arm/mach-s3c2416/mach-smdk2416.c +++ b/arch/arm/mach-s3c2416/mach-smdk2416.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -36,16 +37,19 @@ #include #include -#include #include #include #include +#include #include #include #include #include +#include +#include + #include static struct map_desc smdk2416_iodesc[] __initdata = { @@ -109,7 +113,54 @@ static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = { } }; +struct s3c_fb_pd_win smdk2416_fb_win[] = { + [0] = { + /* think this is the same as the smdk6410 */ + .win_mode = { + .pixclock = 41094, + .left_margin = 8, + .right_margin = 13, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, + }, + .default_bpp = 16, + .max_bpp = 32, + }, +}; + +static void s3c2416_fb_gpio_setup_24bpp(void) +{ + unsigned int gpio; + + for (gpio = S3C2410_GPC(1); gpio <= S3C2410_GPC(4); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + } + + for (gpio = S3C2410_GPC(8); gpio <= S3C2410_GPC(15); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + } + + for (gpio = S3C2410_GPD(0); gpio <= S3C2410_GPD(15); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + } +} + +static struct s3c_fb_platdata smdk2416_fb_platdata = { + .win[0] = &smdk2416_fb_win[0], + .setup_gpio = s3c2416_fb_gpio_setup_24bpp, + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, +}; + static struct platform_device *smdk2416_devices[] __initdata = { + &s3c_device_fb, &s3c_device_wdt, &s3c_device_ohci, &s3c_device_i2c0, @@ -119,20 +170,25 @@ static struct platform_device *smdk2416_devices[] __initdata = { static void __init smdk2416_map_io(void) { - s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs)); - } static void __init smdk2416_machine_init(void) { s3c_i2c0_set_platdata(NULL); + s3c_fb_set_platdata(&smdk2416_fb_platdata); gpio_request(S3C2410_GPB(4), "USBHost Power"); gpio_direction_output(S3C2410_GPB(4), 1); + gpio_request(S3C2410_GPB(3), "Display Power"); + gpio_direction_output(S3C2410_GPB(3), 1); + + gpio_request(S3C2410_GPB(1), "Display Reset"); + gpio_direction_output(S3C2410_GPB(1), 1); + platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices)); smdk_machine_init(); } diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c index 3bff05745d0b..35dabccd0ac2 100644 --- a/arch/arm/mach-s3c2416/s3c2416.c +++ b/arch/arm/mach-s3c2416/s3c2416.c @@ -90,6 +90,8 @@ int __init s3c2416_init(void) s3c_i2c0_setname("s3c2440-i2c"); s3c_i2c1_setname("s3c2440-i2c"); + s3c_device_fb.name = "s3c2443-fb"; + return sysdev_register(&s3c2416_sysdev); } -- cgit v1.2.3-59-g8ed1b From a0026418d3d99b68dbd6c91f277d6f764fe41956 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Wed, 12 May 2010 10:22:41 +0300 Subject: ARM: S3C244X: fix gpiolib port J support Increase GPIOs number for S3C244X, and make S3C_GPIO_END point to BANKJ end, otherwise gpiolib refuses to register BANKJ Signed-off-by: Vasily Khoruzhick [ben-linux@fluff.org: Move pm fix to new patch] Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/gpio-track.h | 2 +- arch/arm/mach-s3c2410/include/mach/gpio.h | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-track.h b/arch/arm/mach-s3c2410/include/mach/gpio-track.h index acb259103808..6371eaa5fe4d 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-track.h +++ b/arch/arm/mach-s3c2410/include/mach/gpio-track.h @@ -23,7 +23,7 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin) { struct s3c_gpio_chip *chip; - if (pin > S3C2410_GPG(10)) + if (pin > S3C_GPIO_END) return NULL; chip = &s3c24xx_gpios[pin/32]; diff --git a/arch/arm/mach-s3c2410/include/mach/gpio.h b/arch/arm/mach-s3c2410/include/mach/gpio.h index 15f0b3e7ce69..b649bf2ccd5c 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio.h +++ b/arch/arm/mach-s3c2410/include/mach/gpio.h @@ -20,10 +20,18 @@ * devices that need GPIO. */ +#ifdef CONFIG_CPU_S3C244X +#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA) +#else #define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA) +#endif #include #include #include +#ifdef CONFIG_CPU_S3C24XX +#define S3C_GPIO_END (S3C2410_GPIO_BANKJ + 32) +#else #define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32) +#endif -- cgit v1.2.3-59-g8ed1b From 2c8fcfbf735e2d3b139e4247eb3e73edf64bb23f Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 17 May 2010 14:13:16 +0900 Subject: ARM: S3C24XX: Start cleanup of GPIO numbering Start cleaning up the numbering of GPIO banks by removing the old bank start definitions currently being used by some of the header files. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/gpio-nrs.h | 5 ----- arch/arm/mach-s3c2412/gpio.c | 8 ++++---- 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h index f3182ff847cb..ad94e1ac2463 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h +++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h @@ -16,12 +16,7 @@ #define S3C2410_GPIONO(bank,offset) ((bank) + (offset)) -#define S3C2410_GPIO_BANKA (32*0) -#define S3C2410_GPIO_BANKB (32*1) #define S3C2410_GPIO_BANKC (32*2) -#define S3C2410_GPIO_BANKD (32*3) -#define S3C2410_GPIO_BANKE (32*4) -#define S3C2410_GPIO_BANKF (32*5) #define S3C2410_GPIO_BANKG (32*6) #define S3C2410_GPIO_BANKH (32*7) diff --git a/arch/arm/mach-s3c2412/gpio.c b/arch/arm/mach-s3c2412/gpio.c index f7afece7fc38..71c579349dd5 100644 --- a/arch/arm/mach-s3c2412/gpio.c +++ b/arch/arm/mach-s3c2412/gpio.c @@ -33,14 +33,14 @@ int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state) offs *= 2; - if (pin < S3C2410_GPIO_BANKB) + if (pin < S3C2410_GPB(0)) return -EINVAL; - if (pin >= S3C2410_GPIO_BANKF && - pin <= S3C2410_GPIO_BANKG) + if (pin >= S3C2410_GPF(0) && + pin <= S3C2410_GPG(16)) return -EINVAL; - if (pin > (S3C2410_GPIO_BANKH + 32)) + if (pin > S3C2410_GPH(16)) return -EINVAL; local_irq_save(flags); -- cgit v1.2.3-59-g8ed1b From 7987bd7a7051c979f7b9b572898f92dbef6aaeb1 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 17 May 2010 14:28:44 +0900 Subject: ARM: S3C24XX: Update missed gpio calls to use gpiolib Update a couple of S3C24XX and S3C2412 files that are still using the GPIO number to register mapping calls to get the s3c_gpio_chip and use the base field from that. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2412/gpio.c | 12 +++++++----- arch/arm/plat-s3c24xx/gpio.c | 8 +++++--- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2412/gpio.c b/arch/arm/mach-s3c2412/gpio.c index 71c579349dd5..3404a876b33e 100644 --- a/arch/arm/mach-s3c2412/gpio.c +++ b/arch/arm/mach-s3c2412/gpio.c @@ -16,18 +16,20 @@ #include #include #include +#include #include #include #include - #include +#include + int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state) { - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long offs = S3C2410_GPIO_OFFSET(pin); + struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); + unsigned long offs = pin - chip->chip.base; unsigned long flags; unsigned long slpcon; @@ -45,12 +47,12 @@ int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state) local_irq_save(flags); - slpcon = __raw_readl(base + 0x0C); + slpcon = __raw_readl(chip->base + 0x0C); slpcon &= ~(3 << offs); slpcon |= state << offs; - __raw_writel(slpcon, base + 0x0C); + __raw_writel(slpcon, chip->base + 0x0C); local_irq_restore(flags); diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c index 45126d3aafc6..2f3d7c089dfa 100644 --- a/arch/arm/plat-s3c24xx/gpio.c +++ b/arch/arm/plat-s3c24xx/gpio.c @@ -34,6 +34,8 @@ #include +#include + /* gpiolib wrappers until these are totally eliminated */ void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) @@ -68,10 +70,10 @@ EXPORT_SYMBOL(s3c2410_gpio_setpin); unsigned int s3c2410_gpio_getpin(unsigned int pin) { - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long offs = S3C2410_GPIO_OFFSET(pin); + struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); + unsigned long offs = pin - chip->chip.base; - return __raw_readl(base + 0x04) & (1<< offs); + return __raw_readl(chip->base + 0x04) & (1<< offs); } EXPORT_SYMBOL(s3c2410_gpio_getpin); -- cgit v1.2.3-59-g8ed1b From 1635ca4aaf835794401da33079e50ce1d6bbb5d0 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 17 May 2010 14:53:48 +0900 Subject: ARM: S3C24XX: Remove macros mapping GPIO number to base As part of the cleanup, remove the old macros mapping GPIO numbers to the base of the register now we have gpiolib to manage the GPIO mappings for us. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/gpio-nrs.h | 1 - arch/arm/mach-s3c2410/include/mach/gpio-track.h | 2 +- arch/arm/mach-s3c2410/include/mach/regs-gpio.h | 22 ++-------------------- 3 files changed, 3 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h index ad94e1ac2463..ad4a04acf67a 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h +++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h @@ -16,7 +16,6 @@ #define S3C2410_GPIONO(bank,offset) ((bank) + (offset)) -#define S3C2410_GPIO_BANKC (32*2) #define S3C2410_GPIO_BANKG (32*6) #define S3C2410_GPIO_BANKH (32*7) diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-track.h b/arch/arm/mach-s3c2410/include/mach/gpio-track.h index 6371eaa5fe4d..d67819dde42a 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-track.h +++ b/arch/arm/mach-s3c2410/include/mach/gpio-track.h @@ -27,7 +27,7 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin) return NULL; chip = &s3c24xx_gpios[pin/32]; - return (S3C2410_GPIO_OFFSET(pin) < chip->chip.ngpio) ? chip : NULL; + return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL; } #endif /* __ASM_ARCH_GPIO_CORE_H */ diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h index 821b966bf05a..95e29fefec34 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h @@ -17,29 +17,11 @@ #include #ifdef CONFIG_CPU_S3C2400 -#define S3C24XX_GPIO_BASE(x) S3C2400_GPIO_BASE(x) -#define S3C24XX_MISCCR S3C2400_MISCCR +#define S3C24XX_MISCCR S3C2400_MISCCR #else -#define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x) -#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80) +#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80) #endif /* CONFIG_CPU_S3C2400 */ - -/* S3C2400 doesn't have a 1:1 mapping to S3C2410 gpio base pins */ - -#define S3C2400_BANKNUM(pin) (((pin) & ~31) / 32) -#define S3C2400_BASEA2B(pin) ((((pin) & ~31) >> 2)) -#define S3C2400_BASEC2H(pin) ((S3C2400_BANKNUM(pin) * 10) + \ - (2 * (S3C2400_BANKNUM(pin)-2))) - -#define S3C2400_GPIO_BASE(pin) (pin < S3C2410_GPIO_BANKC ? \ - S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \ - S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO) - - -#define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO) -#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31) - /* general configuration options */ #define S3C2410_GPIO_LEAVE (0xFFFFFFFF) -- cgit v1.2.3-59-g8ed1b From 4ac2a39767c2a93c06b654a0bf1c635e03ff75ac Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 17 May 2010 15:12:33 +0900 Subject: ARM: S3C24XX: Add note on GPIO bank sizes Add a table for the GPIO bank sizes for each SoC Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/gpio-nrs.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h index ad4a04acf67a..4f7bf3272e87 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h +++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h @@ -19,6 +19,25 @@ #define S3C2410_GPIO_BANKG (32*6) #define S3C2410_GPIO_BANKH (32*7) +/* GPIO sizes for various SoCs: + * + * 2442 + * 2410 2412 2440 2443 2416 + * ---- ---- ---- ---- ---- + * A 23 22 25 16 25 + * B 11 11 11 11 9 + * C 16 15 16 16 16 + * D 16 16 16 16 16 + * E 16 16 16 16 16 + * F 8 8 8 8 8 + * G 16 16 16 16 8 + * H 11 11 9 15 15 + * J -- -- 13 16 -- + * K -- -- -- -- 16 + * L -- -- -- 15 7 + * M -- -- -- 2 2 + */ + /* GPIO bank sizes */ #define S3C2410_GPIO_A_NR (32) #define S3C2410_GPIO_B_NR (32) -- cgit v1.2.3-59-g8ed1b From 32b6cb3872883861f3a2669cce880f3a7ef8979a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 18 May 2010 19:07:05 +0900 Subject: ARM: SAMSUNG: Fix additional increment when running through gpios The pm-gpio.c code was incrementing the gpio_nr from the nr_gpios field and the bank-bank offset inside the loop, and also in the for() loop with a ++. Remove the ++, as the number is already at the next GPIO, thus ensuring that we don't skip a gpio bank by accident. Signed-off-by: Ben Dooks --- arch/arm/plat-samsung/pm-gpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c index 69a4c7f02e25..d50ab9d2af53 100644 --- a/arch/arm/plat-samsung/pm-gpio.c +++ b/arch/arm/plat-samsung/pm-gpio.c @@ -329,7 +329,7 @@ void s3c_pm_save_gpios(void) struct s3c_gpio_chip *ourchip; unsigned int gpio_nr; - for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) { + for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) { ourchip = s3c_gpiolib_getchip(gpio_nr); if (!ourchip) continue; @@ -367,7 +367,7 @@ void s3c_pm_restore_gpios(void) struct s3c_gpio_chip *ourchip; unsigned int gpio_nr; - for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) { + for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) { ourchip = s3c_gpiolib_getchip(gpio_nr); if (!ourchip) continue; -- cgit v1.2.3-59-g8ed1b From 602bf0cfbdedfd988e43203d2a26bdbbab639309 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 16:02:26 +0900 Subject: ARM: S5PV210: Add audio platform devices Define platform devices for all audio devices found on S5PV210 Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/Makefile | 4 + arch/arm/mach-s5pv210/dev-audio.c | 327 ++++++++++++++++++++++++++++++ arch/arm/mach-s5pv210/include/mach/map.h | 13 ++ arch/arm/plat-samsung/include/plat/devs.h | 8 + 4 files changed, 352 insertions(+) create mode 100644 arch/arm/mach-s5pv210/dev-audio.c (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 8ebf51c52a01..e435afe7cffe 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -18,3 +18,7 @@ obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o + +# device support + +obj-y += dev-audio.o diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c new file mode 100644 index 000000000000..6e215330a1be --- /dev/null +++ b/arch/arm/mach-s5pv210/dev-audio.c @@ -0,0 +1,327 @@ +/* linux/arch/arm/mach-s5pv210/dev-audio.c + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Jaswinder Singh + * + * 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 +#include + +#include +#include + +#include +#include +#include +#include + +static int s5pv210_cfg_i2s(struct platform_device *pdev) +{ + /* configure GPIO for i2s port */ + switch (pdev->id) { + case 1: + s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(2)); + break; + + case 2: + s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(4)); + s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(4)); + s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(4)); + s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(4)); + s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(4)); + break; + + case -1: + s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPI(5), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPI(6), S3C_GPIO_SFN(2)); + break; + + default: + printk(KERN_ERR "Invalid Device %d\n", pdev->id); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata s3c_i2s_pdata = { + .cfg_gpio = s5pv210_cfg_i2s, +}; + +static struct resource s5pv210_iis0_resource[] = { + [0] = { + .start = S5PV210_PA_IIS0, + .end = S5PV210_PA_IIS0 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S0_TX, + .end = DMACH_I2S0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S0_RX, + .end = DMACH_I2S0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv210_device_iis0 = { + .name = "s3c64xx-iis-v4", + .id = -1, + .num_resources = ARRAY_SIZE(s5pv210_iis0_resource), + .resource = s5pv210_iis0_resource, + .dev = { + .platform_data = &s3c_i2s_pdata, + }, +}; + +static struct resource s5pv210_iis1_resource[] = { + [0] = { + .start = S5PV210_PA_IIS1, + .end = S5PV210_PA_IIS1 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S1_TX, + .end = DMACH_I2S1_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S1_RX, + .end = DMACH_I2S1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv210_device_iis1 = { + .name = "s3c64xx-iis", + .id = 1, + .num_resources = ARRAY_SIZE(s5pv210_iis1_resource), + .resource = s5pv210_iis1_resource, + .dev = { + .platform_data = &s3c_i2s_pdata, + }, +}; + +static struct resource s5pv210_iis2_resource[] = { + [0] = { + .start = S5PV210_PA_IIS2, + .end = S5PV210_PA_IIS2 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S2_TX, + .end = DMACH_I2S2_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S2_RX, + .end = DMACH_I2S2_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv210_device_iis2 = { + .name = "s3c64xx-iis", + .id = 2, + .num_resources = ARRAY_SIZE(s5pv210_iis2_resource), + .resource = s5pv210_iis2_resource, + .dev = { + .platform_data = &s3c_i2s_pdata, + }, +}; + +/* PCM Controller platform_devices */ + +static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev) +{ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(3)); + break; + case 1: + s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(3)); + break; + case 2: + s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(2)); + break; + default: + printk(KERN_DEBUG "Invalid PCM Controller number!"); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata s3c_pcm_pdata = { + .cfg_gpio = s5pv210_pcm_cfg_gpio, +}; + +static struct resource s5pv210_pcm0_resource[] = { + [0] = { + .start = S5PV210_PA_PCM0, + .end = S5PV210_PA_PCM0 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_PCM0_TX, + .end = DMACH_PCM0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_PCM0_RX, + .end = DMACH_PCM0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv210_device_pcm0 = { + .name = "samsung-pcm", + .id = 0, + .num_resources = ARRAY_SIZE(s5pv210_pcm0_resource), + .resource = s5pv210_pcm0_resource, + .dev = { + .platform_data = &s3c_pcm_pdata, + }, +}; + +static struct resource s5pv210_pcm1_resource[] = { + [0] = { + .start = S5PV210_PA_PCM1, + .end = S5PV210_PA_PCM1 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_PCM1_TX, + .end = DMACH_PCM1_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_PCM1_RX, + .end = DMACH_PCM1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv210_device_pcm1 = { + .name = "samsung-pcm", + .id = 1, + .num_resources = ARRAY_SIZE(s5pv210_pcm1_resource), + .resource = s5pv210_pcm1_resource, + .dev = { + .platform_data = &s3c_pcm_pdata, + }, +}; + +static struct resource s5pv210_pcm2_resource[] = { + [0] = { + .start = S5PV210_PA_PCM2, + .end = S5PV210_PA_PCM2 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_PCM2_TX, + .end = DMACH_PCM2_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_PCM2_RX, + .end = DMACH_PCM2_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv210_device_pcm2 = { + .name = "samsung-pcm", + .id = 2, + .num_resources = ARRAY_SIZE(s5pv210_pcm2_resource), + .resource = s5pv210_pcm2_resource, + .dev = { + .platform_data = &s3c_pcm_pdata, + }, +}; + +/* AC97 Controller platform devices */ + +static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev) +{ + s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(4)); + s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(4)); + s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(4)); + s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(4)); + s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(4)); + + return 0; +} + +static struct resource s5pv210_ac97_resource[] = { + [0] = { + .start = S5PV210_PA_AC97, + .end = S5PV210_PA_AC97 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_AC97_PCMOUT, + .end = DMACH_AC97_PCMOUT, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_AC97_PCMIN, + .end = DMACH_AC97_PCMIN, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = DMACH_AC97_MICIN, + .end = DMACH_AC97_MICIN, + .flags = IORESOURCE_DMA, + }, + [4] = { + .start = IRQ_AC97, + .end = IRQ_AC97, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_audio_pdata s3c_ac97_pdata = { + .cfg_gpio = s5pv210_ac97_cfg_gpio, +}; + +static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32); + +struct platform_device s5pv210_device_ac97 = { + .name = "s3c-ac97", + .id = -1, + .num_resources = ARRAY_SIZE(s5pv210_ac97_resource), + .resource = s5pv210_ac97_resource, + .dev = { + .platform_data = &s3c_ac97_pdata, + .dma_mask = &s5pv210_ac97_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index c22694c8231f..bcd2e82c2e2b 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -58,6 +58,19 @@ #define S5PV210_PA_SDRAM (0x20000000) #define S5P_PA_SDRAM S5PV210_PA_SDRAM +/* I2S */ +#define S5PV210_PA_IIS0 0xEEE30000 +#define S5PV210_PA_IIS1 0xE2100000 +#define S5PV210_PA_IIS2 0xE2A00000 + +/* PCM */ +#define S5PV210_PA_PCM0 0xE2300000 +#define S5PV210_PA_PCM1 0xE1200000 +#define S5PV210_PA_PCM2 0xE2B00000 + +/* AC97 */ +#define S5PV210_PA_AC97 0xE2200000 + /* compatibiltiy defines. */ #define S3C_PA_UART S5PV210_PA_UART #define S3C_PA_IIC S5PV210_PA_IIC0 diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 796d24258313..d8fda3a6db62 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -64,6 +64,14 @@ extern struct platform_device s3c_device_nand; extern struct platform_device s3c_device_usbgadget; extern struct platform_device s3c_device_usb_hsotg; +extern struct platform_device s5pv210_device_ac97; +extern struct platform_device s5pv210_device_pcm0; +extern struct platform_device s5pv210_device_pcm1; +extern struct platform_device s5pv210_device_pcm2; +extern struct platform_device s5pv210_device_iis0; +extern struct platform_device s5pv210_device_iis1; +extern struct platform_device s5pv210_device_iis2; + /* s3c2440 specific devices */ #ifdef CONFIG_CPU_S3C2440 -- cgit v1.2.3-59-g8ed1b From 9b5f1e08c95a9df7de9a96a7a4240362358acd5f Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 16:02:30 +0900 Subject: ARM: SMDKV210: Add audio devices on board Add audio platform devices on the smdk by default. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/mach-smdkv210.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index a27883253204..3c29e18528a5 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -72,6 +72,8 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = { }; static struct platform_device *smdkv210_devices[] __initdata = { + &s5pv210_device_iis0, + &s5pv210_device_ac97, }; static void __init smdkv210_map_io(void) -- cgit v1.2.3-59-g8ed1b From 95fa6e6cd34d33915504d207a832920d98e4e932 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 16:02:35 +0900 Subject: ARM: SMDKC110: Add audio devices on board Add audio platform devices on the smdk by default. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/mach-smdkc110.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c index ab4869df30c0..6f9fd3274e2e 100644 --- a/arch/arm/mach-s5pv210/mach-smdkc110.c +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c @@ -72,6 +72,8 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = { }; static struct platform_device *smdkc110_devices[] __initdata = { + &s5pv210_device_iis0, + &s5pv210_device_ac97, }; static void __init smdkc110_map_io(void) -- cgit v1.2.3-59-g8ed1b From 070c808546f69bc37db14db96e043a3b8894e0e2 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 16:02:50 +0900 Subject: ARM: S5P6442: Add audio platform devices Define platform devices for all audio devices found on S5P6442 Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6442/Makefile | 3 + arch/arm/mach-s5p6442/dev-audio.c | 197 ++++++++++++++++++++++++++++++ arch/arm/mach-s5p6442/include/mach/map.h | 8 ++ arch/arm/plat-samsung/include/plat/devs.h | 5 + 4 files changed, 213 insertions(+) create mode 100644 arch/arm/mach-s5p6442/dev-audio.c (limited to 'arch') diff --git a/arch/arm/mach-s5p6442/Makefile b/arch/arm/mach-s5p6442/Makefile index dde39a6ce6bc..a43d5da5c583 100644 --- a/arch/arm/mach-s5p6442/Makefile +++ b/arch/arm/mach-s5p6442/Makefile @@ -17,3 +17,6 @@ obj-$(CONFIG_CPU_S5P6442) += cpu.o init.o clock.o # machine support obj-$(CONFIG_MACH_SMDK6442) += mach-smdk6442.o + +# device support +obj-y += dev-audio.o diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c new file mode 100644 index 000000000000..cb801e1f5e23 --- /dev/null +++ b/arch/arm/mach-s5p6442/dev-audio.c @@ -0,0 +1,197 @@ +/* linux/arch/arm/mach-s5p6442/dev-audio.c + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Jaswinder Singh + * + * 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 +#include + +#include +#include + +#include +#include +#include +#include + +static int s5p6442_cfg_i2s(struct platform_device *pdev) +{ + /* configure GPIO for i2s port */ + switch (pdev->id) { + case 1: + s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(2)); + break; + + case -1: + s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(2)); + break; + + default: + printk(KERN_ERR "Invalid Device %d\n", pdev->id); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata s3c_i2s_pdata = { + .cfg_gpio = s5p6442_cfg_i2s, +}; + +static struct resource s5p6442_iis0_resource[] = { + [0] = { + .start = S5P6442_PA_I2S0, + .end = S5P6442_PA_I2S0 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S0_TX, + .end = DMACH_I2S0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S0_RX, + .end = DMACH_I2S0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5p6442_device_iis0 = { + .name = "s3c64xx-iis-v4", + .id = -1, + .num_resources = ARRAY_SIZE(s5p6442_iis0_resource), + .resource = s5p6442_iis0_resource, + .dev = { + .platform_data = &s3c_i2s_pdata, + }, +}; + +static struct resource s5p6442_iis1_resource[] = { + [0] = { + .start = S5P6442_PA_I2S1, + .end = S5P6442_PA_I2S1 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S1_TX, + .end = DMACH_I2S1_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S1_RX, + .end = DMACH_I2S1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5p6442_device_iis1 = { + .name = "s3c64xx-iis", + .id = 1, + .num_resources = ARRAY_SIZE(s5p6442_iis1_resource), + .resource = s5p6442_iis1_resource, + .dev = { + .platform_data = &s3c_i2s_pdata, + }, +}; + +/* PCM Controller platform_devices */ + +static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev) +{ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(3)); + break; + + case 1: + s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(3)); + s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(3)); + break; + + default: + printk(KERN_DEBUG "Invalid PCM Controller number!"); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata s3c_pcm_pdata = { + .cfg_gpio = s5p6442_pcm_cfg_gpio, +}; + +static struct resource s5p6442_pcm0_resource[] = { + [0] = { + .start = S5P6442_PA_PCM0, + .end = S5P6442_PA_PCM0 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_PCM0_TX, + .end = DMACH_PCM0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_PCM0_RX, + .end = DMACH_PCM0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5p6442_device_pcm0 = { + .name = "samsung-pcm", + .id = 0, + .num_resources = ARRAY_SIZE(s5p6442_pcm0_resource), + .resource = s5p6442_pcm0_resource, + .dev = { + .platform_data = &s3c_pcm_pdata, + }, +}; + +static struct resource s5p6442_pcm1_resource[] = { + [0] = { + .start = S5P6442_PA_PCM1, + .end = S5P6442_PA_PCM1 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_PCM1_TX, + .end = DMACH_PCM1_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_PCM1_RX, + .end = DMACH_PCM1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5p6442_device_pcm1 = { + .name = "samsung-pcm", + .id = 1, + .num_resources = ARRAY_SIZE(s5p6442_pcm1_resource), + .resource = s5p6442_pcm1_resource, + .dev = { + .platform_data = &s3c_pcm_pdata, + }, +}; diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h index 685277d792fb..767c596143c4 100644 --- a/arch/arm/mach-s5p6442/include/mach/map.h +++ b/arch/arm/mach-s5p6442/include/mach/map.h @@ -51,6 +51,14 @@ #define S5P6442_PA_SDRAM (0x20000000) #define S5P_PA_SDRAM S5P6442_PA_SDRAM +/* I2S */ +#define S5P6442_PA_I2S0 0xC0B00000 +#define S5P6442_PA_I2S1 0xF2200000 + +/* PCM */ +#define S5P6442_PA_PCM0 0xF2400000 +#define S5P6442_PA_PCM1 0xF2500000 + /* compatibiltiy defines. */ #define S3C_PA_UART S5P6442_PA_UART #define S3C_PA_IIC S5P6442_PA_IIC0 diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index d8fda3a6db62..ebf0387fb201 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -72,6 +72,11 @@ extern struct platform_device s5pv210_device_iis0; extern struct platform_device s5pv210_device_iis1; extern struct platform_device s5pv210_device_iis2; +extern struct platform_device s5p6442_device_pcm0; +extern struct platform_device s5p6442_device_pcm1; +extern struct platform_device s5p6442_device_iis0; +extern struct platform_device s5p6442_device_iis1; + /* s3c2440 specific devices */ #ifdef CONFIG_CPU_S3C2440 -- cgit v1.2.3-59-g8ed1b From 78a368234f51e54a8878ab00375be91a22e945b3 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 16:02:58 +0900 Subject: ARM: SMDK6442: Add audio devices on board Add audio platform devices on the smdk by default. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6442/mach-smdk6442.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-s5p6442/mach-smdk6442.c b/arch/arm/mach-s5p6442/mach-smdk6442.c index 0d63371ce07c..ebcf99777259 100644 --- a/arch/arm/mach-s5p6442/mach-smdk6442.c +++ b/arch/arm/mach-s5p6442/mach-smdk6442.c @@ -65,6 +65,7 @@ static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = { }; static struct platform_device *smdk6442_devices[] __initdata = { + &s5p6442_device_iis0, }; static void __init smdk6442_map_io(void) -- cgit v1.2.3-59-g8ed1b From 08885d0a4c4fa929c386e17c9682bf0d524146b9 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 16:03:02 +0900 Subject: ARM: S5P6440: Add audio platform devices Define platform devices for all audio devices found on S5P6440 Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/Makefile | 3 + arch/arm/mach-s5p6440/dev-audio.c | 127 ++++++++++++++++++++++++++++++ arch/arm/mach-s5p6440/include/mach/map.h | 6 ++ arch/arm/plat-samsung/include/plat/devs.h | 3 + 4 files changed, 139 insertions(+) create mode 100644 arch/arm/mach-s5p6440/dev-audio.c (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile index 1ad894b1d3ab..a2e99a249767 100644 --- a/arch/arm/mach-s5p6440/Makefile +++ b/arch/arm/mach-s5p6440/Makefile @@ -17,3 +17,6 @@ obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o # machine support obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o + +# device support +obj-y += dev-audio.o diff --git a/arch/arm/mach-s5p6440/dev-audio.c b/arch/arm/mach-s5p6440/dev-audio.c new file mode 100644 index 000000000000..0c5367962830 --- /dev/null +++ b/arch/arm/mach-s5p6440/dev-audio.c @@ -0,0 +1,127 @@ +/* linux/arch/arm/mach-s5p6440/dev-audio.c + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Jaswinder Singh + * + * 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 +#include + +#include +#include + +#include +#include +#include +#include + +static int s5p6440_cfg_i2s(struct platform_device *pdev) +{ + /* configure GPIO for i2s port */ + switch (pdev->id) { + case -1: + s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5)); + break; + + default: + printk(KERN_ERR "Invalid Device %d\n", pdev->id); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata s3c_i2s_pdata = { + .cfg_gpio = s5p6440_cfg_i2s, +}; + +static struct resource s5p6440_iis0_resource[] = { + [0] = { + .start = S5P6440_PA_I2S, + .end = S5P6440_PA_I2S + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S0_TX, + .end = DMACH_I2S0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S0_RX, + .end = DMACH_I2S0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5p6440_device_iis = { + .name = "s3c64xx-iis-v4", + .id = -1, + .num_resources = ARRAY_SIZE(s5p6440_iis0_resource), + .resource = s5p6440_iis0_resource, + .dev = { + .platform_data = &s3c_i2s_pdata, + }, +}; + +/* PCM Controller platform_devices */ + +static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev) +{ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2)); + break; + + default: + printk(KERN_DEBUG "Invalid PCM Controller number!"); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata s3c_pcm_pdata = { + .cfg_gpio = s5p6440_pcm_cfg_gpio, +}; + +static struct resource s5p6440_pcm0_resource[] = { + [0] = { + .start = S5P6440_PA_PCM, + .end = S5P6440_PA_PCM + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_PCM0_TX, + .end = DMACH_PCM0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_PCM0_RX, + .end = DMACH_PCM0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5p6440_device_pcm = { + .name = "samsung-pcm", + .id = 0, + .num_resources = ARRAY_SIZE(s5p6440_pcm0_resource), + .resource = s5p6440_pcm0_resource, + .dev = { + .platform_data = &s3c_pcm_pdata, + }, +}; diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h index 8924e5a4d6a6..ccbfdaea6eb6 100644 --- a/arch/arm/mach-s5p6440/include/mach/map.h +++ b/arch/arm/mach-s5p6440/include/mach/map.h @@ -61,6 +61,12 @@ #define S5P6440_PA_SDRAM (0x20000000) #define S5P_PA_SDRAM S5P6440_PA_SDRAM +/* I2S */ +#define S5P6440_PA_I2S 0xF2000000 + +/* PCM */ +#define S5P6440_PA_PCM 0xF2100000 + /* compatibiltiy defines. */ #define S3C_PA_UART S5P6440_PA_UART #define S3C_PA_IIC S5P6440_PA_IIC0 diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index ebf0387fb201..ef69e56b2885 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -77,6 +77,9 @@ extern struct platform_device s5p6442_device_pcm1; extern struct platform_device s5p6442_device_iis0; extern struct platform_device s5p6442_device_iis1; +extern struct platform_device s5p6440_device_pcm; +extern struct platform_device s5p6440_device_iis; + /* s3c2440 specific devices */ #ifdef CONFIG_CPU_S3C2440 -- cgit v1.2.3-59-g8ed1b From 734552072335b00476b626b027ca4a9f57147b6f Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 18 May 2010 16:03:07 +0900 Subject: ARM: SMDK6440: Add audio devices on board Add audio platform devices on the smdk by default. Signed-off-by: Jassi Brar Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/mach-smdk6440.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/mach-smdk6440.c b/arch/arm/mach-s5p6440/mach-smdk6440.c index 3ae88f2c7c77..d7fede971ca6 100644 --- a/arch/arm/mach-s5p6440/mach-smdk6440.c +++ b/arch/arm/mach-s5p6440/mach-smdk6440.c @@ -84,6 +84,7 @@ static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = { }; static struct platform_device *smdk6440_devices[] __initdata = { + &s5p6440_device_iis, }; static void __init smdk6440_map_io(void) -- cgit v1.2.3-59-g8ed1b From 91e8512e75f5e36b83490072cfba9d9793103035 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 4 Jan 2010 15:34:16 +0100 Subject: OMAP: Enable DSS2 in OMAP3EVM defconfig Signed-off-by: Vaibhav Hiremath [tomi.valkeinen@nokia.com: removed the board file changes] Signed-off-by: Tomi Valkeinen --- arch/arm/configs/omap3_evm_defconfig | 51 +++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/configs/omap3_evm_defconfig b/arch/arm/configs/omap3_evm_defconfig index a6dd6d1af806..b02e371b0997 100644 --- a/arch/arm/configs/omap3_evm_defconfig +++ b/arch/arm/configs/omap3_evm_defconfig @@ -911,7 +911,56 @@ CONFIG_DAB=y # # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m -# CONFIG_FB is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_OMAP2_VRAM=y +CONFIG_OMAP2_VRFB=y +CONFIG_OMAP2_DSS=y +CONFIG_OMAP2_VRAM_SIZE=4 +# CONFIG_OMAP2_DSS_DEBUG_SUPPORT is not set +# CONFIG_OMAP2_DSS_RFBI is not set +CONFIG_OMAP2_DSS_VENC=y +# CONFIG_OMAP2_DSS_SDI is not set +# CONFIG_OMAP2_DSS_DSI is not set +# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set +CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=4 +CONFIG_FB_OMAP2=y +# CONFIG_FB_OMAP2_DEBUG_SUPPORT is not set +# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set +CONFIG_FB_OMAP2_NUM_FBS=3 + +# +# OMAP2/3 Display Device Drivers +# +CONFIG_PANEL_GENERIC=y +# CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C is not set +CONFIG_PANEL_SHARP_LS037V7DW01=y # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -- cgit v1.2.3-59-g8ed1b From 14ec4740ff64e4111216287b1e8d51d515618b56 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Wed, 13 Jan 2010 17:17:10 +0530 Subject: OMAP: AM3517: Enable DSS2 in AM3517EVM defconfig Signed-off-by: Vaibhav Hiremath [tomi.valkeinen@nokia.com: removed the board file changes] Signed-off-by: Tomi Valkeinen --- arch/arm/configs/am3517_evm_defconfig | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/configs/am3517_evm_defconfig b/arch/arm/configs/am3517_evm_defconfig index 66a10b50d938..214ef42466f3 100644 --- a/arch/arm/configs/am3517_evm_defconfig +++ b/arch/arm/configs/am3517_evm_defconfig @@ -692,7 +692,57 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_OMAP2_VRAM=y +CONFIG_OMAP2_VRFB=y +CONFIG_OMAP2_DSS=y +CONFIG_OMAP2_VRAM_SIZE=4 +CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y +# CONFIG_OMAP2_DSS_RFBI is not set +CONFIG_OMAP2_DSS_VENC=y +# CONFIG_OMAP2_DSS_SDI is not set +# CONFIG_OMAP2_DSS_DSI is not set +# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set +CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=4 +CONFIG_FB_OMAP2=y +CONFIG_FB_OMAP2_DEBUG_SUPPORT=y +# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set +CONFIG_FB_OMAP2_NUM_FBS=3 + +# +# OMAP2/3 Display Device Drivers +# +CONFIG_PANEL_GENERIC=y +# CONFIG_PANEL_SHARP_LS037V7DW01 is not set +CONFIG_PANEL_SHARP_LQ043T1DG01=y # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -- cgit v1.2.3-59-g8ed1b From 03e111045e362e16e97fdd79a49590a763fe5216 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 10 May 2010 10:35:17 +0200 Subject: OMAP: RX51: Add LCD Panel support Adds basic support for LCD Panel on Nokia N900 Signed-off-by: Roger Quadros Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/Makefile | 1 + arch/arm/mach-omap2/board-rx51-peripherals.c | 13 ++++ arch/arm/mach-omap2/board-rx51-video.c | 109 +++++++++++++++++++++++++++ arch/arm/mach-omap2/board-rx51.c | 2 + 4 files changed, 125 insertions(+) create mode 100644 arch/arm/mach-omap2/board-rx51-video.c (limited to 'arch') diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 4b9fc57770db..b03cbb434a31 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -122,6 +122,7 @@ obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ board-rx51-sdram.o \ board-rx51-peripherals.o \ + board-rx51-video.o \ hsmmc.o obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \ board-zoom-peripherals.o \ diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 4377a4cf36eb..f40453774855 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -45,6 +45,7 @@ /* list all spi devices here */ enum { RX51_SPI_WL1251, + RX51_SPI_MIPID, /* LCD panel */ }; static struct wl12xx_platform_data wl1251_pdata; @@ -54,6 +55,11 @@ static struct omap2_mcspi_device_config wl1251_mcspi_config = { .single_channel = 1, }; +static struct omap2_mcspi_device_config mipid_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, +}; + static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { [RX51_SPI_WL1251] = { .modalias = "wl1251", @@ -64,6 +70,13 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { .controller_data = &wl1251_mcspi_config, .platform_data = &wl1251_pdata, }, + [RX51_SPI_MIPID] = { + .modalias = "acx565akm", + .bus_num = 1, + .chip_select = 2, + .max_speed_hz = 6000000, + .controller_data = &mipid_mcspi_config, + }, }; #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c new file mode 100644 index 000000000000..b743a4f42649 --- /dev/null +++ b/arch/arm/mach-omap2/board-rx51-video.c @@ -0,0 +1,109 @@ +/* + * linux/arch/arm/mach-omap2/board-rx51-video.c + * + * Copyright (C) 2010 Nokia + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "mux.h" + +#define RX51_LCD_RESET_GPIO 90 + +#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) + +static int rx51_lcd_enable(struct omap_dss_device *dssdev) +{ + gpio_set_value(dssdev->reset_gpio, 1); + return 0; +} + +static void rx51_lcd_disable(struct omap_dss_device *dssdev) +{ + gpio_set_value(dssdev->reset_gpio, 0); +} + +static struct omap_dss_device rx51_lcd_device = { + .name = "lcd", + .driver_name = "panel-acx565akm", + .type = OMAP_DISPLAY_TYPE_SDI, + .phy.sdi.datapairs = 2, + .reset_gpio = RX51_LCD_RESET_GPIO, + .platform_enable = rx51_lcd_enable, + .platform_disable = rx51_lcd_disable, +}; + +static struct omap_dss_device *rx51_dss_devices[] = { + &rx51_lcd_device, +}; + +static struct omap_dss_board_info rx51_dss_board_info = { + .num_devices = ARRAY_SIZE(rx51_dss_devices), + .devices = rx51_dss_devices, + .default_device = &rx51_lcd_device, +}; + +struct platform_device rx51_display_device = { + .name = "omapdss", + .id = -1, + .dev = { + .platform_data = &rx51_dss_board_info, + }, +}; + +static struct platform_device *rx51_video_devices[] __initdata = { + &rx51_display_device, +}; + +static int __init rx51_video_init(void) +{ + if (!machine_is_nokia_rx51()) + return 0; + + if (omap_mux_init_gpio(RX51_LCD_RESET_GPIO, OMAP_PIN_OUTPUT)) { + pr_err("%s cannot configure MUX for LCD RESET\n", __func__); + return 0; + } + + if (gpio_request(RX51_LCD_RESET_GPIO, "LCD ACX565AKM reset")) { + pr_err("%s failed to get LCD Reset GPIO\n", __func__); + return 0; + } + + gpio_direction_output(RX51_LCD_RESET_GPIO, 1); + + platform_add_devices(rx51_video_devices, + ARRAY_SIZE(rx51_video_devices)); + return 0; +} + +subsys_initcall(rx51_video_init); + +void __init rx51_video_mem_init(void) +{ + /* + * GFX 864x480x32bpp + * VID1/2 1280x720x32bpp double buffered + */ + omap_vram_set_sdram_vram(PAGE_ALIGN(864 * 480 * 4) + + 2 * PAGE_ALIGN(1280 * 720 * 4 * 2), 0); +} + +#else +void __init rx51_video_mem_init(void) { } +#endif /* defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) */ diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index b155c366c650..1b86b5bb87a2 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c @@ -36,6 +36,7 @@ #define RX51_GPIO_SLEEP_IND 162 struct omap_sdrc_params *rx51_get_sdram_timings(void); +extern void rx51_video_mem_init(void); static struct gpio_led gpio_leds[] = { { @@ -143,6 +144,7 @@ static void __init rx51_init(void) static void __init rx51_map_io(void) { omap2_set_globals_343x(); + rx51_video_mem_init(); omap34xx_map_common_io(); } -- cgit v1.2.3-59-g8ed1b From 6996e7ff215c1cbad3dc7db3216fc6cf4815988c Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 22 Mar 2010 17:16:25 +0200 Subject: OMAP: RX51: Add Touch Controller in SPI board info The Touch controller and LCD Panel share the same SPI bus 1. So, we need to define the touch controller in the SPI board info else, the SPI bus will be contended due to invalid state of Touch controller's Chip Select thus preventing the LCD panel from working. Signed-off-by: Roger Quadros Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/board-rx51-peripherals.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index f40453774855..d27a4ef6eb63 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -46,6 +46,7 @@ enum { RX51_SPI_WL1251, RX51_SPI_MIPID, /* LCD panel */ + RX51_SPI_TSC2005, /* Touch Controller */ }; static struct wl12xx_platform_data wl1251_pdata; @@ -60,6 +61,11 @@ static struct omap2_mcspi_device_config mipid_mcspi_config = { .single_channel = 1, }; +static struct omap2_mcspi_device_config tsc2005_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, +}; + static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { [RX51_SPI_WL1251] = { .modalias = "wl1251", @@ -77,6 +83,15 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { .max_speed_hz = 6000000, .controller_data = &mipid_mcspi_config, }, + [RX51_SPI_TSC2005] = { + .modalias = "tsc2005", + .bus_num = 1, + .chip_select = 0, + /* .irq = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO),*/ + .max_speed_hz = 6000000, + .controller_data = &tsc2005_mcspi_config, + /* .platform_data = &tsc2005_config,*/ + }, }; #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -- cgit v1.2.3-59-g8ed1b From 2c59ff5501e5a37d36f232e757c961ced12eb99f Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 23 Mar 2010 11:22:05 +0200 Subject: OMAP: RX51: Update board defconfig Add LCD, Boot-up logo, framebuffer console, Keypad and Power button support Signed-off-by: Roger Quadros Signed-off-by: Tomi Valkeinen --- arch/arm/configs/rx51_defconfig | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/configs/rx51_defconfig b/arch/arm/configs/rx51_defconfig index 473f9e13f08b..56d4928cd4c9 100644 --- a/arch/arm/configs/rx51_defconfig +++ b/arch/arm/configs/rx51_defconfig @@ -784,6 +784,7 @@ CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_TWL4030=y # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set @@ -809,6 +810,7 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_POWERMATE is not set # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_TWL4030_PWRBUTTON=y CONFIG_INPUT_UINPUT=m # @@ -1110,7 +1112,40 @@ CONFIG_RADIO_ADAPTERS=y # # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y + +# Frame buffer hardware drivers +# +CONFIG_OMAP2_VRAM=y +CONFIG_OMAP2_VRFB=y +CONFIG_OMAP2_DSS=y +CONFIG_OMAP2_VRAM_SIZE=0 +# CONFIG_OMAP2_DSS_DEBUG_SUPPORT is not set +# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set +# CONFIG_OMAP2_DSS_DPI is not set +# CONFIG_OMAP2_DSS_RFBI is not set +# CONFIG_OMAP2_DSS_VENC is not set +CONFIG_OMAP2_DSS_SDI=y +# CONFIG_OMAP2_DSS_DSI is not set +# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set +CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0 +CONFIG_FB_OMAP2=y +CONFIG_FB_OMAP2_DEBUG_SUPPORT=y +CONFIG_FB_OMAP2_NUM_FBS=3 + +# +# OMAP2/3 Display Device Drivers +# +# CONFIG_PANEL_GENERIC is not set +# CONFIG_PANEL_SHARP_LS037V7DW01 is not set +# CONFIG_PANEL_SHARP_LQ043T1DG01 is not set +# CONFIG_PANEL_TOPPOLY_TDO35S is not set +# CONFIG_PANEL_TPO_TD043MTEA1 is not set +CONFIG_PANEL_ACX565AKM=y + # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -1127,6 +1162,8 @@ CONFIG_DISPLAY_SUPPORT=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y CONFIG_SOUND=y # CONFIG_SOUND_OSS_CORE is not set CONFIG_SND=y -- cgit v1.2.3-59-g8ed1b From 044d32ffbcb4a1d400088e3575508f46c0a9face Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 22 Apr 2010 10:23:42 +0200 Subject: board-omap3-beagle: add DSS2 support This patch adds DSS2 support to the beagleboard boardfile. DVI and TV-out are supported. Signed-off-by: Koen Kooi Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/board-omap3beagle.c | 101 ++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 962d377970e9..69b154cdc75d 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -106,6 +107,77 @@ static struct platform_device omap3beagle_nand_device = { .resource = &omap3beagle_nand_resource, }; +/* DSS */ + +static int beagle_enable_dvi(struct omap_dss_device *dssdev) +{ + if (gpio_is_valid(dssdev->reset_gpio)) + gpio_set_value(dssdev->reset_gpio, 1); + + return 0; +} + +static void beagle_disable_dvi(struct omap_dss_device *dssdev) +{ + if (gpio_is_valid(dssdev->reset_gpio)) + gpio_set_value(dssdev->reset_gpio, 0); +} + +static struct omap_dss_device beagle_dvi_device = { + .type = OMAP_DISPLAY_TYPE_DPI, + .name = "dvi", + .driver_name = "generic_panel", + .phy.dpi.data_lines = 24, + .reset_gpio = 170, + .platform_enable = beagle_enable_dvi, + .platform_disable = beagle_disable_dvi, +}; + +static struct omap_dss_device beagle_tv_device = { + .name = "tv", + .driver_name = "venc", + .type = OMAP_DISPLAY_TYPE_VENC, + .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, +}; + +static struct omap_dss_device *beagle_dss_devices[] = { + &beagle_dvi_device, + &beagle_tv_device, +}; + +static struct omap_dss_board_info beagle_dss_data = { + .num_devices = ARRAY_SIZE(beagle_dss_devices), + .devices = beagle_dss_devices, + .default_device = &beagle_dvi_device, +}; + +static struct platform_device beagle_dss_device = { + .name = "omapdss", + .id = -1, + .dev = { + .platform_data = &beagle_dss_data, + }, +}; + +static struct regulator_consumer_supply beagle_vdac_supply = + REGULATOR_SUPPLY("vdda_dac", "omapdss"); + +static struct regulator_consumer_supply beagle_vdvi_supply = + REGULATOR_SUPPLY("vdds_dsi", "omapdss"); + +static void __init beagle_display_init(void) +{ + int r; + + r = gpio_request(beagle_dvi_device.reset_gpio, "DVI reset"); + if (r < 0) { + printk(KERN_ERR "Unable to get DVI reset GPIO\n"); + return; + } + + gpio_direction_output(beagle_dvi_device.reset_gpio, 0); +} + #include "sdram-micron-mt46h32m32lf-6.h" static struct omap2_hsmmc_info mmc[] = { @@ -117,15 +189,6 @@ static struct omap2_hsmmc_info mmc[] = { {} /* Terminator */ }; -static struct platform_device omap3_beagle_lcd_device = { - .name = "omap3beagle_lcd", - .id = -1, -}; - -static struct omap_lcd_config omap3_beagle_lcd_config __initdata = { - .ctrl_name = "internal", -}; - static struct regulator_consumer_supply beagle_vmmc1_supply = { .supply = "vmmc", }; @@ -181,16 +244,6 @@ static struct twl4030_gpio_platform_data beagle_gpio_data = { .setup = beagle_twl_gpio_setup, }; -static struct regulator_consumer_supply beagle_vdac_supply = { - .supply = "vdac", - .dev = &omap3_beagle_lcd_device.dev, -}; - -static struct regulator_consumer_supply beagle_vdvi_supply = { - .supply = "vdvi", - .dev = &omap3_beagle_lcd_device.dev, -}; - /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ static struct regulator_init_data beagle_vmmc1 = { .constraints = { @@ -349,14 +402,8 @@ static struct platform_device keys_gpio = { }, }; -static struct omap_board_config_kernel omap3_beagle_config[] __initdata = { - { OMAP_TAG_LCD, &omap3_beagle_lcd_config }, -}; - static void __init omap3_beagle_init_irq(void) { - omap_board_config = omap3_beagle_config; - omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); omap2_init_common_hw(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); omap_init_irq(); @@ -367,9 +414,9 @@ static void __init omap3_beagle_init_irq(void) } static struct platform_device *omap3_beagle_devices[] __initdata = { - &omap3_beagle_lcd_device, &leds_gpio, &keys_gpio, + &beagle_dss_device, }; static void __init omap3beagle_flash_init(void) @@ -456,6 +503,8 @@ static void __init omap3_beagle_init(void) /* Ensure SDRC pins are mux'd for self-refresh */ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); + + beagle_display_init(); } static void __init omap3_beagle_map_io(void) -- cgit v1.2.3-59-g8ed1b From 82b22c887e02fc6ebeebc8ec43fb1d348e2a6a58 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 6 May 2010 19:36:06 +0200 Subject: [IA64] removing redundant ifdef Pointless to use #ifdef CONFIG_NUMA in code that is already inside another #ifdef CONFIG_NUMA. Signed-off-by: Jiri Olsa Signed-off-by: Tony Luck --- arch/ia64/include/asm/mmzone.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/ia64/include/asm/mmzone.h b/arch/ia64/include/asm/mmzone.h index f2ca32069b3f..e0de61709cf1 100644 --- a/arch/ia64/include/asm/mmzone.h +++ b/arch/ia64/include/asm/mmzone.h @@ -19,16 +19,12 @@ static inline int pfn_to_nid(unsigned long pfn) { -#ifdef CONFIG_NUMA extern int paddr_to_nid(unsigned long); int nid = paddr_to_nid(pfn << PAGE_SHIFT); if (nid < 0) return 0; else return nid; -#else - return 0; -#endif } #ifdef CONFIG_IA64_DIG /* DIG systems are small */ -- cgit v1.2.3-59-g8ed1b From 80aa9bf0d8083554967400d48dbec078aa8f128e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 5 Apr 2010 12:05:31 -0700 Subject: [IA64] arch/ia64/hp/common/sba_iommu.c: Rename dev_info to adi There is a macro called dev_info that prints struct device specific information. Having variables with the same name can be confusing and prevents conversion of the macro to a function. Rename the existing dev_info variables to something else in preparation to converting the dev_info macro to a function. Signed-off-by: Joe Perches Signed-off-by: Tony Luck --- arch/ia64/hp/common/sba_iommu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index e14c492a8a93..4ce8d1358fee 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -2046,13 +2046,13 @@ acpi_sba_ioc_add(struct acpi_device *device) struct ioc *ioc; acpi_status status; u64 hpa, length; - struct acpi_device_info *dev_info; + struct acpi_device_info *adi; status = hp_acpi_csr_space(device->handle, &hpa, &length); if (ACPI_FAILURE(status)) return 1; - status = acpi_get_object_info(device->handle, &dev_info); + status = acpi_get_object_info(device->handle, &adi); if (ACPI_FAILURE(status)) return 1; @@ -2060,13 +2060,13 @@ acpi_sba_ioc_add(struct acpi_device *device) * For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI * root bridges, and its CSR space includes the IOC function. */ - if (strncmp("HWP0001", dev_info->hardware_id.string, 7) == 0) { + if (strncmp("HWP0001", adi->hardware_id.string, 7) == 0) { hpa += ZX1_IOC_OFFSET; /* zx1 based systems default to kernel page size iommu pages */ if (!iovp_shift) iovp_shift = min(PAGE_SHIFT, 16); } - kfree(dev_info); + kfree(adi); /* * default anything not caught above or specified on cmdline to 4k -- cgit v1.2.3-59-g8ed1b From 93f7c93bee6382e01c34ea0c34ff8fb98c648734 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 26 Mar 2010 23:02:47 +0100 Subject: [IA64] Use set_cpus_allowed_ptr Use set_cpus_allowed_ptr rather than set_cpus_allowed. Signed-off-by: Julia Lawall Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/sn2/sn_hwperf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 55ac3c4e11d2..f6c1c5fd075d 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -629,9 +629,9 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info) else { /* migrate the task before calling SAL */ save_allowed = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); sn_hwperf_call_sal(op_info); - set_cpus_allowed(current, save_allowed); + set_cpus_allowed_ptr(current, &save_allowed); } } r = op_info->ret; -- cgit v1.2.3-59-g8ed1b From 552dce3a071f0de2a84023fbba7f3b4ac36602cd Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 26 Mar 2010 23:02:23 +0100 Subject: [IA64] Use set_cpus_allowed_ptr Use set_cpus_allowed_ptr rather than set_cpus_allowed. Signed-off-by: Julia Lawall Signed-off-by: Tony Luck --- arch/ia64/kernel/cpufreq/acpi-cpufreq.c | 10 +++++----- arch/ia64/kernel/salinfo.c | 5 ++--- arch/ia64/kernel/topology.c | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index b0b4e6e710f2..22f61526a8e1 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c @@ -113,7 +113,7 @@ processor_get_freq ( dprintk("processor_get_freq\n"); saved_mask = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); if (smp_processor_id() != cpu) goto migrate_end; @@ -121,7 +121,7 @@ processor_get_freq ( ret = processor_get_pstate(&value); if (ret) { - set_cpus_allowed(current, saved_mask); + set_cpus_allowed_ptr(current, &saved_mask); printk(KERN_WARNING "get performance failed with error %d\n", ret); ret = 0; @@ -131,7 +131,7 @@ processor_get_freq ( ret = (clock_freq*1000); migrate_end: - set_cpus_allowed(current, saved_mask); + set_cpus_allowed_ptr(current, &saved_mask); return ret; } @@ -151,7 +151,7 @@ processor_set_freq ( dprintk("processor_set_freq\n"); saved_mask = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); if (smp_processor_id() != cpu) { retval = -EAGAIN; goto migrate_end; @@ -208,7 +208,7 @@ processor_set_freq ( retval = 0; migrate_end: - set_cpus_allowed(current, saved_mask); + set_cpus_allowed_ptr(current, &saved_mask); return (retval); } diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index e6676fca4828..aa8b5fa1a8de 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -404,10 +404,9 @@ static void call_on_cpu(int cpu, void (*fn)(void *), void *arg) { cpumask_t save_cpus_allowed = current->cpus_allowed; - cpumask_t new_cpus_allowed = cpumask_of_cpu(cpu); - set_cpus_allowed(current, new_cpus_allowed); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); (*fn)(arg); - set_cpus_allowed(current, save_cpus_allowed); + set_cpus_allowed_ptr(current, &save_cpus_allowed); } static void diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 28f299de2903..0baa1bbb65fe 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -361,12 +361,12 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) return 0; oldmask = current->cpus_allowed; - retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); + retval = set_cpus_allowed_ptr(current, cpumask_of(cpu)); if (unlikely(retval)) return retval; retval = cpu_cache_sysfs_init(cpu); - set_cpus_allowed(current, oldmask); + set_cpus_allowed_ptr(current, &oldmask); if (unlikely(retval < 0)) return retval; -- cgit v1.2.3-59-g8ed1b From 7683a3f9748f7adfbe47e33002a4f710ab557293 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 28 Feb 2010 19:58:14 +0900 Subject: [IA64] use __ratelimit Replace open-coded rate limiting logic with __ratelimit(). Signed-off-by: Akinobu Mita Signed-off-by: Tony Luck --- arch/ia64/kernel/irq_ia64.c | 9 +++------ arch/ia64/kernel/unaligned.c | 24 +++++------------------- 2 files changed, 8 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 640479304ac0..f14c35f9b03a 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -467,13 +468,9 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) sp = ia64_getreg(_IA64_REG_SP); if ((sp - bsp) < 1024) { - static unsigned char count; - static long last_time; + static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5); - if (time_after(jiffies, last_time + 5 * HZ)) - count = 0; - if (++count < 5) { - last_time = jiffies; + if (__ratelimit(&ratelimit)) { printk("ia64_handle_irq: DANGER: less than " "1KB of free stack space!!\n" "(bsp=0x%lx, sp=%lx)\n", bsp, sp); diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index 776dd40397e2..622772b7fb6c 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -1283,24 +1284,9 @@ emulate_store_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs) /* * Make sure we log the unaligned access, so that user/sysadmin can notice it and * eventually fix the program. However, we don't want to do that for every access so we - * pace it with jiffies. This isn't really MP-safe, but it doesn't really have to be - * either... + * pace it with jiffies. */ -static int -within_logging_rate_limit (void) -{ - static unsigned long count, last_time; - - if (time_after(jiffies, last_time + 5 * HZ)) - count = 0; - if (count < 5) { - last_time = jiffies; - count++; - return 1; - } - return 0; - -} +static DEFINE_RATELIMIT_STATE(logging_rate_limit, 5 * HZ, 5); void ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) @@ -1337,7 +1323,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) if (!no_unaligned_warning && !(current->thread.flags & IA64_THREAD_UAC_NOPRINT) && - within_logging_rate_limit()) + __ratelimit(&logging_rate_limit)) { char buf[200]; /* comm[] is at most 16 bytes... */ size_t len; @@ -1370,7 +1356,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) } } } else { - if (within_logging_rate_limit()) { + if (__ratelimit(&logging_rate_limit)) { printk(KERN_WARNING "kernel unaligned access to 0x%016lx, ip=0x%016lx\n", ifa, regs->cr_iip + ipsr->ri); if (unaligned_dump_stack) -- cgit v1.2.3-59-g8ed1b From 0c3b96e44739cdba7a75030107a2b47a15ee5f60 Mon Sep 17 00:00:00 2001 From: "npiggin@suse.de" Date: Fri, 7 May 2010 14:34:33 -0700 Subject: [IA64] invoke oom-killer from page fault As explained in commit 1c0fe6e3bd, we want to call the architecture independent oom killer when getting an unexplained OOM from handle_mm_fault, rather than simply killing current. Acked-by: David Rientjes Signed-off-by: Nick Piggin Signed-off-by: Tony Luck --- arch/ia64/mm/fault.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 19261a99e623..0799fea4c588 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -148,7 +148,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re if ((vma->vm_flags & mask) != mask) goto bad_area; - survive: /* * If for any reason at all we couldn't handle the fault, make * sure we exit gracefully rather than endlessly redo the @@ -276,13 +275,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { - yield(); - down_read(&mm->mmap_sem); - goto survive; - } - printk(KERN_CRIT "VM: killing process %s\n", current->comm); - if (user_mode(regs)) - do_group_exit(SIGKILL); - goto no_context; + if (!user_mode(regs)) + goto no_context; + pagefault_out_of_memory(); } -- cgit v1.2.3-59-g8ed1b From 2a2ae2426bba944ce6dbcad35e1580df57aafcf1 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 12 May 2010 09:30:27 -0700 Subject: [IA64] Drop duplicated "config IOMMU_HELPER" One entry for this in arch/ia64/Kconfig should be enough. Reported-by: Christoph Egger Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 4d4f4188cdf1..9676100b83ee 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -59,9 +59,6 @@ config NEED_DMA_MAP_STATE config SWIOTLB bool -config IOMMU_HELPER - bool - config GENERIC_LOCKBREAK def_bool n -- cgit v1.2.3-59-g8ed1b From a02ce953a14d6a8aab721b129b3c8ff4981a76e6 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Wed, 5 May 2010 17:08:49 +0800 Subject: x86/PCI: make ACPI MCFG reserved error messages ACPI specific Both ACPI and SFI firmwares will have MCFG space, but the error message isn't valid on SFI, so don't print the message in that case. Signed-off-by: Feng Tang Signed-off-by: Jesse Barnes --- arch/x86/pci/mmconfig-shared.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 39b9ebe8f886..a918553ebc75 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -483,16 +483,17 @@ static void __init pci_mmcfg_reject_broken(int early) list_for_each_entry(cfg, &pci_mmcfg_list, list) { int valid = 0; - if (!early && !acpi_disabled) + if (!early && !acpi_disabled) { valid = is_mmconf_reserved(is_acpi_reserved, cfg, 0); - if (valid) - continue; - - if (!early) - printk(KERN_ERR FW_BUG PREFIX - "MMCONFIG at %pR not reserved in " - "ACPI motherboard resources\n", &cfg->res); + if (valid) + continue; + else + printk(KERN_ERR FW_BUG PREFIX + "MMCONFIG at %pR not reserved in " + "ACPI motherboard resources\n", + &cfg->res); + } /* Don't try to do this check unless configuration type 1 is available. how about type 2 ?*/ -- cgit v1.2.3-59-g8ed1b From 61c7a080a5a061c976988fd4b844dfb468dda255 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:29 -0700 Subject: of: Always use 'struct device.of_node' to get device node pointer. The following structure elements duplicate the information in 'struct device.of_node' and so are being eliminated. This patch makes all readers of these elements use device.of_node instead. (struct of_device *)->node (struct dev_archdata *)->prom_node (sparc) (struct dev_archdata *)->of_node (powerpc & microblaze) Signed-off-by: Grant Likely --- arch/microblaze/kernel/of_device.c | 8 +++---- arch/microblaze/kernel/of_platform.c | 4 ++-- arch/powerpc/include/asm/macio.h | 2 +- arch/powerpc/kernel/ibmebus.c | 4 ++-- arch/powerpc/kernel/of_device.c | 8 +++---- arch/powerpc/kernel/of_platform.c | 16 +++++++------- arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 4 ++-- arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 16 +++++++------- arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 6 +++--- arch/powerpc/platforms/82xx/ep8248e.c | 6 +++--- arch/powerpc/platforms/83xx/suspend.c | 2 +- arch/powerpc/platforms/cell/axon_msi.c | 2 +- arch/powerpc/platforms/pasemi/gpio_mdio.c | 2 +- arch/powerpc/sysdev/axonram.c | 6 +++--- arch/powerpc/sysdev/bestcomm/bestcomm.c | 8 +++---- arch/powerpc/sysdev/fsl_msi.c | 14 ++++++------- arch/powerpc/sysdev/fsl_pmc.c | 2 +- arch/powerpc/sysdev/fsl_rio.c | 30 +++++++++++++-------------- arch/powerpc/sysdev/pmi.c | 2 +- arch/sparc/include/asm/fb.h | 2 +- arch/sparc/include/asm/floppy_64.h | 4 ++-- arch/sparc/include/asm/parport.h | 2 +- arch/sparc/kernel/auxio_64.c | 2 +- arch/sparc/kernel/central.c | 4 ++-- arch/sparc/kernel/chmc.c | 10 ++++----- arch/sparc/kernel/ioport.c | 2 +- arch/sparc/kernel/of_device_32.c | 14 ++++++------- arch/sparc/kernel/of_device_64.c | 26 +++++++++++------------ arch/sparc/kernel/of_device_common.c | 4 ++-- arch/sparc/kernel/pci.c | 12 +++++------ arch/sparc/kernel/pci_common.c | 9 ++++---- arch/sparc/kernel/pci_fire.c | 4 ++-- arch/sparc/kernel/pci_msi.c | 18 ++++++++-------- arch/sparc/kernel/pci_psycho.c | 4 ++-- arch/sparc/kernel/pci_sabre.c | 4 ++-- arch/sparc/kernel/pci_schizo.c | 14 ++++++------- arch/sparc/kernel/pci_sun4v.c | 8 +++---- arch/sparc/kernel/power.c | 4 ++-- arch/sparc/kernel/psycho_common.c | 2 +- arch/sparc/kernel/sbus.c | 16 +++++++------- arch/sparc/kernel/time_32.c | 2 +- arch/sparc/kernel/time_64.c | 6 +++--- drivers/ata/pata_macio.c | 2 +- drivers/ata/pata_mpc52xx.c | 10 ++++----- drivers/ata/pata_of_platform.c | 2 +- drivers/ata/sata_fsl.c | 4 ++-- drivers/atm/fore200e.c | 16 +++++++------- drivers/block/swim3.c | 2 +- drivers/block/xsysace.c | 8 +++---- drivers/cdrom/viocd.c | 2 +- drivers/char/hw_random/n2-drv.c | 2 +- drivers/char/hw_random/pasemi-rng.c | 2 +- drivers/char/ipmi/ipmi_si_intf.c | 4 ++-- drivers/char/viotape.c | 2 +- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 6 +++--- drivers/crypto/talitos.c | 2 +- drivers/dma/fsldma.c | 6 +++--- drivers/gpio/pca953x.c | 2 +- drivers/i2c/busses/i2c-cpm.c | 20 +++++++++--------- drivers/i2c/busses/i2c-ibm_iic.c | 4 ++-- drivers/i2c/busses/i2c-mpc.c | 17 ++++++++------- drivers/ide/pmac.c | 10 ++++----- drivers/infiniband/hw/ehca/ehca_main.c | 11 +++++----- drivers/input/serio/i8042-sparcio.h | 2 +- drivers/input/serio/xilinx_ps2.c | 8 +++---- drivers/leds/leds-gpio.c | 2 +- drivers/macintosh/macio_asic.c | 16 +++++++------- drivers/macintosh/macio_sysfs.c | 6 +++--- drivers/macintosh/mediabay.c | 2 +- drivers/macintosh/rack-meter.c | 4 ++-- drivers/macintosh/therm_pm72.c | 2 +- drivers/mmc/host/of_mmc_spi.c | 4 ++-- drivers/mmc/host/sdhci-of-core.c | 2 +- drivers/mtd/maps/physmap_of.c | 6 +++--- drivers/mtd/maps/sun_uflash.c | 2 +- drivers/mtd/nand/fsl_elbc_nand.c | 6 +++--- drivers/mtd/nand/ndfc.c | 10 ++++----- drivers/mtd/nand/pasemi_nand.c | 2 +- drivers/net/can/sja1000/sja1000_of_platform.c | 4 ++-- drivers/net/ehea/ehea_main.c | 14 ++++++------- drivers/net/fec_mpc52xx.c | 12 +++++------ drivers/net/fec_mpc52xx_phy.c | 4 ++-- drivers/net/fs_enet/fs_enet-main.c | 8 +++---- drivers/net/fs_enet/mac-fcc.c | 8 +++---- drivers/net/fs_enet/mac-fec.c | 4 ++-- drivers/net/fs_enet/mac-scc.c | 6 +++--- drivers/net/fs_enet/mii-fec.c | 6 +++--- drivers/net/fsl_pq_mdio.c | 2 +- drivers/net/gianfar.c | 6 +++--- drivers/net/greth.c | 3 ++- drivers/net/ibm_newemac/core.c | 13 ++++++------ drivers/net/ibm_newemac/debug.c | 9 ++++---- drivers/net/ibm_newemac/debug.h | 4 ++-- drivers/net/ibm_newemac/mal.c | 28 ++++++++++++------------- drivers/net/ibm_newemac/rgmii.c | 12 +++++------ drivers/net/ibm_newemac/tah.c | 7 ++++--- drivers/net/ibm_newemac/zmii.c | 9 ++++---- drivers/net/ll_temac_main.c | 10 ++++----- drivers/net/myri_sbus.c | 2 +- drivers/net/niu.c | 10 ++++----- drivers/net/phy/mdio-gpio.c | 6 +++--- drivers/net/sunbmac.c | 6 +++--- drivers/net/sunhme.c | 8 +++---- drivers/net/sunlance.c | 6 +++--- drivers/net/sunqe.c | 6 +++--- drivers/net/ucc_geth.c | 2 +- drivers/net/xilinx_emaclite.c | 10 ++++----- drivers/of/device.c | 20 +++++++++--------- drivers/of/of_i2c.c | 2 +- drivers/of/of_mdio.c | 4 ++-- drivers/pcmcia/electra_cf.c | 2 +- drivers/sbus/char/bbc_envctrl.c | 4 ++-- drivers/sbus/char/bbc_i2c.c | 4 ++-- drivers/sbus/char/display7seg.c | 2 +- drivers/sbus/char/envctrl.c | 2 +- drivers/sbus/char/flash.c | 4 ++-- drivers/sbus/char/uctrl.c | 2 +- drivers/scsi/ibmvscsi/ibmvfc.c | 2 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 2 +- drivers/scsi/qlogicpti.c | 10 ++++----- drivers/scsi/sun_esp.c | 16 +++++++------- drivers/serial/apbuart.c | 2 +- drivers/serial/cpm_uart/cpm_uart_core.c | 2 +- drivers/serial/mpc52xx_uart.c | 8 +++---- drivers/serial/nwpserial.c | 2 +- drivers/serial/of_serial.c | 4 ++-- drivers/serial/pmac_zilog.c | 2 +- drivers/serial/sunhv.c | 2 +- drivers/serial/sunsab.c | 6 +++--- drivers/serial/sunsu.c | 6 +++--- drivers/serial/sunzilog.c | 8 +++---- drivers/serial/uartlite.c | 6 +++--- drivers/serial/ucc_uart.c | 2 +- drivers/spi/mpc52xx_psc_spi.c | 11 +++++----- drivers/spi/mpc52xx_spi.c | 14 ++++++------- drivers/spi/spi_mpc8xxx.c | 8 +++---- drivers/usb/host/ehci-ppc-of.c | 2 +- drivers/usb/host/fhci-hcd.c | 4 ++-- drivers/usb/host/isp1760-if.c | 2 +- drivers/usb/host/ohci-ppc-of.c | 2 +- drivers/video/cg6.c | 2 +- drivers/video/ffb.c | 2 +- drivers/video/fsl-diu-fb.c | 2 +- drivers/video/platinumfb.c | 2 +- drivers/video/sunxvr1000.c | 2 +- drivers/video/xilinxfb.c | 18 ++++++++-------- drivers/watchdog/cpwd.c | 2 +- sound/aoa/fabrics/layout.c | 2 +- sound/aoa/soundbus/core.c | 8 +++---- sound/aoa/soundbus/i2sbus/control.c | 2 +- sound/aoa/soundbus/i2sbus/core.c | 4 ++-- sound/aoa/soundbus/sysfs.c | 4 ++-- sound/soc/fsl/mpc5200_dma.c | 6 +++--- sound/soc/fsl/mpc5200_psc_i2s.c | 2 +- sound/soc/fsl/mpc8610_hpcd.c | 2 +- sound/sparc/cs4231.c | 6 +++--- sound/sparc/dbri.c | 2 +- 157 files changed, 497 insertions(+), 488 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index f6c521898ebf..90d2246e15c0 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -12,7 +12,7 @@ void of_device_make_bus_id(struct of_device *dev) { static atomic_t bus_no_reg_magic; - struct device_node *node = dev->node; + struct device_node *node = dev->dev.of_node; const u32 *reg; u64 addr; int magic; @@ -76,17 +76,17 @@ int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) ofdev = to_of_device(dev); - if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name)) + if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) return -ENOMEM; - if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type)) + if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) return -ENOMEM; /* Since the compatible field can contain pretty much anything * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(ofdev->node, "compatible", &cplen); + compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); while (compat && *compat && cplen > 0) { if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) return -ENOMEM; diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index 0dc755286d38..46a1e105a6bd 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -166,7 +166,7 @@ EXPORT_SYMBOL(of_platform_bus_probe); static int of_dev_node_match(struct device *dev, void *data) { - return to_of_device(dev)->node == data; + return to_of_device(dev)->dev.of_node == data; } struct of_device *of_find_device_by_node(struct device_node *np) @@ -184,7 +184,7 @@ EXPORT_SYMBOL(of_find_device_by_node); static int of_dev_phandle_match(struct device *dev, void *data) { phandle *ph = data; - return to_of_device(dev)->node->phandle == *ph; + return to_of_device(dev)->dev.of_node->phandle == *ph; } struct of_device *of_find_device_by_phandle(phandle ph) diff --git a/arch/powerpc/include/asm/macio.h b/arch/powerpc/include/asm/macio.h index a062c57696d0..19a661b4cb98 100644 --- a/arch/powerpc/include/asm/macio.h +++ b/arch/powerpc/include/asm/macio.h @@ -108,7 +108,7 @@ static inline void* macio_get_drvdata(struct macio_dev *dev) static inline struct device_node *macio_get_of_node(struct macio_dev *mdev) { - return mdev->ofdev.node; + return mdev->ofdev.dev.of_node; } #ifdef CONFIG_PCI diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 71cf280da184..a9f31631a293 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -140,14 +140,14 @@ static struct dma_map_ops ibmebus_dma_ops = { static int ibmebus_match_path(struct device *dev, void *data) { - struct device_node *dn = to_of_device(dev)->node; + struct device_node *dn = to_of_device(dev)->dev.of_node; return (dn->full_name && (strcasecmp((char *)data, dn->full_name) == 0)); } static int ibmebus_match_node(struct device *dev, void *data) { - return to_of_device(dev)->node == data; + return to_of_device(dev)->dev.of_node == data; } static int ibmebus_create_device(struct device_node *dn) diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 9577e6f4e3bf..285c8490c547 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -13,7 +13,7 @@ static void of_device_make_bus_id(struct of_device *dev) { static atomic_t bus_no_reg_magic; - struct device_node *node = dev->node; + struct device_node *node = dev->dev.of_node; const u32 *reg; u64 addr; int magic; @@ -96,17 +96,17 @@ int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) ofdev = to_of_device(dev); - if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name)) + if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) return -ENOMEM; - if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type)) + if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) return -ENOMEM; /* Since the compatible field can contain pretty much anything * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(ofdev->node, "compatible", &cplen); + compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); while (compat && *compat && cplen > 0) { if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) return -ENOMEM; diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 6c1dfc3ff8bc..1c747c474415 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -195,7 +195,7 @@ EXPORT_SYMBOL(of_platform_bus_probe); static int of_dev_node_match(struct device *dev, void *data) { - return to_of_device(dev)->node == data; + return to_of_device(dev)->dev.of_node == data; } struct of_device *of_find_device_by_node(struct device_node *np) @@ -213,7 +213,7 @@ EXPORT_SYMBOL(of_find_device_by_node); static int of_dev_phandle_match(struct device *dev, void *data) { phandle *ph = data; - return to_of_device(dev)->node->phandle == *ph; + return to_of_device(dev)->dev.of_node->phandle == *ph; } struct of_device *of_find_device_by_phandle(phandle ph) @@ -246,10 +246,10 @@ static int __devinit of_pci_phb_probe(struct of_device *dev, if (ppc_md.pci_setup_phb == NULL) return -ENODEV; - printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name); + pr_info("Setting up PCI bus %s\n", dev->dev.of_node->full_name); /* Alloc and setup PHB data structure */ - phb = pcibios_alloc_controller(dev->node); + phb = pcibios_alloc_controller(dev->dev.of_node); if (!phb) return -ENODEV; @@ -263,19 +263,19 @@ static int __devinit of_pci_phb_probe(struct of_device *dev, } /* Process "ranges" property */ - pci_process_bridge_OF_ranges(phb, dev->node, 0); + pci_process_bridge_OF_ranges(phb, dev->dev.of_node, 0); /* Init pci_dn data structures */ pci_devs_phb_init_dynamic(phb); /* Register devices with EEH */ #ifdef CONFIG_EEH - if (dev->node->child) - eeh_add_device_tree_early(dev->node); + if (dev->dev.of_node->child) + eeh_add_device_tree_early(dev->dev.of_node); #endif /* CONFIG_EEH */ /* Scan the bus */ - pcibios_scan_phb(phb, dev->node); + pcibios_scan_phb(phb, dev->dev.of_node); if (phb->bus == NULL) return -ENXIO; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index fda7c2a18282..576669fc4fbf 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -168,7 +168,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, ofchip->gc.get = mpc52xx_wkup_gpio_get; ofchip->gc.set = mpc52xx_wkup_gpio_set; - ret = of_mm_gpiochip_add(ofdev->node, &chip->mmchip); + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); if (ret) return ret; @@ -329,7 +329,7 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, ofchip->gc.get = mpc52xx_simple_gpio_get; ofchip->gc.set = mpc52xx_simple_gpio_set; - ret = of_mm_gpiochip_add(ofdev->node, &chip->mmchip); + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); if (ret) return ret; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index a60ee39d3b78..42c507f9c35b 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -734,8 +734,8 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, spin_lock_init(&gpt->lock); gpt->dev = &ofdev->dev; - gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->node); - gpt->regs = of_iomap(ofdev->node, 0); + gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); + gpt->regs = of_iomap(ofdev->dev.of_node, 0); if (!gpt->regs) { kfree(gpt); return -ENOMEM; @@ -743,21 +743,21 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, dev_set_drvdata(&ofdev->dev, gpt); - mpc52xx_gpt_gpio_setup(gpt, ofdev->node); - mpc52xx_gpt_irq_setup(gpt, ofdev->node); + mpc52xx_gpt_gpio_setup(gpt, ofdev->dev.of_node); + mpc52xx_gpt_irq_setup(gpt, ofdev->dev.of_node); mutex_lock(&mpc52xx_gpt_list_mutex); list_add(&gpt->list, &mpc52xx_gpt_list); mutex_unlock(&mpc52xx_gpt_list_mutex); /* check if this device could be a watchdog */ - if (of_get_property(ofdev->node, "fsl,has-wdt", NULL) || - of_get_property(ofdev->node, "has-wdt", NULL)) { + if (of_get_property(ofdev->dev.of_node, "fsl,has-wdt", NULL) || + of_get_property(ofdev->dev.of_node, "has-wdt", NULL)) { const u32 *on_boot_wdt; gpt->wdt_mode = MPC52xx_GPT_CAN_WDT; - on_boot_wdt = of_get_property(ofdev->node, "fsl,wdt-on-boot", - NULL); + on_boot_wdt = of_get_property(ofdev->dev.of_node, + "fsl,wdt-on-boot", NULL); if (on_boot_wdt) { dev_info(gpt->dev, "used as watchdog\n"); gpt->wdt_mode |= MPC52xx_GPT_IS_WDT; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index d4f8be307cd5..17b99ba7a8cc 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -445,14 +445,14 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) if (lpbfifo.dev != NULL) return -ENOSPC; - lpbfifo.irq = irq_of_parse_and_map(op->node, 0); + lpbfifo.irq = irq_of_parse_and_map(op->dev.of_node, 0); if (!lpbfifo.irq) return -ENODEV; - if (of_address_to_resource(op->node, 0, &res)) + if (of_address_to_resource(op->dev.of_node, 0, &res)) return -ENODEV; lpbfifo.regs_phys = res.start; - lpbfifo.regs = of_iomap(op->node, 0); + lpbfifo.regs = of_iomap(op->dev.of_node, 0); if (!lpbfifo.regs) return -ENOMEM; diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index f21555d3395a..0176ae8249d5 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -119,12 +119,12 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, struct device_node *node; int ret; - node = of_get_parent(ofdev->node); + node = of_get_parent(ofdev->dev.of_node); of_node_put(node); if (node != ep8248e_bcsr_node) return -ENODEV; - ret = of_address_to_resource(ofdev->node, 0, &res); + ret = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (ret) return ret; @@ -142,7 +142,7 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, bus->parent = &ofdev->dev; snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); - ret = of_mdiobus_register(bus, ofdev->node); + ret = of_mdiobus_register(bus, ofdev->dev.of_node); if (ret) goto err_free_irq; diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 43805348b81e..aa0b764b1cc4 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -321,7 +321,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { static int pmc_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct pmc_type *type = match->data; int ret = 0; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 8efe48192f3f..177a4f1369b4 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -345,7 +345,7 @@ static int axon_msi_shutdown(struct of_device *device) static int axon_msi_probe(struct of_device *device, const struct of_device_id *device_id) { - struct device_node *dn = device->node; + struct device_node *dn = device->dev.of_node; struct axon_msic *msic; unsigned int virq; int dcr_base, dcr_len; diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index 0f881f64583e..c44e1b3b91db 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -220,7 +220,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mii_bus *new_bus; struct gpio_priv *priv; const unsigned int *prop; diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 88f4ae787832..88b21fccf0c9 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -185,7 +185,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) axon_ram_bank_id++; dev_info(&device->dev, "Found memory controller on %s\n", - device->node->full_name); + device->dev.of_node->full_name); bank = kzalloc(sizeof(struct axon_ram_bank), GFP_KERNEL); if (bank == NULL) { @@ -198,7 +198,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) bank->device = device; - if (of_address_to_resource(device->node, 0, &resource) != 0) { + if (of_address_to_resource(device->dev.of_node, 0, &resource) != 0) { dev_err(&device->dev, "Cannot access device tree\n"); rc = -EFAULT; goto failed; @@ -253,7 +253,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) blk_queue_logical_block_size(bank->disk->queue, AXON_RAM_SECTOR_SIZE); add_disk(bank->disk); - bank->irq_id = irq_of_parse_and_map(device->node, 0); + bank->irq_id = irq_of_parse_and_map(device->dev.of_node, 0); if (bank->irq_id == NO_IRQ) { dev_err(&device->dev, "Cannot access ECC interrupt ID\n"); rc = -EFAULT; diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index 378ebd9aac18..d32d5389b67a 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c @@ -377,7 +377,7 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) printk(KERN_INFO "DMA: MPC52xx BestComm driver\n"); /* Get the bestcomm node */ - of_node_get(op->node); + of_node_get(op->dev.of_node); /* Prepare SRAM */ ofn_sram = of_find_matching_node(NULL, mpc52xx_sram_ids); @@ -406,10 +406,10 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) } /* Save the node */ - bcom_eng->ofnode = op->node; + bcom_eng->ofnode = op->dev.of_node; /* Get, reserve & map io */ - if (of_address_to_resource(op->node, 0, &res_bcom)) { + if (of_address_to_resource(op->dev.of_node, 0, &res_bcom)) { printk(KERN_ERR DRIVER_NAME ": " "Can't get resource\n"); rv = -EINVAL; @@ -453,7 +453,7 @@ error_sramclean: kfree(bcom_eng); bcom_sram_cleanup(); error_ofput: - of_node_put(op->node); + of_node_put(op->dev.of_node); printk(KERN_ERR "DMA: MPC52xx BestComm init failed !\n"); diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 3482e3fd89c0..569dae8ea1ce 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -249,7 +249,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, goto error_out; } - msi->irqhost = irq_alloc_host(dev->node, IRQ_HOST_MAP_LINEAR, + msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR, NR_MSI_IRQS, &fsl_msi_host_ops, 0); if (msi->irqhost == NULL) { @@ -259,10 +259,10 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, } /* Get the MSI reg base */ - err = of_address_to_resource(dev->node, 0, &res); + err = of_address_to_resource(dev->dev.of_node, 0, &res); if (err) { dev_err(&dev->dev, "%s resource error!\n", - dev->node->full_name); + dev->dev.of_node->full_name); goto error_out; } @@ -285,16 +285,16 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, goto error_out; } - p = of_get_property(dev->node, "interrupts", &count); + p = of_get_property(dev->dev.of_node, "interrupts", &count); if (!p) { dev_err(&dev->dev, "no interrupts property found on %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); err = -ENODEV; goto error_out; } if (count % 8 != 0) { dev_err(&dev->dev, "Malformed interrupts property on %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); err = -EINVAL; goto error_out; } @@ -303,7 +303,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, for (i = 0; i < count / 2; i++) { if (i > NR_MSI_REG) break; - virt_msir = irq_of_parse_and_map(dev->node, i); + virt_msir = irq_of_parse_and_map(dev->dev.of_node, i); if (virt_msir != NO_IRQ) { set_irq_data(virt_msir, (void *)i); set_irq_chained_handler(virt_msir, fsl_msi_cascade); diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index a7635a993dca..2ebe817ca72f 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -60,7 +60,7 @@ static struct platform_suspend_ops pmc_suspend_ops = { static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id) { - pmc_regs = of_iomap(ofdev->node, 0); + pmc_regs = of_iomap(ofdev->dev.of_node, 0); if (!pmc_regs) return -ENOMEM; diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 71fba88f50db..a98d51639243 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1015,41 +1015,41 @@ int fsl_rio_setup(struct of_device *dev) u64 law_start, law_size; int paw, aw, sw; - if (!dev->node) { + if (!dev->dev.of_node) { dev_err(&dev->dev, "Device OF-Node is NULL"); return -EFAULT; } - rc = of_address_to_resource(dev->node, 0, ®s); + rc = of_address_to_resource(dev->dev.of_node, 0, ®s); if (rc) { dev_err(&dev->dev, "Can't get %s property 'reg'\n", - dev->node->full_name); + dev->dev.of_node->full_name); return -EFAULT; } - dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name); + dev_info(&dev->dev, "Of-device full name %s\n", dev->dev.of_node->full_name); dev_info(&dev->dev, "Regs: %pR\n", ®s); - dt_range = of_get_property(dev->node, "ranges", &rlen); + dt_range = of_get_property(dev->dev.of_node, "ranges", &rlen); if (!dt_range) { dev_err(&dev->dev, "Can't get %s property 'ranges'\n", - dev->node->full_name); + dev->dev.of_node->full_name); return -EFAULT; } /* Get node address wide */ - cell = of_get_property(dev->node, "#address-cells", NULL); + cell = of_get_property(dev->dev.of_node, "#address-cells", NULL); if (cell) aw = *cell; else - aw = of_n_addr_cells(dev->node); + aw = of_n_addr_cells(dev->dev.of_node); /* Get node size wide */ - cell = of_get_property(dev->node, "#size-cells", NULL); + cell = of_get_property(dev->dev.of_node, "#size-cells", NULL); if (cell) sw = *cell; else - sw = of_n_size_cells(dev->node); + sw = of_n_size_cells(dev->dev.of_node); /* Get parent address wide wide */ - paw = of_n_addr_cells(dev->node); + paw = of_n_addr_cells(dev->dev.of_node); law_start = of_read_number(dt_range + aw, paw); law_size = of_read_number(dt_range + aw + paw, sw); @@ -1089,9 +1089,9 @@ int fsl_rio_setup(struct of_device *dev) port->iores.flags = IORESOURCE_MEM; port->iores.name = "rio_io_win"; - priv->bellirq = irq_of_parse_and_map(dev->node, 2); - priv->txirq = irq_of_parse_and_map(dev->node, 3); - priv->rxirq = irq_of_parse_and_map(dev->node, 4); + priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2); + priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3); + priv->rxirq = irq_of_parse_and_map(dev->dev.of_node, 4); dev_info(&dev->dev, "bellirq: %d, txirq: %d, rxirq %d\n", priv->bellirq, priv->txirq, priv->rxirq); @@ -1195,7 +1195,7 @@ static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev, { int rc; printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); rc = fsl_rio_setup(dev); if (rc) diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index 652652db4ce2..ff758bff1b7a 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -124,7 +124,7 @@ static void pmi_notify_handlers(struct work_struct *work) static int pmi_of_probe(struct of_device *dev, const struct of_device_id *match) { - struct device_node *np = dev->node; + struct device_node *np = dev->dev.of_node; int rc; if (data) { diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/fb.h index b83e44729655..e834880be204 100644 --- a/arch/sparc/include/asm/fb.h +++ b/arch/sparc/include/asm/fb.h @@ -18,7 +18,7 @@ static inline int fb_is_primary_device(struct fb_info *info) struct device *dev = info->device; struct device_node *node; - node = dev->archdata.prom_node; + node = dev->of_node; if (node && node == of_console_device) return 1; diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index 36439d67ad71..8fac3ab22f36 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h @@ -589,7 +589,7 @@ static unsigned long __init sun_floppy_init(void) if (!op) return 0; - state_prop = of_get_property(op->node, "status", NULL); + state_prop = of_get_property(op->dev.of_node, "status", NULL); if (state_prop && !strncmp(state_prop, "disabled", 8)) return 0; @@ -716,7 +716,7 @@ static unsigned long __init sun_floppy_init(void) return sun_floppy_types[0]; } - prop = of_get_property(op->node, "status", NULL); + prop = of_get_property(op->dev.of_node, "status", NULL); if (prop && !strncmp(state, "disabled", 8)) return 0; diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index ff9ead640c4a..1bb6a41b00f2 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -113,7 +113,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id struct parport *p; int slot, err; - parent = op->node->parent; + parent = op->dev.of_node->parent; if (!strcmp(parent->name, "dma")) { p = parport_pc_probe_port(base, base + 0x400, op->irqs[0], PARPORT_DMA_NOFIFO, diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index 9f52db2d441c..bd8421a26856 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -104,7 +104,7 @@ MODULE_DEVICE_TABLE(of, auxio_match); static int __devinit auxio_probe(struct of_device *dev, const struct of_device_id *match) { - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; unsigned long size; if (!strcmp(dp->parent->name, "ebus")) { diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 415c86d5a8da..d533f3d5d484 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -168,7 +168,7 @@ static int __devinit fhc_probe(struct of_device *op, goto out; } - if (!strcmp(op->node->parent->name, "central")) + if (!strcmp(op->dev.of_node->parent->name, "central")) p->central = true; p->pregs = of_ioremap(&op->resource[0], 0, @@ -183,7 +183,7 @@ static int __devinit fhc_probe(struct of_device *op, reg = upa_readl(p->pregs + FHC_PREGS_BSR); p->board_num = ((reg >> 16) & 1) | ((reg >> 12) & 0x0e); } else { - p->board_num = of_getintprop_default(op->node, "board#", -1); + p->board_num = of_getintprop_default(op->dev.of_node, "board#", -1); if (p->board_num == -1) { printk(KERN_ERR "fhc: No board# property\n"); goto out_unmap_pregs; diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index e1a9598e2a4d..936879639eb6 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -425,7 +425,7 @@ static int __devinit jbusmc_probe(struct of_device *op, INIT_LIST_HEAD(&p->list); err = -ENODEV; - prop = of_get_property(op->node, "portid", &len); + prop = of_get_property(op->dev.of_node, "portid", &len); if (!prop || len != 4) { printk(KERN_ERR PFX "Cannot find portid.\n"); goto out_free; @@ -433,7 +433,7 @@ static int __devinit jbusmc_probe(struct of_device *op, p->portid = *prop; - prop = of_get_property(op->node, "memory-control-register-1", &len); + prop = of_get_property(op->dev.of_node, "memory-control-register-1", &len); if (!prop || len != 8) { printk(KERN_ERR PFX "Cannot get memory control register 1.\n"); goto out_free; @@ -449,7 +449,7 @@ static int __devinit jbusmc_probe(struct of_device *op, } err = -ENODEV; - ml = of_get_property(op->node, "memory-layout", &p->layout_len); + ml = of_get_property(op->dev.of_node, "memory-layout", &p->layout_len); if (!ml) { printk(KERN_ERR PFX "Cannot get memory layout property.\n"); goto out_iounmap; @@ -466,7 +466,7 @@ static int __devinit jbusmc_probe(struct of_device *op, mc_list_add(&p->list); printk(KERN_INFO PFX "UltraSPARC-IIIi memory controller at %s\n", - op->node->full_name); + op->dev.of_node->full_name); dev_set_drvdata(&op->dev, p); @@ -693,7 +693,7 @@ static void chmc_fetch_decode_regs(struct chmc *p) static int __devinit chmc_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; unsigned long ver; const void *pval; int len, portid; diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 84e5386714cd..703e4aa9bc38 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -290,7 +290,7 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len, if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) goto err_noiommu; - res->name = op->node->name; + res->name = op->dev.of_node->name; return (void *)(unsigned long)res->start; diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 4926c1babd84..707311716142 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -254,10 +254,10 @@ static void __init build_device_resources(struct of_device *op, return; p_op = to_of_device(parent); - bus = of_match_bus(p_op->node); - bus->count_cells(op->node, &na, &ns); + bus = of_match_bus(p_op->dev.of_node); + bus->count_cells(op->dev.of_node, &na, &ns); - preg = of_get_property(op->node, bus->addr_prop_name, &num_reg); + preg = of_get_property(op->dev.of_node, bus->addr_prop_name, &num_reg); if (!preg || num_reg == 0) return; @@ -271,8 +271,8 @@ static void __init build_device_resources(struct of_device *op, struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; const u32 *reg = (preg + (index * ((na + ns) * 4))); - struct device_node *dp = op->node; - struct device_node *pp = p_op->node; + struct device_node *dp = op->dev.of_node; + struct device_node *pp = p_op->dev.of_node; struct of_bus *pbus, *dbus; u64 size, result = OF_BAD_ADDR; unsigned long flags; @@ -321,7 +321,7 @@ static void __init build_device_resources(struct of_device *op, if (of_resource_verbose) printk("%s reg[%d] -> %llx\n", - op->node->full_name, index, + op->dev.of_node->full_name, index, result); if (result != OF_BAD_ADDR) { @@ -329,7 +329,7 @@ static void __init build_device_resources(struct of_device *op, r->end = result + size - 1; r->flags = flags | ((result >> 32ULL) & 0xffUL); } - r->name = op->node->name; + r->name = op->dev.of_node->name; } } diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 5bc74161667c..c8e352e0a098 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -323,10 +323,10 @@ static void __init build_device_resources(struct of_device *op, return; p_op = to_of_device(parent); - bus = of_match_bus(p_op->node); - bus->count_cells(op->node, &na, &ns); + bus = of_match_bus(p_op->dev.of_node); + bus->count_cells(op->dev.of_node, &na, &ns); - preg = of_get_property(op->node, bus->addr_prop_name, &num_reg); + preg = of_get_property(op->dev.of_node, bus->addr_prop_name, &num_reg); if (!preg || num_reg == 0) return; @@ -340,7 +340,7 @@ static void __init build_device_resources(struct of_device *op, if (num_reg > PROMREG_MAX) { printk(KERN_WARNING "%s: Too many regs (%d), " "limiting to %d.\n", - op->node->full_name, num_reg, PROMREG_MAX); + op->dev.of_node->full_name, num_reg, PROMREG_MAX); num_reg = PROMREG_MAX; } @@ -348,8 +348,8 @@ static void __init build_device_resources(struct of_device *op, struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; const u32 *reg = (preg + (index * ((na + ns) * 4))); - struct device_node *dp = op->node; - struct device_node *pp = p_op->node; + struct device_node *dp = op->dev.of_node; + struct device_node *pp = p_op->dev.of_node; struct of_bus *pbus, *dbus; u64 size, result = OF_BAD_ADDR; unsigned long flags; @@ -397,7 +397,7 @@ static void __init build_device_resources(struct of_device *op, if (of_resource_verbose) printk("%s reg[%d] -> %llx\n", - op->node->full_name, index, + op->dev.of_node->full_name, index, result); if (result != OF_BAD_ADDR) { @@ -408,7 +408,7 @@ static void __init build_device_resources(struct of_device *op, r->end = result + size - 1; r->flags = flags; } - r->name = op->node->name; + r->name = op->dev.of_node->name; } } @@ -530,7 +530,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, struct device *parent, unsigned int irq) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct device_node *pp, *ip; unsigned int orig_irq = irq; int nid; @@ -575,7 +575,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, if (of_irq_verbose) printk("%s: Apply [%s:%x] imap --> [%s:%x]\n", - op->node->full_name, + op->dev.of_node->full_name, pp->full_name, this_orig_irq, (iret ? iret->full_name : "NULL"), irq); @@ -594,7 +594,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, if (of_irq_verbose) printk("%s: PCI swizzle [%s] " "%x --> %x\n", - op->node->full_name, + op->dev.of_node->full_name, pp->full_name, this_orig_irq, irq); @@ -611,11 +611,11 @@ static unsigned int __init build_one_device_irq(struct of_device *op, if (!ip) return orig_irq; - irq = ip->irq_trans->irq_build(op->node, irq, + irq = ip->irq_trans->irq_build(op->dev.of_node, irq, ip->irq_trans->data); if (of_irq_verbose) printk("%s: Apply IRQ trans [%s] %x --> %x\n", - op->node->full_name, ip->full_name, orig_irq, irq); + op->dev.of_node->full_name, ip->full_name, orig_irq, irq); out: nid = of_node_to_nid(dp); diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index 0247e68210b3..10c6c36a6e75 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -16,7 +16,7 @@ static int node_match(struct device *dev, void *data) struct of_device *op = to_of_device(dev); struct device_node *dp = data; - return (op->node == dp); + return (op->dev.of_node == dp); } struct of_device *of_find_device_by_node(struct device_node *dp) @@ -48,7 +48,7 @@ EXPORT_SYMBOL(irq_of_parse_and_map); void of_propagate_archdata(struct of_device *bus) { struct dev_archdata *bus_sd = &bus->dev.archdata; - struct device_node *bus_dp = bus->node; + struct device_node *bus_dp = bus->dev.of_node; struct device_node *dp; for (dp = bus_dp->child; dp; dp = dp->sibling) { diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 0c920147b4ef..c7a214ec5aff 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -654,7 +654,7 @@ show_pciobppath_attr(struct device * dev, struct device_attribute * attr, char * struct device_node *dp; pdev = to_pci_dev(dev); - dp = pdev->dev.archdata.prom_node; + dp = pdev->dev.of_node; return snprintf (buf, PAGE_SIZE, "%s\n", dp->full_name); } @@ -684,7 +684,7 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, struct device *parent) { - struct device_node *node = pbm->op->node; + struct device_node *node = pbm->op->dev.of_node; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); @@ -1023,7 +1023,7 @@ void arch_teardown_msi_irq(unsigned int virt_irq) struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) { - return pdev->dev.archdata.prom_node; + return pdev->dev.of_node; } EXPORT_SYMBOL(pci_device_to_OF_node); @@ -1152,15 +1152,13 @@ static int __init of_pci_slot_init(void) struct device_node *node; if (pbus->self) { - struct dev_archdata *sd = pbus->self->sysdata; - /* PCI->PCI bridge */ - node = sd->prom_node; + node = pbus->self->dev.of_node; } else { struct pci_pbm_info *pbm = pbus->sysdata; /* Host PCI controller */ - node = pbm->op->node; + node = pbm->op->dev.of_node; } pci_bus_slot_names(node, pbus); diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 8a000583b5cf..6c7a33af3ba6 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -314,12 +314,12 @@ struct pci_ops sun4v_pci_ops = { void pci_get_pbm_props(struct pci_pbm_info *pbm) { - const u32 *val = of_get_property(pbm->op->node, "bus-range", NULL); + const u32 *val = of_get_property(pbm->op->dev.of_node, "bus-range", NULL); pbm->pci_first_busno = val[0]; pbm->pci_last_busno = val[1]; - val = of_get_property(pbm->op->node, "ino-bitmap", NULL); + val = of_get_property(pbm->op->dev.of_node, "ino-bitmap", NULL); if (val) { pbm->ino_bitmap = (((u64)val[1] << 32UL) | ((u64)val[0] << 0UL)); @@ -365,7 +365,8 @@ static void pci_register_legacy_regions(struct resource *io_res, static void pci_register_iommu_region(struct pci_pbm_info *pbm) { - const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); + const u32 *vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma", + NULL); if (vdma) { struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); @@ -394,7 +395,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) int num_pbm_ranges; saw_mem = saw_io = 0; - pbm_ranges = of_get_property(pbm->op->node, "ranges", &i); + pbm_ranges = of_get_property(pbm->op->dev.of_node, "ranges", &i); if (!pbm_ranges) { prom_printf("PCI: Fatal error, missing PBM ranges property " " for %s\n", diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index d53f45bc7dda..ff844baa28e6 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -413,7 +413,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, struct of_device *op, u32 portid) { const struct linux_prom64_registers *regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; int err; pbm->numa_node = -1; @@ -458,7 +458,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, static int __devinit fire_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; struct iommu *iommu; u32 portid; diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c index e0ef847219c3..548b8ca9c210 100644 --- a/arch/sparc/kernel/pci_msi.c +++ b/arch/sparc/kernel/pci_msi.c @@ -324,7 +324,7 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, const u32 *val; int len; - val = of_get_property(pbm->op->node, "#msi-eqs", &len); + val = of_get_property(pbm->op->dev.of_node, "#msi-eqs", &len); if (!val || len != 4) goto no_msi; pbm->msiq_num = *val; @@ -347,16 +347,16 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, u32 msi64_len; } *arng; - val = of_get_property(pbm->op->node, "msi-eq-size", &len); + val = of_get_property(pbm->op->dev.of_node, "msi-eq-size", &len); if (!val || len != 4) goto no_msi; pbm->msiq_ent_count = *val; - mqp = of_get_property(pbm->op->node, + mqp = of_get_property(pbm->op->dev.of_node, "msi-eq-to-devino", &len); if (!mqp) - mqp = of_get_property(pbm->op->node, + mqp = of_get_property(pbm->op->dev.of_node, "msi-eq-devino", &len); if (!mqp || len != sizeof(struct msiq_prop)) goto no_msi; @@ -364,27 +364,27 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, pbm->msiq_first = mqp->first_msiq; pbm->msiq_first_devino = mqp->first_devino; - val = of_get_property(pbm->op->node, "#msi", &len); + val = of_get_property(pbm->op->dev.of_node, "#msi", &len); if (!val || len != 4) goto no_msi; pbm->msi_num = *val; - mrng = of_get_property(pbm->op->node, "msi-ranges", &len); + mrng = of_get_property(pbm->op->dev.of_node, "msi-ranges", &len); if (!mrng || len != sizeof(struct msi_range_prop)) goto no_msi; pbm->msi_first = mrng->first_msi; - val = of_get_property(pbm->op->node, "msi-data-mask", &len); + val = of_get_property(pbm->op->dev.of_node, "msi-data-mask", &len); if (!val || len != 4) goto no_msi; pbm->msi_data_mask = *val; - val = of_get_property(pbm->op->node, "msix-data-width", &len); + val = of_get_property(pbm->op->dev.of_node, "msix-data-width", &len); if (!val || len != 4) goto no_msi; pbm->msix_data_width = *val; - arng = of_get_property(pbm->op->node, "msi-address-ranges", + arng = of_get_property(pbm->op->dev.of_node, "msi-address-ranges", &len); if (!arng || len != sizeof(struct addr_range_prop)) goto no_msi; diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 142b9d6984a8..e675e21c6df6 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -285,7 +285,7 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id) #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ static void psycho_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->node); + struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); unsigned long base = pbm->controller_regs; u64 tmp; int err; @@ -507,7 +507,7 @@ static int __devinit psycho_probe(struct of_device *op, const struct of_device_id *match) { const struct linux_prom64_registers *pr_regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; struct iommu *iommu; int is_pbm_a, err; diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index ba6fbeba3e2c..5048498daade 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -310,7 +310,7 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id) static void sabre_register_error_handlers(struct pci_pbm_info *pbm) { - struct device_node *dp = pbm->op->node; + struct device_node *dp = pbm->op->dev.of_node; struct of_device *op; unsigned long base = pbm->controller_regs; u64 tmp; @@ -456,7 +456,7 @@ static int __devinit sabre_probe(struct of_device *op, const struct of_device_id *match) { const struct linux_prom64_registers *pr_regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; u32 upa_portid, dma_mask; struct iommu *iommu; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 2b5cdde77af7..2f3f9212b063 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -844,7 +844,7 @@ static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) */ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->node); + struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); u64 tmp, err_mask, err_no_mask; int err; @@ -939,7 +939,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) static void schizo_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->node); + struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); u64 tmp, err_mask, err_no_mask; int err; @@ -1068,7 +1068,7 @@ static void __devinit schizo_scan_bus(struct pci_pbm_info *pbm, { pbm_config_busmastering(pbm); pbm->is_66mhz_capable = - (of_find_property(pbm->op->node, "66mhz-capable", NULL) + (of_find_property(pbm->op->dev.of_node, "66mhz-capable", NULL) != NULL); pbm->pci_bus = pci_scan_one_pbm(pbm, parent); @@ -1138,7 +1138,7 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) u32 dma_mask; u64 control; - vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); + vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma", NULL); if (!vdma) vdma = vdma_default; @@ -1268,7 +1268,7 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; - if (!of_find_property(pbm->op->node, "no-bus-parking", NULL)) + if (!of_find_property(pbm->op->dev.of_node, "no-bus-parking", NULL)) tmp |= SCHIZO_PCICTRL_PARK; else tmp &= ~SCHIZO_PCICTRL_PARK; @@ -1311,7 +1311,7 @@ static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm, int chip_type) { const struct linux_prom64_registers *regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; const char *chipset_name; int is_pbm_a, err; @@ -1415,7 +1415,7 @@ static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid, static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; struct iommu *iommu; u32 portid; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 23c33ff9c31e..5c11f56cedf8 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -540,7 +540,7 @@ static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm, struct property *prop; struct device_node *dp; - dp = pbm->op->node; + dp = pbm->op->dev.of_node; prop = of_find_property(dp, "66mhz-capable", NULL); pbm->is_66mhz_capable = (prop != NULL); pbm->pci_bus = pci_scan_one_pbm(pbm, parent); @@ -584,7 +584,7 @@ static int __devinit pci_sun4v_iommu_init(struct pci_pbm_info *pbm) u32 dma_mask, dma_offset; const u32 *vdma; - vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); + vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma", NULL); if (!vdma) vdma = vdma_default; @@ -881,7 +881,7 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm, struct of_device *op, u32 devhandle) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; int err; pbm->numa_node = of_node_to_nid(dp); @@ -929,7 +929,7 @@ static int __devinit pci_sun4v_probe(struct of_device *op, u32 devhandle; int i, err; - dp = op->node; + dp = op->dev.of_node; if (!hvapi_negotiated++) { err = sun4v_hvapi_register(HV_GRP_PCI, diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index e2a045c235a1..e3f806a7423b 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -41,9 +41,9 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id power_reg = of_ioremap(res, 0, 0x4, "power"); printk(KERN_INFO "%s: Control reg at %llx\n", - op->node->name, res->start); + op->dev.of_node->name, res->start); - if (has_button_interrupt(irq, op->node)) { + if (has_button_interrupt(irq, op->dev.of_node)) { if (request_irq(irq, power_handler, 0, "power", NULL) < 0) printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); diff --git a/arch/sparc/kernel/psycho_common.c b/arch/sparc/kernel/psycho_common.c index 8f1478475421..3f34ac853931 100644 --- a/arch/sparc/kernel/psycho_common.c +++ b/arch/sparc/kernel/psycho_common.c @@ -450,7 +450,7 @@ int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize, void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct of_device *op, const char *chip_name, int chip_type) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; pbm->name = dp->full_name; pbm->numa_node = -1; diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c index 406e0872504e..cfeaf04b9cdf 100644 --- a/arch/sparc/kernel/sbus.c +++ b/arch/sparc/kernel/sbus.c @@ -63,10 +63,10 @@ void sbus_set_sbus64(struct device *dev, int bursts) int slot; u64 val; - regs = of_get_property(op->node, "reg", NULL); + regs = of_get_property(op->dev.of_node, "reg", NULL); if (!regs) { printk(KERN_ERR "sbus_set_sbus64: Cannot find regs for %s\n", - op->node->full_name); + op->dev.of_node->full_name); return; } slot = regs->which_io; @@ -287,7 +287,7 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id) SYSIO_UEAFSR_SPIO | SYSIO_UEAFSR_SDRD | SYSIO_UEAFSR_SDWR); upa_writeq(error_bits, afsr_reg); - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); /* Log the error. */ printk("SYSIO[%x]: Uncorrectable ECC Error, primary error type[%s]\n", @@ -361,7 +361,7 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id) SYSIO_CEAFSR_SPIO | SYSIO_CEAFSR_SDRD | SYSIO_CEAFSR_SDWR); upa_writeq(error_bits, afsr_reg); - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); printk("SYSIO[%x]: Correctable ECC Error, primary error type[%s]\n", portid, @@ -439,7 +439,7 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) SYSIO_SBAFSR_SLE | SYSIO_SBAFSR_STO | SYSIO_SBAFSR_SBERR); upa_writeq(error_bits, afsr_reg); - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); /* Log the error. */ printk("SYSIO[%x]: SBUS Error, primary error type[%s] read(%d)\n", @@ -496,7 +496,7 @@ static void __init sysio_register_error_handlers(struct of_device *op) u64 control; int portid; - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); irq = sbus_build_irq(op, SYSIO_UE_INO); if (request_irq(irq, sysio_ue_handler, 0, @@ -537,7 +537,7 @@ static void __init sysio_register_error_handlers(struct of_device *op) static void __init sbus_iommu_init(struct of_device *op) { const struct linux_prom64_registers *pr; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct iommu *iommu; struct strbuf *strbuf; unsigned long regs, reg_base; @@ -589,7 +589,7 @@ static void __init sbus_iommu_init(struct of_device *op) */ iommu->write_complete_reg = regs + 0x2000UL; - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); printk(KERN_INFO "SYSIO: UPA portID %x, at %016lx\n", portid, regs); diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 0d4c09b15efc..e0dbed9503d4 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -152,7 +152,7 @@ static struct platform_device m48t59_rtc = { static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); if (!model) diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index c7bbe6cf7b85..9099ca095641 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -424,7 +424,7 @@ static int __devinit rtc_probe(struct of_device *op, const struct of_device_id * struct resource *r; printk(KERN_INFO "%s: RTC regs at 0x%llx\n", - op->node->full_name, op->resource[0].start); + op->dev.of_node->full_name, op->resource[0].start); /* The CMOS RTC driver only accepts IORESOURCE_IO, so cons * up a fake resource so that the probe works for all cases. @@ -480,7 +480,7 @@ static int __devinit bq4802_probe(struct of_device *op, const struct of_device_i { printk(KERN_INFO "%s: BQ4802 regs at 0x%llx\n", - op->node->full_name, op->resource[0].start); + op->dev.of_node->full_name, op->resource[0].start); rtc_bq4802_device.resource = &op->resource[0]; return platform_device_register(&rtc_bq4802_device); @@ -534,7 +534,7 @@ static struct platform_device m48t59_rtc = { static int __devinit mostek_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; /* On an Enterprise system there can be multiple mostek clocks. * We should only match the one that is on the central FHC bus. diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 211b6438b3a0..c74f13bc9876 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -1139,7 +1139,7 @@ static int __devinit pata_macio_attach(struct macio_dev *mdev, "Failed to allocate private memory\n"); return -ENOMEM; } - priv->node = of_node_get(mdev->ofdev.node); + priv->node = of_node_get(mdev->ofdev.dev.of_node); priv->mdev = mdev; priv->dev = &mdev->ofdev.dev; diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 9f5b053611dd..4cce719add3f 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -694,7 +694,7 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match) struct bcom_task *dmatsk = NULL; /* Get ipb frequency */ - ipb_freq = mpc5xxx_get_bus_frequency(op->node); + ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); if (!ipb_freq) { dev_err(&op->dev, "could not determine IPB bus frequency\n"); return -ENODEV; @@ -702,7 +702,7 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match) /* Get device base address from device tree, request the region * and ioremap it. */ - rv = of_address_to_resource(op->node, 0, &res_mem); + rv = of_address_to_resource(op->dev.of_node, 0, &res_mem); if (rv) { dev_err(&op->dev, "could not determine device base address\n"); return rv; @@ -735,14 +735,14 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match) * The MPC5200 ATA controller supports MWDMA modes 0, 1 and 2 and * UDMA modes 0, 1 and 2. */ - prop = of_get_property(op->node, "mwdma-mode", &proplen); + prop = of_get_property(op->dev.of_node, "mwdma-mode", &proplen); if ((prop) && (proplen >= 4)) mwdma_mask = ATA_MWDMA2 & ((1 << (*prop + 1)) - 1); - prop = of_get_property(op->node, "udma-mode", &proplen); + prop = of_get_property(op->dev.of_node, "udma-mode", &proplen); if ((prop) && (proplen >= 4)) udma_mask = ATA_UDMA2 & ((1 << (*prop + 1)) - 1); - ata_irq = irq_of_parse_and_map(op->node, 0); + ata_irq = irq_of_parse_and_map(op->dev.of_node, 0); if (ata_irq == NO_IRQ) { dev_err(&op->dev, "error mapping irq\n"); return -EINVAL; diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index 1f18ad9e4fe1..19da29f011db 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -18,7 +18,7 @@ static int __devinit pata_of_platform_probe(struct of_device *ofdev, const struct of_device_id *match) { int ret; - struct device_node *dn = ofdev->node; + struct device_node *dn = ofdev->dev.of_node; struct resource io_res; struct resource ctl_res; struct resource irq_res; diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index a69192b38b43..e3339e25b152 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1313,7 +1313,7 @@ static int sata_fsl_probe(struct of_device *ofdev, dev_printk(KERN_INFO, &ofdev->dev, "Sata FSL Platform/CSB Driver init\n"); - hcr_base = of_iomap(ofdev->node, 0); + hcr_base = of_iomap(ofdev->dev.of_node, 0); if (!hcr_base) goto error_exit_with_cleanup; @@ -1332,7 +1332,7 @@ static int sata_fsl_probe(struct of_device *ofdev, host_priv->ssr_base = ssr_base; host_priv->csr_base = csr_base; - irq = irq_of_parse_and_map(ofdev->node, 0); + irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); if (irq < 0) { dev_printk(KERN_ERR, &ofdev->dev, "invalid irq from platform\n"); goto error_exit_with_cleanup; diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index f7d6ebaa0418..593a03a376e4 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -789,7 +789,7 @@ static int __init fore200e_sba_map(struct fore200e *fore200e) fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */ /* get the supported DVMA burst sizes */ - bursts = of_getintprop_default(op->node->parent, "burst-sizes", 0x00); + bursts = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0x00); if (sbus_can_dma_64bit()) sbus_set_sbus64(&op->dev, bursts); @@ -820,18 +820,20 @@ static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_ const u8 *prop; int len; - prop = of_get_property(op->node, "madaddrlo2", &len); + prop = of_get_property(op->dev.of_node, "madaddrlo2", &len); if (!prop) return -ENODEV; memcpy(&prom->mac_addr[4], prop, 4); - prop = of_get_property(op->node, "madaddrhi4", &len); + prop = of_get_property(op->dev.of_node, "madaddrhi4", &len); if (!prop) return -ENODEV; memcpy(&prom->mac_addr[2], prop, 4); - prom->serial_number = of_getintprop_default(op->node, "serialnumber", 0); - prom->hw_revision = of_getintprop_default(op->node, "promversion", 0); + prom->serial_number = of_getintprop_default(op->dev.of_node, + "serialnumber", 0); + prom->hw_revision = of_getintprop_default(op->dev.of_node, + "promversion", 0); return 0; } @@ -841,10 +843,10 @@ static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page) struct of_device *op = fore200e->bus_dev; const struct linux_prom_registers *regs; - regs = of_get_property(op->node, "reg", NULL); + regs = of_get_property(op->dev.of_node, "reg", NULL); return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", - (regs ? regs->which_io : 0), op->node->name); + (regs ? regs->which_io : 0), op->dev.of_node->name); } #endif /* CONFIG_SBUS */ diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 59ca2b77b574..52f2d11bc7b9 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -1004,7 +1004,7 @@ static const struct block_device_operations floppy_fops = { static int swim3_add_device(struct macio_dev *mdev, int index) { - struct device_node *swim = mdev->ofdev.node; + struct device_node *swim = mdev->ofdev.dev.of_node; struct floppy_state *fs = &floppy_states[index]; int rc = -EBUSY; diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index e1c95e208a66..3094909b0613 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1198,10 +1198,10 @@ ace_of_probe(struct of_device *op, const struct of_device_id *match) dev_dbg(&op->dev, "ace_of_probe(%p, %p)\n", op, match); /* device id */ - id = of_get_property(op->node, "port-number", NULL); + id = of_get_property(op->dev.of_node, "port-number", NULL); /* physaddr */ - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); return rc; @@ -1209,11 +1209,11 @@ ace_of_probe(struct of_device *op, const struct of_device_id *match) physaddr = res.start; /* irq */ - irq = irq_of_parse_and_map(op->node, 0); + irq = irq_of_parse_and_map(op->dev.of_node, 0); /* bus width */ bus_width = ACE_BUS_WIDTH_16; - if (of_find_property(op->node, "8-bit", NULL)) + if (of_find_property(op->dev.of_node, "8-bit", NULL)) bus_width = ACE_BUS_WIDTH_8; /* Call the bus-independant setup code */ diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index cc435be0bc13..451cd7071b1d 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -567,7 +567,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) struct disk_info *d; struct cdrom_device_info *c; struct request_queue *q; - struct device_node *node = vdev->dev.archdata.of_node; + struct device_node *node = vdev->dev.of_node; deviceno = vdev->unit_address; if (deviceno >= VIOCD_MAX_CD) diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 10f868eefaa6..0861d99cd75b 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -660,7 +660,7 @@ static int __devinit n2rng_probe(struct of_device *op, np->hvapi_major); goto out_hvapi_unregister; } - np->num_units = of_getintprop_default(op->node, + np->num_units = of_getintprop_default(op->dev.of_node, "rng-#units", 0); if (!np->num_units) { dev_err(&op->dev, "VF RNG lacks rng-#units property\n"); diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index 7fa61dd1d9d9..b213855bae68 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -98,7 +98,7 @@ static int __devinit rng_probe(struct of_device *ofdev, const struct of_device_id *match) { void __iomem *rng_regs; - struct device_node *rng_np = ofdev->node; + struct device_node *rng_np = ofdev->dev.of_node; struct resource res; int err = 0; diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 4462b113ba3f..2b44a0e1b988 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2469,7 +2469,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, struct smi_info *info; struct resource resource; const int *regsize, *regspacing, *regshift; - struct device_node *np = dev->node; + struct device_node *np = dev->dev.of_node; int ret; int proplen; @@ -2525,7 +2525,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, info->io.regspacing = regspacing ? *regspacing : DEFAULT_REGSPACING; info->io.regshift = regshift ? *regshift : 0; - info->irq = irq_of_parse_and_map(dev->node, 0); + info->irq = irq_of_parse_and_map(dev->dev.of_node, 0); info->dev = &dev->dev; dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n", diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 1144a04cda6e..42f7fa442ff8 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -866,7 +866,7 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) { int i = vdev->unit_address; int j; - struct device_node *node = vdev->dev.archdata.of_node; + struct device_node *node = vdev->dev.of_node; if (i >= VIOTAPE_MAX_TAPE) return -ENODEV; diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 7261b8d9087c..5a0a31e2029c 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -772,18 +772,18 @@ hwicap_of_probe(struct of_device *op, const struct of_device_id *match) dev_dbg(&op->dev, "hwicap_of_probe(%p, %p)\n", op, match); - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); return rc; } - id = of_get_property(op->node, "port-number", NULL); + id = of_get_property(op->dev.of_node, "port-number", NULL); /* It's most likely that we're using V4, if the family is not specified */ regs = &v4_config_registers; - family = of_get_property(op->node, "xlnx,family", NULL); + family = of_get_property(op->dev.of_node, "xlnx,family", NULL); if (family) { if (!strcmp(family, "virtex2p")) { diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index dc558a097311..5a02f3482dba 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1807,7 +1807,7 @@ static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct talitos_private *priv; const unsigned int *prop; int i, err; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 88f470f0d820..0e376eb37417 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1313,7 +1313,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, INIT_LIST_HEAD(&fdev->common.channels); /* ioremap the registers for use */ - fdev->regs = of_iomap(op->node, 0); + fdev->regs = of_iomap(op->dev.of_node, 0); if (!fdev->regs) { dev_err(&op->dev, "unable to ioremap registers\n"); err = -ENOMEM; @@ -1321,7 +1321,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, } /* map the channel IRQ if it exists, but don't hookup the handler yet */ - fdev->irq = irq_of_parse_and_map(op->node, 0); + fdev->irq = irq_of_parse_and_map(op->dev.of_node, 0); dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask); dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask); @@ -1343,7 +1343,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, * of_platform_bus_remove(). Instead, we manually instantiate every DMA * channel object. */ - for_each_child_of_node(op->node, child) { + for_each_child_of_node(op->dev.of_node, child) { if (of_device_is_compatible(child, "fsl,eloplus-dma-channel")) { fsl_dma_chan_probe(fdev, child, FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN, diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 7d521e1d17e1..1db114b09990 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -437,7 +437,7 @@ pca953x_get_alt_pdata(struct i2c_client *client) struct device_node *node; const uint16_t *val; - node = dev_archdata_get_node(&client->dev.archdata); + node = client->dev.of_node; if (node == NULL) return NULL; diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 9c2e10082b79..48d2c1a0d4ce 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -440,7 +440,7 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) init_waitqueue_head(&cpm->i2c_wait); - cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL); + cpm->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (cpm->irq == NO_IRQ) return -EINVAL; @@ -451,13 +451,13 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) return ret; /* I2C parameter RAM */ - i2c_base = of_iomap(ofdev->node, 1); + i2c_base = of_iomap(ofdev->dev.of_node, 1); if (i2c_base == NULL) { ret = -EINVAL; goto out_irq; } - if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) { + if (of_device_is_compatible(ofdev->dev.of_node, "fsl,cpm1-i2c")) { /* Check for and use a microcode relocation patch. */ cpm->i2c_ram = i2c_base; @@ -474,7 +474,7 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) cpm->version = 1; - } else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) { + } else if (of_device_is_compatible(ofdev->dev.of_node, "fsl,cpm2-i2c")) { cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64); cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr); out_be16(i2c_base, cpm->i2c_addr); @@ -489,24 +489,24 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) } /* I2C control/status registers */ - cpm->i2c_reg = of_iomap(ofdev->node, 0); + cpm->i2c_reg = of_iomap(ofdev->dev.of_node, 0); if (cpm->i2c_reg == NULL) { ret = -EINVAL; goto out_ram; } - data = of_get_property(ofdev->node, "fsl,cpm-command", &len); + data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) { ret = -EINVAL; goto out_reg; } cpm->cp_command = *data; - data = of_get_property(ofdev->node, "linux,i2c-class", &len); + data = of_get_property(ofdev->dev.of_node, "linux,i2c-class", &len); if (data && len == 4) cpm->adap.class = *data; - data = of_get_property(ofdev->node, "clock-frequency", &len); + data = of_get_property(ofdev->dev.of_node, "clock-frequency", &len); if (data && len == 4) cpm->freq = *data; else @@ -661,7 +661,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev, /* register new adapter to i2c module... */ - data = of_get_property(ofdev->node, "linux,i2c-index", &len); + data = of_get_property(ofdev->dev.of_node, "linux,i2c-index", &len); if (data && len == 4) { cpm->adap.nr = *data; result = i2c_add_numbered_adapter(&cpm->adap); @@ -679,7 +679,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev, /* * register OF I2C devices */ - of_register_i2c_devices(&cpm->adap, ofdev->node); + of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node); return 0; out_shut: diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index b1bc6e277d2a..e66dc83953c5 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -664,7 +664,7 @@ static inline u8 iic_clckdiv(unsigned int opb) static int __devinit iic_request_irq(struct of_device *ofdev, struct ibm_iic_private *dev) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; int irq; if (iic_force_poll) @@ -695,7 +695,7 @@ static int __devinit iic_request_irq(struct of_device *ofdev, static int __devinit iic_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct ibm_iic_private *dev; struct i2c_adapter *adap; const u32 *freq; diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index f1321f763789..69473b6c260c 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -560,14 +560,14 @@ static int __devinit fsl_i2c_probe(struct of_device *op, init_waitqueue_head(&i2c->queue); - i2c->base = of_iomap(op->node, 0); + i2c->base = of_iomap(op->dev.of_node, 0); if (!i2c->base) { dev_err(i2c->dev, "failed to map controller\n"); result = -ENOMEM; goto fail_map; } - i2c->irq = irq_of_parse_and_map(op->node, 0); + i2c->irq = irq_of_parse_and_map(op->dev.of_node, 0); if (i2c->irq != NO_IRQ) { /* i2c->irq = NO_IRQ implies polling */ result = request_irq(i2c->irq, mpc_i2c_isr, IRQF_SHARED, "i2c-mpc", i2c); @@ -577,21 +577,22 @@ static int __devinit fsl_i2c_probe(struct of_device *op, } } - if (of_get_property(op->node, "fsl,preserve-clocking", NULL)) { + if (of_get_property(op->dev.of_node, "fsl,preserve-clocking", NULL)) { clock = MPC_I2C_CLOCK_PRESERVE; } else { - prop = of_get_property(op->node, "clock-frequency", &plen); + prop = of_get_property(op->dev.of_node, "clock-frequency", + &plen); if (prop && plen == sizeof(u32)) clock = *prop; } if (match->data) { struct mpc_i2c_data *data = match->data; - data->setup(op->node, i2c, clock, data->prescaler); + data->setup(op->dev.of_node, i2c, clock, data->prescaler); } else { /* Backwards compatibility */ - if (of_get_property(op->node, "dfsrr", NULL)) - mpc_i2c_setup_8xxx(op->node, i2c, clock, 0); + if (of_get_property(op->dev.of_node, "dfsrr", NULL)) + mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0); } dev_set_drvdata(&op->dev, i2c); @@ -605,7 +606,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op, dev_err(i2c->dev, "failed to add adapter\n"); goto fail_add; } - of_register_i2c_devices(&i2c->adap, op->node); + of_register_i2c_devices(&i2c->adap, op->dev.of_node); return result; diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 159955d16c47..183fa38760d8 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c @@ -1153,7 +1153,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) if (macio_resource_count(mdev) == 0) { printk(KERN_WARNING "ide-pmac: no address for %s\n", - mdev->ofdev.node->full_name); + mdev->ofdev.dev.of_node->full_name); rc = -ENXIO; goto out_free_pmif; } @@ -1161,7 +1161,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) /* Request memory resource for IO ports */ if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) { printk(KERN_ERR "ide-pmac: can't request MMIO resource for " - "%s!\n", mdev->ofdev.node->full_name); + "%s!\n", mdev->ofdev.dev.of_node->full_name); rc = -EBUSY; goto out_free_pmif; } @@ -1173,7 +1173,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) */ if (macio_irq_count(mdev) == 0) { printk(KERN_WARNING "ide-pmac: no intrs for device %s, using " - "13\n", mdev->ofdev.node->full_name); + "13\n", mdev->ofdev.dev.of_node->full_name); irq = irq_create_mapping(NULL, 13); } else irq = macio_irq(mdev, 0); @@ -1182,7 +1182,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) regbase = (unsigned long) base; pmif->mdev = mdev; - pmif->node = mdev->ofdev.node; + pmif->node = mdev->ofdev.dev.of_node; pmif->regbase = regbase; pmif->irq = irq; pmif->kauai_fcr = NULL; @@ -1191,7 +1191,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) if (macio_request_resource(mdev, 1, "ide-pmac (dma)")) printk(KERN_WARNING "ide-pmac: can't request DMA " "resource for %s!\n", - mdev->ofdev.node->full_name); + mdev->ofdev.dev.of_node->full_name); else pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000); } else diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 129a6bebd6e3..26391853277f 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -291,8 +291,9 @@ static int ehca_sense_attributes(struct ehca_shca *shca) }; ehca_gen_dbg("Probing adapter %s...", - shca->ofdev->node->full_name); - loc_code = of_get_property(shca->ofdev->node, "ibm,loc-code", NULL); + shca->ofdev->dev.of_node->full_name); + loc_code = of_get_property(shca->ofdev->dev.of_node, "ibm,loc-code", + NULL); if (loc_code) ehca_gen_dbg(" ... location lode=%s", loc_code); @@ -720,16 +721,16 @@ static int __devinit ehca_probe(struct of_device *dev, int ret, i, eq_size; unsigned long flags; - handle = of_get_property(dev->node, "ibm,hca-handle", NULL); + handle = of_get_property(dev->dev.of_node, "ibm,hca-handle", NULL); if (!handle) { ehca_gen_err("Cannot get eHCA handle for adapter: %s.", - dev->node->full_name); + dev->dev.of_node->full_name); return -ENODEV; } if (!(*handle)) { ehca_gen_err("Wrong eHCA handle for adapter: %s.", - dev->node->full_name); + dev->dev.of_node->full_name); return -ENODEV; } diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index 5071af2c0604..29e17698b2a4 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -51,7 +51,7 @@ static inline void i8042_write_command(int val) static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; dp = dp->child; while (dp) { diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index f84f8e32e3f1..7a288c0ef1a6 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -244,17 +244,17 @@ static int __devinit xps2_of_probe(struct of_device *ofdev, int error; dev_info(dev, "Device Tree Probing \'%s\'\n", - ofdev->node->name); + ofdev->dev.of_node->name); /* Get iospace for the device */ - error = of_address_to_resource(ofdev->node, 0, &r_mem); + error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); if (error) { dev_err(dev, "invalid address\n"); return error; } /* Get IRQ for the device */ - if (of_irq_to_resource(ofdev->node, 0, &r_irq) == NO_IRQ) { + if (of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq) == NO_IRQ) { dev_err(dev, "no IRQ found\n"); return -ENODEV; } @@ -342,7 +342,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) iounmap(drvdata->base_address); /* Get iospace of the device */ - if (of_address_to_resource(of_dev->node, 0, &r_mem)) + if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem)) dev_err(dev, "invalid address\n"); else release_mem_region(r_mem.start, resource_size(&r_mem)); diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index c6e4b772b757..a77a23e783db 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -211,7 +211,7 @@ struct gpio_led_of_platform_data { static int __devinit of_gpio_leds_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node, *child; + struct device_node *np = ofdev->dev.of_node, *child; struct gpio_led_of_platform_data *pdata; int count = 0, ret; diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 26a303a1d1ab..67fe13ffe90b 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -248,7 +248,7 @@ static void macio_create_fixup_irq(struct macio_dev *dev, int index, static void macio_add_missing_resources(struct macio_dev *dev) { - struct device_node *np = dev->ofdev.node; + struct device_node *np = dev->ofdev.dev.of_node; unsigned int irq_base; /* Gatwick has some missing interrupts on child nodes */ @@ -289,7 +289,7 @@ static void macio_add_missing_resources(struct macio_dev *dev) static void macio_setup_interrupts(struct macio_dev *dev) { - struct device_node *np = dev->ofdev.node; + struct device_node *np = dev->ofdev.dev.of_node; unsigned int irq; int i = 0, j = 0; @@ -317,7 +317,7 @@ static void macio_setup_interrupts(struct macio_dev *dev) static void macio_setup_resources(struct macio_dev *dev, struct resource *parent_res) { - struct device_node *np = dev->ofdev.node; + struct device_node *np = dev->ofdev.dev.of_node; struct resource r; int index; @@ -373,7 +373,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, dev->bus = &chip->lbus; dev->media_bay = in_bay; - dev->ofdev.node = np; + dev->ofdev.dev.of_node = np; dev->ofdev.dma_mask = 0xffffffffUL; dev->ofdev.dev.dma_mask = &dev->ofdev.dma_mask; dev->ofdev.dev.parent = parent; @@ -494,9 +494,9 @@ static void macio_pci_add_devices(struct macio_chip *chip) } /* Add media bay devices if any */ + pnode = mbdev->ofdev.dev.of_node; if (mbdev) - for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np)) - != NULL;) { + for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { if (macio_skip_device(np)) continue; of_node_get(np); @@ -506,9 +506,9 @@ static void macio_pci_add_devices(struct macio_chip *chip) } /* Add serial ports if any */ + pnode = sdev->ofdev.dev.of_node; if (sdev) { - for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np)) - != NULL;) { + for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { if (macio_skip_device(np)) continue; of_node_get(np); diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 9e9453b58425..6999ce59fd10 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -9,7 +9,7 @@ field##_show (struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ struct macio_dev *mdev = to_macio_device (dev); \ - return sprintf (buf, format_string, mdev->ofdev.node->field); \ + return sprintf (buf, format_string, mdev->ofdev.dev.of_node->field); \ } static ssize_t @@ -21,7 +21,7 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf) int length = 0; of = &to_macio_device (dev)->ofdev; - compat = of_get_property(of->node, "compatible", &cplen); + compat = of_get_property(of->dev.of_node, "compatible", &cplen); if (!compat) { *buf = '\0'; return 0; @@ -58,7 +58,7 @@ static ssize_t devspec_show(struct device *dev, struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s\n", ofdev->node->full_name); + return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); } macio_config_of_attr (name, "%s\n"); diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 08002b88f342..288acce76b74 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -564,7 +564,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de unsigned long base; int i; - ofnode = mdev->ofdev.node; + ofnode = mdev->ofdev.dev.of_node; if (macio_resource_count(mdev) < 1) return -ENODEV; diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 7c54d80c4fb2..12946c5f583f 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -375,7 +375,7 @@ static int __devinit rackmeter_probe(struct macio_dev* mdev, pr_debug("rackmeter_probe()\n"); /* Get i2s-a node */ - while ((i2s = of_get_next_child(mdev->ofdev.node, i2s)) != NULL) + while ((i2s = of_get_next_child(mdev->ofdev.dev.of_node, i2s)) != NULL) if (strcmp(i2s->name, "i2s-a") == 0) break; if (i2s == NULL) { @@ -431,7 +431,7 @@ static int __devinit rackmeter_probe(struct macio_dev* mdev, of_address_to_resource(i2s, 1, &rdma)) { printk(KERN_ERR "rackmeter: found match but lacks resources: %s", - mdev->ofdev.node->full_name); + mdev->ofdev.dev.of_node->full_name); rc = -ENXIO; goto bail_free; } diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index b18fa948f3d1..9314be9a2fc8 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -2215,7 +2215,7 @@ static int fcu_of_probe(struct of_device* dev, const struct of_device_id *match) state = state_detached; /* Lookup the fans in the device tree */ - fcu_lookup_fans(dev->node); + fcu_lookup_fans(dev->dev.of_node); /* Add the driver */ return i2c_add_driver(&therm_pm72_driver); diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index bb6cc54b558e..1247e5de9faa 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c @@ -64,7 +64,7 @@ static int of_mmc_spi_get_ro(struct device *dev) struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi) { struct device *dev = &spi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; struct of_mmc_spi *oms; const u32 *voltage_ranges; int num_ranges; @@ -135,7 +135,7 @@ EXPORT_SYMBOL(mmc_spi_get_pdata); void mmc_spi_put_pdata(struct spi_device *spi) { struct device *dev = &spi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; struct of_mmc_spi *oms = to_of_mmc_spi(dev); int i; diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index 55e33135edb4..dfe5ceae6794 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -118,7 +118,7 @@ static bool __devinit sdhci_of_wp_inverted(struct device_node *np) static int __devinit sdhci_of_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct sdhci_of_data *sdhci_of_data = match->data; struct sdhci_host *host; struct sdhci_of_host *of_host; diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 101ee6ead05c..3dc7a2fbf025 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -143,7 +143,7 @@ static int of_flash_remove(struct of_device *dev) static struct mtd_info * __devinit obsolete_probe(struct of_device *dev, struct map_info *map) { - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; const char *of_probe; struct mtd_info *mtd; static const char *rom_probe_types[] @@ -180,7 +180,7 @@ static int __devinit of_flash_probe(struct of_device *dev, static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; #endif - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; struct resource res; struct of_flash *info; const char *probe_type = match->data; @@ -204,7 +204,7 @@ static int __devinit of_flash_probe(struct of_device *dev, p = of_get_property(dp, "reg", &count); if (count % reg_tuple_size != 0) { dev_err(&dev->dev, "Malformed reg property on %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); err = -EINVAL; goto err_flash_remove; } diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index fadc4c45b455..5945a23e681f 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -110,7 +110,7 @@ int uflash_devinit(struct of_device *op, struct device_node *dp) static int __devinit uflash_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; /* Flashprom must have the "user" property in order to * be used by this driver. diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index ae30fb6eed97..4a6079588ab2 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -1030,14 +1030,14 @@ static int __devinit fsl_elbc_ctrl_probe(struct of_device *ofdev, init_waitqueue_head(&ctrl->controller.wq); init_waitqueue_head(&ctrl->irq_wait); - ctrl->regs = of_iomap(ofdev->node, 0); + ctrl->regs = of_iomap(ofdev->dev.of_node, 0); if (!ctrl->regs) { dev_err(&ofdev->dev, "failed to get memory region\n"); ret = -ENODEV; goto err; } - ctrl->irq = of_irq_to_resource(ofdev->node, 0, NULL); + ctrl->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (ctrl->irq == NO_IRQ) { dev_err(&ofdev->dev, "failed to get irq resource\n"); ret = -ENODEV; @@ -1058,7 +1058,7 @@ static int __devinit fsl_elbc_ctrl_probe(struct of_device *ofdev, goto err; } - for_each_child_of_node(ofdev->node, child) + for_each_child_of_node(ofdev->dev.of_node, child) if (of_device_is_compatible(child, "fsl,elbc-fcm-nand")) fsl_elbc_chip_probe(ctrl, child); diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index b983cae8c298..c0e05f5ff8a4 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -239,14 +239,14 @@ static int __devinit ndfc_probe(struct of_device *ofdev, dev_set_drvdata(&ofdev->dev, ndfc); /* Read the reg property to get the chip select */ - reg = of_get_property(ofdev->node, "reg", &len); + reg = of_get_property(ofdev->dev.of_node, "reg", &len); if (reg == NULL || len != 12) { dev_err(&ofdev->dev, "unable read reg property (%d)\n", len); return -ENOENT; } ndfc->chip_select = reg[0]; - ndfc->ndfcbase = of_iomap(ofdev->node, 0); + ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0); if (!ndfc->ndfcbase) { dev_err(&ofdev->dev, "failed to get memory\n"); return -EIO; @@ -255,20 +255,20 @@ static int __devinit ndfc_probe(struct of_device *ofdev, ccr = NDFC_CCR_BS(ndfc->chip_select); /* It is ok if ccr does not exist - just default to 0 */ - reg = of_get_property(ofdev->node, "ccr", NULL); + reg = of_get_property(ofdev->dev.of_node, "ccr", NULL); if (reg) ccr |= *reg; out_be32(ndfc->ndfcbase + NDFC_CCR, ccr); /* Set the bank settings if given */ - reg = of_get_property(ofdev->node, "bank-settings", NULL); + reg = of_get_property(ofdev->dev.of_node, "bank-settings", NULL); if (reg) { int offset = NDFC_BCFG0 + (ndfc->chip_select << 2); out_be32(ndfc->ndfcbase + offset, *reg); } - err = ndfc_chip_init(ndfc, ofdev->node); + err = ndfc_chip_init(ndfc, ofdev->dev.of_node); if (err) { iounmap(ndfc->ndfcbase); return err; diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index a8b9376cf324..edfc27b78513 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -93,7 +93,7 @@ static int __devinit pasemi_nand_probe(struct of_device *ofdev, const struct of_device_id *match) { struct pci_dev *pdev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct nand_chip *chip; int err = 0; diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index 9dd076a626a5..dc5f20cdf93c 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -72,7 +72,7 @@ static int __devexit sja1000_ofp_remove(struct of_device *ofdev) { struct net_device *dev = dev_get_drvdata(&ofdev->dev); struct sja1000_priv *priv = netdev_priv(dev); - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; dev_set_drvdata(&ofdev->dev, NULL); @@ -91,7 +91,7 @@ static int __devexit sja1000_ofp_remove(struct of_device *ofdev) static int __devinit sja1000_ofp_probe(struct of_device *ofdev, const struct of_device_id *id) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct net_device *dev; struct sja1000_priv *priv; struct resource res; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 809ccc9ff09c..59dac232006c 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -3035,7 +3035,7 @@ static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id, static void __devinit logical_port_release(struct device *dev) { struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev); - of_node_put(port->ofdev.node); + of_node_put(port->ofdev.dev.of_node); } static struct device *ehea_register_port(struct ehea_port *port, @@ -3043,7 +3043,7 @@ static struct device *ehea_register_port(struct ehea_port *port, { int ret; - port->ofdev.node = of_node_get(dn); + port->ofdev.dev.of_node = of_node_get(dn); port->ofdev.dev.parent = &port->adapter->ofdev->dev; port->ofdev.dev.bus = &ibmebus_bus_type; @@ -3210,7 +3210,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) const u32 *dn_log_port_id; int i = 0; - lhea_dn = adapter->ofdev->node; + lhea_dn = adapter->ofdev->dev.of_node; while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", @@ -3249,7 +3249,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, struct device_node *eth_dn = NULL; const u32 *dn_log_port_id; - lhea_dn = adapter->ofdev->node; + lhea_dn = adapter->ofdev->dev.of_node; while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", @@ -3379,7 +3379,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, const u64 *adapter_handle; int ret; - if (!dev || !dev->node) { + if (!dev || !dev->dev.of_node) { ehea_error("Invalid ibmebus device probed"); return -EINVAL; } @@ -3395,14 +3395,14 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, adapter->ofdev = dev; - adapter_handle = of_get_property(dev->node, "ibm,hea-handle", + adapter_handle = of_get_property(dev->dev.of_node, "ibm,hea-handle", NULL); if (adapter_handle) adapter->handle = *adapter_handle; if (!adapter->handle) { dev_err(&dev->dev, "failed getting handle for adapter" - " '%s'\n", dev->node->full_name); + " '%s'\n", dev->dev.of_node->full_name); ret = -ENODEV; goto out_free_ad; } diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 4a43e56b7394..3342056f8aac 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -873,7 +873,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) priv->ndev = ndev; /* Reserve FEC control zone */ - rv = of_address_to_resource(op->node, 0, &mem); + rv = of_address_to_resource(op->dev.of_node, 0, &mem); if (rv) { printk(KERN_ERR DRIVER_NAME ": " "Error while parsing device node resource\n" ); @@ -921,7 +921,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) /* Get the IRQ we need one by one */ /* Control */ - ndev->irq = irq_of_parse_and_map(op->node, 0); + ndev->irq = irq_of_parse_and_map(op->dev.of_node, 0); /* RX */ priv->r_irq = bcom_get_task_irq(priv->rx_dmatsk); @@ -944,20 +944,20 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) /* Start with safe defaults for link connection */ priv->speed = 100; priv->duplex = DUPLEX_HALF; - priv->mdio_speed = ((mpc5xxx_get_bus_frequency(op->node) >> 20) / 5) << 1; + priv->mdio_speed = ((mpc5xxx_get_bus_frequency(op->dev.of_node) >> 20) / 5) << 1; /* The current speed preconfigures the speed of the MII link */ - prop = of_get_property(op->node, "current-speed", &prop_size); + prop = of_get_property(op->dev.of_node, "current-speed", &prop_size); if (prop && (prop_size >= sizeof(u32) * 2)) { priv->speed = prop[0]; priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF; } /* If there is a phy handle, then get the PHY node */ - priv->phy_node = of_parse_phandle(op->node, "phy-handle", 0); + priv->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); /* the 7-wire property means don't use MII mode */ - if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) { + if (of_find_property(op->dev.of_node, "fsl,7-wire-mode", NULL)) { priv->seven_wire_mode = 1; dev_info(&ndev->dev, "using 7-wire PHY mode\n"); } diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index 7658a082e390..0d099e5a652d 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -66,7 +66,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_id *match) { struct device *dev = &of->dev; - struct device_node *np = of->node; + struct device_node *np = of->dev.of_node; struct mii_bus *bus; struct mpc52xx_fec_mdio_priv *priv; struct resource res = {}; @@ -107,7 +107,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, /* set MII speed */ out_be32(&priv->regs->mii_speed, - ((mpc5xxx_get_bus_frequency(of->node) >> 20) / 5) << 1); + ((mpc5xxx_get_bus_frequency(of->dev.of_node) >> 20) / 5) << 1); err = of_mdiobus_register(bus, np); if (err) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 0770e2f6da6b..caeb88b67bc6 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -1015,7 +1015,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, return -ENOMEM; if (!IS_FEC(match)) { - data = of_get_property(ofdev->node, "fsl,cpm-command", &len); + data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; @@ -1027,8 +1027,8 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, fpi->rx_copybreak = 240; fpi->use_napi = 1; fpi->napi_weight = 17; - fpi->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0); - if ((!fpi->phy_node) && (!of_get_property(ofdev->node, "fixed-link", + fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); + if ((!fpi->phy_node) && (!of_get_property(ofdev->dev.of_node, "fixed-link", NULL))) goto out_free_fpi; @@ -1061,7 +1061,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, spin_lock_init(&fep->lock); spin_lock_init(&fep->tx_lock); - mac_addr = of_get_mac_address(ofdev->node); + mac_addr = of_get_mac_address(ofdev->dev.of_node); if (mac_addr) memcpy(ndev->dev_addr, mac_addr, 6); diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 0a973e71876b..9d4f272137d6 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -88,19 +88,19 @@ static int do_pd_setup(struct fs_enet_private *fep) struct fs_platform_info *fpi = fep->fpi; int ret = -EINVAL; - fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (fep->interrupt == NO_IRQ) goto out; - fep->fcc.fccp = of_iomap(ofdev->node, 0); + fep->fcc.fccp = of_iomap(ofdev->dev.of_node, 0); if (!fep->fcc.fccp) goto out; - fep->fcc.ep = of_iomap(ofdev->node, 1); + fep->fcc.ep = of_iomap(ofdev->dev.of_node, 1); if (!fep->fcc.ep) goto out_fccp; - fep->fcc.fcccp = of_iomap(ofdev->node, 2); + fep->fcc.fcccp = of_iomap(ofdev->dev.of_node, 2); if (!fep->fcc.fcccp) goto out_ep; diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index ec81f50d5919..bd7a6e7064bb 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -98,11 +98,11 @@ static int do_pd_setup(struct fs_enet_private *fep) { struct of_device *ofdev = to_of_device(fep->dev); - fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (fep->interrupt == NO_IRQ) return -EINVAL; - fep->fec.fecp = of_iomap(ofdev->node, 0); + fep->fec.fecp = of_iomap(ofdev->dev.of_node, 0); if (!fep->fcc.fccp) return -EINVAL; diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 34d3da751eb4..49a4d8c60168 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -98,15 +98,15 @@ static int do_pd_setup(struct fs_enet_private *fep) { struct of_device *ofdev = to_of_device(fep->dev); - fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (fep->interrupt == NO_IRQ) return -EINVAL; - fep->scc.sccp = of_iomap(ofdev->node, 0); + fep->scc.sccp = of_iomap(ofdev->dev.of_node, 0); if (!fep->scc.sccp) return -EINVAL; - fep->scc.ep = of_iomap(ofdev->node, 1); + fep->scc.ep = of_iomap(ofdev->dev.of_node, 1); if (!fep->scc.ep) { iounmap(fep->scc.sccp); return -EINVAL; diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index 5944b65082cb..dc862e779c1f 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -124,7 +124,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, new_bus->write = &fs_enet_fec_mii_write; new_bus->reset = &fs_enet_fec_mii_reset; - ret = of_address_to_resource(ofdev->node, 0, &res); + ret = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (ret) goto out_res; @@ -135,7 +135,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, goto out_fec; if (get_bus_freq) { - clock = get_bus_freq(ofdev->node); + clock = get_bus_freq(ofdev->dev.of_node); if (!clock) { /* Use maximum divider if clock is unknown */ dev_warn(&ofdev->dev, "could not determine IPS clock\n"); @@ -172,7 +172,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); - ret = of_mdiobus_register(new_bus, ofdev->node); + ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); if (ret) goto out_free_irqs; diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index d5160edf2fcf..72489a213bf7 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -271,7 +271,7 @@ static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) static int fsl_pq_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node *tbi; struct fsl_pq_mdio_priv *priv; struct fsl_pq_mdio __iomem *regs = NULL; diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 080d1cea5b26..b71bba91064c 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -603,7 +603,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) int err = 0, i; struct net_device *dev = NULL; struct gfar_private *priv = NULL; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node *child = NULL; const u32 *stash; const u32 *stash_len; @@ -641,7 +641,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) return -ENOMEM; priv = netdev_priv(dev); - priv->node = ofdev->node; + priv->node = ofdev->dev.of_node; priv->ndev = dev; dev->num_tx_queues = num_tx_qs; @@ -888,7 +888,7 @@ static int gfar_probe(struct of_device *ofdev, priv = netdev_priv(dev); priv->ndev = dev; priv->ofdev = ofdev; - priv->node = ofdev->node; + priv->node = ofdev->dev.of_node; SET_NETDEV_DEV(dev, &ofdev->dev); spin_lock_init(&priv->bflock); diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 3a90430de918..61fd54d35f63 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -1500,7 +1500,8 @@ static int __devinit greth_of_probe(struct of_device *ofdev, const struct of_dev if (i == 6) { const unsigned char *addr; int len; - addr = of_get_property(ofdev->node, "local-mac-address", &len); + addr = of_get_property(ofdev->dev.of_node, "local-mac-address", + &len); if (addr != NULL && len == 6) { for (i = 0; i < 6; i++) macaddr[i] = (unsigned int) addr[i]; diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index dd873cc41c2b..cda2ba891344 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -136,7 +136,8 @@ static inline void emac_report_timeout_error(struct emac_instance *dev, EMAC_FTR_440EP_PHY_CLK_FIX)) DBG(dev, "%s" NL, error); else if (net_ratelimit()) - printk(KERN_ERR "%s: %s\n", dev->ofdev->node->full_name, error); + printk(KERN_ERR "%s: %s\n", dev->ofdev->dev.of_node->full_name, + error); } /* EMAC PHY clock workaround: @@ -2185,7 +2186,7 @@ static void emac_ethtool_get_drvinfo(struct net_device *ndev, strcpy(info->version, DRV_VERSION); info->fw_version[0] = '\0'; sprintf(info->bus_info, "PPC 4xx EMAC-%d %s", - dev->cell_index, dev->ofdev->node->full_name); + dev->cell_index, dev->ofdev->dev.of_node->full_name); info->regdump_len = emac_ethtool_get_regs_len(ndev); } @@ -2379,7 +2380,7 @@ static int __devinit emac_read_uint_prop(struct device_node *np, const char *nam static int __devinit emac_init_phy(struct emac_instance *dev) { - struct device_node *np = dev->ofdev->node; + struct device_node *np = dev->ofdev->dev.of_node; struct net_device *ndev = dev->ndev; u32 phy_map, adv; int i; @@ -2514,7 +2515,7 @@ static int __devinit emac_init_phy(struct emac_instance *dev) static int __devinit emac_init_config(struct emac_instance *dev) { - struct device_node *np = dev->ofdev->node; + struct device_node *np = dev->ofdev->dev.of_node; const void *p; unsigned int plen; const char *pm, *phy_modes[] = { @@ -2723,7 +2724,7 @@ static int __devinit emac_probe(struct of_device *ofdev, { struct net_device *ndev; struct emac_instance *dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node **blist = NULL; int err, i; @@ -2810,7 +2811,7 @@ static int __devinit emac_probe(struct of_device *ofdev, err = mal_register_commac(dev->mal, &dev->commac); if (err) { printk(KERN_ERR "%s: failed to register with mal %s!\n", - np->full_name, dev->mal_dev->node->full_name); + np->full_name, dev->mal_dev->dev.of_node->full_name); goto err_rel_deps; } dev->rx_skb_size = emac_rx_skb_size(ndev->mtu); diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c index 775c850a425a..3995fafc1e08 100644 --- a/drivers/net/ibm_newemac/debug.c +++ b/drivers/net/ibm_newemac/debug.c @@ -33,7 +33,7 @@ static void emac_desc_dump(struct emac_instance *p) int i; printk("** EMAC %s TX BDs **\n" " tx_cnt = %d tx_slot = %d ack_slot = %d\n", - p->ofdev->node->full_name, + p->ofdev->dev.of_node->full_name, p->tx_cnt, p->tx_slot, p->ack_slot); for (i = 0; i < NUM_TX_BUFF / 2; ++i) printk @@ -49,7 +49,7 @@ static void emac_desc_dump(struct emac_instance *p) printk("** EMAC %s RX BDs **\n" " rx_slot = %d flags = 0x%lx rx_skb_size = %d rx_sync_size = %d\n" " rx_sg_skb = 0x%p\n", - p->ofdev->node->full_name, + p->ofdev->dev.of_node->full_name, p->rx_slot, p->commac.flags, p->rx_skb_size, p->rx_sync_size, p->rx_sg_skb); for (i = 0; i < NUM_RX_BUFF / 2; ++i) @@ -77,7 +77,8 @@ static void emac_mac_dump(struct emac_instance *dev) "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n" "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n", - dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1), + dev->ofdev->dev.of_node->full_name, + in_be32(&p->mr0), in_be32(&p->mr1), in_be32(&p->tmr0), in_be32(&p->tmr1), in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser), in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid), @@ -128,7 +129,7 @@ static void emac_mal_dump(struct mal_instance *mal) "CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n" "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n" "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n", - mal->ofdev->node->full_name, + mal->ofdev->dev.of_node->full_name, get_mal_dcrn(mal, MAL_CFG), get_mal_dcrn(mal, MAL_ESR), get_mal_dcrn(mal, MAL_IER), get_mal_dcrn(mal, MAL_TXCASR), get_mal_dcrn(mal, MAL_TXCARR), diff --git a/drivers/net/ibm_newemac/debug.h b/drivers/net/ibm_newemac/debug.h index b631842ec8d0..e596c77ccdf7 100644 --- a/drivers/net/ibm_newemac/debug.h +++ b/drivers/net/ibm_newemac/debug.h @@ -53,8 +53,8 @@ extern void emac_dbg_dump_all(void); #endif -#define EMAC_DBG(dev, name, fmt, arg...) \ - printk(KERN_DEBUG #name "%s: " fmt, dev->ofdev->node->full_name, ## arg) +#define EMAC_DBG(d, name, fmt, arg...) \ + printk(KERN_DEBUG #name "%s: " fmt, d->ofdev->dev.of_node->full_name, ## arg) #if DBG_LEVEL > 0 # define DBG(d,f,x...) EMAC_DBG(d, emac, f, ##x) diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index 5b3d94419fe6..aba17947e208 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -538,11 +538,11 @@ static int __devinit mal_probe(struct of_device *ofdev, } mal->index = index; mal->ofdev = ofdev; - mal->version = of_device_is_compatible(ofdev->node, "ibm,mcmal2") ? 2 : 1; + mal->version = of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal2") ? 2 : 1; MAL_DBG(mal, "probe" NL); - prop = of_get_property(ofdev->node, "num-tx-chans", NULL); + prop = of_get_property(ofdev->dev.of_node, "num-tx-chans", NULL); if (prop == NULL) { printk(KERN_ERR "mal%d: can't find MAL num-tx-chans property!\n", @@ -552,7 +552,7 @@ static int __devinit mal_probe(struct of_device *ofdev, } mal->num_tx_chans = prop[0]; - prop = of_get_property(ofdev->node, "num-rx-chans", NULL); + prop = of_get_property(ofdev->dev.of_node, "num-rx-chans", NULL); if (prop == NULL) { printk(KERN_ERR "mal%d: can't find MAL num-rx-chans property!\n", @@ -562,14 +562,14 @@ static int __devinit mal_probe(struct of_device *ofdev, } mal->num_rx_chans = prop[0]; - dcr_base = dcr_resource_start(ofdev->node, 0); + dcr_base = dcr_resource_start(ofdev->dev.of_node, 0); if (dcr_base == 0) { printk(KERN_ERR "mal%d: can't find DCR resource!\n", index); err = -ENODEV; goto fail; } - mal->dcr_host = dcr_map(ofdev->node, dcr_base, 0x100); + mal->dcr_host = dcr_map(ofdev->dev.of_node, dcr_base, 0x100); if (!DCR_MAP_OK(mal->dcr_host)) { printk(KERN_ERR "mal%d: failed to map DCRs !\n", index); @@ -577,28 +577,28 @@ static int __devinit mal_probe(struct of_device *ofdev, goto fail; } - if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez")) { + if (of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal-405ez")) { #if defined(CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT) && \ defined(CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR) mal->features |= (MAL_FTR_CLEAR_ICINTSTAT | MAL_FTR_COMMON_ERR_INT); #else printk(KERN_ERR "%s: Support for 405EZ not enabled!\n", - ofdev->node->full_name); + ofdev->dev.of_node->full_name); err = -ENODEV; goto fail; #endif } - mal->txeob_irq = irq_of_parse_and_map(ofdev->node, 0); - mal->rxeob_irq = irq_of_parse_and_map(ofdev->node, 1); - mal->serr_irq = irq_of_parse_and_map(ofdev->node, 2); + mal->txeob_irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); + mal->rxeob_irq = irq_of_parse_and_map(ofdev->dev.of_node, 1); + mal->serr_irq = irq_of_parse_and_map(ofdev->dev.of_node, 2); if (mal_has_feature(mal, MAL_FTR_COMMON_ERR_INT)) { mal->txde_irq = mal->rxde_irq = mal->serr_irq; } else { - mal->txde_irq = irq_of_parse_and_map(ofdev->node, 3); - mal->rxde_irq = irq_of_parse_and_map(ofdev->node, 4); + mal->txde_irq = irq_of_parse_and_map(ofdev->dev.of_node, 3); + mal->rxde_irq = irq_of_parse_and_map(ofdev->dev.of_node, 4); } if (mal->txeob_irq == NO_IRQ || mal->rxeob_irq == NO_IRQ || @@ -629,7 +629,7 @@ static int __devinit mal_probe(struct of_device *ofdev, /* Current Axon is not happy with priority being non-0, it can * deadlock, fix it up here */ - if (of_device_is_compatible(ofdev->node, "ibm,mcmal-axon")) + if (of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal-axon")) cfg &= ~(MAL2_CFG_RPP_10 | MAL2_CFG_WPP_10); /* Apply configuration */ @@ -701,7 +701,7 @@ static int __devinit mal_probe(struct of_device *ofdev, printk(KERN_INFO "MAL v%d %s, %d TX channels, %d RX channels\n", - mal->version, ofdev->node->full_name, + mal->version, ofdev->dev.of_node->full_name, mal->num_tx_chans, mal->num_rx_chans); /* Advertise this instance to the rest of the world */ diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 5b90d34c8455..6ab630a79e31 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -103,7 +103,7 @@ int __devinit rgmii_attach(struct of_device *ofdev, int input, int mode) /* Check if we need to attach to a RGMII */ if (input < 0 || !rgmii_valid_mode(mode)) { printk(KERN_ERR "%s: unsupported settings !\n", - ofdev->node->full_name); + ofdev->dev.of_node->full_name); return -ENODEV; } @@ -113,7 +113,7 @@ int __devinit rgmii_attach(struct of_device *ofdev, int input, int mode) out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input)); printk(KERN_NOTICE "%s: input %d in %s mode\n", - ofdev->node->full_name, input, rgmii_mode_name(mode)); + ofdev->dev.of_node->full_name, input, rgmii_mode_name(mode)); ++dev->users; @@ -231,7 +231,7 @@ void *rgmii_dump_regs(struct of_device *ofdev, void *buf) static int __devinit rgmii_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct rgmii_instance *dev; struct resource regs; int rc; @@ -264,11 +264,11 @@ static int __devinit rgmii_probe(struct of_device *ofdev, } /* Check for RGMII flags */ - if (of_get_property(ofdev->node, "has-mdio", NULL)) + if (of_get_property(ofdev->dev.of_node, "has-mdio", NULL)) dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO; /* CAB lacks the right properties, fix this up */ - if (of_device_is_compatible(ofdev->node, "ibm,rgmii-axon")) + if (of_device_is_compatible(ofdev->dev.of_node, "ibm,rgmii-axon")) dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO; DBG2(dev, " Boot FER = 0x%08x, SSR = 0x%08x\n", @@ -279,7 +279,7 @@ static int __devinit rgmii_probe(struct of_device *ofdev, printk(KERN_INFO "RGMII %s initialized with%s MDIO support\n", - ofdev->node->full_name, + ofdev->dev.of_node->full_name, (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out"); wmb(); diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index 30173a9fb557..4f64b00dd5e8 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -57,7 +57,8 @@ void tah_reset(struct of_device *ofdev) --n; if (unlikely(!n)) - printk(KERN_ERR "%s: reset timeout\n", ofdev->node->full_name); + printk(KERN_ERR "%s: reset timeout\n", + ofdev->dev.of_node->full_name); /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */ out_be32(&p->mr, @@ -89,7 +90,7 @@ void *tah_dump_regs(struct of_device *ofdev, void *buf) static int __devinit tah_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct tah_instance *dev; struct resource regs; int rc; @@ -127,7 +128,7 @@ static int __devinit tah_probe(struct of_device *ofdev, tah_reset(ofdev); printk(KERN_INFO - "TAH %s initialized\n", ofdev->node->full_name); + "TAH %s initialized\n", ofdev->dev.of_node->full_name); wmb(); return 0; diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c index 1f038f808ab3..b4fa823ed201 100644 --- a/drivers/net/ibm_newemac/zmii.c +++ b/drivers/net/ibm_newemac/zmii.c @@ -121,13 +121,14 @@ int __devinit zmii_attach(struct of_device *ofdev, int input, int *mode) dev->mode = *mode; printk(KERN_NOTICE "%s: bridge in %s mode\n", - ofdev->node->full_name, zmii_mode_name(dev->mode)); + ofdev->dev.of_node->full_name, + zmii_mode_name(dev->mode)); } else { /* All inputs must use the same mode */ if (*mode != PHY_MODE_NA && *mode != dev->mode) { printk(KERN_ERR "%s: invalid mode %d specified for input %d\n", - ofdev->node->full_name, *mode, input); + ofdev->dev.of_node->full_name, *mode, input); mutex_unlock(&dev->lock); return -EINVAL; } @@ -233,7 +234,7 @@ void *zmii_dump_regs(struct of_device *ofdev, void *buf) static int __devinit zmii_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct zmii_instance *dev; struct resource regs; int rc; @@ -273,7 +274,7 @@ static int __devinit zmii_probe(struct of_device *ofdev, out_be32(&dev->base->fer, 0); printk(KERN_INFO - "ZMII %s initialized\n", ofdev->node->full_name); + "ZMII %s initialized\n", ofdev->dev.of_node->full_name); wmb(); dev_set_drvdata(&ofdev->dev, dev); diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index ba617e3cf1bb..9c7395c10e44 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -858,14 +858,14 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) mutex_init(&lp->indirect_mutex); /* map device registers */ - lp->regs = of_iomap(op->node, 0); + lp->regs = of_iomap(op->dev.of_node, 0); if (!lp->regs) { dev_err(&op->dev, "could not map temac regs.\n"); goto nodev; } /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ - np = of_parse_phandle(op->node, "llink-connected", 0); + np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); if (!np) { dev_err(&op->dev, "could not find DMA node\n"); goto nodev; @@ -890,7 +890,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) of_node_put(np); /* Finished with the DMA node; drop the reference */ /* Retrieve the MAC address */ - addr = of_get_property(op->node, "local-mac-address", &size); + addr = of_get_property(op->dev.of_node, "local-mac-address", &size); if ((!addr) || (size != 6)) { dev_err(&op->dev, "could not find MAC address\n"); rc = -ENODEV; @@ -898,11 +898,11 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) } temac_set_mac_address(ndev, (void *)addr); - rc = temac_mdio_setup(lp, op->node); + rc = temac_mdio_setup(lp, op->dev.of_node); if (rc) dev_warn(&op->dev, "error registering MDIO bus\n"); - lp->phy_node = of_parse_phandle(op->node, "phy-handle", 0); + lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); if (lp->phy_node) dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np); diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index b72e749afdf1..e21439f1e775 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -928,7 +928,7 @@ static const struct net_device_ops myri_ops = { static int __devinit myri_sbus_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; static unsigned version_printed; struct net_device *dev; struct myri_eth *mp; diff --git a/drivers/net/niu.c b/drivers/net/niu.c index d5cd16bfc907..9c1604c04450 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -9094,7 +9094,7 @@ static int __devinit niu_n2_irq_init(struct niu *np, u8 *ldg_num_map) const u32 *int_prop; int i; - int_prop = of_get_property(op->node, "interrupts", NULL); + int_prop = of_get_property(op->dev.of_node, "interrupts", NULL); if (!int_prop) return -ENODEV; @@ -9245,7 +9245,7 @@ static int __devinit niu_get_of_props(struct niu *np) int prop_len; if (np->parent->plat_type == PLAT_TYPE_NIU) - dp = np->op->node; + dp = np->op->dev.of_node; else dp = pci_device_to_OF_node(np->pdev); @@ -10056,10 +10056,10 @@ static int __devinit niu_of_probe(struct of_device *op, niu_driver_version(); - reg = of_get_property(op->node, "reg", NULL); + reg = of_get_property(op->dev.of_node, "reg", NULL); if (!reg) { dev_err(&op->dev, "%s: No 'reg' property, aborting\n", - op->node->full_name); + op->dev.of_node->full_name); return -ENODEV; } @@ -10072,7 +10072,7 @@ static int __devinit niu_of_probe(struct of_device *op, np = netdev_priv(dev); memset(&parent_id, 0, sizeof(parent_id)); - parent_id.of = of_get_parent(op->node); + parent_id.of = of_get_parent(op->dev.of_node); np->parent = niu_get_parent(np, &parent_id, PLAT_TYPE_NIU); diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 35897134a5dd..641973ca2417 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -199,12 +199,12 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, if (!pdata) return -ENOMEM; - ret = of_get_gpio(ofdev->node, 0); + ret = of_get_gpio(ofdev->dev.of_node, 0); if (ret < 0) goto out_free; pdata->mdc = ret; - ret = of_get_gpio(ofdev->node, 1); + ret = of_get_gpio(ofdev->dev.of_node, 1); if (ret < 0) goto out_free; pdata->mdio = ret; @@ -213,7 +213,7 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, if (!new_bus) goto out_free; - ret = of_mdiobus_register(new_bus, ofdev->node); + ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); if (ret) mdio_gpio_bus_deinit(&ofdev->dev); diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index ed7865a0b5b2..bd286ec5abd9 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1133,8 +1133,8 @@ static int __devinit bigmac_ether_init(struct of_device *op, goto fail_and_cleanup; /* Get supported SBUS burst sizes. */ - bsizes = of_getintprop_default(qec_op->node, "burst-sizes", 0xff); - bsizes_more = of_getintprop_default(qec_op->node, "burst-sizes", 0xff); + bsizes = of_getintprop_default(qec_op->dev.of_node, "burst-sizes", 0xff); + bsizes_more = of_getintprop_default(qec_op->dev.of_node, "burst-sizes", 0xff); bsizes &= 0xff; if (bsizes_more != 0xff) @@ -1186,7 +1186,7 @@ static int __devinit bigmac_ether_init(struct of_device *op, } /* Get the board revision of this BigMAC. */ - bp->board_rev = of_getintprop_default(bp->bigmac_op->node, + bp->board_rev = of_getintprop_default(bp->bigmac_op->dev.of_node, "board-version", 1); /* Init auto-negotiation timer state. */ diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index b17dbb11bd67..c6463f71c916 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2483,7 +2483,7 @@ static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info else { const struct linux_prom_registers *regs; struct of_device *op = hp->happy_dev; - regs = of_get_property(op->node, "regs", NULL); + regs = of_get_property(op->dev.of_node, "regs", NULL); if (regs) sprintf(info->bus_info, "SBUS:%d", regs->which_io); @@ -2643,14 +2643,14 @@ static const struct net_device_ops hme_netdev_ops = { #ifdef CONFIG_SBUS static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe) { - struct device_node *dp = op->node, *sbus_dp; + struct device_node *dp = op->dev.of_node, *sbus_dp; struct quattro *qp = NULL; struct happy_meal *hp; struct net_device *dev; int i, qfe_slot = -1; int err = -ENODEV; - sbus_dp = to_of_device(op->dev.parent)->node; + sbus_dp = to_of_device(op->dev.parent)->dev.of_node; /* We can match PCI devices too, do not accept those here. */ if (strcmp(sbus_dp->name, "sbus")) @@ -3241,7 +3241,7 @@ static void happy_meal_pci_exit(void) #ifdef CONFIG_SBUS static int __devinit hme_sbus_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); int is_qfe = (match->data != NULL); diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 0c21653ff9f9..28afc86e0694 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1324,7 +1324,7 @@ static int __devinit sparc_lance_probe_one(struct of_device *op, struct of_device *ledma, struct of_device *lebuffer) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; static unsigned version_printed; struct lance_private *lp; struct net_device *dev; @@ -1411,7 +1411,7 @@ static int __devinit sparc_lance_probe_one(struct of_device *op, lp->burst_sizes = 0; if (lp->ledma) { - struct device_node *ledma_dp = ledma->node; + struct device_node *ledma_dp = ledma->dev.of_node; struct device_node *sbus_dp; unsigned int sbmask; const char *prop; @@ -1507,7 +1507,7 @@ fail: static int __devinit sunlance_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct of_device *parent = to_of_device(op->dev.parent); - struct device_node *parent_dp = parent->node; + struct device_node *parent_dp = parent->dev.of_node; int err; if (!strcmp(parent_dp->name, "ledma")) { diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index be637dce944c..9864f4fa69d5 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -696,7 +696,7 @@ static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) strcpy(info->version, "3.0"); op = qep->op; - regs = of_get_property(op->node, "reg", NULL); + regs = of_get_property(op->dev.of_node, "reg", NULL); if (regs) sprintf(info->bus_info, "SBUS:%d", regs->which_io); @@ -800,7 +800,7 @@ static struct sunqec * __devinit get_qec(struct of_device *child) if (qec_global_reset(qecp->gregs)) goto fail; - qecp->qec_bursts = qec_get_burst(op->node); + qecp->qec_bursts = qec_get_burst(op->dev.of_node); qec_init_once(qecp, op); @@ -858,7 +858,7 @@ static int __devinit qec_ether_init(struct of_device *op) res = -ENODEV; - i = of_getintprop_default(op->node, "channel#", -1); + i = of_getintprop_default(op->dev.of_node, "channel#", -1); if (i == -1) goto fail; qe->channel = i; diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 1b0aef37e495..88ebfc976735 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3721,7 +3721,7 @@ static const struct net_device_ops ucc_geth_netdev_ops = { static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match) { struct device *device = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct net_device *dev = NULL; struct ucc_geth_private *ugeth = NULL; struct ucc_geth_info *ug_info; diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 1e783ccc306e..3dd2416db540 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -1090,7 +1090,7 @@ static void xemaclite_remove_ndev(struct net_device *ndev) */ static bool get_bool(struct of_device *ofdev, const char *s) { - u32 *p = (u32 *)of_get_property(ofdev->node, s, NULL); + u32 *p = (u32 *)of_get_property(ofdev->dev.of_node, s, NULL); if (p) { return (bool)*p; @@ -1132,14 +1132,14 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, dev_info(dev, "Device Tree Probing\n"); /* Get iospace for the device */ - rc = of_address_to_resource(ofdev->node, 0, &r_mem); + rc = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); if (rc) { dev_err(dev, "invalid address\n"); return rc; } /* Get IRQ for the device */ - rc = of_irq_to_resource(ofdev->node, 0, &r_irq); + rc = of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq); if (rc == NO_IRQ) { dev_err(dev, "no IRQ found\n"); return rc; @@ -1184,7 +1184,7 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, lp->next_rx_buf_to_use = 0x0; lp->tx_ping_pong = get_bool(ofdev, "xlnx,tx-ping-pong"); lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong"); - mac_address = of_get_mac_address(ofdev->node); + mac_address = of_get_mac_address(ofdev->dev.of_node); if (mac_address) /* Set the MAC address. */ @@ -1199,7 +1199,7 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, /* Set the MAC address in the EmacLite device */ xemaclite_update_address(lp, ndev->dev_addr); - lp->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0); + lp->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); rc = xemaclite_mdio_setup(lp, &ofdev->dev); if (rc) dev_warn(&ofdev->dev, "error registering MDIO bus\n"); diff --git a/drivers/of/device.c b/drivers/of/device.c index 224ae6bc67b6..24068bbbce1a 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -21,9 +21,9 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches, const struct of_device *dev) { - if (!dev->node) + if (!dev->dev.of_node) return NULL; - return of_match_node(matches, dev->node); + return of_match_node(matches, dev->dev.of_node); } EXPORT_SYMBOL(of_match_device); @@ -54,7 +54,7 @@ static ssize_t devspec_show(struct device *dev, struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s\n", ofdev->node->full_name); + return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); } static ssize_t name_show(struct device *dev, @@ -63,7 +63,7 @@ static ssize_t name_show(struct device *dev, struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s\n", ofdev->node->name); + return sprintf(buf, "%s\n", ofdev->dev.of_node->name); } static ssize_t modalias_show(struct device *dev, @@ -97,14 +97,14 @@ void of_release_dev(struct device *dev) struct of_device *ofdev; ofdev = to_of_device(dev); - of_node_put(ofdev->node); + of_node_put(ofdev->dev.of_node); kfree(ofdev); } EXPORT_SYMBOL(of_release_dev); int of_device_register(struct of_device *ofdev) { - BUG_ON(ofdev->node == NULL); + BUG_ON(ofdev->dev.of_node == NULL); device_initialize(&ofdev->dev); @@ -112,7 +112,7 @@ int of_device_register(struct of_device *ofdev) * the parent. If there is no parent defined, set the node * explicitly */ if (!ofdev->dev.parent) - set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->node)); + set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node)); return device_add(&ofdev->dev); } @@ -132,11 +132,11 @@ ssize_t of_device_get_modalias(struct of_device *ofdev, ssize_t tsize, csize, repend; /* Name & Type */ - csize = snprintf(str, len, "of:N%sT%s", - ofdev->node->name, ofdev->node->type); + csize = snprintf(str, len, "of:N%sT%s", ofdev->dev.of_node->name, + ofdev->dev.of_node->type); /* Get compatible property if any */ - compat = of_get_property(ofdev->node, "compatible", &cplen); + compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); if (!compat) return csize; diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index e690a2aa6fef..604ba966e1c9 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -69,7 +69,7 @@ EXPORT_SYMBOL(of_register_i2c_devices); static int of_dev_node_match(struct device *dev, void *data) { - return dev_archdata_get_node(&dev->archdata) == data; + return dev->of_node == data; } /* must call put_device() when done with returned i2c_client device */ diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 12090f57dc87..01d794abe105 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -101,7 +101,7 @@ EXPORT_SYMBOL(of_mdiobus_register); /* Helper function for of_phy_find_device */ static int of_phy_match(struct device *dev, void *phy_np) { - return dev_archdata_get_node(&dev->archdata) == phy_np; + return dev->of_node == phy_np; } /** @@ -167,7 +167,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, if (!dev->dev.parent) return NULL; - net_np = dev_archdata_get_node(&dev->dev.parent->archdata); + net_np = dev->dev.parent->of_node; if (!net_np) return NULL; diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 2e59fe947d28..a22d32d71bf2 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -185,7 +185,7 @@ static int __devinit electra_cf_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *device = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct electra_cf_socket *cf; struct resource mem, io; int status; diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index b4951eb0358e..103fdf6b0b89 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c @@ -565,9 +565,9 @@ int bbc_envctrl_init(struct bbc_i2c_bus *bp) int devidx = 0; while ((op = bbc_i2c_getdev(bp, devidx++)) != NULL) { - if (!strcmp(op->node->name, "temperature")) + if (!strcmp(op->dev.of_node->name, "temperature")) attach_one_temp(bp, op, temp_index++); - if (!strcmp(op->node->name, "fan-control")) + if (!strcmp(op->dev.of_node->name, "fan-control")) attach_one_fan(bp, op, fan_index++); } if (temp_index != 0 && fan_index != 0) { diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 7e30e5f6e032..1543ac32b79b 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -97,7 +97,7 @@ struct bbc_i2c_client *bbc_i2c_attach(struct bbc_i2c_bus *bp, struct of_device * client->bp = bp; client->op = op; - reg = of_get_property(op->node, "reg", NULL); + reg = of_get_property(op->dev.of_node, "reg", NULL); if (!reg) { kfree(client); return NULL; @@ -327,7 +327,7 @@ static struct bbc_i2c_bus * __init attach_one_i2c(struct of_device *op, int inde spin_lock_init(&bp->lock); entry = 0; - for (dp = op->node->child; + for (dp = op->dev.of_node->child; dp && entry < 8; dp = dp->sibling, entry++) { struct of_device *child_op; diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 3e59189f4137..7fc7f34f3466 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -216,7 +216,7 @@ static int __devinit d7s_probe(struct of_device *op, writeb(regs, p->regs); printk(KERN_INFO PFX "7-Segment Display%s at [%s:0x%llx] %s\n", - op->node->full_name, + op->dev.of_node->full_name, (regs & D7S_FLIP) ? " (FLIPPED)" : "", op->resource[0].start, sol_compat ? "in sol_compat mode" : ""); diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index c6e2eff19409..a5fe20faf4f7 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1043,7 +1043,7 @@ static int __devinit envctrl_probe(struct of_device *op, return -ENOMEM; index = 0; - dp = op->node->child; + dp = op->dev.of_node->child; while (dp) { if (!strcmp(dp->name, "gpio")) { i2c_childlist[index].i2ctype = I2C_GPIO; diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 19f255b97c86..202ff8f75afb 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -162,7 +162,7 @@ static struct miscdevice flash_dev = { FLASH_MINOR, "flash", &flash_fops }; static int __devinit flash_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct device_node *parent; parent = dp->parent; @@ -184,7 +184,7 @@ static int __devinit flash_probe(struct of_device *op, flash.busy = 0; printk(KERN_INFO "%s: OBP Flash, RD %lx[%lx] WR %lx[%lx]\n", - op->node->full_name, + op->dev.of_node->full_name, flash.read_base, flash.read_size, flash.write_base, flash.write_size); diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 2c56fd56ec63..acc6738aa61f 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -382,7 +382,7 @@ static int __devinit uctrl_probe(struct of_device *op, sbus_writel(UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK, &p->regs->uctrl_intr); printk(KERN_INFO "%s: uctrl regs[0x%p] (irq %d)\n", - op->node->full_name, p->regs, p->irq); + op->dev.of_node->full_name, p->regs, p->irq); uctrl_get_event_status(p); uctrl_get_external_status(p); diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index c2eea711a5ce..60cd4ec51eae 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -1157,7 +1157,7 @@ static void ibmvfc_gather_partition_info(struct ibmvfc_host *vhost) static void ibmvfc_set_login_info(struct ibmvfc_host *vhost) { struct ibmvfc_npiv_login *login_info = &vhost->login_info; - struct device_node *of_node = vhost->dev->archdata.of_node; + struct device_node *of_node = vhost->dev->of_node; const char *location; memset(login_info, 0, sizeof(*login_info)); diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index ff5ec5ac1fb5..cc38fefc2612 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -957,7 +957,7 @@ static void send_mad_capabilities(struct ibmvscsi_host_data *hostdata) struct viosrp_capabilities *req; struct srp_event_struct *evt_struct; unsigned long flags; - struct device_node *of_node = hostdata->dev->archdata.of_node; + struct device_node *of_node = hostdata->dev->of_node; const char *location; evt_struct = get_event_struct(&hostdata->pool); diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index aa406497eebc..35433d23b7ce 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -755,7 +755,7 @@ static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti) struct of_device *op = qpti->op; struct device_node *dp; - dp = op->node; + dp = op->dev.of_node; qpti->scsi_id = of_getintprop_default(dp, "initiator-id", -1); if (qpti->scsi_id == -1) @@ -776,8 +776,8 @@ static void qpti_get_bursts(struct qlogicpti *qpti) struct of_device *op = qpti->op; u8 bursts, bmask; - bursts = of_getintprop_default(op->node, "burst-sizes", 0xff); - bmask = of_getintprop_default(op->node->parent, "burst-sizes", 0xff); + bursts = of_getintprop_default(op->dev.of_node, "burst-sizes", 0xff); + bmask = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0xff); if (bmask != 0xff) bursts &= bmask; if (bursts == 0xff || @@ -1293,7 +1293,7 @@ static struct scsi_host_template qpti_template = { static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct scsi_host_template *tpnt = match->data; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct Scsi_Host *host; struct qlogicpti *qpti; static int nqptis; @@ -1315,7 +1315,7 @@ static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_devic qpti->qhost = host; qpti->op = op; qpti->qpti_id = nqptis; - strcpy(qpti->prom_name, op->node->name); + strcpy(qpti->prom_name, op->dev.of_node->name); qpti->is_pti = strcmp(qpti->prom_name, "QLGC,isp"); if (qpti_map_regs(qpti) < 0) diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index fc23d273fb1a..151df73df475 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -125,7 +125,7 @@ static void __devinit esp_get_scsi_id(struct esp *esp, struct of_device *espdma) struct of_device *op = esp->dev; struct device_node *dp; - dp = op->node; + dp = op->dev.of_node; esp->scsi_id = of_getintprop_default(dp, "initiator-id", 0xff); if (esp->scsi_id != 0xff) goto done; @@ -134,7 +134,7 @@ static void __devinit esp_get_scsi_id(struct esp *esp, struct of_device *espdma) if (esp->scsi_id != 0xff) goto done; - esp->scsi_id = of_getintprop_default(espdma->node, + esp->scsi_id = of_getintprop_default(espdma->dev.of_node, "scsi-initiator-id", 7); done: @@ -147,7 +147,7 @@ static void __devinit esp_get_differential(struct esp *esp) struct of_device *op = esp->dev; struct device_node *dp; - dp = op->node; + dp = op->dev.of_node; if (of_find_property(dp, "differential", NULL)) esp->flags |= ESP_FLAG_DIFFERENTIAL; else @@ -160,7 +160,7 @@ static void __devinit esp_get_clock_params(struct esp *esp) struct device_node *bus_dp, *dp; int fmhz; - dp = op->node; + dp = op->dev.of_node; bus_dp = dp->parent; fmhz = of_getintprop_default(dp, "clock-frequency", 0); @@ -172,12 +172,12 @@ static void __devinit esp_get_clock_params(struct esp *esp) static void __devinit esp_get_bursts(struct esp *esp, struct of_device *dma_of) { - struct device_node *dma_dp = dma_of->node; + struct device_node *dma_dp = dma_of->dev.of_node; struct of_device *op = esp->dev; struct device_node *dp; u8 bursts, val; - dp = op->node; + dp = op->dev.of_node; bursts = of_getintprop_default(dp, "burst-sizes", 0xff); val = of_getintprop_default(dma_dp, "burst-sizes", 0xff); if (val != 0xff) @@ -565,7 +565,7 @@ fail: static int __devinit esp_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dma_node = NULL; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct of_device *dma_of = NULL; int hme = 0; @@ -574,7 +574,7 @@ static int __devinit esp_sbus_probe(struct of_device *op, const struct of_device !strcmp(dp->parent->name, "dma"))) dma_node = dp->parent; else if (!strcmp(dp->name, "SUNW,fas")) { - dma_node = op->node; + dma_node = op->dev.of_node; hme = 1; } if (dma_node) diff --git a/drivers/serial/apbuart.c b/drivers/serial/apbuart.c index fe91319b5f65..52015d7031bb 100644 --- a/drivers/serial/apbuart.c +++ b/drivers/serial/apbuart.c @@ -559,7 +559,7 @@ static int __devinit apbuart_probe(struct of_device *op, i = 0; for (i = 0; i < grlib_apbuart_port_nr; i++) { - if (op->node == grlib_apbuart_nodes[i]) + if (op->dev.of_node == grlib_apbuart_nodes[i]) break; } diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 300cea768d74..7866cdf8a754 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1342,7 +1342,7 @@ static int __devinit cpm_uart_probe(struct of_device *ofdev, /* initialize the device pointer for the port */ pinfo->port.dev = &ofdev->dev; - ret = cpm_uart_init_port(ofdev->node, pinfo); + ret = cpm_uart_init_port(ofdev->dev.of_node, pinfo); if (ret) return ret; diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 3119fddaedb5..cb079387c5ae 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -1328,14 +1328,14 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) /* Check validity & presence */ for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++) - if (mpc52xx_uart_nodes[idx] == op->node) + if (mpc52xx_uart_nodes[idx] == op->dev.of_node) break; if (idx >= MPC52xx_PSC_MAXNUM) return -EINVAL; pr_debug("Found %s assigned to ttyPSC%x\n", mpc52xx_uart_nodes[idx]->full_name, idx); - uartclk = psc_ops->getuartclk(op->node); + uartclk = psc_ops->getuartclk(op->dev.of_node); if (uartclk == 0) { dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); return -EINVAL; @@ -1355,7 +1355,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) port->dev = &op->dev; /* Search for IRQ and mapbase */ - ret = of_address_to_resource(op->node, 0, &res); + ret = of_address_to_resource(op->dev.of_node, 0, &res); if (ret) return ret; @@ -1365,7 +1365,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) return -EINVAL; } - psc_ops->get_irq(port, op->node); + psc_ops->get_irq(port, op->dev.of_node); if (port->irq == NO_IRQ) { dev_dbg(&op->dev, "Could not get irq\n"); return -EINVAL; diff --git a/drivers/serial/nwpserial.c b/drivers/serial/nwpserial.c index e1ab8ec0a4a6..3c02fa96f282 100644 --- a/drivers/serial/nwpserial.c +++ b/drivers/serial/nwpserial.c @@ -344,7 +344,7 @@ int nwpserial_register_port(struct uart_port *port) mutex_lock(&nwpserial_mutex); - dn = to_of_device(port->dev)->node; + dn = to_of_device(port->dev)->dev.of_node; if (dn == NULL) goto out; diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 4abfebdb0fcc..29539805e593 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -31,7 +31,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, int type, struct uart_port *port) { struct resource resource; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; const unsigned int *clk, *spd; const u32 *prop; int ret, prop_size; @@ -88,7 +88,7 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev, int port_type; int ret; - if (of_find_property(ofdev->node, "used-by-rtas", NULL)) + if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) return -EBUSY; info = kmalloc(sizeof(*info), GFP_KERNEL); diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 4eaa043ca2a8..1e43bf59c44d 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -1609,7 +1609,7 @@ static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) /* Iterate the pmz_ports array to find a matching entry */ for (i = 0; i < MAX_ZS_PORTS; i++) - if (pmz_ports[i].node == mdev->ofdev.node) { + if (pmz_ports[i].node == mdev->ofdev.dev.of_node) { struct uart_pmac_port *uap = &pmz_ports[i]; uap->dev = mdev; diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index d14cca7fb88d..d1eedf13d85c 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c @@ -565,7 +565,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m if (err) goto out_free_con_read_page; - sunserial_console_match(&sunhv_console, op->node, + sunserial_console_match(&sunhv_console, op->dev.of_node, &sunhv_reg, port->line, false); err = uart_add_one_port(&sunhv_reg, port); diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index d2e0321049e2..9176c41b74ad 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options) printk("Console: ttyS%d (SAB82532)\n", (sunsab_reg.minor - 64) + con->index); - sunserial_console_termios(con, to_of_device(up->port.dev)->node); + sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_node); switch (con->cflag & CBAUD) { case B150: baud = 150; break; @@ -1026,11 +1026,11 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * if (err) goto out1; - sunserial_console_match(SUNSAB_CONSOLE(), op->node, + sunserial_console_match(SUNSAB_CONSOLE(), op->dev.of_node, &sunsab_reg, up[0].port.line, false); - sunserial_console_match(SUNSAB_CONSOLE(), op->node, + sunserial_console_match(SUNSAB_CONSOLE(), op->dev.of_node, &sunsab_reg, up[1].port.line, false); diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 01f7731e59b8..a647b2448071 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1200,7 +1200,7 @@ static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up) return -ENODEV; printk("%s: %s port at %llx, irq %u\n", - to_of_device(up->port.dev)->node->full_name, + to_of_device(up->port.dev)->dev.of_node->full_name, (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", (unsigned long long) up->port.mapbase, up->port.irq); @@ -1352,7 +1352,7 @@ static int __init sunsu_console_setup(struct console *co, char *options) spin_lock_init(&port->lock); /* Get firmware console settings. */ - sunserial_console_termios(co, to_of_device(port->dev)->node); + sunserial_console_termios(co, to_of_device(port->dev)->dev.of_node); memset(&termios, 0, sizeof(struct ktermios)); termios.c_cflag = co->cflag; @@ -1409,7 +1409,7 @@ static enum su_type __devinit su_get_type(struct device_node *dp) static int __devinit su_probe(struct of_device *op, const struct of_device_id *match) { static int inst; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct uart_sunsu_port *up; struct resource *rp; enum su_type type; diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 2c7a66af4f52..20f9be8cd949 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) (sunzilog_reg.minor - 64) + con->index, con->index); /* Get firmware console settings. */ - sunserial_console_termios(con, to_of_device(up->port.dev)->node); + sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_node); /* Firmware console speed is limited to 150-->38400 baud so * this hackish cflag thing is OK. @@ -1358,7 +1358,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m int keyboard_mouse = 0; int err; - if (of_find_property(op->node, "keyboard", NULL)) + if (of_find_property(op->dev.of_node, "keyboard", NULL)) keyboard_mouse = 1; /* uarts must come before keyboards/mice */ @@ -1415,7 +1415,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m sunzilog_init_hw(&up[1]); if (!keyboard_mouse) { - if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, + if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node, &sunzilog_reg, up[0].port.line, false)) up->flags |= SUNZILOG_FLAG_IS_CONS; @@ -1425,7 +1425,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m rp, sizeof(struct zilog_layout)); return err; } - if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, + if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node, &sunzilog_reg, up[1].port.line, false)) up->flags |= SUNZILOG_FLAG_IS_CONS; diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index f0a6c61b17f7..8fc2583d06ff 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -591,15 +591,15 @@ ulite_of_probe(struct of_device *op, const struct of_device_id *match) dev_dbg(&op->dev, "%s(%p, %p)\n", __func__, op, match); - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); return rc; } - irq = irq_of_parse_and_map(op->node, 0); + irq = irq_of_parse_and_map(op->dev.of_node, 0); - id = of_get_property(op->node, "port-number", NULL); + id = of_get_property(op->dev.of_node, "port-number", NULL); return ulite_assign(&op->dev, id ? *id : -1, res.start+3, irq); } diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 074904912f64..529890f044e2 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c @@ -1197,7 +1197,7 @@ static void uart_firmware_cont(const struct firmware *fw, void *context) static int ucc_uart_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; const unsigned int *iprop; /* Integer OF properties */ const char *sprop; /* String OF properties */ struct uart_qe_port *qe_port = NULL; diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 77d4cc88edea..7fcf28405860 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -472,18 +472,18 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, s16 id = -1; int rc; - regaddr_p = of_get_address(op->node, 0, &size64, NULL); + regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL); if (!regaddr_p) { dev_err(&op->dev, "Invalid PSC address\n"); return -EINVAL; } - regaddr64 = of_translate_address(op->node, regaddr_p); + regaddr64 = of_translate_address(op->dev.of_node, regaddr_p); /* get PSC id (1..6, used by port_config) */ if (op->dev.platform_data == NULL) { const u32 *psc_nump; - psc_nump = of_get_property(op->node, "cell-index", NULL); + psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL); if (!psc_nump || *psc_nump > 5) { dev_err(&op->dev, "Invalid cell-index property\n"); return -EINVAL; @@ -492,9 +492,10 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, } rc = mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64, - irq_of_parse_and_map(op->node, 0), id); + irq_of_parse_and_map(op->dev.of_node, 0), id); if (rc == 0) - of_register_spi_devices(dev_get_drvdata(&op->dev), op->node); + of_register_spi_devices(dev_get_drvdata(&op->dev), + op->dev.of_node); return rc; } diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index cd68f1ce5cc3..6573233bf7c9 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -403,7 +403,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, /* MMIO registers */ dev_dbg(&op->dev, "probing mpc5200 SPI device\n"); - regs = of_iomap(op->node, 0); + regs = of_iomap(op->dev.of_node, 0); if (!regs) return -ENODEV; @@ -445,11 +445,11 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, ms = spi_master_get_devdata(master); ms->master = master; ms->regs = regs; - ms->irq0 = irq_of_parse_and_map(op->node, 0); - ms->irq1 = irq_of_parse_and_map(op->node, 1); + ms->irq0 = irq_of_parse_and_map(op->dev.of_node, 0); + ms->irq1 = irq_of_parse_and_map(op->dev.of_node, 1); ms->state = mpc52xx_spi_fsmstate_idle; - ms->ipb_freq = mpc5xxx_get_bus_frequency(op->node); - ms->gpio_cs_count = of_gpio_count(op->node); + ms->ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); + ms->gpio_cs_count = of_gpio_count(op->dev.of_node); if (ms->gpio_cs_count > 0) { master->num_chipselect = ms->gpio_cs_count; ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int), @@ -460,7 +460,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, } for (i = 0; i < ms->gpio_cs_count; i++) { - gpio_cs = of_get_gpio(op->node, i); + gpio_cs = of_get_gpio(op->dev.of_node, i); if (gpio_cs < 0) { dev_err(&op->dev, "could not parse the gpio field " @@ -512,7 +512,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, if (rc) goto err_register; - of_register_spi_devices(master, op->node); + of_register_spi_devices(master, op->dev.of_node); dev_info(&ms->master->dev, "registered MPC5200 SPI bus\n"); return rc; diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 14d052316502..7572f98a419e 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -797,7 +797,7 @@ static void mpc8xxx_spi_free_dummy_rx(void) static unsigned long mpc8xxx_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) { struct device *dev = mspi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; const u32 *iprop; int size; unsigned long spi_base_ofs; @@ -851,7 +851,7 @@ static unsigned long mpc8xxx_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) static int mpc8xxx_spi_cpm_init(struct mpc8xxx_spi *mspi) { struct device *dev = mspi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; const u32 *iprop; int size; unsigned long pram_ofs; @@ -1123,7 +1123,7 @@ static void mpc8xxx_spi_cs_control(struct spi_device *spi, bool on) static int of_mpc8xxx_spi_get_chipselects(struct device *dev) { - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; struct fsl_spi_platform_data *pdata = dev->platform_data; struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); unsigned int ngpios; @@ -1224,7 +1224,7 @@ static int __devinit of_mpc8xxx_spi_probe(struct of_device *ofdev, const struct of_device_id *ofid) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mpc8xxx_spi_probe_info *pinfo; struct fsl_spi_platform_data *pdata; struct spi_master *master; diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 8df33b8a634c..ad0662354a5e 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -108,7 +108,7 @@ ppc44x_enable_bmt(struct device_node *dn) static int __devinit ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dn = op->node; + struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; struct ehci_hcd *ehci = NULL; struct resource res; diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 15379c636143..6135732d8057 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -565,7 +565,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev, const struct of_device_id *ofid) { struct device *dev = &ofdev->dev; - struct device_node *node = ofdev->node; + struct device_node *node = dev->of_node; struct usb_hcd *hcd; struct fhci_hcd *fhci; struct resource usb_regs; @@ -670,7 +670,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev, } for (j = 0; j < NUM_PINS; j++) { - fhci->pins[j] = qe_pin_request(ofdev->node, j); + fhci->pins[j] = qe_pin_request(node, j); if (IS_ERR(fhci->pins[j])) { ret = PTR_ERR(fhci->pins[j]); dev_err(dev, "can't get pin %d: %d\n", j, ret); diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 4293cfd28d61..36360e24a9b9 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -31,7 +31,7 @@ static int of_isp1760_probe(struct of_device *dev, const struct of_device_id *match) { struct usb_hcd *hcd; - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; struct resource *res; struct resource memory; struct of_irq oirq; diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 103263c230cf..003aea21c35e 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -83,7 +83,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = { static int __devinit ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dn = op->node; + struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; struct ohci_hcd *ohci; struct resource res; diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 6d0fcb43696e..7f59b0fe5dc2 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -740,7 +740,7 @@ static void cg6_unmap_regs(struct of_device *op, struct fb_info *info, static int __devinit cg6_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct cg6_par *par; int linebytes, err; diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index a42fabab69df..ddd46f71e250 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -896,7 +896,7 @@ static void ffb_init_fix(struct fb_info *info) static int __devinit ffb_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct ffb_fbc __iomem *fbc; struct ffb_dac __iomem *dac; struct fb_info *info; diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 994358a4f302..930a2522a631 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -1421,7 +1421,7 @@ static ssize_t show_monitor(struct device *device, static int __devinit fsl_diu_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mfb_info *mfbi; phys_addr_t dummy_ad_addr; int ret, i, error = 0; diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 8a204e7a5b5b..69d78d50f0f6 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -536,7 +536,7 @@ static int __init platinumfb_setup(char *options) static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match) { - struct device_node *dp = odev->node; + struct device_node *dp = odev->dev.of_node; struct fb_info *info; struct fb_info_platinum *pinfo; volatile __u8 *fbuffer; diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c index 23e69e834a18..ad92a200fafa 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/sunxvr1000.c @@ -114,7 +114,7 @@ static int __devinit gfb_set_fbinfo(struct gfb_info *gp) static int __devinit gfb_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct gfb_info *gp; int err; diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 3fcb83f03881..6fcec553662c 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -423,7 +423,7 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) * To check whether the core is connected directly to DCR or PLB * interface and initialize the tft_access accordingly. */ - p = (u32 *)of_get_property(op->node, "xlnx,dcr-splb-slave-if", NULL); + p = (u32 *)of_get_property(op->dev.of_node, "xlnx,dcr-splb-slave-if", NULL); tft_access = p ? *p : 0; /* @@ -432,41 +432,41 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) */ if (tft_access) { drvdata->flags |= PLB_ACCESS_FLAG; - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); goto err; } } else { res.start = 0; - start = dcr_resource_start(op->node, 0); - drvdata->dcr_len = dcr_resource_len(op->node, 0); - drvdata->dcr_host = dcr_map(op->node, start, drvdata->dcr_len); + start = dcr_resource_start(op->dev.of_node, 0); + drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0); + drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len); if (!DCR_MAP_OK(drvdata->dcr_host)) { dev_err(&op->dev, "invalid DCR address\n"); goto err; } } - prop = of_get_property(op->node, "phys-size", &size); + prop = of_get_property(op->dev.of_node, "phys-size", &size); if ((prop) && (size >= sizeof(u32)*2)) { pdata.screen_width_mm = prop[0]; pdata.screen_height_mm = prop[1]; } - prop = of_get_property(op->node, "resolution", &size); + prop = of_get_property(op->dev.of_node, "resolution", &size); if ((prop) && (size >= sizeof(u32)*2)) { pdata.xres = prop[0]; pdata.yres = prop[1]; } - prop = of_get_property(op->node, "virtual-resolution", &size); + prop = of_get_property(op->dev.of_node, "virtual-resolution", &size); if ((prop) && (size >= sizeof(u32)*2)) { pdata.xvirt = prop[0]; pdata.yvirt = prop[1]; } - if (of_find_property(op->node, "rotate-display", NULL)) + if (of_find_property(op->dev.of_node, "rotate-display", NULL)) pdata.rotate_screen = 1; dev_set_drvdata(&op->dev, drvdata); diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index ba2efce4b40e..2fcc3cf7ef62 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -577,7 +577,7 @@ static int __devinit cpwd_probe(struct of_device *op, * interrupt_mask register cannot be written, so no timer * interrupts can be masked within the PLD. */ - str_prop = of_get_property(op->node, "model", NULL); + str_prop = of_get_property(op->dev.of_node, "model", NULL); p->broken = (str_prop && !strcmp(str_prop, WD_BADMODEL)); if (!p->enabled) diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c index 1cd9b301df03..3fd1a7e24928 100644 --- a/sound/aoa/fabrics/layout.c +++ b/sound/aoa/fabrics/layout.c @@ -992,7 +992,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) return -ENODEV; /* by breaking out we keep a reference */ - while ((sound = of_get_next_child(sdev->ofdev.node, sound))) { + while ((sound = of_get_next_child(sdev->ofdev.dev.of_node, sound))) { if (sound->type && strcasecmp(sound->type, "soundchip") == 0) break; } diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c index fa8ab2815a98..99ca7120e269 100644 --- a/sound/aoa/soundbus/core.c +++ b/sound/aoa/soundbus/core.c @@ -74,11 +74,11 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env) of = &soundbus_dev->ofdev; /* stuff we want to pass to /sbin/hotplug */ - retval = add_uevent_var(env, "OF_NAME=%s", of->node->name); + retval = add_uevent_var(env, "OF_NAME=%s", of->dev.of_node->name); if (retval) return retval; - retval = add_uevent_var(env, "OF_TYPE=%s", of->node->type); + retval = add_uevent_var(env, "OF_TYPE=%s", of->dev.of_node->type); if (retval) return retval; @@ -86,7 +86,7 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env) * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(of->node, "compatible", &cplen); + compat = of_get_property(of->dev.of_node, "compatible", &cplen); while (compat && cplen > 0) { int tmp = env->buflen; retval = add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); @@ -169,7 +169,7 @@ int soundbus_add_one(struct soundbus_dev *dev) /* sanity checks */ if (!dev->attach_codec || - !dev->ofdev.node || + !dev->ofdev.dev.of_node || dev->pcmname || dev->pcmid != -1) { printk(KERN_ERR "soundbus: adding device failed sanity check!\n"); diff --git a/sound/aoa/soundbus/i2sbus/control.c b/sound/aoa/soundbus/i2sbus/control.c index 47f854c2001f..4dc9b49c02cf 100644 --- a/sound/aoa/soundbus/i2sbus/control.c +++ b/sound/aoa/soundbus/i2sbus/control.c @@ -42,7 +42,7 @@ int i2sbus_control_add_dev(struct i2sbus_control *c, { struct device_node *np; - np = i2sdev->sound.ofdev.node; + np = i2sdev->sound.ofdev.dev.of_node; i2sdev->enable = pmf_find_function(np, "enable"); i2sdev->cell_enable = pmf_find_function(np, "cell-enable"); i2sdev->clock_enable = pmf_find_function(np, "clock-enable"); diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 9d6f3b176ed1..7672b4d145ae 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c @@ -221,8 +221,8 @@ static int i2sbus_add_dev(struct macio_dev *macio, mutex_init(&dev->lock); spin_lock_init(&dev->low_lock); - dev->sound.ofdev.node = np; dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask; + dev->sound.ofdev.dev.of_node = np; dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask; dev->sound.ofdev.dev.parent = &macio->ofdev.dev; dev->sound.ofdev.dev.release = i2sbus_release_dev; @@ -346,7 +346,7 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match) return -ENODEV; } - while ((np = of_get_next_child(dev->ofdev.node, np))) { + while ((np = of_get_next_child(dev->ofdev.dev.of_node, np))) { if (of_device_is_compatible(np, "i2sbus") || of_device_is_compatible(np, "i2s-modem")) { got += i2sbus_add_dev(dev, control, np); diff --git a/sound/aoa/soundbus/sysfs.c b/sound/aoa/soundbus/sysfs.c index f580942b5c09..6496e754f00a 100644 --- a/sound/aoa/soundbus/sysfs.c +++ b/sound/aoa/soundbus/sysfs.c @@ -9,7 +9,7 @@ field##_show (struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ struct soundbus_dev *mdev = to_soundbus_device (dev); \ - return sprintf (buf, format_string, mdev->ofdev.node->field); \ + return sprintf (buf, format_string, mdev->ofdev.dev.of_node->field); \ } static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, @@ -25,7 +25,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, length = strlen(buf); } else { length = sprintf(buf, "of:N%sT%s\n", - of->node->name, of->node->type); + of->dev.of_node->name, of->dev.of_node->type); } return length; diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index d639e55c5124..1d4e7164e80a 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -380,8 +380,8 @@ int mpc5200_audio_dma_create(struct of_device *op) int ret; /* Fetch the registers and IRQ of the PSC */ - irq = irq_of_parse_and_map(op->node, 0); - if (of_address_to_resource(op->node, 0, &res)) { + irq = irq_of_parse_and_map(op->dev.of_node, 0); + if (of_address_to_resource(op->dev.of_node, 0, &res)) { dev_err(&op->dev, "Missing reg property\n"); return -ENODEV; } @@ -399,7 +399,7 @@ int mpc5200_audio_dma_create(struct of_device *op) } /* Get the PSC ID */ - prop = of_get_property(op->node, "cell-index", &size); + prop = of_get_property(op->dev.of_node, "cell-index", &size); if (!prop || size < sizeof *prop) { ret = -ENODEV; goto out_free; diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index ce8de90fb94a..748cc0f0df38 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -181,7 +181,7 @@ static int __devinit psc_i2s_of_probe(struct of_device *op, /* Check for the codec handle. If it is not present then we * are done */ - if (!of_get_property(op->node, "codec-handle", NULL)) + if (!of_get_property(op->dev.of_node, "codec-handle", NULL)) return 0; /* Due to errata in the dma mode; need to line up enabling diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 83de1c81c8c4..e3f78f255a60 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -203,7 +203,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = { static int mpc8610_hpcd_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node *codec_np = NULL; struct device_node *guts_np = NULL; struct device_node *dma_np = NULL; diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 7dcc06512e86..6a4c872e00df 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -2075,12 +2075,12 @@ static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_dev static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match) { #ifdef EBUS_SUPPORT - if (!strcmp(op->node->parent->name, "ebus")) + if (!strcmp(op->dev.of_node->parent->name, "ebus")) return cs4231_ebus_probe(op, match); #endif #ifdef SBUS_SUPPORT - if (!strcmp(op->node->parent->name, "sbus") || - !strcmp(op->node->parent->name, "sbi")) + if (!strcmp(op->dev.of_node->parent->name, "sbus") || + !strcmp(op->dev.of_node->parent->name, "sbi")) return cs4231_sbus_probe(op, match); #endif return -ENODEV; diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 2eab6ce48852..1b5192eb5ae5 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2651,7 +2651,7 @@ static int __devinit dbri_probe(struct of_device *op, const struct of_device_id printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", dev, dbri->regs, - dbri->irq, op->node->name[9], dbri->mm.version); + dbri->irq, op->dev.of_node->name[9], dbri->mm.version); dev++; return 0; -- cgit v1.2.3-59-g8ed1b From 58f9b0b02414062eaff46716bc04b47d7e79add5 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:56 -0700 Subject: of: eliminate of_device->node and dev_archdata->{of,prom}_node This patch eliminates the node pointer from struct of_device and the of_node (or prom_node) pointer from struct dev_archdata since the node pointer is now part of struct device proper when CONFIG_OF is set, and all users of the old pointer locations have already been converted over to use device->of_node. Also remove dev_archdata_{get,set}_node() as it is no longer used by anything. Signed-off-by: Grant Likely --- arch/microblaze/include/asm/device.h | 15 --------------- arch/microblaze/include/asm/of_device.h | 1 - arch/microblaze/kernel/of_device.c | 4 +--- arch/powerpc/include/asm/device.h | 15 --------------- arch/powerpc/include/asm/of_device.h | 1 - arch/powerpc/kernel/of_device.c | 4 +--- arch/powerpc/kernel/pci-common.c | 1 - arch/powerpc/kernel/vio.c | 17 ++++++++--------- arch/powerpc/platforms/cell/iommu.c | 5 ++--- arch/powerpc/platforms/pasemi/setup.c | 4 ++-- arch/powerpc/platforms/ps3/system-bus.c | 1 - arch/powerpc/platforms/pseries/iommu.c | 2 +- arch/sparc/include/asm/device.h | 15 --------------- arch/sparc/include/asm/of_device.h | 1 - arch/sparc/kernel/of_device_32.c | 2 -- arch/sparc/kernel/of_device_64.c | 2 -- arch/sparc/kernel/pci.c | 3 +-- drivers/of/of_i2c.c | 1 - drivers/of/of_mdio.c | 1 - drivers/of/of_spi.c | 1 - 20 files changed, 16 insertions(+), 80 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h index 402b46e630f6..15b0058aa7ff 100644 --- a/arch/microblaze/include/asm/device.h +++ b/arch/microblaze/include/asm/device.h @@ -12,9 +12,6 @@ struct device_node; struct dev_archdata { - /* Optional pointer to an OF device node */ - struct device_node *of_node; - /* DMA operations on that device */ struct dma_map_ops *dma_ops; void *dma_data; @@ -23,18 +20,6 @@ struct dev_archdata { struct pdev_archdata { }; -static inline void dev_archdata_set_node(struct dev_archdata *ad, - struct device_node *np) -{ - ad->of_node = np; -} - -static inline struct device_node * -dev_archdata_get_node(const struct dev_archdata *ad) -{ - return ad->of_node; -} - #endif /* _ASM_MICROBLAZE_DEVICE_H */ diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index ba917cfaefe6..ab25a40b481c 100644 --- a/arch/microblaze/include/asm/of_device.h +++ b/arch/microblaze/include/asm/of_device.h @@ -21,7 +21,6 @@ * probed using OF properties. */ struct of_device { - struct device_node *node; /* to be obsoleted */ u64 dma_mask; /* DMA mask */ struct device dev; /* Generic device interface */ }; diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index 90d2246e15c0..ac7e6e10d0ab 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -49,12 +49,10 @@ struct of_device *of_device_alloc(struct device_node *np, if (!dev) return NULL; - dev->node = of_node_get(np); + dev->dev.of_node = of_node_get(np); dev->dev.dma_mask = &dev->dma_mask; dev->dev.parent = parent; dev->dev.release = of_release_dev; - dev->dev.archdata.of_node = np; - dev->dev.of_node = np; if (bus_id) dev_set_name(&dev->dev, bus_id); diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 6d94d27ed850..f23f8d8bd68d 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -10,9 +10,6 @@ struct dma_map_ops; struct device_node; struct dev_archdata { - /* Optional pointer to an OF device node */ - struct device_node *of_node; - /* DMA operations on that device */ struct dma_map_ops *dma_ops; @@ -30,18 +27,6 @@ struct dev_archdata { #endif }; -static inline void dev_archdata_set_node(struct dev_archdata *ad, - struct device_node *np) -{ - ad->of_node = np; -} - -static inline struct device_node * -dev_archdata_get_node(const struct dev_archdata *ad) -{ - return ad->of_node; -} - struct pdev_archdata { }; diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h index a64debf177dc..8b26f96b9f9e 100644 --- a/arch/powerpc/include/asm/of_device.h +++ b/arch/powerpc/include/asm/of_device.h @@ -12,7 +12,6 @@ */ struct of_device { - struct device_node *node; /* to be obsoleted */ u64 dma_mask; /* DMA mask */ struct device dev; /* Generic device interface */ }; diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 285c8490c547..20b3474b6f6b 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -69,12 +69,10 @@ struct of_device *of_device_alloc(struct device_node *np, if (!dev) return NULL; - dev->node = of_node_get(np); + dev->dev.of_node = of_node_get(np); dev->dev.dma_mask = &dev->dma_mask; dev->dev.parent = parent; dev->dev.release = of_release_dev; - dev->dev.archdata.of_node = np; - dev->dev.of_node = np; if (bus_id) dev_set_name(&dev->dev, "%s", bus_id); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 88da282047c3..6646005dffb1 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1098,7 +1098,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) continue; /* Setup OF node pointer in the device */ - sd->of_node = pci_device_to_OF_node(dev); dev->dev.of_node = pci_device_to_OF_node(dev); /* Fixup NUMA node as it may not be setup yet by the generic diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index d6708da114ee..4cdd0f6df8bf 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -705,7 +705,7 @@ static int vio_cmo_bus_probe(struct vio_dev *viodev) * Check to see that device has a DMA window and configure * entitlement for the device. */ - if (of_get_property(viodev->dev.archdata.of_node, + if (of_get_property(viodev->dev.of_node, "ibm,my-dma-window", NULL)) { /* Check that the driver is CMO enabled and get desired DMA */ if (!viodrv->get_desired_dma) { @@ -1049,7 +1049,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) if (firmware_has_feature(FW_FEATURE_ISERIES)) return vio_build_iommu_table_iseries(dev); - dma_window = of_get_property(dev->dev.archdata.of_node, + dma_window = of_get_property(dev->dev.of_node, "ibm,my-dma-window", NULL); if (!dma_window) return NULL; @@ -1058,7 +1058,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) if (tbl == NULL) return NULL; - of_parse_dma_window(dev->dev.archdata.of_node, dma_window, + of_parse_dma_window(dev->dev.of_node, dma_window, &tbl->it_index, &offset, &size); /* TCE table size - measured in tce entries */ @@ -1086,7 +1086,7 @@ static const struct vio_device_id *vio_match_device( { while (ids->type[0] != '\0') { if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) && - of_device_is_compatible(dev->dev.archdata.of_node, + of_device_is_compatible(dev->dev.of_node, ids->compat)) return ids; ids++; @@ -1179,7 +1179,7 @@ EXPORT_SYMBOL(vio_unregister_driver); static void __devinit vio_dev_release(struct device *dev) { /* XXX should free TCE table */ - of_node_put(dev->archdata.of_node); + of_node_put(dev->of_node); kfree(to_vio_dev(dev)); } @@ -1231,7 +1231,6 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) viodev->unit_address = *unit_address; } viodev->dev.of_node = of_node_get(of_node); - viodev->dev.archdata.of_node = viodev->dev.of_node; if (firmware_has_feature(FW_FEATURE_CMO)) vio_cmo_set_dma_ops(viodev); @@ -1316,7 +1315,7 @@ static ssize_t name_show(struct device *dev, static ssize_t devspec_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct device_node *of_node = dev->archdata.of_node; + struct device_node *of_node = dev->of_node; return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none"); } @@ -1348,7 +1347,7 @@ static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env) struct device_node *dn; const char *cp; - dn = dev->archdata.of_node; + dn = dev->of_node; if (!dn) return -ENODEV; cp = of_get_property(dn, "compatible", NULL); @@ -1379,7 +1378,7 @@ static struct bus_type vio_bus_type = { */ const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length) { - return of_get_property(vdev->dev.archdata.of_node, which, length); + return of_get_property(vdev->dev.of_node, which, length); } EXPORT_SYMBOL(vio_get_attribute); diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index e3ec4976fae7..22667a09d40e 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -545,7 +545,6 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) { struct iommu_window *window; struct cbe_iommu *iommu; - struct dev_archdata *archdata = &dev->archdata; /* Current implementation uses the first window available in that * node's iommu. We -might- do something smarter later though it may @@ -554,7 +553,7 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) iommu = cell_iommu_for_node(dev_to_node(dev)); if (iommu == NULL || list_empty(&iommu->windows)) { printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n", - archdata->of_node ? archdata->of_node->full_name : "?", + dev->of_node ? dev->of_node->full_name : "?", dev_to_node(dev)); return NULL; } @@ -897,7 +896,7 @@ static u64 cell_iommu_get_fixed_address(struct device *dev) const u32 *ranges = NULL; int i, len, best, naddr, nsize, pna, range_size; - np = of_node_get(dev->archdata.of_node); + np = of_node_get(dev->of_node); while (1) { naddr = of_n_addr_cells(np); nsize = of_n_size_cells(np); diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index ac6fdd973291..f372ec1691a3 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -360,10 +360,10 @@ static int pcmcia_notify(struct notifier_block *nb, unsigned long action, /* We know electra_cf devices will always have of_node set, since * electra_cf is an of_platform driver. */ - if (!parent->archdata.of_node) + if (!parent->of_node) return 0; - if (!of_device_is_compatible(parent->archdata.of_node, "electra-cf")) + if (!of_device_is_compatible(parent->of_node, "electra-cf")) return 0; /* We use the direct ops for localbus */ diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index e546c86a539b..23083c397528 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -767,7 +767,6 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) }; dev->core.of_node = NULL; - dev->core.archdata.of_node = NULL; set_dev_node(&dev->core, 0); pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core)); diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 1a0000a4b6d6..d26182d42cbf 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -468,7 +468,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) pr_debug("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev)); - dn = dev->dev.archdata.of_node; + dn = dev->dev.of_node; /* If we're the direct child of a root bus, then we need to allocate * an iommu table ourselves. The bus setup code should have setup diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h index f3b85b6b0b76..d4c452147412 100644 --- a/arch/sparc/include/asm/device.h +++ b/arch/sparc/include/asm/device.h @@ -13,25 +13,10 @@ struct dev_archdata { void *iommu; void *stc; void *host_controller; - - struct device_node *prom_node; struct of_device *op; - int numa_node; }; -static inline void dev_archdata_set_node(struct dev_archdata *ad, - struct device_node *np) -{ - ad->prom_node = np; -} - -static inline struct device_node * -dev_archdata_get_node(const struct dev_archdata *ad) -{ - return ad->prom_node; -} - struct pdev_archdata { }; diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h index a5d9811f9697..f320246a0586 100644 --- a/arch/sparc/include/asm/of_device.h +++ b/arch/sparc/include/asm/of_device.h @@ -14,7 +14,6 @@ */ struct of_device { - struct device_node *node; struct device dev; struct resource resource[PROMREG_MAX]; unsigned int irqs[PROMINTR_MAX]; diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 707311716142..47e63f1e719c 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -345,11 +345,9 @@ static struct of_device * __init scan_one_device(struct device_node *dp, return NULL; sd = &op->dev.archdata; - sd->prom_node = dp; sd->op = op; op->dev.of_node = dp; - op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", (25*1000*1000)); diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index c8e352e0a098..1dae8079f728 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -640,11 +640,9 @@ static struct of_device * __init scan_one_device(struct device_node *dp, return NULL; sd = &op->dev.archdata; - sd->prom_node = dp; sd->op = op; op->dev.of_node = dp; - op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", (25*1000*1000)); diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index c7a214ec5aff..8a8363adb8bd 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -261,8 +261,6 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, sd->iommu = pbm->iommu; sd->stc = &pbm->stc; sd->host_controller = pbm; - sd->prom_node = node; - dev->dev.of_node = node; sd->op = op = of_find_device_by_node(node); sd->numa_node = pbm->numa_node; @@ -286,6 +284,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->sysdata = node; dev->dev.parent = bus->bridge; dev->dev.bus = &pci_bus_type; + dev->dev.of_node = node; dev->devfn = devfn; dev->multifunction = 0; /* maybe a lie? */ set_pcie_port_type(dev); diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index 604ba966e1c9..ab6522c8e4fe 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -42,7 +42,6 @@ void of_register_i2c_devices(struct i2c_adapter *adap, info.addr = be32_to_cpup(addr); - dev_archdata_set_node(&dev_ad, node); info.of_node = node; info.archdata = &dev_ad; diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 01d794abe105..794fbc2ef73d 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -79,7 +79,6 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) /* Associate the OF node with the device structure so it * can be looked up later */ of_node_get(child); - dev_archdata_set_node(&phy->dev.archdata, child); phy->dev.of_node = child; /* All data is now stored in the phy struct; register it */ diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index f3119a0836af..5fed7e3c7da3 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -80,7 +80,6 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) /* Store a pointer to the node in the device structure */ of_node_get(nc); spi->dev.of_node = nc; - spi->dev.archdata.of_node = nc; /* Register the new device */ request_module(spi->modalias); -- cgit v1.2.3-59-g8ed1b From 273fca0ecad9305247043815e185d1bfd04047d4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 18 May 2010 15:23:58 -0700 Subject: sparc: Define ARCH_SLAB_MINALIGN Because SLOB fancies being different, the default minimum alignment is only "unsigned long" instead of SLAB/SLUB where the default is "unsigned long long" The inconsistency makes no sense and is asking for trouble, but define ARCH_SLAB_MINALIGN to get it right in all cases even after they fix the inconsistency. Signed-off-by: David S. Miller --- arch/sparc/include/asm/cache.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h index 41f85ae4bd4a..78b07009f60a 100644 --- a/arch/sparc/include/asm/cache.h +++ b/arch/sparc/include/asm/cache.h @@ -7,6 +7,8 @@ #ifndef _SPARC_CACHE_H #define _SPARC_CACHE_H +#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long) + #define L1_CACHE_SHIFT 5 #define L1_CACHE_BYTES 32 #define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))) -- cgit v1.2.3-59-g8ed1b From b2be05273a1744d175bf4b67f6665637bb9ac7a8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 3 Apr 2010 19:34:56 +0100 Subject: panic: Allow warnings to set different taint flags WARN() is used in some places to report firmware or hardware bugs that are then worked-around. These bugs do not affect the stability of the kernel and should not set the flag for TAINT_WARN. To allow for this, add WARN_TAINT() and WARN_TAINT_ONCE() macros that take a taint number as argument. Architectures that implement warnings using trap instructions instead of calls to warn_slowpath_*() now implement __WARN_TAINT(taint) instead of __WARN(). Signed-off-by: Ben Hutchings Acked-by: Helge Deller Tested-by: Paul Mundt Signed-off-by: David Woodhouse --- Documentation/oops-tracing.txt | 1 + arch/parisc/include/asm/bug.h | 8 ++++---- arch/powerpc/include/asm/bug.h | 6 +++--- arch/s390/include/asm/bug.h | 8 ++++---- arch/sh/include/asm/bug.h | 4 ++-- include/asm-generic/bug.h | 34 ++++++++++++++++++++++++++++++++-- kernel/panic.c | 24 ++++++++++++++++++++---- lib/bug.c | 2 +- 8 files changed, 67 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt index c10c022b911c..069fab3ea4d6 100644 --- a/Documentation/oops-tracing.txt +++ b/Documentation/oops-tracing.txt @@ -256,6 +256,7 @@ characters, each representing a particular tainted value. 9: 'A' if the ACPI table has been overridden. 10: 'W' if a warning has previously been issued by the kernel. + (Though some warnings may set more specific taint flags.) 11: 'C' if a staging driver has been loaded. diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h index 75e46c557a16..72cfdb0cfdd1 100644 --- a/arch/parisc/include/asm/bug.h +++ b/arch/parisc/include/asm/bug.h @@ -44,7 +44,7 @@ #endif #ifdef CONFIG_DEBUG_BUGVERBOSE -#define __WARN() \ +#define __WARN_TAINT(taint) \ do { \ asm volatile("\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \ @@ -54,11 +54,11 @@ "\t.org 2b+%c3\n" \ "\t.popsection" \ : : "i" (__FILE__), "i" (__LINE__), \ - "i" (BUGFLAG_WARNING), \ + "i" (BUGFLAG_TAINT(taint)), \ "i" (sizeof(struct bug_entry)) ); \ } while(0) #else -#define __WARN() \ +#define __WARN_TAINT(taint) \ do { \ asm volatile("\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \ @@ -67,7 +67,7 @@ "\t.short %c0\n" \ "\t.org 2b+%c1\n" \ "\t.popsection" \ - : : "i" (BUGFLAG_WARNING), \ + : : "i" (BUGFLAG_TAINT(taint)), \ "i" (sizeof(struct bug_entry)) ); \ } while(0) #endif diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index 2c15212e1700..065c590c991d 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -85,12 +85,12 @@ } \ } while (0) -#define __WARN() do { \ +#define __WARN_TAINT(taint) do { \ __asm__ __volatile__( \ "1: twi 31,0,0\n" \ _EMIT_BUG_ENTRY \ : : "i" (__FILE__), "i" (__LINE__), \ - "i" (BUGFLAG_WARNING), \ + "i" (BUGFLAG_TAINT(taint)), \ "i" (sizeof(struct bug_entry))); \ } while (0) @@ -104,7 +104,7 @@ "1: "PPC_TLNEI" %4,0\n" \ _EMIT_BUG_ENTRY \ : : "i" (__FILE__), "i" (__LINE__), \ - "i" (BUGFLAG_WARNING), \ + "i" (BUGFLAG_TAINT(TAINT_WARN)), \ "i" (sizeof(struct bug_entry)), \ "r" (__ret_warn_on)); \ } \ diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h index 9beeb9db9b23..bf90d1fd97a5 100644 --- a/arch/s390/include/asm/bug.h +++ b/arch/s390/include/asm/bug.h @@ -46,18 +46,18 @@ unreachable(); \ } while (0) -#define __WARN() do { \ - __EMIT_BUG(BUGFLAG_WARNING); \ +#define __WARN_TAINT(taint) do { \ + __EMIT_BUG(BUGFLAG_TAINT(taint)); \ } while (0) #define WARN_ON(x) ({ \ int __ret_warn_on = !!(x); \ if (__builtin_constant_p(__ret_warn_on)) { \ if (__ret_warn_on) \ - __EMIT_BUG(BUGFLAG_WARNING); \ + __WARN(); \ } else { \ if (unlikely(__ret_warn_on)) \ - __EMIT_BUG(BUGFLAG_WARNING); \ + __WARN(); \ } \ unlikely(__ret_warn_on); \ }) diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h index d02c01b3e6b9..6323f864d111 100644 --- a/arch/sh/include/asm/bug.h +++ b/arch/sh/include/asm/bug.h @@ -48,7 +48,7 @@ do { \ "i" (sizeof(struct bug_entry))); \ } while (0) -#define __WARN() \ +#define __WARN_TAINT(taint) \ do { \ __asm__ __volatile__ ( \ "1:\t.short %O0\n" \ @@ -57,7 +57,7 @@ do { \ : "n" (TRAPA_BUG_OPCODE), \ "i" (__FILE__), \ "i" (__LINE__), \ - "i" (BUGFLAG_WARNING), \ + "i" (BUGFLAG_TAINT(taint)), \ "i" (sizeof(struct bug_entry))); \ } while (0) diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 18c435d7c082..c2c9ba032d46 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -25,7 +25,10 @@ struct bug_entry { }; #endif /* __ASSEMBLY__ */ -#define BUGFLAG_WARNING (1<<0) +#define BUGFLAG_WARNING (1 << 0) +#define BUGFLAG_TAINT(taint) (BUGFLAG_WARNING | ((taint) << 8)) +#define BUG_GET_TAINT(bug) ((bug)->flags >> 8) + #endif /* CONFIG_GENERIC_BUG */ /* @@ -56,17 +59,25 @@ struct bug_entry { * appear at runtime. Use the versions with printk format strings * to provide better diagnostics. */ -#ifndef __WARN +#ifndef __WARN_TAINT #ifndef __ASSEMBLY__ extern void warn_slowpath_fmt(const char *file, const int line, const char *fmt, ...) __attribute__((format(printf, 3, 4))); +extern void warn_slowpath_fmt_taint(const char *file, const int line, + unsigned taint, const char *fmt, ...) + __attribute__((format(printf, 4, 5))); extern void warn_slowpath_null(const char *file, const int line); #define WANT_WARN_ON_SLOWPATH #endif #define __WARN() warn_slowpath_null(__FILE__, __LINE__) #define __WARN_printf(arg...) warn_slowpath_fmt(__FILE__, __LINE__, arg) +#define __WARN_printf_taint(taint, arg...) \ + warn_slowpath_fmt_taint(__FILE__, __LINE__, taint, arg) #else +#define __WARN() __WARN_TAINT(TAINT_WARN) #define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0) +#define __WARN_printf_taint(taint, arg...) \ + do { printk(arg); __WARN_TAINT(taint); } while (0) #endif #ifndef WARN_ON @@ -87,6 +98,13 @@ extern void warn_slowpath_null(const char *file, const int line); }) #endif +#define WARN_TAINT(condition, taint, format...) ({ \ + int __ret_warn_on = !!(condition); \ + if (unlikely(__ret_warn_on)) \ + __WARN_printf_taint(taint, format); \ + unlikely(__ret_warn_on); \ +}) + #else /* !CONFIG_BUG */ #ifndef HAVE_ARCH_BUG #define BUG() do {} while(0) @@ -110,6 +128,8 @@ extern void warn_slowpath_null(const char *file, const int line); }) #endif +#define WARN_TAINT(condition, taint, format...) WARN_ON(condition) + #endif #define WARN_ON_ONCE(condition) ({ \ @@ -132,6 +152,16 @@ extern void warn_slowpath_null(const char *file, const int line); unlikely(__ret_warn_once); \ }) +#define WARN_TAINT_ONCE(condition, taint, format...) ({ \ + static bool __warned; \ + int __ret_warn_once = !!(condition); \ + \ + if (unlikely(__ret_warn_once)) \ + if (WARN_TAINT(!__warned, taint, format)) \ + __warned = true; \ + unlikely(__ret_warn_once); \ +}) + #define WARN_ON_RATELIMIT(condition, state) \ WARN_ON((condition) && __ratelimit(state)) diff --git a/kernel/panic.c b/kernel/panic.c index 13d966b4c14a..8b821bce66e6 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -365,7 +365,8 @@ struct slowpath_args { va_list args; }; -static void warn_slowpath_common(const char *file, int line, void *caller, struct slowpath_args *args) +static void warn_slowpath_common(const char *file, int line, void *caller, + unsigned taint, struct slowpath_args *args) { const char *board; @@ -381,7 +382,7 @@ static void warn_slowpath_common(const char *file, int line, void *caller, struc print_modules(); dump_stack(); print_oops_end_marker(); - add_taint(TAINT_WARN); + add_taint(taint); } void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) @@ -390,14 +391,29 @@ void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) args.fmt = fmt; va_start(args.args, fmt); - warn_slowpath_common(file, line, __builtin_return_address(0), &args); + warn_slowpath_common(file, line, __builtin_return_address(0), + TAINT_WARN, &args); va_end(args.args); } EXPORT_SYMBOL(warn_slowpath_fmt); +void warn_slowpath_fmt_taint(const char *file, int line, + unsigned taint, const char *fmt, ...) +{ + struct slowpath_args args; + + args.fmt = fmt; + va_start(args.args, fmt); + warn_slowpath_common(file, line, __builtin_return_address(0), + taint, &args); + va_end(args.args); +} +EXPORT_SYMBOL(warn_slowpath_fmt_taint); + void warn_slowpath_null(const char *file, int line) { - warn_slowpath_common(file, line, __builtin_return_address(0), NULL); + warn_slowpath_common(file, line, __builtin_return_address(0), + TAINT_WARN, NULL); } EXPORT_SYMBOL(warn_slowpath_null); #endif diff --git a/lib/bug.c b/lib/bug.c index 300e41afbf97..f13daf435211 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -165,7 +165,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) (void *)bugaddr); show_regs(regs); - add_taint(TAINT_WARN); + add_taint(BUG_GET_TAINT(bug)); return BUG_TRAP_TYPE_WARN; } -- cgit v1.2.3-59-g8ed1b From 5a7388c2d2faa2cc70c2d4717c8d7836d55459e0 Mon Sep 17 00:00:00 2001 From: Eric Northup Date: Mon, 26 Apr 2010 17:00:05 -0700 Subject: KVM: MMU: fix hashing for TDP and non-paging modes For TDP mode, avoid creating multiple page table roots for the single guest-to-host physical address map by fixing the inputs used for the shadow page table hash in mmu_alloc_roots(). Signed-off-by: Eric Northup Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index ddfa8658fb6d..9696d654b01f 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2059,10 +2059,12 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu) hpa_t root = vcpu->arch.mmu.root_hpa; ASSERT(!VALID_PAGE(root)); - if (tdp_enabled) - direct = 1; if (mmu_check_root(vcpu, root_gfn)) return 1; + if (tdp_enabled) { + direct = 1; + root_gfn = 0; + } sp = kvm_mmu_get_page(vcpu, root_gfn, 0, PT64_ROOT_LEVEL, direct, ACC_ALL, NULL); @@ -2072,8 +2074,6 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu) return 0; } direct = !is_paging(vcpu); - if (tdp_enabled) - direct = 1; for (i = 0; i < 4; ++i) { hpa_t root = vcpu->arch.mmu.pae_root[i]; @@ -2089,6 +2089,10 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu) root_gfn = 0; if (mmu_check_root(vcpu, root_gfn)) return 1; + if (tdp_enabled) { + direct = 1; + root_gfn = i << 30; + } sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, PT32_ROOT_LEVEL, direct, ACC_ALL, NULL); -- cgit v1.2.3-59-g8ed1b From d35b8dd9355805f17225fdbfee4bc704d7bf7547 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Tue, 27 Apr 2010 10:39:49 +0800 Subject: KVM: Fix mmu shrinker error kvm_mmu_remove_one_alloc_mmu_page() assumes kvm_mmu_zap_page() only reclaims only one sp, but that's not the case. This will cause mmu shrinker returns a wrong number. This patch fix the counting error. Signed-off-by: Gui Jianfeng Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 9696d654b01f..18d2f584945b 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2902,13 +2902,13 @@ restart: kvm_flush_remote_tlbs(kvm); } -static void kvm_mmu_remove_one_alloc_mmu_page(struct kvm *kvm) +static int kvm_mmu_remove_some_alloc_mmu_pages(struct kvm *kvm) { struct kvm_mmu_page *page; page = container_of(kvm->arch.active_mmu_pages.prev, struct kvm_mmu_page, link); - kvm_mmu_zap_page(kvm, page); + return kvm_mmu_zap_page(kvm, page) + 1; } static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask) @@ -2920,7 +2920,7 @@ static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask) spin_lock(&kvm_lock); list_for_each_entry(kvm, &vm_list, vm_list) { - int npages, idx; + int npages, idx, freed_pages; idx = srcu_read_lock(&kvm->srcu); spin_lock(&kvm->mmu_lock); @@ -2928,8 +2928,8 @@ static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask) kvm->arch.n_free_mmu_pages; cache_count += npages; if (!kvm_freed && nr_to_scan > 0 && npages > 0) { - kvm_mmu_remove_one_alloc_mmu_page(kvm); - cache_count--; + freed_pages = kvm_mmu_remove_some_alloc_mmu_pages(kvm); + cache_count -= freed_pages; kvm_freed = kvm; } nr_to_scan--; -- cgit v1.2.3-59-g8ed1b From 329d20ba451b5a9fd17a4ce9471e4d335b3b8c74 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 27 Apr 2010 15:49:17 +1000 Subject: KVM: powerpc: use of kzalloc/kfree requires including slab.h Signed-off-by: Stephen Rothwell Signed-off-by: Marcelo Tosatti --- arch/powerpc/kvm/book3s.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 9f97dbe25e4e..28e785fb2cab 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -16,6 +16,7 @@ #include #include +#include #include #include -- cgit v1.2.3-59-g8ed1b From 22c9b2d166a88573a933e8d355833d36579d83be Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Wed, 28 Apr 2010 11:54:44 +0800 Subject: KVM: MMU: fix for calculating gpa in invlpg code If the guest is 32-bit, we should use 'quadrant' to adjust gpa offset Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/paging_tmpl.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index d0cc07eb6eda..3464fdbdb98f 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -478,8 +478,13 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) || ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) { struct kvm_mmu_page *sp = page_header(__pa(sptep)); + int offset, shift; - pte_gpa = (sp->gfn << PAGE_SHIFT); + shift = PAGE_SHIFT - + (PT_LEVEL_BITS - PT64_LEVEL_BITS) * level; + offset = sp->role.quadrant << shift; + + pte_gpa = (sp->gfn << PAGE_SHIFT) + offset; pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t); if (is_shadow_present_pte(*sptep)) { -- cgit v1.2.3-59-g8ed1b From 85f2067c3192212bce3bd2e1d6ad10153d6f2a4e Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Wed, 28 Apr 2010 11:54:55 +0800 Subject: KVM: MMU: convert mmu tracepoints Convert mmu tracepoints by using DECLARE_EVENT_CLASS Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmutrace.h | 69 +++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h index 40a1786f36c7..42f07b1bfbc9 100644 --- a/arch/x86/kvm/mmutrace.h +++ b/arch/x86/kvm/mmutrace.h @@ -92,15 +92,15 @@ TRACE_EVENT( TP_printk("pte %llx level %u", __entry->pte, __entry->level) ); -/* We set a pte accessed bit */ -TRACE_EVENT( - kvm_mmu_set_accessed_bit, +DECLARE_EVENT_CLASS(kvm_mmu_set_bit_class, + TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size), + TP_ARGS(table_gfn, index, size), TP_STRUCT__entry( __field(__u64, gpa) - ), + ), TP_fast_assign( __entry->gpa = ((u64)table_gfn << PAGE_SHIFT) @@ -110,22 +110,20 @@ TRACE_EVENT( TP_printk("gpa %llx", __entry->gpa) ); -/* We set a pte dirty bit */ -TRACE_EVENT( - kvm_mmu_set_dirty_bit, +/* We set a pte accessed bit */ +DEFINE_EVENT(kvm_mmu_set_bit_class, kvm_mmu_set_accessed_bit, + TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size), - TP_ARGS(table_gfn, index, size), - TP_STRUCT__entry( - __field(__u64, gpa) - ), + TP_ARGS(table_gfn, index, size) +); - TP_fast_assign( - __entry->gpa = ((u64)table_gfn << PAGE_SHIFT) - + index * size; - ), +/* We set a pte dirty bit */ +DEFINE_EVENT(kvm_mmu_set_bit_class, kvm_mmu_set_dirty_bit, - TP_printk("gpa %llx", __entry->gpa) + TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size), + + TP_ARGS(table_gfn, index, size) ); TRACE_EVENT( @@ -164,54 +162,39 @@ TRACE_EVENT( __entry->created ? "new" : "existing") ); -TRACE_EVENT( - kvm_mmu_sync_page, +DECLARE_EVENT_CLASS(kvm_mmu_page_class, + TP_PROTO(struct kvm_mmu_page *sp), TP_ARGS(sp), TP_STRUCT__entry( KVM_MMU_PAGE_FIELDS - ), + ), TP_fast_assign( KVM_MMU_PAGE_ASSIGN(sp) - ), + ), TP_printk("%s", KVM_MMU_PAGE_PRINTK()) ); -TRACE_EVENT( - kvm_mmu_unsync_page, +DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu_sync_page, TP_PROTO(struct kvm_mmu_page *sp), - TP_ARGS(sp), - - TP_STRUCT__entry( - KVM_MMU_PAGE_FIELDS - ), - - TP_fast_assign( - KVM_MMU_PAGE_ASSIGN(sp) - ), - TP_printk("%s", KVM_MMU_PAGE_PRINTK()) + TP_ARGS(sp) ); -TRACE_EVENT( - kvm_mmu_zap_page, +DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu_unsync_page, TP_PROTO(struct kvm_mmu_page *sp), - TP_ARGS(sp), - TP_STRUCT__entry( - KVM_MMU_PAGE_FIELDS - ), + TP_ARGS(sp) +); - TP_fast_assign( - KVM_MMU_PAGE_ASSIGN(sp) - ), +DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu_zap_page, + TP_PROTO(struct kvm_mmu_page *sp), - TP_printk("%s", KVM_MMU_PAGE_PRINTK()) + TP_ARGS(sp) ); - #endif /* _TRACE_KVMMMU_H */ #undef TRACE_INCLUDE_PATH -- cgit v1.2.3-59-g8ed1b From 5e1b3ddbf220d2256a6a0d676a219ed76b8048d0 Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Wed, 28 Apr 2010 11:55:06 +0800 Subject: KVM: MMU: move unsync/sync tracpoints to proper place Move unsync/sync tracepoints to the proper place, it's good for us to obtain unsync page live time Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 18d2f584945b..51eb6d6abd86 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1189,6 +1189,7 @@ static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn) static void kvm_unlink_unsync_page(struct kvm *kvm, struct kvm_mmu_page *sp) { WARN_ON(!sp->unsync); + trace_kvm_mmu_sync_page(sp); sp->unsync = 0; --kvm->stat.mmu_unsync; } @@ -1202,7 +1203,6 @@ static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) return 1; } - trace_kvm_mmu_sync_page(sp); if (rmap_write_protect(vcpu->kvm, sp->gfn)) kvm_flush_remote_tlbs(vcpu->kvm); kvm_unlink_unsync_page(vcpu->kvm, sp); @@ -1730,7 +1730,6 @@ static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) struct kvm_mmu_page *s; struct hlist_node *node, *n; - trace_kvm_mmu_unsync_page(sp); index = kvm_page_table_hashfn(sp->gfn); bucket = &vcpu->kvm->arch.mmu_page_hash[index]; /* don't unsync if pagetable is shadowed with multiple roles */ @@ -1740,6 +1739,7 @@ static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) if (s->role.word != sp->role.word) return 1; } + trace_kvm_mmu_unsync_page(sp); ++vcpu->kvm->stat.mmu_unsync; sp->unsync = 1; -- cgit v1.2.3-59-g8ed1b From 884a0ff0b68b3ece5987507de168215e14ef7849 Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Wed, 28 Apr 2010 11:55:15 +0800 Subject: KVM: MMU: cleanup invlpg code Using is_last_spte() to cleanup invlpg code Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/paging_tmpl.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 3464fdbdb98f..89d66ca4d87c 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -474,9 +474,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) level = iterator.level; sptep = iterator.sptep; - if (level == PT_PAGE_TABLE_LEVEL || - ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) || - ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) { + if (is_last_spte(*sptep, level)) { struct kvm_mmu_page *sp = page_header(__pa(sptep)); int offset, shift; -- cgit v1.2.3-59-g8ed1b From 0ee75bead83da4791e5cbf659806c54d8ee40f12 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 28 Apr 2010 15:39:01 +0300 Subject: KVM: Let vcpu structure alignment be determined at runtime vmx and svm vcpus have different contents and therefore may have different alignmment requirements. Let each specify its required alignment. Signed-off-by: Avi Kivity --- arch/ia64/kvm/vmm.c | 2 +- arch/powerpc/kvm/44x.c | 2 +- arch/powerpc/kvm/book3s.c | 3 ++- arch/powerpc/kvm/e500.c | 2 +- arch/s390/kvm/kvm-s390.c | 2 +- arch/x86/kvm/svm.c | 2 +- arch/x86/kvm/vmx.c | 3 ++- include/linux/kvm_host.h | 2 +- virt/kvm/kvm_main.c | 7 ++++--- 9 files changed, 14 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kvm/vmm.c b/arch/ia64/kvm/vmm.c index 7a62f75778c5..f0b9cac82414 100644 --- a/arch/ia64/kvm/vmm.c +++ b/arch/ia64/kvm/vmm.c @@ -51,7 +51,7 @@ static int __init kvm_vmm_init(void) vmm_fpswa_interface = fpswa_interface; /*Register vmm data to kvm side*/ - return kvm_init(&vmm_info, 1024, THIS_MODULE); + return kvm_init(&vmm_info, 1024, 0, THIS_MODULE); } static void __exit kvm_vmm_exit(void) diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c index 689a57c2ac80..73c0a3f64ed1 100644 --- a/arch/powerpc/kvm/44x.c +++ b/arch/powerpc/kvm/44x.c @@ -147,7 +147,7 @@ static int __init kvmppc_44x_init(void) if (r) return r; - return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), THIS_MODULE); + return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), 0, THIS_MODULE); } static void __exit kvmppc_44x_exit(void) diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 28e785fb2cab..11f226ff4468 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -1385,7 +1385,8 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) static int kvmppc_book3s_init(void) { - return kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), THIS_MODULE); + return kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), 0, + THIS_MODULE); } static void kvmppc_book3s_exit(void) diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index 669a5c5fc7d7..bc2b4004eb26 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -161,7 +161,7 @@ static int __init kvmppc_e500_init(void) flush_icache_range(kvmppc_booke_handlers, kvmppc_booke_handlers + max_ivor + kvmppc_handler_len); - return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE); + return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE); } static void __init kvmppc_e500_exit(void) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ee7c713686ce..8093e6f47f49 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -752,7 +752,7 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) static int __init kvm_s390_init(void) { int ret; - ret = kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE); + ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); if (ret) return ret; diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 889f66022e57..2511664ff671 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3319,7 +3319,7 @@ static struct kvm_x86_ops svm_x86_ops = { static int __init svm_init(void) { return kvm_init(&svm_x86_ops, sizeof(struct vcpu_svm), - THIS_MODULE); + __alignof__(struct vcpu_svm), THIS_MODULE); } static void __exit svm_exit(void) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 875b785228f6..2e8729678600 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -4245,7 +4245,8 @@ static int __init vmx_init(void) set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */ - r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx), THIS_MODULE); + r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx), + __alignof__(struct vcpu_vmx), THIS_MODULE); if (r) goto out3; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ce027d518096..7cb116afa1cd 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -243,7 +243,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu); void vcpu_load(struct kvm_vcpu *vcpu); void vcpu_put(struct kvm_vcpu *vcpu); -int kvm_init(void *opaque, unsigned int vcpu_size, +int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, struct module *module); void kvm_exit(void); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 9ab1a77941ef..f032806a212f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2178,7 +2178,7 @@ static void kvm_sched_out(struct preempt_notifier *pn, kvm_arch_vcpu_put(vcpu); } -int kvm_init(void *opaque, unsigned int vcpu_size, +int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, struct module *module) { int r; @@ -2228,8 +2228,9 @@ int kvm_init(void *opaque, unsigned int vcpu_size, goto out_free_4; /* A kmem cache lets us meet the alignment requirements of fx_save. */ - kvm_vcpu_cache = kmem_cache_create("kvm_vcpu", vcpu_size, - __alignof__(struct kvm_vcpu), + if (!vcpu_align) + vcpu_align = __alignof__(struct kvm_vcpu); + kvm_vcpu_cache = kmem_cache_create("kvm_vcpu", vcpu_size, vcpu_align, 0, NULL); if (!kvm_vcpu_cache) { r = -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 19b95dba0324e55505682a18ff9a437fbf4a2592 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 28 Apr 2010 15:40:31 +0300 Subject: KVM: VMX: Add definition for msr autoload entry Signed-off-by: Avi Kivity --- arch/x86/include/asm/vmx.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index fb9a080740ec..449731890763 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -25,6 +25,8 @@ * */ +#include + /* * Definitions of Primary Processor-Based VM-Execution Controls. */ @@ -394,6 +396,10 @@ enum vmcs_field { #define ASM_VMX_INVEPT ".byte 0x66, 0x0f, 0x38, 0x80, 0x08" #define ASM_VMX_INVVPID ".byte 0x66, 0x0f, 0x38, 0x81, 0x08" - +struct vmx_msr_entry { + u32 index; + u32 reserved; + u64 value; +} __aligned(16); #endif -- cgit v1.2.3-59-g8ed1b From 5dfa3d170e17cbf9e4816a5ba2f5913c31c03e93 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 28 Apr 2010 15:41:03 +0300 Subject: KVM: VMX: Add definitions for guest and host EFER autoswitch vmcs entries Signed-off-by: Avi Kivity --- arch/x86/include/asm/vmx.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 449731890763..9e6779f7cf2d 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -122,6 +122,8 @@ enum vmcs_field { GUEST_IA32_DEBUGCTL_HIGH = 0x00002803, GUEST_IA32_PAT = 0x00002804, GUEST_IA32_PAT_HIGH = 0x00002805, + GUEST_IA32_EFER = 0x00002806, + GUEST_IA32_EFER_HIGH = 0x00002807, GUEST_PDPTR0 = 0x0000280a, GUEST_PDPTR0_HIGH = 0x0000280b, GUEST_PDPTR1 = 0x0000280c, @@ -132,6 +134,8 @@ enum vmcs_field { GUEST_PDPTR3_HIGH = 0x00002811, HOST_IA32_PAT = 0x00002c00, HOST_IA32_PAT_HIGH = 0x00002c01, + HOST_IA32_EFER = 0x00002c02, + HOST_IA32_EFER_HIGH = 0x00002c03, PIN_BASED_VM_EXEC_CONTROL = 0x00004000, CPU_BASED_VM_EXEC_CONTROL = 0x00004002, EXCEPTION_BITMAP = 0x00004004, -- cgit v1.2.3-59-g8ed1b From 61d2ef2ce3e0161bedf5d2867f546a8df77fa9bc Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 28 Apr 2010 16:40:38 +0300 Subject: KVM: VMX: Add facility to atomically switch MSRs on guest entry/exit Some guest msr values cannot be used on the host (for example. EFER.NX=0), so we need to switch them atomically during guest entry or exit. Add a facility to program the vmx msr autoload registers accordingly. Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 2e8729678600..ae22dcf17211 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -98,6 +98,8 @@ module_param(ple_gap, int, S_IRUGO); static int ple_window = KVM_VMX_DEFAULT_PLE_WINDOW; module_param(ple_window, int, S_IRUGO); +#define NR_AUTOLOAD_MSRS 1 + struct vmcs { u32 revision_id; u32 abort; @@ -125,6 +127,11 @@ struct vcpu_vmx { u64 msr_guest_kernel_gs_base; #endif struct vmcs *vmcs; + struct msr_autoload { + unsigned nr; + struct vmx_msr_entry guest[NR_AUTOLOAD_MSRS]; + struct vmx_msr_entry host[NR_AUTOLOAD_MSRS]; + } msr_autoload; struct { int loaded; u16 fs_sel, gs_sel, ldt_sel; @@ -595,6 +602,46 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu) vmcs_write32(EXCEPTION_BITMAP, eb); } +static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr) +{ + unsigned i; + struct msr_autoload *m = &vmx->msr_autoload; + + for (i = 0; i < m->nr; ++i) + if (m->guest[i].index == msr) + break; + + if (i == m->nr) + return; + --m->nr; + m->guest[i] = m->guest[m->nr]; + m->host[i] = m->host[m->nr]; + vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, m->nr); + vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->nr); +} + +static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr, + u64 guest_val, u64 host_val) +{ + unsigned i; + struct msr_autoload *m = &vmx->msr_autoload; + + for (i = 0; i < m->nr; ++i) + if (m->guest[i].index == msr) + break; + + if (i == m->nr) { + ++m->nr; + vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, m->nr); + vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->nr); + } + + m->guest[i].index = msr; + m->guest[i].value = guest_val; + m->host[i].index = msr; + m->host[i].value = host_val; +} + static void reload_tss(void) { /* @@ -2470,7 +2517,9 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */ vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0); vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0); + vmcs_write64(VM_EXIT_MSR_LOAD_ADDR, __pa(vmx->msr_autoload.host)); vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0); + vmcs_write64(VM_ENTRY_MSR_LOAD_ADDR, __pa(vmx->msr_autoload.guest)); rdmsr(MSR_IA32_SYSENTER_CS, host_sysenter_cs, junk); vmcs_write32(HOST_IA32_SYSENTER_CS, host_sysenter_cs); -- cgit v1.2.3-59-g8ed1b From 84ad33ef5dbc12665ad42ee07a2daed473d3ec54 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 28 Apr 2010 16:42:29 +0300 Subject: KVM: VMX: Atomically switch efer if EPT && !EFER.NX When EPT is enabled, we cannot emulate EFER.NX=0 through the shadow page tables. This causes accesses through ptes with bit 63 set to succeed instead of failing a reserved bit check. Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ae22dcf17211..c4f3955c64e0 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -678,6 +678,17 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) guest_efer |= host_efer & ignore_bits; vmx->guest_msrs[efer_offset].data = guest_efer; vmx->guest_msrs[efer_offset].mask = ~ignore_bits; + + clear_atomic_switch_msr(vmx, MSR_EFER); + /* On ept, can't emulate nx, and must switch nx atomically */ + if (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX)) { + guest_efer = vmx->vcpu.arch.efer; + if (!(guest_efer & EFER_LMA)) + guest_efer &= ~EFER_LME; + add_atomic_switch_msr(vmx, MSR_EFER, guest_efer, host_efer); + return false; + } + return true; } @@ -1734,6 +1745,7 @@ static void exit_lmode(struct kvm_vcpu *vcpu) vmcs_write32(VM_ENTRY_CONTROLS, vmcs_read32(VM_ENTRY_CONTROLS) & ~VM_ENTRY_IA32E_MODE); + vmx_set_efer(vcpu, vcpu->arch.efer); } #endif -- cgit v1.2.3-59-g8ed1b From f1d86e469b60f9e1afed5c17a6e723c2c9c55ceb Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Mon, 3 May 2010 23:04:27 -0300 Subject: KVM: x86: properly update ready_for_interrupt_injection The recent changes to emulate string instructions without entering guest mode exposed a bug where pending interrupts are not properly reflected in ready_for_interrupt_injection. The result is that userspace overwrites a previously queued interrupt, when irqchip's are emulated in userspace. Fix by always updating state before returning to userspace. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6b2ce1d2d748..dff08e527ec7 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4653,7 +4653,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) } srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); - post_kvm_run_save(vcpu); vapic_exit(vcpu); @@ -4703,6 +4702,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) r = __vcpu_run(vcpu); out: + post_kvm_run_save(vcpu); if (vcpu->sigset_active) sigprocmask(SIG_SETMASK, &sigsaved, NULL); -- cgit v1.2.3-59-g8ed1b From cafd66595d92591e4bd25c3904e004fc6f897e2d Mon Sep 17 00:00:00 2001 From: Shane Wang Date: Thu, 29 Apr 2010 12:09:01 -0400 Subject: KVM: VMX: enable VMXON check with SMX enabled (Intel TXT) Per document, for feature control MSR: Bit 1 enables VMXON in SMX operation. If the bit is clear, execution of VMXON in SMX operation causes a general-protection exception. Bit 2 enables VMXON outside SMX operation. If the bit is clear, execution of VMXON outside SMX operation causes a general-protection exception. This patch is to enable this kind of check with SMX for VMXON in KVM. Signed-off-by: Shane Wang Signed-off-by: Avi Kivity --- arch/x86/include/asm/msr-index.h | 5 +++-- arch/x86/kernel/tboot.c | 1 + arch/x86/kvm/vmx.c | 32 +++++++++++++++++++++----------- include/linux/tboot.h | 1 + 4 files changed, 26 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index bc473acfa7f9..f9324851eba0 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -202,8 +202,9 @@ #define MSR_IA32_EBL_CR_POWERON 0x0000002a #define MSR_IA32_FEATURE_CONTROL 0x0000003a -#define FEATURE_CONTROL_LOCKED (1<<0) -#define FEATURE_CONTROL_VMXON_ENABLED (1<<2) +#define FEATURE_CONTROL_LOCKED (1<<0) +#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1) +#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) #define MSR_IA32_APICBASE 0x0000001b #define MSR_IA32_APICBASE_BSP (1<<8) diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 86c9f91b48ae..46b827778d16 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c @@ -46,6 +46,7 @@ /* Global pointer to shared data; NULL means no measured launch. */ struct tboot *tboot __read_mostly; +EXPORT_SYMBOL(tboot); /* timeout for APs (in secs) to enter wait-for-SIPI state during shutdown */ #define AP_WAIT_TIMEOUT 1 diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c4f3955c64e0..d2a47aefdee7 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "kvm_cache_regs.h" #include "x86.h" @@ -1272,9 +1273,16 @@ static __init int vmx_disabled_by_bios(void) u64 msr; rdmsrl(MSR_IA32_FEATURE_CONTROL, msr); - return (msr & (FEATURE_CONTROL_LOCKED | - FEATURE_CONTROL_VMXON_ENABLED)) - == FEATURE_CONTROL_LOCKED; + if (msr & FEATURE_CONTROL_LOCKED) { + if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX) + && tboot_enabled()) + return 1; + if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX) + && !tboot_enabled()) + return 1; + } + + return 0; /* locked but not enabled */ } @@ -1282,21 +1290,23 @@ static int hardware_enable(void *garbage) { int cpu = raw_smp_processor_id(); u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); - u64 old; + u64 old, test_bits; if (read_cr4() & X86_CR4_VMXE) return -EBUSY; INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu)); rdmsrl(MSR_IA32_FEATURE_CONTROL, old); - if ((old & (FEATURE_CONTROL_LOCKED | - FEATURE_CONTROL_VMXON_ENABLED)) - != (FEATURE_CONTROL_LOCKED | - FEATURE_CONTROL_VMXON_ENABLED)) + + test_bits = FEATURE_CONTROL_LOCKED; + test_bits |= FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX; + if (tboot_enabled()) + test_bits |= FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX; + + if ((old & test_bits) != test_bits) { /* enable and lock */ - wrmsrl(MSR_IA32_FEATURE_CONTROL, old | - FEATURE_CONTROL_LOCKED | - FEATURE_CONTROL_VMXON_ENABLED); + wrmsrl(MSR_IA32_FEATURE_CONTROL, old | test_bits); + } write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */ asm volatile (ASM_VMX_VMXON_RAX : : "a"(&phys_addr), "m"(phys_addr) diff --git a/include/linux/tboot.h b/include/linux/tboot.h index bf2a0c748878..1dba6ee55203 100644 --- a/include/linux/tboot.h +++ b/include/linux/tboot.h @@ -150,6 +150,7 @@ extern int tboot_force_iommu(void); #else +#define tboot_enabled() 0 #define tboot_probe() do { } while (0) #define tboot_shutdown(shutdown_type) do { } while (0) #define tboot_sleep(sleep_state, pm1a_control, pm1b_control) \ -- cgit v1.2.3-59-g8ed1b From 8facbbff071ff2b19268d3732e31badc60471e21 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 4 May 2010 12:58:32 +0300 Subject: KVM: MMU: Don't read pdptrs with mmu spinlock held in mmu_alloc_roots On svm, kvm_read_pdptr() may require reading guest memory, which can sleep. Push the spinlock into mmu_alloc_roots(), and only take it after we've read the pdptr. Tested-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 51eb6d6abd86..de996380ec26 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2065,11 +2065,13 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu) direct = 1; root_gfn = 0; } + spin_lock(&vcpu->kvm->mmu_lock); sp = kvm_mmu_get_page(vcpu, root_gfn, 0, PT64_ROOT_LEVEL, direct, ACC_ALL, NULL); root = __pa(sp->spt); ++sp->root_count; + spin_unlock(&vcpu->kvm->mmu_lock); vcpu->arch.mmu.root_hpa = root; return 0; } @@ -2093,11 +2095,14 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu) direct = 1; root_gfn = i << 30; } + spin_lock(&vcpu->kvm->mmu_lock); sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, PT32_ROOT_LEVEL, direct, ACC_ALL, NULL); root = __pa(sp->spt); ++sp->root_count; + spin_unlock(&vcpu->kvm->mmu_lock); + vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK; } vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root); @@ -2466,7 +2471,9 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu) goto out; spin_lock(&vcpu->kvm->mmu_lock); kvm_mmu_free_some_pages(vcpu); + spin_unlock(&vcpu->kvm->mmu_lock); r = mmu_alloc_roots(vcpu); + spin_lock(&vcpu->kvm->mmu_lock); mmu_sync_roots(vcpu); spin_unlock(&vcpu->kvm->mmu_lock); if (r) -- cgit v1.2.3-59-g8ed1b From 9ed3c444ab8987c7b219173a2f7807e3f71e234e Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 4 May 2010 15:00:37 +0300 Subject: KVM: Fix wallclock version writing race Wallclock writing uses an unprotected global variable to hold the version; this can cause one guest to interfere with another if both write their wallclock at the same time. Acked-by: Glauber Costa Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index dff08e527ec7..54f73b6a006b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -754,14 +754,22 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) { - static int version; + int version; + int r; struct pvclock_wall_clock wc; struct timespec boot; if (!wall_clock) return; - version++; + r = kvm_read_guest(kvm, wall_clock, &version, sizeof(version)); + if (r) + return; + + if (version & 1) + ++version; /* first time write, random junk */ + + ++version; kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); -- cgit v1.2.3-59-g8ed1b From 3f0fd2927b737c0ac2e04af7858b60d1e927d4b1 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 5 May 2010 16:04:41 +0200 Subject: KVM: x86: Fix exception reinjection forced to true The patch merged recently which allowed to mark an exception as reinjected has a bug as it always marks the exception as reinjected. This breaks nested-svm shadow-on-shadow implementation. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 54f73b6a006b..161ede2b5f91 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -277,7 +277,7 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, vcpu->arch.exception.has_error_code = has_error; vcpu->arch.exception.nr = nr; vcpu->arch.exception.error_code = error_code; - vcpu->arch.exception.reinject = true; + vcpu->arch.exception.reinject = reinject; return; } -- cgit v1.2.3-59-g8ed1b From 0d945bd9351199744c1e89d57a70615b6ee9f394 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 5 May 2010 16:04:45 +0200 Subject: KVM: SVM: Don't allow nested guest to VMMCALL into host This patch disables the possibility for a l2-guest to do a VMMCALL directly into the host. This would happen if the l1-hypervisor doesn't intercept VMMCALL and the l2-guest executes this instruction. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/svm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 2511664ff671..4a66ffe1dc87 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2036,6 +2036,9 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK; } + /* We don't want to see VMMCALLs from a nested guest */ + svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMMCALL); + /* * We don't want a nested guest to be more powerful than the guest, so * all intercepts are ORed -- cgit v1.2.3-59-g8ed1b From b69e8caef5b190af48c525f6d715e7b7728a77f6 Mon Sep 17 00:00:00 2001 From: "Roedel, Joerg" Date: Thu, 6 May 2010 11:38:43 +0200 Subject: KVM: x86: Inject #GP with the right rip on efer writes This patch fixes a bug in the KVM efer-msr write path. If a guest writes to a reserved efer bit the set_efer function injects the #GP directly. The architecture dependent wrmsr function does not see this, assumes success and advances the rip. This results in a #GP in the guest with the wrong rip. This patch fixes this by reporting efer write errors back to the architectural wrmsr function. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 161ede2b5f91..fe6d126633d8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -683,37 +683,29 @@ static u32 emulated_msrs[] = { MSR_IA32_MISC_ENABLE, }; -static void set_efer(struct kvm_vcpu *vcpu, u64 efer) +static int set_efer(struct kvm_vcpu *vcpu, u64 efer) { - if (efer & efer_reserved_bits) { - kvm_inject_gp(vcpu, 0); - return; - } + if (efer & efer_reserved_bits) + return 1; if (is_paging(vcpu) - && (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME)) { - kvm_inject_gp(vcpu, 0); - return; - } + && (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME)) + return 1; if (efer & EFER_FFXSR) { struct kvm_cpuid_entry2 *feat; feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0); - if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) { - kvm_inject_gp(vcpu, 0); - return; - } + if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) + return 1; } if (efer & EFER_SVME) { struct kvm_cpuid_entry2 *feat; feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0); - if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) { - kvm_inject_gp(vcpu, 0); - return; - } + if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) + return 1; } kvm_x86_ops->set_efer(vcpu, efer); @@ -725,6 +717,8 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer) vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled; kvm_mmu_reset_context(vcpu); + + return 0; } void kvm_enable_efer_bits(u64 mask) @@ -1153,8 +1147,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) { switch (msr) { case MSR_EFER: - set_efer(vcpu, data); - break; + return set_efer(vcpu, data); case MSR_K7_HWCR: data &= ~(u64)0x40; /* ignore flush filter disable */ data &= ~(u64)0x100; /* ignore ignne emulation enable */ -- cgit v1.2.3-59-g8ed1b From 424c32f1aa3112632a657d45698c8e7666668f78 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 11 May 2010 12:17:39 -0400 Subject: x86, paravirt: Enable pvclock flags in vcpu_time_info structure This patch removes one padding byte and transform it into a flags field. New versions of guests using pvclock will query these flags upon each read. Flags, however, will only be interpreted when the guest decides to. It uses the pvclock_valid_flags function to signal that a specific set of flags should be taken into consideration. Which flags are valid are usually devised via HV negotiation. Signed-off-by: Glauber Costa CC: Jeremy Fitzhardinge Acked-by: Zachary Amsden Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/pvclock-abi.h | 3 ++- arch/x86/include/asm/pvclock.h | 1 + arch/x86/kernel/pvclock.c | 9 +++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/pvclock-abi.h b/arch/x86/include/asm/pvclock-abi.h index 6d93508f2626..ec5c41ac4bef 100644 --- a/arch/x86/include/asm/pvclock-abi.h +++ b/arch/x86/include/asm/pvclock-abi.h @@ -29,7 +29,8 @@ struct pvclock_vcpu_time_info { u64 system_time; u32 tsc_to_system_mul; s8 tsc_shift; - u8 pad[3]; + u8 flags; + u8 pad[2]; } __attribute__((__packed__)); /* 32 bytes */ struct pvclock_wall_clock { diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index 53235fd5f8ce..cd02f324aa6b 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h @@ -6,6 +6,7 @@ /* some helper functions for xen and kvm pv clock sources */ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src); +void pvclock_set_flags(u8 flags); unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src); void pvclock_read_wallclock(struct pvclock_wall_clock *wall, struct pvclock_vcpu_time_info *vcpu, diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 03801f2f761f..f7fdd56bc0ab 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -31,8 +31,16 @@ struct pvclock_shadow_time { u32 tsc_to_nsec_mul; int tsc_shift; u32 version; + u8 flags; }; +static u8 valid_flags __read_mostly = 0; + +void pvclock_set_flags(u8 flags) +{ + valid_flags = flags; +} + /* * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, * yielding a 64-bit result. @@ -91,6 +99,7 @@ static unsigned pvclock_get_time_values(struct pvclock_shadow_time *dst, dst->system_timestamp = src->system_time; dst->tsc_to_nsec_mul = src->tsc_to_system_mul; dst->tsc_shift = src->tsc_shift; + dst->flags = src->flags; rmb(); /* test version after fetching data */ } while ((src->version & 1) || (dst->version != src->version)); -- cgit v1.2.3-59-g8ed1b From 489fb490dbf8dab0249ad82b56688ae3842a79e8 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 11 May 2010 12:17:40 -0400 Subject: x86, paravirt: Add a global synchronization point for pvclock In recent stress tests, it was found that pvclock-based systems could seriously warp in smp systems. Using ingo's time-warp-test.c, I could trigger a scenario as bad as 1.5mi warps a minute in some systems. (to be fair, it wasn't that bad in most of them). Investigating further, I found out that such warps were caused by the very offset-based calculation pvclock is based on. This happens even on some machines that report constant_tsc in its tsc flags, specially on multi-socket ones. Two reads of the same kernel timestamp at approx the same time, will likely have tsc timestamped in different occasions too. This means the delta we calculate is unpredictable at best, and can probably be smaller in a cpu that is legitimately reading clock in a forward ocasion. Some adjustments on the host could make this window less likely to happen, but still, it pretty much poses as an intrinsic problem of the mechanism. A while ago, I though about using a shared variable anyway, to hold clock last state, but gave up due to the high contention locking was likely to introduce, possibly rendering the thing useless on big machines. I argue, however, that locking is not necessary. We do a read-and-return sequence in pvclock, and between read and return, the global value can have changed. However, it can only have changed by means of an addition of a positive value. So if we detected that our clock timestamp is less than the current global, we know that we need to return a higher one, even though it is not exactly the one we compared to. OTOH, if we detect we're greater than the current time source, we atomically replace the value with our new readings. This do causes contention on big boxes (but big here means *BIG*), but it seems like a good trade off, since it provide us with a time source guaranteed to be stable wrt time warps. After this patch is applied, I don't see a single warp in time during 5 days of execution, in any of the machines I saw them before. Signed-off-by: Glauber Costa Acked-by: Zachary Amsden CC: Jeremy Fitzhardinge CC: Avi Kivity CC: Marcelo Tosatti CC: Zachary Amsden Signed-off-by: Marcelo Tosatti --- arch/x86/kernel/pvclock.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index f7fdd56bc0ab..f5bc40e1697e 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -118,11 +118,14 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src) return pv_tsc_khz; } +static atomic64_t last_value = ATOMIC64_INIT(0); + cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) { struct pvclock_shadow_time shadow; unsigned version; cycle_t ret, offset; + u64 last; do { version = pvclock_get_time_values(&shadow, src); @@ -132,6 +135,27 @@ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) barrier(); } while (version != src->version); + /* + * Assumption here is that last_value, a global accumulator, always goes + * forward. If we are less than that, we should not be much smaller. + * We assume there is an error marging we're inside, and then the correction + * does not sacrifice accuracy. + * + * For reads: global may have changed between test and return, + * but this means someone else updated poked the clock at a later time. + * We just need to make sure we are not seeing a backwards event. + * + * For updates: last_value = ret is not enough, since two vcpus could be + * updating at the same time, and one of them could be slightly behind, + * making the assumption that last_value always go forward fail to hold. + */ + last = atomic64_read(&last_value); + do { + if (ret < last) + return last; + last = atomic64_cmpxchg(&last_value, last, ret); + } while (unlikely(last != ret)); + return ret; } -- cgit v1.2.3-59-g8ed1b From 11c6bffa42b85e703c21a1d2372dce7262daca8e Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 11 May 2010 12:17:41 -0400 Subject: KVM: x86: change msr numbers for kvmclock Avi pointed out a while ago that those MSRs falls into the pentium PMU range. So the idea here is to add new ones, and after a while, deprecate the old ones. Signed-off-by: Glauber Costa Acked-by: Zachary Amsden Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_para.h | 4 ++++ arch/x86/kvm/x86.c | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index ffae1420e7d7..97348082782a 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -20,6 +20,10 @@ #define MSR_KVM_WALL_CLOCK 0x11 #define MSR_KVM_SYSTEM_TIME 0x12 +/* Custom MSRs falls in the range 0x4b564d00-0x4b564dff */ +#define MSR_KVM_WALL_CLOCK_NEW 0x4b564d00 +#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01 + #define KVM_MAX_MMU_OP_BATCH 32 /* Operations for KVM_HC_MMU_OP */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fe6d126633d8..73d342c69ed4 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -664,9 +664,10 @@ static inline u32 bit(int bitno) * kvm-specific. Those are put in the beginning of the list. */ -#define KVM_SAVE_MSRS_BEGIN 5 +#define KVM_SAVE_MSRS_BEGIN 7 static u32 msrs_to_save[] = { MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, + MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, HV_X64_MSR_APIC_ASSIST_PAGE, MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, @@ -1193,10 +1194,12 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) case MSR_IA32_MISC_ENABLE: vcpu->arch.ia32_misc_enable_msr = data; break; + case MSR_KVM_WALL_CLOCK_NEW: case MSR_KVM_WALL_CLOCK: vcpu->kvm->arch.wall_clock = data; kvm_write_wall_clock(vcpu->kvm, data); break; + case MSR_KVM_SYSTEM_TIME_NEW: case MSR_KVM_SYSTEM_TIME: { if (vcpu->arch.time_page) { kvm_release_page_dirty(vcpu->arch.time_page); @@ -1468,9 +1471,11 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) data = vcpu->arch.efer; break; case MSR_KVM_WALL_CLOCK: + case MSR_KVM_WALL_CLOCK_NEW: data = vcpu->kvm->arch.wall_clock; break; case MSR_KVM_SYSTEM_TIME: + case MSR_KVM_SYSTEM_TIME_NEW: data = vcpu->arch.time; break; case MSR_IA32_P5_MC_ADDR: -- cgit v1.2.3-59-g8ed1b From 0e6ac58acbcddbc9d1687214f0d43d8657cc036c Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 11 May 2010 12:17:42 -0400 Subject: KVM: x86: add new KVMCLOCK cpuid feature This cpuid, KVM_CPUID_CLOCKSOURCE2, will indicate to the guest that kvmclock is available through a new set of MSRs. The old ones are deprecated. Signed-off-by: Glauber Costa Acked-by: Zachary Amsden Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_para.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 97348082782a..f019f8cb182e 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -16,6 +16,10 @@ #define KVM_FEATURE_CLOCKSOURCE 0 #define KVM_FEATURE_NOP_IO_DELAY 1 #define KVM_FEATURE_MMU_OP 2 +/* This indicates that the new set of kvmclock msrs + * are available. The use of 0x11 and 0x12 is deprecated + */ +#define KVM_FEATURE_CLOCKSOURCE2 3 #define MSR_KVM_WALL_CLOCK 0x11 #define MSR_KVM_SYSTEM_TIME 0x12 -- cgit v1.2.3-59-g8ed1b From 84478c829d0f474a1d6749207c53daacc305d4e1 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 11 May 2010 12:17:43 -0400 Subject: KVM: x86: export paravirtual cpuid flags in KVM_GET_SUPPORTED_CPUID Right now, we were using individual KVM_CAP entities to communicate userspace about which cpuids we support. This is suboptimal, since it generates a delay between the feature arriving in the host, and being available at the guest. A much better mechanism is to list para features in KVM_GET_SUPPORTED_CPUID. This makes userspace automatically aware of what we provide. And if we ever add a new cpuid bit in the future, we have to do that again, which create some complexity and delay in feature adoption. Signed-off-by: Glauber Costa Acked-by: Zachary Amsden Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 73d342c69ed4..419c4512e270 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1972,6 +1972,23 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, } break; } + case KVM_CPUID_SIGNATURE: { + char signature[12] = "KVMKVMKVM\0\0"; + u32 *sigptr = (u32 *)signature; + entry->eax = 0; + entry->ebx = sigptr[0]; + entry->ecx = sigptr[1]; + entry->edx = sigptr[2]; + break; + } + case KVM_CPUID_FEATURES: + entry->eax = (1 << KVM_FEATURE_CLOCKSOURCE) | + (1 << KVM_FEATURE_NOP_IO_DELAY) | + (1 << KVM_FEATURE_CLOCKSOURCE2); + entry->ebx = 0; + entry->ecx = 0; + entry->edx = 0; + break; case 0x80000000: entry->eax = min(entry->eax, 0x8000001a); break; @@ -2018,6 +2035,23 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func) do_cpuid_ent(&cpuid_entries[nent], func, 0, &nent, cpuid->nent); + + + + r = -E2BIG; + if (nent >= cpuid->nent) + goto out_free; + + do_cpuid_ent(&cpuid_entries[nent], KVM_CPUID_SIGNATURE, 0, &nent, + cpuid->nent); + + r = -E2BIG; + if (nent >= cpuid->nent) + goto out_free; + + do_cpuid_ent(&cpuid_entries[nent], KVM_CPUID_FEATURES, 0, &nent, + cpuid->nent); + r = -E2BIG; if (nent >= cpuid->nent) goto out_free; -- cgit v1.2.3-59-g8ed1b From 838815a78785022f6611e5c48386567aea7b818b Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 11 May 2010 12:17:44 -0400 Subject: x86: KVM guest: Try using new kvm clock msrs We now added a new set of clock-related msrs in replacement of the old ones. In theory, we could just try to use them and get a return value indicating they do not exist, due to our use of kvm_write_msr_save. However, kvm clock registration happens very early, and if we ever try to write to a non-existant MSR, we raise a lethal #GP, since our idt handlers are not in place yet. So this patch tests for a cpuid feature exported by the host to decide which set of msrs are supported. Signed-off-by: Glauber Costa Acked-by: Zachary Amsden Signed-off-by: Marcelo Tosatti --- arch/x86/kernel/kvmclock.c | 53 ++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index feaeb0d3aa4f..59c740fcb9b3 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -29,6 +29,8 @@ #define KVM_SCALE 22 static int kvmclock = 1; +static int msr_kvm_system_time = MSR_KVM_SYSTEM_TIME; +static int msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK; static int parse_no_kvmclock(char *arg) { @@ -54,7 +56,8 @@ static unsigned long kvm_get_wallclock(void) low = (int)__pa_symbol(&wall_clock); high = ((u64)__pa_symbol(&wall_clock) >> 32); - native_write_msr(MSR_KVM_WALL_CLOCK, low, high); + + native_write_msr(msr_kvm_wall_clock, low, high); vcpu_time = &get_cpu_var(hv_clock); pvclock_read_wallclock(&wall_clock, vcpu_time, &ts); @@ -130,7 +133,8 @@ static int kvm_register_clock(char *txt) high = ((u64)__pa(&per_cpu(hv_clock, cpu)) >> 32); printk(KERN_INFO "kvm-clock: cpu %d, msr %x:%x, %s\n", cpu, high, low, txt); - return native_write_msr_safe(MSR_KVM_SYSTEM_TIME, low, high); + + return native_write_msr_safe(msr_kvm_system_time, low, high); } #ifdef CONFIG_X86_LOCAL_APIC @@ -165,14 +169,14 @@ static void __init kvm_smp_prepare_boot_cpu(void) #ifdef CONFIG_KEXEC static void kvm_crash_shutdown(struct pt_regs *regs) { - native_write_msr_safe(MSR_KVM_SYSTEM_TIME, 0, 0); + native_write_msr(msr_kvm_system_time, 0, 0); native_machine_crash_shutdown(regs); } #endif static void kvm_shutdown(void) { - native_write_msr_safe(MSR_KVM_SYSTEM_TIME, 0, 0); + native_write_msr(msr_kvm_system_time, 0, 0); native_machine_shutdown(); } @@ -181,27 +185,34 @@ void __init kvmclock_init(void) if (!kvm_para_available()) return; - if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { - if (kvm_register_clock("boot clock")) - return; - pv_time_ops.sched_clock = kvm_clock_read; - x86_platform.calibrate_tsc = kvm_get_tsc_khz; - x86_platform.get_wallclock = kvm_get_wallclock; - x86_platform.set_wallclock = kvm_set_wallclock; + if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE2)) { + msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW; + msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW; + } else if (!(kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE))) + return; + + printk(KERN_INFO "kvm-clock: Using msrs %x and %x", + msr_kvm_system_time, msr_kvm_wall_clock); + + if (kvm_register_clock("boot clock")) + return; + pv_time_ops.sched_clock = kvm_clock_read; + x86_platform.calibrate_tsc = kvm_get_tsc_khz; + x86_platform.get_wallclock = kvm_get_wallclock; + x86_platform.set_wallclock = kvm_set_wallclock; #ifdef CONFIG_X86_LOCAL_APIC - x86_cpuinit.setup_percpu_clockev = - kvm_setup_secondary_clock; + x86_cpuinit.setup_percpu_clockev = + kvm_setup_secondary_clock; #endif #ifdef CONFIG_SMP - smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; + smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; #endif - machine_ops.shutdown = kvm_shutdown; + machine_ops.shutdown = kvm_shutdown; #ifdef CONFIG_KEXEC - machine_ops.crash_shutdown = kvm_crash_shutdown; + machine_ops.crash_shutdown = kvm_crash_shutdown; #endif - kvm_get_preset_lpj(); - clocksource_register(&kvm_clock); - pv_info.paravirt_enabled = 1; - pv_info.name = "KVM"; - } + kvm_get_preset_lpj(); + clocksource_register(&kvm_clock); + pv_info.paravirt_enabled = 1; + pv_info.name = "KVM"; } -- cgit v1.2.3-59-g8ed1b From 3a0d7256a6fb8c13f9fac6cd63250f97a8f0d8de Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 11 May 2010 12:17:45 -0400 Subject: x86, paravirt: don't compute pvclock adjustments if we trust the tsc If the HV told us we can fully trust the TSC, skip any correction Signed-off-by: Glauber Costa Acked-by: Zachary Amsden Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_para.h | 5 +++++ arch/x86/include/asm/pvclock-abi.h | 1 + arch/x86/kernel/kvmclock.c | 3 +++ arch/x86/kernel/pvclock.c | 4 ++++ 4 files changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index f019f8cb182e..05eba5e9a8e8 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -21,6 +21,11 @@ */ #define KVM_FEATURE_CLOCKSOURCE2 3 +/* The last 8 bits are used to indicate how to interpret the flags field + * in pvclock structure. If no bits are set, all flags are ignored. + */ +#define KVM_FEATURE_CLOCKSOURCE_STABLE_BIT 24 + #define MSR_KVM_WALL_CLOCK 0x11 #define MSR_KVM_SYSTEM_TIME 0x12 diff --git a/arch/x86/include/asm/pvclock-abi.h b/arch/x86/include/asm/pvclock-abi.h index ec5c41ac4bef..35f2d1948ada 100644 --- a/arch/x86/include/asm/pvclock-abi.h +++ b/arch/x86/include/asm/pvclock-abi.h @@ -39,5 +39,6 @@ struct pvclock_wall_clock { u32 nsec; } __attribute__((__packed__)); +#define PVCLOCK_TSC_STABLE_BIT (1 << 0) #endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_PVCLOCK_ABI_H */ diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 59c740fcb9b3..eb9b76c716c2 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -215,4 +215,7 @@ void __init kvmclock_init(void) clocksource_register(&kvm_clock); pv_info.paravirt_enabled = 1; pv_info.name = "KVM"; + + if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)) + pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT); } diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index f5bc40e1697e..239427ca02af 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -135,6 +135,10 @@ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) barrier(); } while (version != src->version); + if ((valid_flags & PVCLOCK_TSC_STABLE_BIT) && + (shadow.flags & PVCLOCK_TSC_STABLE_BIT)) + return ret; + /* * Assumption here is that last_value, a global accumulator, always goes * forward. If we are less than that, we should not be much smaller. -- cgit v1.2.3-59-g8ed1b From 371bcf646d170ee1325abaf4f3e73485b4fd4d2d Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 11 May 2010 12:17:46 -0400 Subject: KVM: x86: Tell the guest we'll warn it about tsc stability This patch puts up the flag that tells the guest that we'll warn it about the tsc being trustworthy or not. By now, we also say it is not. Signed-off-by: Glauber Costa Acked-by: Zachary Amsden Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 419c4512e270..474a27fc42df 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -857,6 +857,8 @@ static void kvm_write_guest_time(struct kvm_vcpu *v) vcpu->hv_clock.system_time = ts.tv_nsec + (NSEC_PER_SEC * (u64)ts.tv_sec) + v->kvm->arch.kvmclock_offset; + vcpu->hv_clock.flags = 0; + /* * The interface expects us to write an even number signaling that the * update is finished. Since the guest won't see the intermediate @@ -1984,7 +1986,8 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, case KVM_CPUID_FEATURES: entry->eax = (1 << KVM_FEATURE_CLOCKSOURCE) | (1 << KVM_FEATURE_NOP_IO_DELAY) | - (1 << KVM_FEATURE_CLOCKSOURCE2); + (1 << KVM_FEATURE_CLOCKSOURCE2) | + (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT); entry->ebx = 0; entry->ecx = 0; entry->edx = 0; -- cgit v1.2.3-59-g8ed1b From f78e917688edbf1f14c318d2e50dc8e7dad20445 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 12 May 2010 00:28:44 +0300 Subject: KVM: Don't allow lmsw to clear cr0.pe The current lmsw implementation allows the guest to clear cr0.pe, contrary to the manual, which breaks EMM386.EXE. Fix by ORing the old cr0.pe with lmsw's operand. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 474a27fc42df..fa1c51925597 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -470,7 +470,7 @@ EXPORT_SYMBOL_GPL(kvm_set_cr0); void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) { - kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0ful) | (msw & 0x0f)); + kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0eul) | (msw & 0x0f)); } EXPORT_SYMBOL_GPL(kvm_lmsw); -- cgit v1.2.3-59-g8ed1b From a3d204e28579427609c3d15d2310127ebaa47d94 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Wed, 12 May 2010 16:40:40 +0800 Subject: KVM: x86: Check LMA bit before set_efer kvm_x86_ops->set_efer() would execute vcpu->arch.efer = efer, so the checking of LMA bit didn't work. Signed-off-by: Sheng Yang Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fa1c51925597..f0846d2aa956 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -709,11 +709,11 @@ static int set_efer(struct kvm_vcpu *vcpu, u64 efer) return 1; } - kvm_x86_ops->set_efer(vcpu, efer); - efer &= ~EFER_LMA; efer |= vcpu->arch.efer & EFER_LMA; + kvm_x86_ops->set_efer(vcpu, efer); + vcpu->arch.efer = efer; vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled; -- cgit v1.2.3-59-g8ed1b From 3dbe141595faa48a067add3e47bba3205b79d33c Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 12 May 2010 11:48:18 +0300 Subject: KVM: MMU: Segregate shadow pages with different cr0.wp When cr0.wp=0, we may shadow a gpte having u/s=1 and r/w=0 with an spte having u/s=0 and r/w=1. This allows excessive access if the guest sets cr0.wp=1 and accesses through this spte. Fix by making cr0.wp part of the base role; we'll have different sptes for the two cases and the problem disappears. Signed-off-by: Avi Kivity Signed-off-by: Marcelo Tosatti --- Documentation/kvm/mmu.txt | 2 ++ arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/mmu.c | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/Documentation/kvm/mmu.txt b/Documentation/kvm/mmu.txt index 0cc28fb84f4f..aaed6ab9d7ab 100644 --- a/Documentation/kvm/mmu.txt +++ b/Documentation/kvm/mmu.txt @@ -163,6 +163,8 @@ Shadow pages contain the following information: 32-bit or 64-bit gptes are in use). role.cr4_nxe: Contains the value of efer.nxe for which the page is valid. + role.cr0_wp: + Contains the value of cr0.wp for which the page is valid. gfn: Either the guest page table containing the translations shadowed by this page, or the base page frame for linear translations. See role.direct. diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 3f0007b076da..76f5483cffec 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -179,6 +179,7 @@ union kvm_mmu_page_role { unsigned access:3; unsigned invalid:1; unsigned nxe:1; + unsigned cr0_wp:1; }; }; diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index de996380ec26..81563e76e28f 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -217,7 +217,7 @@ void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, } EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes); -static int is_write_protection(struct kvm_vcpu *vcpu) +static bool is_write_protection(struct kvm_vcpu *vcpu) { return kvm_read_cr0_bits(vcpu, X86_CR0_WP); } @@ -2432,6 +2432,7 @@ static int init_kvm_softmmu(struct kvm_vcpu *vcpu) r = paging32_init_context(vcpu); vcpu->arch.mmu.base_role.cr4_pae = !!is_pae(vcpu); + vcpu->arch.mmu.base_role.cr0_wp = is_write_protection(vcpu); return r; } -- cgit v1.2.3-59-g8ed1b From 98001d8d017cea1ee0f9f35c6227bbd63ef5005b Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 13 May 2010 11:05:49 +0300 Subject: KVM: PPC: Add missing vcpu_load()/vcpu_put() in vcpu ioctls Signed-off-by: Avi Kivity --- arch/powerpc/kvm/book3s.c | 10 ++++++++++ arch/powerpc/kvm/booke.c | 15 ++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 11f226ff4468..b998abf1a63d 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -1110,6 +1110,8 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); int i; + vcpu_load(vcpu); + sregs->pvr = vcpu->arch.pvr; sregs->u.s.sdr1 = to_book3s(vcpu)->sdr1; @@ -1128,6 +1130,9 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, sregs->u.s.ppc32.dbat[i] = vcpu3s->dbat[i].raw; } } + + vcpu_put(vcpu); + return 0; } @@ -1137,6 +1142,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); int i; + vcpu_load(vcpu); + kvmppc_set_pvr(vcpu, sregs->pvr); vcpu3s->sdr1 = sregs->u.s.sdr1; @@ -1163,6 +1170,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, /* Flush the MMU after messing with the segments */ kvmppc_mmu_pte_flush(vcpu, 0, 0); + + vcpu_put(vcpu); + return 0; } diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index c92224071021..a33ab8cc2ccc 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -485,6 +485,8 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) { int i; + vcpu_load(vcpu); + regs->pc = vcpu->arch.pc; regs->cr = kvmppc_get_cr(vcpu); regs->ctr = vcpu->arch.ctr; @@ -505,6 +507,8 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) regs->gpr[i] = kvmppc_get_gpr(vcpu, i); + vcpu_put(vcpu); + return 0; } @@ -512,6 +516,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) { int i; + vcpu_load(vcpu); + vcpu->arch.pc = regs->pc; kvmppc_set_cr(vcpu, regs->cr); vcpu->arch.ctr = regs->ctr; @@ -531,6 +537,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) kvmppc_set_gpr(vcpu, i, regs->gpr[i]); + vcpu_put(vcpu); + return 0; } @@ -559,7 +567,12 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, struct kvm_translation *tr) { - return kvmppc_core_vcpu_translate(vcpu, tr); + int r; + + vcpu_load(vcpu); + r = kvmppc_core_vcpu_translate(vcpu, tr); + vcpu_put(vcpu); + return r; } int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) -- cgit v1.2.3-59-g8ed1b From 8fbf065d625617bbbf6b72d5f78f84ad13c8b547 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 13 May 2010 11:50:19 +0300 Subject: KVM: x86: Add missing locking to arch specific vcpu ioctls Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f0846d2aa956..39f495802050 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1833,6 +1833,7 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, { int r; + vcpu_load(vcpu); r = -E2BIG; if (cpuid->nent < vcpu->arch.cpuid_nent) goto out; @@ -1844,6 +1845,7 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, out: cpuid->nent = vcpu->arch.cpuid_nent; + vcpu_put(vcpu); return r; } @@ -2134,6 +2136,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu, int r; unsigned bank_num = mcg_cap & 0xff, bank; + vcpu_load(vcpu); r = -EINVAL; if (!bank_num || bank_num >= KVM_MAX_MCE_BANKS) goto out; @@ -2148,6 +2151,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu, for (bank = 0; bank < bank_num; bank++) vcpu->arch.mce_banks[bank*4] = ~(u64)0; out: + vcpu_put(vcpu); return r; } @@ -2456,7 +2460,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&mce, argp, sizeof mce)) goto out; + vcpu_load(vcpu); r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce); + vcpu_put(vcpu); break; } case KVM_GET_VCPU_EVENTS: { -- cgit v1.2.3-59-g8ed1b From 1131379b48228afb32fa626fb27586a02246acf9 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 14 May 2010 08:18:52 +0200 Subject: ARM: SAMSUNGy: fix broken timer irq base Timer interrupts range was defined as 43-47, what overlaps with VIC0 range (32-64). This was caused probably by a typo while the common interrupts definition was refactored. This patch moves timer interrupt range to safe area of 11-15 (just before uart range). This fixes the commit 87aef30eb3c5dac0491c83fe3b90bc61f1df24ec ("ARM: S5P: Change S5P_TIMER_IRQ based to 11 for SAMSUNG S5P series.") which meant to move these into the old (and previously reserved) ISA space. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park [ben-linux@fluff.org: update description] Signed-off-by: Ben Dooks --- arch/arm/plat-s5p/include/plat/irqs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h index 42e757f2e40c..9ff3d718be39 100644 --- a/arch/arm/plat-s5p/include/plat/irqs.h +++ b/arch/arm/plat-s5p/include/plat/irqs.h @@ -79,7 +79,7 @@ #define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x)) #define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x)) -#define S5P_TIMER_IRQ(x) S5P_IRQ(11 + (x)) +#define S5P_TIMER_IRQ(x) (11 + (x)) #define IRQ_TIMER0 S5P_TIMER_IRQ(0) #define IRQ_TIMER1 S5P_TIMER_IRQ(1) -- cgit v1.2.3-59-g8ed1b From ea5f50706385b61c1c0d24271bbe7c6e93129fbc Mon Sep 17 00:00:00 2001 From: Pannaga Bhushan Date: Wed, 19 May 2010 17:25:32 +0900 Subject: ARM: S5PV210: Add GPIOlib support This patch adds GPIOlib support for S5PV210. Signed-off-by: Pannaga Bhushan Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pv210/Makefile | 2 +- arch/arm/mach-s5pv210/gpiolib.c | 261 ++++++++++++++++++++++++++++++ arch/arm/mach-s5pv210/include/mach/gpio.h | 18 ++- 3 files changed, 277 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-s5pv210/gpiolib.c (limited to 'arch') diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 8ebf51c52a01..0acbdb34b560 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -12,7 +12,7 @@ obj- := # Core support for S5PV210 system -obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o +obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o gpiolib.o # machine support diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c new file mode 100644 index 000000000000..9ea8972e023d --- /dev/null +++ b/arch/arm/mach-s5pv210/gpiolib.c @@ -0,0 +1,261 @@ +/* linux/arch/arm/mach-s5pv210/gpiolib.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5PV210 - GPIOlib support + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +static struct s3c_gpio_cfg gpio_cfg = { + .set_config = s3c_gpio_setcfg_s3c64xx_4bit, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + +static struct s3c_gpio_cfg gpio_cfg_noint = { + .set_config = s3c_gpio_setcfg_s3c64xx_4bit, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + +/* GPIO bank's base address given the index of the bank in the + * list of all gpio banks. + */ +#define S5PV210_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20)) + +/* + * Following are the gpio banks in v210. + * + * The 'config' member when left to NULL, is initialized to the default + * structure gpio_cfg in the init function below. + * + * The 'base' member is also initialized in the init function below. + * Note: The initialization of 'base' member of s3c_gpio_chip structure + * uses the above macro and depends on the banks being listed in order here. + */ +static struct s3c_gpio_chip s5pv210_gpio_4bit[] = { + { + .chip = { + .base = S5PV210_GPA0(0), + .ngpio = S5PV210_GPIO_A0_NR, + .label = "GPA0", + }, + }, { + .chip = { + .base = S5PV210_GPA1(0), + .ngpio = S5PV210_GPIO_A1_NR, + .label = "GPA1", + }, + }, { + .chip = { + .base = S5PV210_GPB(0), + .ngpio = S5PV210_GPIO_B_NR, + .label = "GPB", + }, + }, { + .chip = { + .base = S5PV210_GPC0(0), + .ngpio = S5PV210_GPIO_C0_NR, + .label = "GPC0", + }, + }, { + .chip = { + .base = S5PV210_GPC1(0), + .ngpio = S5PV210_GPIO_C1_NR, + .label = "GPC1", + }, + }, { + .chip = { + .base = S5PV210_GPD0(0), + .ngpio = S5PV210_GPIO_D0_NR, + .label = "GPD0", + }, + }, { + .chip = { + .base = S5PV210_GPD1(0), + .ngpio = S5PV210_GPIO_D1_NR, + .label = "GPD1", + }, + }, { + .chip = { + .base = S5PV210_GPE0(0), + .ngpio = S5PV210_GPIO_E0_NR, + .label = "GPE0", + }, + }, { + .chip = { + .base = S5PV210_GPE1(0), + .ngpio = S5PV210_GPIO_E1_NR, + .label = "GPE1", + }, + }, { + .chip = { + .base = S5PV210_GPF0(0), + .ngpio = S5PV210_GPIO_F0_NR, + .label = "GPF0", + }, + }, { + .chip = { + .base = S5PV210_GPF1(0), + .ngpio = S5PV210_GPIO_F1_NR, + .label = "GPF1", + }, + }, { + .chip = { + .base = S5PV210_GPF2(0), + .ngpio = S5PV210_GPIO_F2_NR, + .label = "GPF2", + }, + }, { + .chip = { + .base = S5PV210_GPF3(0), + .ngpio = S5PV210_GPIO_F3_NR, + .label = "GPF3", + }, + }, { + .chip = { + .base = S5PV210_GPG0(0), + .ngpio = S5PV210_GPIO_G0_NR, + .label = "GPG0", + }, + }, { + .chip = { + .base = S5PV210_GPG1(0), + .ngpio = S5PV210_GPIO_G1_NR, + .label = "GPG1", + }, + }, { + .chip = { + .base = S5PV210_GPG2(0), + .ngpio = S5PV210_GPIO_G2_NR, + .label = "GPG2", + }, + }, { + .chip = { + .base = S5PV210_GPG3(0), + .ngpio = S5PV210_GPIO_G3_NR, + .label = "GPG3", + }, + }, { + .chip = { + .base = S5PV210_GPI(0), + .ngpio = S5PV210_GPIO_I_NR, + .label = "GPI", + }, + }, { + .chip = { + .base = S5PV210_GPJ0(0), + .ngpio = S5PV210_GPIO_J0_NR, + .label = "GPJ0", + }, + }, { + .chip = { + .base = S5PV210_GPJ1(0), + .ngpio = S5PV210_GPIO_J1_NR, + .label = "GPJ1", + }, + }, { + .chip = { + .base = S5PV210_GPJ2(0), + .ngpio = S5PV210_GPIO_J2_NR, + .label = "GPJ2", + }, + }, { + .chip = { + .base = S5PV210_GPJ3(0), + .ngpio = S5PV210_GPIO_J3_NR, + .label = "GPJ3", + }, + }, { + .chip = { + .base = S5PV210_GPJ4(0), + .ngpio = S5PV210_GPIO_J4_NR, + .label = "GPJ4", + }, + }, { + .config = &gpio_cfg_noint, + .chip = { + .base = S5PV210_MP01(0), + .ngpio = S5PV210_GPIO_MP01_NR, + .label = "MP01", + }, + }, { + .config = &gpio_cfg_noint, + .chip = { + .base = S5PV210_MP02(0), + .ngpio = S5PV210_GPIO_MP02_NR, + .label = "MP02", + }, + }, { + .config = &gpio_cfg_noint, + .chip = { + .base = S5PV210_MP03(0), + .ngpio = S5PV210_GPIO_MP03_NR, + .label = "MP03", + }, + }, { + .base = (S5P_VA_GPIO + 0xC00), + .config = &gpio_cfg_noint, + .chip = { + .base = S5PV210_GPH0(0), + .ngpio = S5PV210_GPIO_H0_NR, + .label = "GPH0", + }, + }, { + .base = (S5P_VA_GPIO + 0xC20), + .config = &gpio_cfg_noint, + .chip = { + .base = S5PV210_GPH1(0), + .ngpio = S5PV210_GPIO_H1_NR, + .label = "GPH1", + }, + }, { + .base = (S5P_VA_GPIO + 0xC40), + .config = &gpio_cfg_noint, + .chip = { + .base = S5PV210_GPH2(0), + .ngpio = S5PV210_GPIO_H2_NR, + .label = "GPH2", + }, + }, { + .base = (S5P_VA_GPIO + 0xC60), + .config = &gpio_cfg_noint, + .chip = { + .base = S5PV210_GPH3(0), + .ngpio = S5PV210_GPIO_H3_NR, + .label = "GPH3", + }, + }, +}; + +static __init int s5pv210_gpiolib_init(void) +{ + struct s3c_gpio_chip *chip = s5pv210_gpio_4bit; + int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit); + int i = 0; + + for (i = 0; i < nr_chips; i++, chip++) { + if (chip->config == NULL) + chip->config = &gpio_cfg; + if (chip->base == NULL) + chip->base = S5PV210_BANK_BASE(i); + } + + samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips); + + return 0; +} +core_initcall(s5pv210_gpiolib_init); diff --git a/arch/arm/mach-s5pv210/include/mach/gpio.h b/arch/arm/mach-s5pv210/include/mach/gpio.h index 533b020e21e9..d6461ba2b71d 100644 --- a/arch/arm/mach-s5pv210/include/mach/gpio.h +++ b/arch/arm/mach-s5pv210/include/mach/gpio.h @@ -18,6 +18,8 @@ #define gpio_cansleep __gpio_cansleep #define gpio_to_irq __gpio_to_irq +/* Practically, GPIO banks upto MP03 are the configurable gpio banks */ + /* GPIO bank sizes */ #define S5PV210_GPIO_A0_NR (8) #define S5PV210_GPIO_A1_NR (4) @@ -47,6 +49,10 @@ #define S5PV210_GPIO_J3_NR (8) #define S5PV210_GPIO_J4_NR (5) +#define S5PV210_GPIO_MP01_NR (8) +#define S5PV210_GPIO_MP02_NR (4) +#define S5PV210_GPIO_MP03_NR (8) + /* GPIO bank numbers */ /* CONFIG_S3C_GPIO_SPACE allows the user to select extra @@ -85,6 +91,9 @@ enum s5p_gpio_number { S5PV210_GPIO_J2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J1), S5PV210_GPIO_J3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J2), S5PV210_GPIO_J4_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J3), + S5PV210_GPIO_MP01_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J4), + S5PV210_GPIO_MP02_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP01), + S5PV210_GPIO_MP03_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP02), }; /* S5PV210 GPIO number definitions */ @@ -115,13 +124,16 @@ enum s5p_gpio_number { #define S5PV210_GPJ2(_nr) (S5PV210_GPIO_J2_START + (_nr)) #define S5PV210_GPJ3(_nr) (S5PV210_GPIO_J3_START + (_nr)) #define S5PV210_GPJ4(_nr) (S5PV210_GPIO_J4_START + (_nr)) +#define S5PV210_MP01(_nr) (S5PV210_GPIO_MP01_START + (_nr)) +#define S5PV210_MP02(_nr) (S5PV210_GPIO_MP02_START + (_nr)) +#define S5PV210_MP03(_nr) (S5PV210_GPIO_MP03_START + (_nr)) /* the end of the S5PV210 specific gpios */ -#define S5PV210_GPIO_END (S5PV210_GPJ4(S5PV210_GPIO_J4_NR) + 1) +#define S5PV210_GPIO_END (S5PV210_MP03(S5PV210_GPIO_MP03_NR) + 1) #define S3C_GPIO_END S5PV210_GPIO_END -/* define the number of gpios we need to the one after the GPJ4() range */ -#define ARCH_NR_GPIOS (S5PV210_GPJ4(S5PV210_GPIO_J4_NR) + \ +/* define the number of gpios we need to the one after the MP03() range */ +#define ARCH_NR_GPIOS (S5PV210_MP03(S5PV210_GPIO_MP03_NR) + \ CONFIG_SAMSUNG_GPIO_EXTRA + 1) #include -- cgit v1.2.3-59-g8ed1b From 838c6d499b780c42fccbbdfecc0f5dcc471d0ef3 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 18 May 2010 12:23:36 +0200 Subject: ARM: SAMSUNG: move driver strength gpio configuration helper to common dir Driver strength parameter can be changed not only on S5PC100 but also on S5PV210/S5PC110 platforms, so move the helper functions to the common plat-samsung directory. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Ben Dooks --- arch/arm/plat-s5p/Kconfig | 1 + arch/arm/plat-s5pc1xx/Kconfig | 2 +- arch/arm/plat-s5pc1xx/Makefile | 1 - arch/arm/plat-s5pc1xx/gpio-config.c | 62 ---------------------- .../plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h | 32 ----------- arch/arm/plat-s5pc1xx/setup-fb-24bpp.c | 1 - arch/arm/plat-samsung/Kconfig | 12 ++--- arch/arm/plat-samsung/gpio-config.c | 48 +++++++++++++++++ arch/arm/plat-samsung/include/plat/gpio-cfg.h | 30 +++++++++++ 9 files changed, 86 insertions(+), 103 deletions(-) delete mode 100644 arch/arm/plat-s5pc1xx/gpio-config.c delete mode 100644 arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h (limited to 'arch') diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index d400a6a20fe4..92bd75607b43 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -13,6 +13,7 @@ config PLAT_S5P select NO_IOPORT select ARCH_REQUIRE_GPIOLIB select S3C_GPIO_TRACK + select S5P_GPIO_DRVSTR select SAMSUNG_GPIOLIB_4BIT select S3C_GPIO_CFG_S3C64XX select S3C_GPIO_PULL_UPDOWN diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig index c7ccdf22eefa..79d3be721dde 100644 --- a/arch/arm/plat-s5pc1xx/Kconfig +++ b/arch/arm/plat-s5pc1xx/Kconfig @@ -16,9 +16,9 @@ config PLAT_S5PC1XX select SAMSUNG_IRQ_VIC_TIMER select S3C_GPIO_TRACK select S3C_GPIO_PULL_UPDOWN + select S5P_GPIO_DRVSTR select S3C_GPIO_CFG_S3C24XX select S3C_GPIO_CFG_S3C64XX - select S5P_GPIO_CFG_S5PC1XX help Base platform code for any Samsung S5PC1XX device diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile index 278f26806089..66a8f3eb7071 100644 --- a/arch/arm/plat-s5pc1xx/Makefile +++ b/arch/arm/plat-s5pc1xx/Makefile @@ -24,7 +24,6 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK) += s5pc100-clock.o # Device setup -obj-$(CONFIG_S5P_GPIO_CFG_S5PC1XX) += gpio-config.o obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o obj-$(CONFIG_S5PC1XX_SETUP_I2C0) += setup-i2c0.o obj-$(CONFIG_S5PC1XX_SETUP_I2C1) += setup-i2c1.o diff --git a/arch/arm/plat-s5pc1xx/gpio-config.c b/arch/arm/plat-s5pc1xx/gpio-config.c deleted file mode 100644 index a4f67e80a150..000000000000 --- a/arch/arm/plat-s5pc1xx/gpio-config.c +++ /dev/null @@ -1,62 +0,0 @@ -/* linux/arch/arm/plat-s5pc1xx/gpio-config.c - * - * Copyright 2009 Samsung Electronics - * - * S5PC1XX GPIO Configuration. - * - * Based on plat-s3c64xx/gpio-config.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 -#include -#include -#include - -#include -#include - -s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off) -{ - struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); - void __iomem *reg; - int shift = off * 2; - u32 drvstr; - - if (!chip) - return -EINVAL; - - reg = chip->base + 0x0C; - - drvstr = __raw_readl(reg); - drvstr = 0xffff & (0x3 << shift); - drvstr = drvstr >> shift; - - return (__force s5p_gpio_drvstr_t)drvstr; -} -EXPORT_SYMBOL(s5p_gpio_get_drvstr); - -int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off, - s5p_gpio_drvstr_t drvstr) -{ - struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); - void __iomem *reg; - int shift = off * 2; - u32 tmp; - - if (!chip) - return -EINVAL; - - reg = chip->base + 0x0C; - - tmp = __raw_readl(reg); - tmp |= drvstr << shift; - - __raw_writel(tmp, reg); - - return 0; -} -EXPORT_SYMBOL(s5p_gpio_set_drvstr); diff --git a/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h deleted file mode 100644 index 72ad59f61efc..000000000000 --- a/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h +++ /dev/null @@ -1,32 +0,0 @@ -/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg.h - * - * Copyright 2009 Samsung Electronic - * - * S5PC1XX Platform - GPIO pin configuration - * - * 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. -*/ - -/* This file contains the necessary definitions to get the basic gpio - * pin configuration done such as setting a pin to input or output or - * changing the pull-{up,down} configurations. - */ - -#ifndef __GPIO_CFG_S5PC1XX_H -#define __GPIO_CFG_S5PC1XX_H __FILE__ - -typedef unsigned int __bitwise__ s5p_gpio_drvstr_t; - -#define S5P_GPIO_DRVSTR_LV1 0x00 -#define S5P_GPIO_DRVSTR_LV2 0x01 -#define S5P_GPIO_DRVSTR_LV3 0x10 -#define S5P_GPIO_DRVSTR_LV4 0x11 - -extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off); - -extern int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off, - s5p_gpio_drvstr_t drvstr); - -#endif /* __GPIO_CFG_S5PC1XX_H */ diff --git a/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c index 1a63768a9a2e..b02c36fb10d1 100644 --- a/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c +++ b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c @@ -19,7 +19,6 @@ #include #include #include -#include #define DISR_OFFSET 0x7008 diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index c91c21ac5fcb..711d5a4cce58 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -90,12 +90,6 @@ config S3C_GPIO_CFG_S3C64XX Internal configuration to enable S3C64XX style GPIO configuration functions. -config S5P_GPIO_CFG_S5PC1XX - bool - help - Internal configuration to enable S5PC1XX style GPIO configuration - functions. - config S3C_GPIO_PULL_UPDOWN bool help @@ -111,6 +105,12 @@ config S3C_GPIO_PULL_UP help Internal configuration to enable the correct GPIO pull helper +config S5P_GPIO_DRVSTR + bool + help + Internal configuration to get and set correct GPIO driver strength + helper + config SAMSUNG_GPIO_EXTRA int "Number of additional GPIO pins" default 0 diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index a76eef533392..57b68a50f45e 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c @@ -261,3 +261,51 @@ s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, } #endif /* CONFIG_S3C_GPIO_PULL_UP */ +#ifdef CONFIG_S5P_GPIO_DRVSTR +s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) +{ + struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); + unsigned int off; + void __iomem *reg; + int shift; + u32 drvstr; + + if (!chip) + return -EINVAL; + + off = chip->chip.base - pin; + shift = off * 2; + reg = chip->base + 0x0C; + + drvstr = __raw_readl(reg); + drvstr = 0xffff & (0x3 << shift); + drvstr = drvstr >> shift; + + return (__force s5p_gpio_drvstr_t)drvstr; +} +EXPORT_SYMBOL(s5p_gpio_get_drvstr); + +int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr) +{ + struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); + unsigned int off; + void __iomem *reg; + int shift; + u32 tmp; + + if (!chip) + return -EINVAL; + + off = chip->chip.base - pin; + shift = off * 2; + reg = chip->base + 0x0C; + + tmp = __raw_readl(reg); + tmp |= drvstr << shift; + + __raw_writel(tmp, reg); + + return 0; +} +EXPORT_SYMBOL(s5p_gpio_set_drvstr); +#endif /* CONFIG_S5P_GPIO_DRVSTR */ diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index 8d01e853df39..34efdd2b032c 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h @@ -25,6 +25,7 @@ #define __PLAT_GPIO_CFG_H __FILE__ typedef unsigned int __bitwise__ s3c_gpio_pull_t; +typedef unsigned int __bitwise__ s5p_gpio_drvstr_t; /* forward declaration if gpio-core.h hasn't been included */ struct s3c_gpio_chip; @@ -118,4 +119,33 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); */ extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); +/* Define values for the drvstr available for each gpio pin. + * + * These values control the value of the output signal driver strength, + * configurable on most pins on the S5C series. + */ +#define S5P_GPIO_DRVSTR_LV1 ((__force s5p_gpio_drvstr_t)0x00) +#define S5P_GPIO_DRVSTR_LV2 ((__force s5p_gpio_drvstr_t)0x01) +#define S5P_GPIO_DRVSTR_LV3 ((__force s5p_gpio_drvstr_t)0x10) +#define S5P_GPIO_DRVSTR_LV4 ((__force s5p_gpio_drvstr_t)0x11) + +/** + * s5c_gpio_get_drvstr() - get the driver streght value of a gpio pin + * @pin: The pin number to get the settings for + * + * Read the driver streght value for the specified pin. +*/ +extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin); + +/** + * s3c_gpio_set_drvstr() - set the driver streght value of a gpio pin + * @pin: The pin number to configure the driver streght value + * @drvstr: The new value of the driver strength + * + * This function sets the driver strength value for the specified pin. + * It will return 0 if successfull, or a negative error code if the pin + * cannot support the requested setting. +*/ +extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr); + #endif /* __PLAT_GPIO_CFG_H */ -- cgit v1.2.3-59-g8ed1b From a0f735812e9ffb65fa4c8a16975f5b63909fb447 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 18 May 2010 12:23:35 +0200 Subject: ARM: SAMSUNG: Copy common I2C0 device helpers to machine directories Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Ben Dooks --- arch/arm/mach-s5p6440/Makefile | 1 + arch/arm/mach-s5p6440/setup-i2c0.c | 25 +++++++++++++++++++++++++ arch/arm/mach-s5p6442/Makefile | 1 + arch/arm/mach-s5p6442/setup-i2c0.c | 25 +++++++++++++++++++++++++ arch/arm/mach-s5pv210/Makefile | 1 + arch/arm/mach-s5pv210/setup-i2c0.c | 25 +++++++++++++++++++++++++ arch/arm/plat-s5p/Makefile | 1 - arch/arm/plat-s5p/setup-i2c0.c | 25 ------------------------- 8 files changed, 78 insertions(+), 26 deletions(-) create mode 100644 arch/arm/mach-s5p6440/setup-i2c0.c create mode 100644 arch/arm/mach-s5p6442/setup-i2c0.c create mode 100644 arch/arm/mach-s5pv210/setup-i2c0.c delete mode 100644 arch/arm/plat-s5p/setup-i2c0.c (limited to 'arch') diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile index 5fd17d3da0cb..44facf43d59f 100644 --- a/arch/arm/mach-s5p6440/Makefile +++ b/arch/arm/mach-s5p6440/Makefile @@ -13,6 +13,7 @@ obj- := # Core support for S5P6440 system obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o dma.o +obj-$(CONFIG_CPU_S5P6440) += setup-i2c0.o # machine support diff --git a/arch/arm/mach-s5p6440/setup-i2c0.c b/arch/arm/mach-s5p6440/setup-i2c0.c new file mode 100644 index 000000000000..69e8a664aedb --- /dev/null +++ b/arch/arm/mach-s5p6440/setup-i2c0.c @@ -0,0 +1,25 @@ +/* linux/arch/arm/mach-s5p6440/setup-i2c0.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * I2C0 GPIO configuration. + * + * Based on plat-s3c64xx/setup-i2c0.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 +#include + +struct platform_device; /* don't need the contents */ + +#include + +void s3c_i2c0_cfg_gpio(struct platform_device *dev) +{ + /* Will be populated later */ +} diff --git a/arch/arm/mach-s5p6442/Makefile b/arch/arm/mach-s5p6442/Makefile index bf30550349cf..e30a7f76aee6 100644 --- a/arch/arm/mach-s5p6442/Makefile +++ b/arch/arm/mach-s5p6442/Makefile @@ -13,6 +13,7 @@ obj- := # Core support for S5P6442 system obj-$(CONFIG_CPU_S5P6442) += cpu.o init.o clock.o dma.o +obj-$(CONFIG_CPU_S5P6442) += setup-i2c0.o # machine support diff --git a/arch/arm/mach-s5p6442/setup-i2c0.c b/arch/arm/mach-s5p6442/setup-i2c0.c new file mode 100644 index 000000000000..662695dd7761 --- /dev/null +++ b/arch/arm/mach-s5p6442/setup-i2c0.c @@ -0,0 +1,25 @@ +/* linux/arch/arm/mach-s5p6442/setup-i2c0.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * I2C0 GPIO configuration. + * + * Based on plat-s3c64xx/setup-i2c0.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 +#include + +struct platform_device; /* don't need the contents */ + +#include + +void s3c_i2c0_cfg_gpio(struct platform_device *dev) +{ + /* Will be populated later */ +} diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 1d60b358589b..99827813d293 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -13,6 +13,7 @@ obj- := # Core support for S5PV210 system obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o +obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o # machine support diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c new file mode 100644 index 000000000000..9ec6845840e5 --- /dev/null +++ b/arch/arm/mach-s5pv210/setup-i2c0.c @@ -0,0 +1,25 @@ +/* linux/arch/arm/mach-s5pv210/setup-i2c0.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * I2C0 GPIO configuration. + * + * Based on plat-s3c64xx/setup-i2c0.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 +#include + +struct platform_device; /* don't need the contents */ + +#include + +void s3c_i2c0_cfg_gpio(struct platform_device *dev) +{ + /* Will be populated later */ +} diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index a7c54b332d27..0ec09a9c36bd 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -16,4 +16,3 @@ obj-y += dev-uart.o obj-y += cpu.o obj-y += clock.o obj-y += irq.o -obj-y += setup-i2c0.o diff --git a/arch/arm/plat-s5p/setup-i2c0.c b/arch/arm/plat-s5p/setup-i2c0.c deleted file mode 100644 index 67a66e02a97a..000000000000 --- a/arch/arm/plat-s5p/setup-i2c0.c +++ /dev/null @@ -1,25 +0,0 @@ -/* linux/arch/arm/plat-s5p/setup-i2c0.c - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * I2C0 GPIO configuration. - * - * Based on plat-s3c64xx/setup-i2c0.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 -#include - -struct platform_device; /* don't need the contents */ - -#include - -void s3c_i2c0_cfg_gpio(struct platform_device *dev) -{ - /* Will be populated later */ -} -- cgit v1.2.3-59-g8ed1b From a443a6373d8527657cfde3d3c515d4a64532c585 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 14 May 2010 16:27:28 +0900 Subject: ARM: S5PC100: Pre-requisite clock patch for plat-s5pc1xx to plat-s5p move This is a pre-requisite clock patch for the plat-s5pc1xx to plat-s5p movement. The patches that perform the movement of the code from plat-s5pc1xx to plat-s5p (and mach-s5pc100) should also enable the build for the mach-s5pc100/clock.c code. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s5pc100/clock.c | 1358 +++++++++++++++++++++++ arch/arm/mach-s5pc100/include/mach/regs-clock.h | 71 ++ arch/arm/plat-s5p/clock.c | 2 +- arch/arm/plat-s5p/include/plat/pll.h | 22 + arch/arm/plat-s5p/include/plat/s5p-clock.h | 2 + 5 files changed, 1454 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-s5pc100/clock.c create mode 100644 arch/arm/mach-s5pc100/include/mach/regs-clock.h (limited to 'arch') diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c new file mode 100644 index 000000000000..e3fed4cfe7ad --- /dev/null +++ b/arch/arm/mach-s5pc100/clock.c @@ -0,0 +1,1358 @@ +/* linux/arch/arm/mach-s5pc100/clock.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5PC100 - Clock support + * + * 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 +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct clk s5p_clk_otgphy = { + .name = "otg_phy", + .id = -1, +}; + +static struct clk *clk_src_mout_href_list[] = { + [0] = &s5p_clk_27m, + [1] = &clk_fin_hpll, +}; + +static struct clksrc_sources clk_src_mout_href = { + .sources = clk_src_mout_href_list, + .nr_sources = ARRAY_SIZE(clk_src_mout_href_list), +}; + +static struct clksrc_clk clk_mout_href = { + .clk = { + .name = "mout_href", + .id = -1, + }, + .sources = &clk_src_mout_href, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 }, +}; + +static struct clk *clk_src_mout_48m_list[] = { + [0] = &clk_xusbxti, + [1] = &s5p_clk_otgphy, +}; + +static struct clksrc_sources clk_src_mout_48m = { + .sources = clk_src_mout_48m_list, + .nr_sources = ARRAY_SIZE(clk_src_mout_48m_list), +}; + +static struct clksrc_clk clk_mout_48m = { + .clk = { + .name = "mout_48m", + .id = -1, + }, + .sources = &clk_src_mout_48m, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 1 }, +}; + +static struct clksrc_clk clk_mout_mpll = { + .clk = { + .name = "mout_mpll", + .id = -1, + }, + .sources = &clk_src_mpll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 }, +}; + + +static struct clksrc_clk clk_mout_apll = { + .clk = { + .name = "mout_apll", + .id = -1, + }, + .sources = &clk_src_apll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 }, +}; + +static struct clksrc_clk clk_mout_epll = { + .clk = { + .name = "mout_epll", + .id = -1, + }, + .sources = &clk_src_epll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 }, +}; + +static struct clk *clk_src_mout_hpll_list[] = { + [0] = &s5p_clk_27m, +}; + +static struct clksrc_sources clk_src_mout_hpll = { + .sources = clk_src_mout_hpll_list, + .nr_sources = ARRAY_SIZE(clk_src_mout_hpll_list), +}; + +static struct clksrc_clk clk_mout_hpll = { + .clk = { + .name = "mout_hpll", + .id = -1, + }, + .sources = &clk_src_mout_hpll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 }, +}; + +static struct clksrc_clk clk_div_apll = { + .clk = { + .name = "div_apll", + .id = -1, + .parent = &clk_mout_apll.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 1 }, +}; + +static struct clksrc_clk clk_div_arm = { + .clk = { + .name = "div_arm", + .id = -1, + .parent = &clk_div_apll.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 }, +}; + +static struct clksrc_clk clk_div_d0_bus = { + .clk = { + .name = "div_d0_bus", + .id = -1, + .parent = &clk_div_arm.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 }, +}; + +static struct clksrc_clk clk_div_pclkd0 = { + .clk = { + .name = "div_pclkd0", + .id = -1, + .parent = &clk_div_d0_bus.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 }, +}; + +static struct clksrc_clk clk_div_secss = { + .clk = { + .name = "div_secss", + .id = -1, + .parent = &clk_div_d0_bus.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 3 }, +}; + +static struct clksrc_clk clk_div_apll2 = { + .clk = { + .name = "div_apll2", + .id = -1, + .parent = &clk_mout_apll.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 3 }, +}; + +static struct clk *clk_src_mout_am_list[] = { + [0] = &clk_mout_mpll.clk, + [1] = &clk_div_apll2.clk, +}; + +struct clksrc_sources clk_src_mout_am = { + .sources = clk_src_mout_am_list, + .nr_sources = ARRAY_SIZE(clk_src_mout_am_list), +}; + +static struct clksrc_clk clk_mout_am = { + .clk = { + .name = "mout_am", + .id = -1, + }, + .sources = &clk_src_mout_am, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 }, +}; + +static struct clksrc_clk clk_div_d1_bus = { + .clk = { + .name = "div_d1_bus", + .id = -1, + .parent = &clk_mout_am.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 3 }, +}; + +static struct clksrc_clk clk_div_mpll2 = { + .clk = { + .name = "div_mpll2", + .id = -1, + .parent = &clk_mout_am.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 1 }, +}; + +static struct clksrc_clk clk_div_mpll = { + .clk = { + .name = "div_mpll", + .id = -1, + .parent = &clk_mout_am.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 2 }, +}; + +static struct clk *clk_src_mout_onenand_list[] = { + [0] = &clk_div_d0_bus.clk, + [1] = &clk_div_d1_bus.clk, +}; + +struct clksrc_sources clk_src_mout_onenand = { + .sources = clk_src_mout_onenand_list, + .nr_sources = ARRAY_SIZE(clk_src_mout_onenand_list), +}; + +static struct clksrc_clk clk_mout_onenand = { + .clk = { + .name = "mout_onenand", + .id = -1, + }, + .sources = &clk_src_mout_onenand, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 }, +}; + +static struct clksrc_clk clk_div_onenand = { + .clk = { + .name = "div_onenand", + .id = -1, + .parent = &clk_mout_onenand.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 2 }, +}; + +static struct clksrc_clk clk_div_pclkd1 = { + .clk = { + .name = "div_pclkd1", + .id = -1, + .parent = &clk_div_d1_bus.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 3 }, +}; + +static struct clksrc_clk clk_div_cam = { + .clk = { + .name = "div_cam", + .id = -1, + .parent = &clk_div_mpll2.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 24, .size = 5 }, +}; + +static struct clksrc_clk clk_div_hdmi = { + .clk = { + .name = "div_hdmi", + .id = -1, + .parent = &clk_mout_hpll.clk, + }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 }, +}; + +static int s5pc100_epll_enable(struct clk *clk, int enable) +{ + unsigned int ctrlbit = clk->ctrlbit; + unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; + + if (enable) + __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); + else + __raw_writel(epll_con, S5P_EPLL_CON); + + return 0; +} + +static unsigned long s5pc100_epll_get_rate(struct clk *clk) +{ + return clk->rate; +} + +static u32 epll_div[][4] = { + { 32750000, 131, 3, 4 }, + { 32768000, 131, 3, 4 }, + { 36000000, 72, 3, 3 }, + { 45000000, 90, 3, 3 }, + { 45158000, 90, 3, 3 }, + { 45158400, 90, 3, 3 }, + { 48000000, 96, 3, 3 }, + { 49125000, 131, 4, 3 }, + { 49152000, 131, 4, 3 }, + { 60000000, 120, 3, 3 }, + { 67737600, 226, 5, 3 }, + { 67738000, 226, 5, 3 }, + { 73800000, 246, 5, 3 }, + { 73728000, 246, 5, 3 }, + { 72000000, 144, 3, 3 }, + { 84000000, 168, 3, 3 }, + { 96000000, 96, 3, 2 }, + { 144000000, 144, 3, 2 }, + { 192000000, 96, 3, 1 } +}; + +static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int epll_con; + unsigned int i; + + if (clk->rate == rate) /* Return if nothing changed */ + return 0; + + epll_con = __raw_readl(S5P_EPLL_CON); + + epll_con &= ~(PLL65XX_MDIV_MASK | PLL65XX_PDIV_MASK | PLL65XX_SDIV_MASK); + + for (i = 0; i < ARRAY_SIZE(epll_div); i++) { + if (epll_div[i][0] == rate) { + epll_con |= (epll_div[i][1] << PLL65XX_MDIV_SHIFT) | + (epll_div[i][2] << PLL65XX_PDIV_SHIFT) | + (epll_div[i][3] << PLL65XX_SDIV_SHIFT); + break; + } + } + + if (i == ARRAY_SIZE(epll_div)) { + printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__); + return -EINVAL; + } + + __raw_writel(epll_con, S5P_EPLL_CON); + + clk->rate = rate; + + return 0; +} + +static struct clk_ops s5pc100_epll_ops = { + .get_rate = s5pc100_epll_get_rate, + .set_rate = s5pc100_epll_set_rate, +}; + +static int s5pc100_d0_0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_D00, clk, enable); +} + +static int s5pc100_d0_1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_D01, clk, enable); +} + +static int s5pc100_d0_2_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_D02, clk, enable); +} + +static int s5pc100_d1_0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_D10, clk, enable); +} + +static int s5pc100_d1_1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_D11, clk, enable); +} + +static int s5pc100_d1_2_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_D12, clk, enable); +} + +static int s5pc100_d1_3_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_D13, clk, enable); +} + +static int s5pc100_d1_4_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_D14, clk, enable); +} + +static int s5pc100_d1_5_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_D15, clk, enable); +} + +static int s5pc100_sclk0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_SCLK0, clk, enable); +} + +static int s5pc100_sclk1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLKGATE_SCLK1, clk, enable); +} + +/* + * The following clocks will be disabled during clock initialization. It is + * recommended to keep the following clocks disabled until the driver requests + * for enabling the clock. + */ +static struct clk init_clocks_disable[] = { + { + .name = "cssys", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_0_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "secss", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_0_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "g2d", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_0_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "mdma", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_0_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "cfcon", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_0_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "nfcon", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_1_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "onenandc", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_1_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "sdm", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_2_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "seckey", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_2_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "hsmmc", + .id = 2, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "hsmmc", + .id = 1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "hsmmc", + .id = 0, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "modemif", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "otg", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "usbhost", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "pdma", + .id = 1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "pdma", + .id = 0, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "lcd", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_1_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "rotator", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_1_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "fimc", + .id = 0, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_1_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "fimc", + .id = 1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_1_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "fimc", + .id = 2, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_1_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "jpeg", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_1_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "mipi-dsim", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_1_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "mipi-csis", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_1_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "g3d", + .id = 0, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "tv", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_2_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "vp", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_2_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "mixer", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_2_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "hdmi", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_2_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "mfc", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_2_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "apc", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_3_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "iec", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_3_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "systimer", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_3_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "watchdog", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_3_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "rtc", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_3_ctrl, + .ctrlbit = (1 << 9), + }, { + .name = "i2c", + .id = 0, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "i2c", + .id = 1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "spi", + .id = 0, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "spi", + .id = 1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "spi", + .id = 2, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "irda", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 9), + }, { + .name = "ccan", + .id = 0, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 10), + }, { + .name = "ccan", + .id = 1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 11), + }, { + .name = "hsitx", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "hsirx", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 13), + }, { + .name = "iis", + .id = 0, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_5_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "iis", + .id = 1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_5_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "iis", + .id = 2, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_5_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "ac97", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_5_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "pcm", + .id = 0, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_5_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "pcm", + .id = 1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_5_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "spdif", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_5_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "adc", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_5_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "keyif", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_5_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "spi_48m", + .id = 0, + .parent = &clk_mout_48m.clk, + .enable = s5pc100_sclk0_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "spi_48m", + .id = 1, + .parent = &clk_mout_48m.clk, + .enable = s5pc100_sclk0_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "spi_48m", + .id = 2, + .parent = &clk_mout_48m.clk, + .enable = s5pc100_sclk0_ctrl, + .ctrlbit = (1 << 9), + }, { + .name = "mmc_48m", + .id = 0, + .parent = &clk_mout_48m.clk, + .enable = s5pc100_sclk0_ctrl, + .ctrlbit = (1 << 15), + }, { + .name = "mmc_48m", + .id = 1, + .parent = &clk_mout_48m.clk, + .enable = s5pc100_sclk0_ctrl, + .ctrlbit = (1 << 16), + }, { + .name = "mmc_48m", + .id = 2, + .parent = &clk_mout_48m.clk, + .enable = s5pc100_sclk0_ctrl, + .ctrlbit = (1 << 17), + }, +}; + +static struct clk clk_vclk54m = { + .name = "vclk_54m", + .id = -1, + .rate = 54000000, +}; + +static struct clk clk_i2scdclk0 = { + .name = "i2s_cdclk0", + .id = -1, +}; + +static struct clk clk_i2scdclk1 = { + .name = "i2s_cdclk1", + .id = -1, +}; + +static struct clk clk_i2scdclk2 = { + .name = "i2s_cdclk2", + .id = -1, +}; + +static struct clk clk_pcmcdclk0 = { + .name = "pcm_cdclk0", + .id = -1, +}; + +static struct clk clk_pcmcdclk1 = { + .name = "pcm_cdclk1", + .id = -1, +}; + +static struct clk *clk_src_group1_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_div_mpll2.clk, + [2] = &clk_fin_epll, + [3] = &clk_mout_hpll.clk, +}; + +struct clksrc_sources clk_src_group1 = { + .sources = clk_src_group1_list, + .nr_sources = ARRAY_SIZE(clk_src_group1_list), +}; + +static struct clk *clk_src_group2_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_div_mpll.clk, +}; + +struct clksrc_sources clk_src_group2 = { + .sources = clk_src_group2_list, + .nr_sources = ARRAY_SIZE(clk_src_group2_list), +}; + +static struct clk *clk_src_group3_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_div_mpll.clk, + [2] = &clk_fin_epll, + [3] = &clk_i2scdclk0, + [4] = &clk_pcmcdclk0, + [5] = &clk_mout_hpll.clk, +}; + +struct clksrc_sources clk_src_group3 = { + .sources = clk_src_group3_list, + .nr_sources = ARRAY_SIZE(clk_src_group3_list), +}; + +static struct clk *clk_src_group4_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_div_mpll.clk, + [2] = &clk_fin_epll, + [3] = &clk_i2scdclk1, + [4] = &clk_pcmcdclk1, + [5] = &clk_mout_hpll.clk, +}; + +struct clksrc_sources clk_src_group4 = { + .sources = clk_src_group4_list, + .nr_sources = ARRAY_SIZE(clk_src_group4_list), +}; + +static struct clk *clk_src_group5_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_div_mpll.clk, + [2] = &clk_fin_epll, + [3] = &clk_i2scdclk2, + [4] = &clk_mout_hpll.clk, +}; + +struct clksrc_sources clk_src_group5 = { + .sources = clk_src_group5_list, + .nr_sources = ARRAY_SIZE(clk_src_group5_list), +}; + +static struct clk *clk_src_group6_list[] = { + [0] = &s5p_clk_27m, + [1] = &clk_vclk54m, + [2] = &clk_div_hdmi.clk, +}; + +struct clksrc_sources clk_src_group6 = { + .sources = clk_src_group6_list, + .nr_sources = ARRAY_SIZE(clk_src_group6_list), +}; + +static struct clk *clk_src_group7_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_div_mpll.clk, + [2] = &clk_mout_hpll.clk, + [3] = &clk_vclk54m, +}; + +struct clksrc_sources clk_src_group7 = { + .sources = clk_src_group7_list, + .nr_sources = ARRAY_SIZE(clk_src_group7_list), +}; + +static struct clk *clk_src_mmc0_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_div_mpll.clk, + [2] = &clk_fin_epll, +}; + +struct clksrc_sources clk_src_mmc0 = { + .sources = clk_src_mmc0_list, + .nr_sources = ARRAY_SIZE(clk_src_mmc0_list), +}; + +static struct clk *clk_src_mmc12_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_div_mpll.clk, + [2] = &clk_fin_epll, + [3] = &clk_mout_hpll.clk, +}; + +struct clksrc_sources clk_src_mmc12 = { + .sources = clk_src_mmc12_list, + .nr_sources = ARRAY_SIZE(clk_src_mmc12_list), +}; + +static struct clk *clk_src_irda_usb_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_div_mpll.clk, + [2] = &clk_fin_epll, + [3] = &clk_mout_hpll.clk, +}; + +struct clksrc_sources clk_src_irda_usb = { + .sources = clk_src_irda_usb_list, + .nr_sources = ARRAY_SIZE(clk_src_irda_usb_list), +}; + +static struct clk *clk_src_pwi_list[] = { + [0] = &clk_fin_epll, + [1] = &clk_mout_epll.clk, + [2] = &clk_div_mpll.clk, +}; + +struct clksrc_sources clk_src_pwi = { + .sources = clk_src_pwi_list, + .nr_sources = ARRAY_SIZE(clk_src_pwi_list), +}; + +static struct clksrc_clk clksrcs[] = { + { + .clk = { + .name = "sclk_spi", + .id = 0, + .ctrlbit = (1 << 4), + .enable = s5pc100_sclk0_ctrl, + + }, + .sources = &clk_src_group1, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 1, + .ctrlbit = (1 << 5), + .enable = s5pc100_sclk0_ctrl, + + }, + .sources = &clk_src_group1, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 2, + .ctrlbit = (1 << 6), + .enable = s5pc100_sclk0_ctrl, + + }, + .sources = &clk_src_group1, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "uclk1", + .id = -1, + .ctrlbit = (1 << 3), + .enable = s5pc100_sclk0_ctrl, + + }, + .sources = &clk_src_group2, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_mixer", + .id = -1, + .ctrlbit = (1 << 6), + .enable = s5pc100_sclk0_ctrl, + + }, + .sources = &clk_src_group6, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 }, + }, { + .clk = { + .name = "sclk_audio", + .id = 0, + .ctrlbit = (1 << 8), + .enable = s5pc100_sclk1_ctrl, + + }, + .sources = &clk_src_group3, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "sclk_audio", + .id = 1, + .ctrlbit = (1 << 9), + .enable = s5pc100_sclk1_ctrl, + + }, + .sources = &clk_src_group4, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_audio", + .id = 2, + .ctrlbit = (1 << 10), + .enable = s5pc100_sclk1_ctrl, + + }, + .sources = &clk_src_group5, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "sclk_lcd", + .id = -1, + .ctrlbit = (1 << 0), + .enable = s5pc100_sclk1_ctrl, + + }, + .sources = &clk_src_group7, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 12, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .id = 0, + .ctrlbit = (1 << 1), + .enable = s5pc100_sclk1_ctrl, + + }, + .sources = &clk_src_group7, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 16, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .id = 1, + .ctrlbit = (1 << 2), + .enable = s5pc100_sclk1_ctrl, + + }, + .sources = &clk_src_group7, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 20, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .id = 2, + .ctrlbit = (1 << 3), + .enable = s5pc100_sclk1_ctrl, + + }, + .sources = &clk_src_group7, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 24, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 24, .size = 4 }, + }, { + .clk = { + .name = "mmc_bus", + .id = 0, + .ctrlbit = (1 << 12), + .enable = s5pc100_sclk1_ctrl, + + }, + .sources = &clk_src_mmc0, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "mmc_bus", + .id = 1, + .ctrlbit = (1 << 13), + .enable = s5pc100_sclk1_ctrl, + + }, + .sources = &clk_src_mmc12, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "mmc_bus", + .id = 2, + .ctrlbit = (1 << 14), + .enable = s5pc100_sclk1_ctrl, + + }, + .sources = &clk_src_mmc12, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "sclk_irda", + .id = 2, + .ctrlbit = (1 << 10), + .enable = s5pc100_sclk0_ctrl, + + }, + .sources = &clk_src_irda_usb, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "sclk_irda", + .id = -1, + .ctrlbit = (1 << 10), + .enable = s5pc100_sclk0_ctrl, + + }, + .sources = &clk_src_mmc12, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_pwi", + .id = -1, + .ctrlbit = (1 << 1), + .enable = s5pc100_sclk0_ctrl, + + }, + .sources = &clk_src_pwi, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 0, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 3 }, + }, { + .clk = { + .name = "sclk_uhost", + .id = -1, + .ctrlbit = (1 << 11), + .enable = s5pc100_sclk0_ctrl, + + }, + .sources = &clk_src_irda_usb, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 20, .size = 4 }, + }, +}; + +/* Clock initialisation code */ +static struct clksrc_clk *sysclks[] = { + &clk_mout_apll, + &clk_mout_epll, + &clk_mout_mpll, + &clk_mout_hpll, + &clk_mout_href, + &clk_mout_48m, + &clk_div_apll, + &clk_div_arm, + &clk_div_d0_bus, + &clk_div_pclkd0, + &clk_div_secss, + &clk_div_apll2, + &clk_mout_am, + &clk_div_d1_bus, + &clk_div_mpll2, + &clk_div_mpll, + &clk_mout_onenand, + &clk_div_onenand, + &clk_div_pclkd1, + &clk_div_cam, + &clk_div_hdmi, +}; + +void __init_or_cpufreq s5pc100_setup_clocks(void) +{ + unsigned long xtal; + unsigned long arm; + unsigned long hclkd0; + unsigned long hclkd1; + unsigned long pclkd0; + unsigned long pclkd1; + unsigned long apll; + unsigned long mpll; + unsigned long epll; + unsigned long hpll; + unsigned int ptr; + + /* Set S5PC100 functions for clk_fout_epll */ + clk_fout_epll.enable = s5pc100_epll_enable; + clk_fout_epll.ops = &s5pc100_epll_ops; + + printk(KERN_DEBUG "%s: registering clocks\n", __func__); + + xtal = clk_get_rate(&clk_xtal); + + printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); + + apll = s5p_get_pll65xx(xtal, __raw_readl(S5P_APLL_CON)); + mpll = s5p_get_pll65xx(xtal, __raw_readl(S5P_MPLL_CON)); + epll = s5p_get_pll65xx(xtal, __raw_readl(S5P_EPLL_CON)); + hpll = s5p_get_pll65xx(xtal, __raw_readl(S5P_HPLL_CON)); + + printk(KERN_INFO "S5PC100: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz, E=%ld.%ldMHz, H=%ld.%ldMHz\n", + print_mhz(apll), print_mhz(mpll), print_mhz(epll), print_mhz(hpll)); + + clk_fout_apll.rate = apll; + clk_fout_mpll.rate = mpll; + clk_fout_epll.rate = epll; + clk_mout_hpll.clk.rate = hpll; + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_set_clksrc(&clksrcs[ptr], true); + + arm = clk_get_rate(&clk_div_arm.clk); + hclkd0 = clk_get_rate(&clk_div_d0_bus.clk); + pclkd0 = clk_get_rate(&clk_div_pclkd0.clk); + hclkd1 = clk_get_rate(&clk_div_d1_bus.clk); + pclkd1 = clk_get_rate(&clk_div_pclkd1.clk); + + printk(KERN_INFO "S5PC100: HCLKD0=%ld.%ldMHz, HCLKD1=%ld.%ldMHz, PCLKD0=%ld.%ldMHz, PCLKD1=%ld.%ldMHz\n", + print_mhz(hclkd0), print_mhz(hclkd1), print_mhz(pclkd0), print_mhz(pclkd1)); + + clk_f.rate = arm; + clk_h.rate = hclkd1; + clk_p.rate = pclkd1; +} + +/* + * The following clocks will be enabled during clock initialization. + */ +static struct clk init_clocks[] = { + { + .name = "tzic", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_0_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "intc", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_0_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "ebi", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_1_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "intmem", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_1_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "sromc", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_1_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "dmc", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_1_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "chipid", + .id = -1, + .parent = &clk_div_d0_bus.clk, + .enable = s5pc100_d0_1_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "gpio", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_3_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "uart", + .id = 0, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "uart", + .id = 1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "uart", + .id = 2, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "uart", + .id = 3, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_4_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "timers", + .id = -1, + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_3_ctrl, + .ctrlbit = (1 << 6), + }, +}; + +static struct clk *clks[] __initdata = { + &clk_ext, + &clk_i2scdclk0, + &clk_i2scdclk1, + &clk_i2scdclk2, + &clk_pcmcdclk0, + &clk_pcmcdclk1, +}; + +void __init s5pc100_register_clocks(void) +{ + struct clk *clkp; + int ret; + int ptr; + + s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); + + for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) + s3c_register_clksrc(sysclks[ptr], 1); + + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); + s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + + clkp = init_clocks_disable; + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { + + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + (clkp->enable)(clkp, 0); + } + + s3c_pwmclk_init(); +} diff --git a/arch/arm/mach-s5pc100/include/mach/regs-clock.h b/arch/arm/mach-s5pc100/include/mach/regs-clock.h new file mode 100644 index 000000000000..f2283bdc941e --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/regs-clock.h @@ -0,0 +1,71 @@ +/* linux/arch/arm/mach-s5pc100/include/mach/regs-clock.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5PC100 - Clock register definitions + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_CLOCK_H +#define __ASM_ARCH_REGS_CLOCK_H __FILE__ + +#include + +#define S5P_CLKREG(x) (S3C_VA_SYS + (x)) + +#define S5P_APLL_LOCK S5P_CLKREG(0x00) +#define S5P_MPLL_LOCK S5P_CLKREG(0x04) +#define S5P_EPLL_LOCK S5P_CLKREG(0x08) +#define S5P_HPLL_LOCK S5P_CLKREG(0x0C) + +#define S5P_APLL_CON S5P_CLKREG(0x100) +#define S5P_MPLL_CON S5P_CLKREG(0x104) +#define S5P_EPLL_CON S5P_CLKREG(0x108) +#define S5P_HPLL_CON S5P_CLKREG(0x10C) + +#define S5P_CLK_SRC0 S5P_CLKREG(0x200) +#define S5P_CLK_SRC1 S5P_CLKREG(0x204) +#define S5P_CLK_SRC2 S5P_CLKREG(0x208) +#define S5P_CLK_SRC3 S5P_CLKREG(0x20C) + +#define S5P_CLK_DIV0 S5P_CLKREG(0x300) +#define S5P_CLK_DIV1 S5P_CLKREG(0x304) +#define S5P_CLK_DIV2 S5P_CLKREG(0x308) +#define S5P_CLK_DIV3 S5P_CLKREG(0x30C) +#define S5P_CLK_DIV4 S5P_CLKREG(0x310) + +#define S5P_CLK_OUT S5P_CLKREG(0x400) + +#define S5P_CLKGATE_D00 S5P_CLKREG(0x500) +#define S5P_CLKGATE_D01 S5P_CLKREG(0x504) +#define S5P_CLKGATE_D02 S5P_CLKREG(0x508) + +#define S5P_CLKGATE_D10 S5P_CLKREG(0x520) +#define S5P_CLKGATE_D11 S5P_CLKREG(0x524) +#define S5P_CLKGATE_D12 S5P_CLKREG(0x528) +#define S5P_CLKGATE_D13 S5P_CLKREG(0x52C) +#define S5P_CLKGATE_D14 S5P_CLKREG(0x530) +#define S5P_CLKGATE_D15 S5P_CLKREG(0x534) + +#define S5P_CLKGATE_D20 S5P_CLKREG(0x540) + +#define S5P_CLKGATE_SCLK0 S5P_CLKREG(0x560) +#define S5P_CLKGATE_SCLK1 S5P_CLKREG(0x564) + +/* CLKDIV0 */ +#define S5P_CLKDIV0_D0_MASK (0x7<<8) +#define S5P_CLKDIV0_D0_SHIFT (8) +#define S5P_CLKDIV0_PCLKD0_MASK (0x7<<12) +#define S5P_CLKDIV0_PCLKD0_SHIFT (12) + +/* CLKDIV1 */ +#define S5P_CLKDIV1_D1_MASK (0x7<<12) +#define S5P_CLKDIV1_D1_SHIFT (12) +#define S5P_CLKDIV1_PCLKD1_MASK (0x7<<16) +#define S5P_CLKDIV1_PCLKD1_SHIFT (16) + +#endif /* __ASM_ARCH_REGS_CLOCK_H */ diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index a8bfabf4b6bc..24a931fd8d3b 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c @@ -38,7 +38,7 @@ struct clk clk_xusbxti = { .id = -1, }; -static struct clk s5p_clk_27m = { +struct clk s5p_clk_27m = { .name = "clk_27m", .id = -1, .rate = 27000000, diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h index d48325bb29e2..7db322726bc2 100644 --- a/arch/arm/plat-s5p/include/plat/pll.h +++ b/arch/arm/plat-s5p/include/plat/pll.h @@ -81,3 +81,25 @@ static inline unsigned long s5p_get_pll90xx(unsigned long baseclk, return result; } + +#define PLL65XX_MDIV_MASK (0x3FF) +#define PLL65XX_PDIV_MASK (0x3F) +#define PLL65XX_SDIV_MASK (0x7) +#define PLL65XX_MDIV_SHIFT (16) +#define PLL65XX_PDIV_SHIFT (8) +#define PLL65XX_SDIV_SHIFT (0) + +static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con) +{ + u32 mdiv, pdiv, sdiv; + u64 fvco = baseclk; + + mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK; + pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK; + sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h index aa0447a18903..09418b1101fe 100644 --- a/arch/arm/plat-s5p/include/plat/s5p-clock.h +++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h @@ -21,10 +21,12 @@ #define clk_fin_mpll clk_ext_xtal_mux #define clk_fin_epll clk_ext_xtal_mux #define clk_fin_vpll clk_ext_xtal_mux +#define clk_fin_hpll clk_ext_xtal_mux extern struct clk clk_ext_xtal_mux; extern struct clk clk_xusbxti; extern struct clk clk_48m; +extern struct clk s5p_clk_27m; extern struct clk clk_fout_apll; extern struct clk clk_fout_mpll; extern struct clk clk_fout_epll; -- cgit v1.2.3-59-g8ed1b From 252b8efeba9cd1e28ade902275b27133114d2382 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 18 May 2010 12:38:40 +0200 Subject: ARM: S5PC100: Use common functions for gpiolib implementation GPIOlib helpers from plat-samsung already have functions for accessing 4bit gpio banks. This patch removes the duplicated functions from plat-s5pc1xx/gpiolib.c. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Ben Dooks --- arch/arm/plat-s5pc1xx/Kconfig | 1 + arch/arm/plat-s5pc1xx/gpiolib.c | 96 ++++------------------------------------- 2 files changed, 10 insertions(+), 87 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig index 79d3be721dde..98bbaf9d2219 100644 --- a/arch/arm/plat-s5pc1xx/Kconfig +++ b/arch/arm/plat-s5pc1xx/Kconfig @@ -19,6 +19,7 @@ config PLAT_S5PC1XX select S5P_GPIO_DRVSTR select S3C_GPIO_CFG_S3C24XX select S3C_GPIO_CFG_S3C64XX + select SAMSUNG_GPIOLIB_4BIT help Base platform code for any Samsung S5PC1XX device diff --git a/arch/arm/plat-s5pc1xx/gpiolib.c b/arch/arm/plat-s5pc1xx/gpiolib.c index 1ffc57ac293d..5a97a8f8e368 100644 --- a/arch/arm/plat-s5pc1xx/gpiolib.c +++ b/arch/arm/plat-s5pc1xx/gpiolib.c @@ -61,74 +61,6 @@ * L3 8 4Bit None */ -#define OFF_GPCON (0x00) -#define OFF_GPDAT (0x04) - -#define con_4bit_shift(__off) ((__off) * 4) - -#if 1 -#define gpio_dbg(x...) do { } while (0) -#else -#define gpio_dbg(x...) printk(KERN_DEBUG x) -#endif - -/* The s5pc1xx_gpiolib routines are to control the gpio banks where - * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the - * following example: - * - * base + 0x00: Control register, 4 bits per gpio - * gpio n: 4 bits starting at (4*n) - * 0000 = input, 0001 = output, others mean special-function - * base + 0x04: Data register, 1 bit per gpio - * bit n: data bit n - * - * Note, since the data register is one bit per gpio and is at base + 0x4 - * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of - * the output. - */ - -static int s5pc1xx_gpiolib_input(struct gpio_chip *chip, unsigned offset) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - unsigned long con; - - con = __raw_readl(base + OFF_GPCON); - con &= ~(0xf << con_4bit_shift(offset)); - __raw_writel(con, base + OFF_GPCON); - - gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); - - return 0; -} - -static int s5pc1xx_gpiolib_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - unsigned long con; - unsigned long dat; - - con = __raw_readl(base + OFF_GPCON); - con &= ~(0xf << con_4bit_shift(offset)); - con |= 0x1 << con_4bit_shift(offset); - - dat = __raw_readl(base + OFF_GPDAT); - if (value) - dat |= 1 << offset; - else - dat &= ~(1 << offset); - - __raw_writel(dat, base + OFF_GPDAT); - __raw_writel(con, base + OFF_GPCON); - __raw_writel(dat, base + OFF_GPDAT); - - gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); - - return 0; -} - static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) { return S3C_IRQ_GPIO(chip->base + offset); @@ -452,11 +384,8 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { extern struct irq_chip s5pc1xx_gpioint; extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc); -static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip) +static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip) { - chip->chip.direction_input = s5pc1xx_gpiolib_input; - chip->chip.direction_output = s5pc1xx_gpiolib_output; - chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); /* Interrupt */ if (chip->config == &gpio_cfg) { @@ -475,26 +404,19 @@ static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip) chip->chip.to_irq = s5pc1xx_gpiolib_to_eint; } -static __init void s5pc1xx_gpiolib_add(struct s3c_gpio_chip *chips, - int nr_chips, - void (*fn)(struct s3c_gpio_chip *)) -{ - for (; nr_chips > 0; nr_chips--, chips++) { - if (fn) - (fn)(chips); - s3c_gpiolib_add(chips); - } -} - static __init int s5pc1xx_gpiolib_init(void) { - struct s3c_gpio_chip *chips; + struct s3c_gpio_chip *chip; int nr_chips; - chips = s5pc100_gpio_chips; - nr_chips = ARRAY_SIZE(s5pc100_gpio_chips); + chip = s5pc100_gpio_chips; + nr_chips = ARRAY_SIZE(s5pc100_gpio_chips); + + for (; nr_chips > 0; nr_chips--, chip++) + s5pc100_gpiolib_link(chip); - s5pc1xx_gpiolib_add(chips, nr_chips, s5pc1xx_gpiolib_link); + samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, + ARRAY_SIZE(s5pc100_gpio_chips)); /* Interrupt */ set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler); -- cgit v1.2.3-59-g8ed1b From 7904449021de399a03ec8a32e536d031a61def5b Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 18 May 2010 12:38:41 +0200 Subject: ARM: S5PC100: Move gpio support from plat-s5pc1xx to mach-s5pc100 Move gpio-lib support from plat-s5pc1xx to mach-s5pc100. Only basic gpio functionality is now supported. Gpio interrupts are disabled temporarly and will be added later. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Ben Dooks --- arch/arm/mach-s5pc100/Makefile | 2 +- arch/arm/mach-s5pc100/gpiolib.c | 428 +++++++++++++++++++++++++ arch/arm/mach-s5pc100/include/mach/regs-gpio.h | 70 ++++ arch/arm/mach-s5pc100/mach-smdkc100.c | 1 - arch/arm/plat-s5pc1xx/Makefile | 3 +- arch/arm/plat-s5pc1xx/gpiolib.c | 425 ------------------------ arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h | 70 ---- 7 files changed, 500 insertions(+), 499 deletions(-) create mode 100644 arch/arm/mach-s5pc100/gpiolib.c create mode 100644 arch/arm/mach-s5pc100/include/mach/regs-gpio.h delete mode 100644 arch/arm/plat-s5pc1xx/gpiolib.c delete mode 100644 arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h (limited to 'arch') diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile index 809ff10f768f..4199ce2b161a 100644 --- a/arch/arm/mach-s5pc100/Makefile +++ b/arch/arm/mach-s5pc100/Makefile @@ -11,7 +11,7 @@ obj- := # Core support for S5PC100 system -obj-$(CONFIG_CPU_S5PC100) += cpu.o +obj-$(CONFIG_CPU_S5PC100) += cpu.o gpiolib.o # Helper and device support diff --git a/arch/arm/mach-s5pc100/gpiolib.c b/arch/arm/mach-s5pc100/gpiolib.c new file mode 100644 index 000000000000..c8e8336a3a12 --- /dev/null +++ b/arch/arm/mach-s5pc100/gpiolib.c @@ -0,0 +1,428 @@ +/* + * arch/arm/plat-s5pc1xx/gpiolib.c + * + * Copyright 2009 Samsung Electronics Co + * Kyungmin Park + * + * S5PC1XX - GPIOlib support + * + * 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 +#include +#include +#include + +#include +#include + +#include +#include +#include + +/* S5PC100 GPIO bank summary: + * + * Bank GPIOs Style INT Type + * A0 8 4Bit GPIO_INT0 + * A1 5 4Bit GPIO_INT1 + * B 8 4Bit GPIO_INT2 + * C 5 4Bit GPIO_INT3 + * D 7 4Bit GPIO_INT4 + * E0 8 4Bit GPIO_INT5 + * E1 6 4Bit GPIO_INT6 + * F0 8 4Bit GPIO_INT7 + * F1 8 4Bit GPIO_INT8 + * F2 8 4Bit GPIO_INT9 + * F3 4 4Bit GPIO_INT10 + * G0 8 4Bit GPIO_INT11 + * G1 3 4Bit GPIO_INT12 + * G2 7 4Bit GPIO_INT13 + * G3 7 4Bit GPIO_INT14 + * H0 8 4Bit WKUP_INT + * H1 8 4Bit WKUP_INT + * H2 8 4Bit WKUP_INT + * H3 8 4Bit WKUP_INT + * I 8 4Bit GPIO_INT15 + * J0 8 4Bit GPIO_INT16 + * J1 5 4Bit GPIO_INT17 + * J2 8 4Bit GPIO_INT18 + * J3 8 4Bit GPIO_INT19 + * J4 4 4Bit GPIO_INT20 + * K0 8 4Bit None + * K1 6 4Bit None + * K2 8 4Bit None + * K3 8 4Bit None + * L0 8 4Bit None + * L1 8 4Bit None + * L2 8 4Bit None + * L3 8 4Bit None + */ + +#if 0 +static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) +{ + return S3C_IRQ_GPIO(chip->base + offset); +} + +static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset) +{ + int base; + + base = chip->base - S5PC100_GPH0(0); + if (base == 0) + return IRQ_EINT(offset); + base = chip->base - S5PC100_GPH1(0); + if (base == 0) + return IRQ_EINT(8 + offset); + base = chip->base - S5PC100_GPH2(0); + if (base == 0) + return IRQ_EINT(16 + offset); + base = chip->base - S5PC100_GPH3(0); + if (base == 0) + return IRQ_EINT(24 + offset); + return -EINVAL; +} +#endif +static struct s3c_gpio_cfg gpio_cfg = { + .set_config = s3c_gpio_setcfg_s3c64xx_4bit, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + +static struct s3c_gpio_cfg gpio_cfg_eint = { + .cfg_eint = 0xf, + .set_config = s3c_gpio_setcfg_s3c64xx_4bit, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + +static struct s3c_gpio_cfg gpio_cfg_noint = { + .set_config = s3c_gpio_setcfg_s3c64xx_4bit, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + +static struct s3c_gpio_chip s5pc100_gpio_chips[] = { + { + .base = S5PC100_GPA0_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPA0(0), + .ngpio = S5PC100_GPIO_A0_NR, + .label = "GPA0", + }, + }, { + .base = S5PC100_GPA1_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPA1(0), + .ngpio = S5PC100_GPIO_A1_NR, + .label = "GPA1", + }, + }, { + .base = S5PC100_GPB_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPB(0), + .ngpio = S5PC100_GPIO_B_NR, + .label = "GPB", + }, + }, { + .base = S5PC100_GPC_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPC(0), + .ngpio = S5PC100_GPIO_C_NR, + .label = "GPC", + }, + }, { + .base = S5PC100_GPD_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPD(0), + .ngpio = S5PC100_GPIO_D_NR, + .label = "GPD", + }, + }, { + .base = S5PC100_GPE0_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPE0(0), + .ngpio = S5PC100_GPIO_E0_NR, + .label = "GPE0", + }, + }, { + .base = S5PC100_GPE1_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPE1(0), + .ngpio = S5PC100_GPIO_E1_NR, + .label = "GPE1", + }, + }, { + .base = S5PC100_GPF0_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPF0(0), + .ngpio = S5PC100_GPIO_F0_NR, + .label = "GPF0", + }, + }, { + .base = S5PC100_GPF1_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPF1(0), + .ngpio = S5PC100_GPIO_F1_NR, + .label = "GPF1", + }, + }, { + .base = S5PC100_GPF2_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPF2(0), + .ngpio = S5PC100_GPIO_F2_NR, + .label = "GPF2", + }, + }, { + .base = S5PC100_GPF3_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPF3(0), + .ngpio = S5PC100_GPIO_F3_NR, + .label = "GPF3", + }, + }, { + .base = S5PC100_GPG0_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPG0(0), + .ngpio = S5PC100_GPIO_G0_NR, + .label = "GPG0", + }, + }, { + .base = S5PC100_GPG1_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPG1(0), + .ngpio = S5PC100_GPIO_G1_NR, + .label = "GPG1", + }, + }, { + .base = S5PC100_GPG2_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPG2(0), + .ngpio = S5PC100_GPIO_G2_NR, + .label = "GPG2", + }, + }, { + .base = S5PC100_GPG3_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPG3(0), + .ngpio = S5PC100_GPIO_G3_NR, + .label = "GPG3", + }, + }, { + .base = S5PC100_GPH0_BASE, + .config = &gpio_cfg_eint, + .chip = { + .base = S5PC100_GPH0(0), + .ngpio = S5PC100_GPIO_H0_NR, + .label = "GPH0", + }, + }, { + .base = S5PC100_GPH1_BASE, + .config = &gpio_cfg_eint, + .chip = { + .base = S5PC100_GPH1(0), + .ngpio = S5PC100_GPIO_H1_NR, + .label = "GPH1", + }, + }, { + .base = S5PC100_GPH2_BASE, + .config = &gpio_cfg_eint, + .chip = { + .base = S5PC100_GPH2(0), + .ngpio = S5PC100_GPIO_H2_NR, + .label = "GPH2", + }, + }, { + .base = S5PC100_GPH3_BASE, + .config = &gpio_cfg_eint, + .chip = { + .base = S5PC100_GPH3(0), + .ngpio = S5PC100_GPIO_H3_NR, + .label = "GPH3", + }, + }, { + .base = S5PC100_GPI_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPI(0), + .ngpio = S5PC100_GPIO_I_NR, + .label = "GPI", + }, + }, { + .base = S5PC100_GPJ0_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPJ0(0), + .ngpio = S5PC100_GPIO_J0_NR, + .label = "GPJ0", + }, + }, { + .base = S5PC100_GPJ1_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPJ1(0), + .ngpio = S5PC100_GPIO_J1_NR, + .label = "GPJ1", + }, + }, { + .base = S5PC100_GPJ2_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPJ2(0), + .ngpio = S5PC100_GPIO_J2_NR, + .label = "GPJ2", + }, + }, { + .base = S5PC100_GPJ3_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPJ3(0), + .ngpio = S5PC100_GPIO_J3_NR, + .label = "GPJ3", + }, + }, { + .base = S5PC100_GPJ4_BASE, + .config = &gpio_cfg, + .chip = { + .base = S5PC100_GPJ4(0), + .ngpio = S5PC100_GPIO_J4_NR, + .label = "GPJ4", + }, + }, { + .base = S5PC100_GPK0_BASE, + .config = &gpio_cfg_noint, + .chip = { + .base = S5PC100_GPK0(0), + .ngpio = S5PC100_GPIO_K0_NR, + .label = "GPK0", + }, + }, { + .base = S5PC100_GPK1_BASE, + .config = &gpio_cfg_noint, + .chip = { + .base = S5PC100_GPK1(0), + .ngpio = S5PC100_GPIO_K1_NR, + .label = "GPK1", + }, + }, { + .base = S5PC100_GPK2_BASE, + .config = &gpio_cfg_noint, + .chip = { + .base = S5PC100_GPK2(0), + .ngpio = S5PC100_GPIO_K2_NR, + .label = "GPK2", + }, + }, { + .base = S5PC100_GPK3_BASE, + .config = &gpio_cfg_noint, + .chip = { + .base = S5PC100_GPK3(0), + .ngpio = S5PC100_GPIO_K3_NR, + .label = "GPK3", + }, + }, { + .base = S5PC100_GPL0_BASE, + .config = &gpio_cfg_noint, + .chip = { + .base = S5PC100_GPL0(0), + .ngpio = S5PC100_GPIO_L0_NR, + .label = "GPL0", + }, + }, { + .base = S5PC100_GPL1_BASE, + .config = &gpio_cfg_noint, + .chip = { + .base = S5PC100_GPL1(0), + .ngpio = S5PC100_GPIO_L1_NR, + .label = "GPL1", + }, + }, { + .base = S5PC100_GPL2_BASE, + .config = &gpio_cfg_noint, + .chip = { + .base = S5PC100_GPL2(0), + .ngpio = S5PC100_GPIO_L2_NR, + .label = "GPL2", + }, + }, { + .base = S5PC100_GPL3_BASE, + .config = &gpio_cfg_noint, + .chip = { + .base = S5PC100_GPL3(0), + .ngpio = S5PC100_GPIO_L3_NR, + .label = "GPL3", + }, + }, { + .base = S5PC100_GPL4_BASE, + .config = &gpio_cfg_noint, + .chip = { + .base = S5PC100_GPL4(0), + .ngpio = S5PC100_GPIO_L4_NR, + .label = "GPL4", + }, + }, +}; + +/* FIXME move from irq-gpio.c */ +extern struct irq_chip s5pc1xx_gpioint; +extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc); + +static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip) +{ +#if 0 + /* Interrupt */ + if (chip->config == &gpio_cfg) { + int i, irq; + + chip->chip.to_irq = s5pc1xx_gpiolib_to_irq; + + for (i = 0; i < chip->chip.ngpio; i++) { + irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i; + set_irq_chip(irq, &s5pc1xx_gpioint); + set_irq_data(irq, &chip->chip); + set_irq_handler(irq, handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } + } else if (chip->config == &gpio_cfg_eint) + chip->chip.to_irq = s5pc1xx_gpiolib_to_eint; +#endif +} + +static __init int s5pc1xx_gpiolib_init(void) +{ + struct s3c_gpio_chip *chip; + int nr_chips; + + chip = s5pc100_gpio_chips; + nr_chips = ARRAY_SIZE(s5pc100_gpio_chips); + + for (; nr_chips > 0; nr_chips--, chip++) + s5pc100_gpiolib_link(chip); + + samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, + ARRAY_SIZE(s5pc100_gpio_chips)); +#if 0 + /* Interrupt */ + set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler); +#endif + return 0; +} +core_initcall(s5pc1xx_gpiolib_init); diff --git a/arch/arm/mach-s5pc100/include/mach/regs-gpio.h b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h new file mode 100644 index 000000000000..43c7bc8bf784 --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h @@ -0,0 +1,70 @@ +/* linux/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h + * + * Copyright 2009 Samsung Electronics Co. + * Byungho Min + * + * S5PC1XX - GPIO register definitions + */ + +#ifndef __ASM_PLAT_S5PC1XX_REGS_GPIO_H +#define __ASM_PLAT_S5PC1XX_REGS_GPIO_H __FILE__ + +#include + +/* S5PC100 */ +#define S5PC100_GPIO_BASE S5PC1XX_VA_GPIO +#define S5PC100_GPA0_BASE (S5PC100_GPIO_BASE + 0x0000) +#define S5PC100_GPA1_BASE (S5PC100_GPIO_BASE + 0x0020) +#define S5PC100_GPB_BASE (S5PC100_GPIO_BASE + 0x0040) +#define S5PC100_GPC_BASE (S5PC100_GPIO_BASE + 0x0060) +#define S5PC100_GPD_BASE (S5PC100_GPIO_BASE + 0x0080) +#define S5PC100_GPE0_BASE (S5PC100_GPIO_BASE + 0x00A0) +#define S5PC100_GPE1_BASE (S5PC100_GPIO_BASE + 0x00C0) +#define S5PC100_GPF0_BASE (S5PC100_GPIO_BASE + 0x00E0) +#define S5PC100_GPF1_BASE (S5PC100_GPIO_BASE + 0x0100) +#define S5PC100_GPF2_BASE (S5PC100_GPIO_BASE + 0x0120) +#define S5PC100_GPF3_BASE (S5PC100_GPIO_BASE + 0x0140) +#define S5PC100_GPG0_BASE (S5PC100_GPIO_BASE + 0x0160) +#define S5PC100_GPG1_BASE (S5PC100_GPIO_BASE + 0x0180) +#define S5PC100_GPG2_BASE (S5PC100_GPIO_BASE + 0x01A0) +#define S5PC100_GPG3_BASE (S5PC100_GPIO_BASE + 0x01C0) +#define S5PC100_GPH0_BASE (S5PC100_GPIO_BASE + 0x0C00) +#define S5PC100_GPH1_BASE (S5PC100_GPIO_BASE + 0x0C20) +#define S5PC100_GPH2_BASE (S5PC100_GPIO_BASE + 0x0C40) +#define S5PC100_GPH3_BASE (S5PC100_GPIO_BASE + 0x0C60) +#define S5PC100_GPI_BASE (S5PC100_GPIO_BASE + 0x01E0) +#define S5PC100_GPJ0_BASE (S5PC100_GPIO_BASE + 0x0200) +#define S5PC100_GPJ1_BASE (S5PC100_GPIO_BASE + 0x0220) +#define S5PC100_GPJ2_BASE (S5PC100_GPIO_BASE + 0x0240) +#define S5PC100_GPJ3_BASE (S5PC100_GPIO_BASE + 0x0260) +#define S5PC100_GPJ4_BASE (S5PC100_GPIO_BASE + 0x0280) +#define S5PC100_GPK0_BASE (S5PC100_GPIO_BASE + 0x02A0) +#define S5PC100_GPK1_BASE (S5PC100_GPIO_BASE + 0x02C0) +#define S5PC100_GPK2_BASE (S5PC100_GPIO_BASE + 0x02E0) +#define S5PC100_GPK3_BASE (S5PC100_GPIO_BASE + 0x0300) +#define S5PC100_GPL0_BASE (S5PC100_GPIO_BASE + 0x0320) +#define S5PC100_GPL1_BASE (S5PC100_GPIO_BASE + 0x0340) +#define S5PC100_GPL2_BASE (S5PC100_GPIO_BASE + 0x0360) +#define S5PC100_GPL3_BASE (S5PC100_GPIO_BASE + 0x0380) +#define S5PC100_GPL4_BASE (S5PC100_GPIO_BASE + 0x03A0) +#define S5PC100_EINT_BASE (S5PC100_GPIO_BASE + 0x0E00) + +#define S5PC100_UHOST (S5PC100_GPIO_BASE + 0x0B68) +#define S5PC100_PDNEN (S5PC100_GPIO_BASE + 0x0F80) + +/* PDNEN */ +#define S5PC100_PDNEN_CFG_PDNEN (1 << 1) +#define S5PC100_PDNEN_CFG_AUTO (0 << 1) +#define S5PC100_PDNEN_POWERDOWN (1 << 0) +#define S5PC100_PDNEN_NORMAL (0 << 0) + +/* Common part */ +/* External interrupt base is same at both s5pc100 and s5pc110 */ +#define S5PC1XX_EINT_BASE (S5PC100_EINT_BASE) + +#define S5PC100_GPx_INPUT(__gpio) (0x0 << ((__gpio) * 4)) +#define S5PC100_GPx_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) +#define S5PC100_GPx_CONMASK(__gpio) (0xf << ((__gpio) * 4)) + +#endif /* __ASM_PLAT_S5PC1XX_REGS_GPIO_H */ + diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c index ae3c52cd0ebb..bfe67db34f04 100644 --- a/arch/arm/mach-s5pc100/mach-smdkc100.c +++ b/arch/arm/mach-s5pc100/mach-smdkc100.c @@ -35,7 +35,6 @@ #include #include -#include #include #include diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile index 66a8f3eb7071..540fca5b4860 100644 --- a/arch/arm/plat-s5pc1xx/Makefile +++ b/arch/arm/plat-s5pc1xx/Makefile @@ -13,9 +13,8 @@ obj- := obj-y += dev-uart.o obj-y += cpu.o -obj-y += irq.o irq-gpio.o irq-eint.o +obj-y += irq.o obj-y += clock.o -obj-y += gpiolib.o # CPU support diff --git a/arch/arm/plat-s5pc1xx/gpiolib.c b/arch/arm/plat-s5pc1xx/gpiolib.c deleted file mode 100644 index 5a97a8f8e368..000000000000 --- a/arch/arm/plat-s5pc1xx/gpiolib.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * arch/arm/plat-s5pc1xx/gpiolib.c - * - * Copyright 2009 Samsung Electronics Co - * Kyungmin Park - * - * S5PC1XX - GPIOlib support - * - * 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 -#include -#include -#include - -#include - -#include -#include -#include -#include - -/* S5PC100 GPIO bank summary: - * - * Bank GPIOs Style INT Type - * A0 8 4Bit GPIO_INT0 - * A1 5 4Bit GPIO_INT1 - * B 8 4Bit GPIO_INT2 - * C 5 4Bit GPIO_INT3 - * D 7 4Bit GPIO_INT4 - * E0 8 4Bit GPIO_INT5 - * E1 6 4Bit GPIO_INT6 - * F0 8 4Bit GPIO_INT7 - * F1 8 4Bit GPIO_INT8 - * F2 8 4Bit GPIO_INT9 - * F3 4 4Bit GPIO_INT10 - * G0 8 4Bit GPIO_INT11 - * G1 3 4Bit GPIO_INT12 - * G2 7 4Bit GPIO_INT13 - * G3 7 4Bit GPIO_INT14 - * H0 8 4Bit WKUP_INT - * H1 8 4Bit WKUP_INT - * H2 8 4Bit WKUP_INT - * H3 8 4Bit WKUP_INT - * I 8 4Bit GPIO_INT15 - * J0 8 4Bit GPIO_INT16 - * J1 5 4Bit GPIO_INT17 - * J2 8 4Bit GPIO_INT18 - * J3 8 4Bit GPIO_INT19 - * J4 4 4Bit GPIO_INT20 - * K0 8 4Bit None - * K1 6 4Bit None - * K2 8 4Bit None - * K3 8 4Bit None - * L0 8 4Bit None - * L1 8 4Bit None - * L2 8 4Bit None - * L3 8 4Bit None - */ - -static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) -{ - return S3C_IRQ_GPIO(chip->base + offset); -} - -static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset) -{ - int base; - - base = chip->base - S5PC100_GPH0(0); - if (base == 0) - return IRQ_EINT(offset); - base = chip->base - S5PC100_GPH1(0); - if (base == 0) - return IRQ_EINT(8 + offset); - base = chip->base - S5PC100_GPH2(0); - if (base == 0) - return IRQ_EINT(16 + offset); - base = chip->base - S5PC100_GPH3(0); - if (base == 0) - return IRQ_EINT(24 + offset); - return -EINVAL; -} - -static struct s3c_gpio_cfg gpio_cfg = { - .set_config = s3c_gpio_setcfg_s3c64xx_4bit, - .set_pull = s3c_gpio_setpull_updown, - .get_pull = s3c_gpio_getpull_updown, -}; - -static struct s3c_gpio_cfg gpio_cfg_eint = { - .cfg_eint = 0xf, - .set_config = s3c_gpio_setcfg_s3c64xx_4bit, - .set_pull = s3c_gpio_setpull_updown, - .get_pull = s3c_gpio_getpull_updown, -}; - -static struct s3c_gpio_cfg gpio_cfg_noint = { - .set_config = s3c_gpio_setcfg_s3c64xx_4bit, - .set_pull = s3c_gpio_setpull_updown, - .get_pull = s3c_gpio_getpull_updown, -}; - -static struct s3c_gpio_chip s5pc100_gpio_chips[] = { - { - .base = S5PC100_GPA0_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPA0(0), - .ngpio = S5PC100_GPIO_A0_NR, - .label = "GPA0", - }, - }, { - .base = S5PC100_GPA1_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPA1(0), - .ngpio = S5PC100_GPIO_A1_NR, - .label = "GPA1", - }, - }, { - .base = S5PC100_GPB_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPB(0), - .ngpio = S5PC100_GPIO_B_NR, - .label = "GPB", - }, - }, { - .base = S5PC100_GPC_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPC(0), - .ngpio = S5PC100_GPIO_C_NR, - .label = "GPC", - }, - }, { - .base = S5PC100_GPD_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPD(0), - .ngpio = S5PC100_GPIO_D_NR, - .label = "GPD", - }, - }, { - .base = S5PC100_GPE0_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPE0(0), - .ngpio = S5PC100_GPIO_E0_NR, - .label = "GPE0", - }, - }, { - .base = S5PC100_GPE1_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPE1(0), - .ngpio = S5PC100_GPIO_E1_NR, - .label = "GPE1", - }, - }, { - .base = S5PC100_GPF0_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPF0(0), - .ngpio = S5PC100_GPIO_F0_NR, - .label = "GPF0", - }, - }, { - .base = S5PC100_GPF1_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPF1(0), - .ngpio = S5PC100_GPIO_F1_NR, - .label = "GPF1", - }, - }, { - .base = S5PC100_GPF2_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPF2(0), - .ngpio = S5PC100_GPIO_F2_NR, - .label = "GPF2", - }, - }, { - .base = S5PC100_GPF3_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPF3(0), - .ngpio = S5PC100_GPIO_F3_NR, - .label = "GPF3", - }, - }, { - .base = S5PC100_GPG0_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPG0(0), - .ngpio = S5PC100_GPIO_G0_NR, - .label = "GPG0", - }, - }, { - .base = S5PC100_GPG1_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPG1(0), - .ngpio = S5PC100_GPIO_G1_NR, - .label = "GPG1", - }, - }, { - .base = S5PC100_GPG2_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPG2(0), - .ngpio = S5PC100_GPIO_G2_NR, - .label = "GPG2", - }, - }, { - .base = S5PC100_GPG3_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPG3(0), - .ngpio = S5PC100_GPIO_G3_NR, - .label = "GPG3", - }, - }, { - .base = S5PC100_GPH0_BASE, - .config = &gpio_cfg_eint, - .chip = { - .base = S5PC100_GPH0(0), - .ngpio = S5PC100_GPIO_H0_NR, - .label = "GPH0", - }, - }, { - .base = S5PC100_GPH1_BASE, - .config = &gpio_cfg_eint, - .chip = { - .base = S5PC100_GPH1(0), - .ngpio = S5PC100_GPIO_H1_NR, - .label = "GPH1", - }, - }, { - .base = S5PC100_GPH2_BASE, - .config = &gpio_cfg_eint, - .chip = { - .base = S5PC100_GPH2(0), - .ngpio = S5PC100_GPIO_H2_NR, - .label = "GPH2", - }, - }, { - .base = S5PC100_GPH3_BASE, - .config = &gpio_cfg_eint, - .chip = { - .base = S5PC100_GPH3(0), - .ngpio = S5PC100_GPIO_H3_NR, - .label = "GPH3", - }, - }, { - .base = S5PC100_GPI_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPI(0), - .ngpio = S5PC100_GPIO_I_NR, - .label = "GPI", - }, - }, { - .base = S5PC100_GPJ0_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPJ0(0), - .ngpio = S5PC100_GPIO_J0_NR, - .label = "GPJ0", - }, - }, { - .base = S5PC100_GPJ1_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPJ1(0), - .ngpio = S5PC100_GPIO_J1_NR, - .label = "GPJ1", - }, - }, { - .base = S5PC100_GPJ2_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPJ2(0), - .ngpio = S5PC100_GPIO_J2_NR, - .label = "GPJ2", - }, - }, { - .base = S5PC100_GPJ3_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPJ3(0), - .ngpio = S5PC100_GPIO_J3_NR, - .label = "GPJ3", - }, - }, { - .base = S5PC100_GPJ4_BASE, - .config = &gpio_cfg, - .chip = { - .base = S5PC100_GPJ4(0), - .ngpio = S5PC100_GPIO_J4_NR, - .label = "GPJ4", - }, - }, { - .base = S5PC100_GPK0_BASE, - .config = &gpio_cfg_noint, - .chip = { - .base = S5PC100_GPK0(0), - .ngpio = S5PC100_GPIO_K0_NR, - .label = "GPK0", - }, - }, { - .base = S5PC100_GPK1_BASE, - .config = &gpio_cfg_noint, - .chip = { - .base = S5PC100_GPK1(0), - .ngpio = S5PC100_GPIO_K1_NR, - .label = "GPK1", - }, - }, { - .base = S5PC100_GPK2_BASE, - .config = &gpio_cfg_noint, - .chip = { - .base = S5PC100_GPK2(0), - .ngpio = S5PC100_GPIO_K2_NR, - .label = "GPK2", - }, - }, { - .base = S5PC100_GPK3_BASE, - .config = &gpio_cfg_noint, - .chip = { - .base = S5PC100_GPK3(0), - .ngpio = S5PC100_GPIO_K3_NR, - .label = "GPK3", - }, - }, { - .base = S5PC100_GPL0_BASE, - .config = &gpio_cfg_noint, - .chip = { - .base = S5PC100_GPL0(0), - .ngpio = S5PC100_GPIO_L0_NR, - .label = "GPL0", - }, - }, { - .base = S5PC100_GPL1_BASE, - .config = &gpio_cfg_noint, - .chip = { - .base = S5PC100_GPL1(0), - .ngpio = S5PC100_GPIO_L1_NR, - .label = "GPL1", - }, - }, { - .base = S5PC100_GPL2_BASE, - .config = &gpio_cfg_noint, - .chip = { - .base = S5PC100_GPL2(0), - .ngpio = S5PC100_GPIO_L2_NR, - .label = "GPL2", - }, - }, { - .base = S5PC100_GPL3_BASE, - .config = &gpio_cfg_noint, - .chip = { - .base = S5PC100_GPL3(0), - .ngpio = S5PC100_GPIO_L3_NR, - .label = "GPL3", - }, - }, { - .base = S5PC100_GPL4_BASE, - .config = &gpio_cfg_noint, - .chip = { - .base = S5PC100_GPL4(0), - .ngpio = S5PC100_GPIO_L4_NR, - .label = "GPL4", - }, - }, -}; - -/* FIXME move from irq-gpio.c */ -extern struct irq_chip s5pc1xx_gpioint; -extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc); - -static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip) -{ - - /* Interrupt */ - if (chip->config == &gpio_cfg) { - int i, irq; - - chip->chip.to_irq = s5pc1xx_gpiolib_to_irq; - - for (i = 0; i < chip->chip.ngpio; i++) { - irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i; - set_irq_chip(irq, &s5pc1xx_gpioint); - set_irq_data(irq, &chip->chip); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } - } else if (chip->config == &gpio_cfg_eint) - chip->chip.to_irq = s5pc1xx_gpiolib_to_eint; -} - -static __init int s5pc1xx_gpiolib_init(void) -{ - struct s3c_gpio_chip *chip; - int nr_chips; - - chip = s5pc100_gpio_chips; - nr_chips = ARRAY_SIZE(s5pc100_gpio_chips); - - for (; nr_chips > 0; nr_chips--, chip++) - s5pc100_gpiolib_link(chip); - - samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, - ARRAY_SIZE(s5pc100_gpio_chips)); - /* Interrupt */ - set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler); - - return 0; -} -core_initcall(s5pc1xx_gpiolib_init); diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h b/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h deleted file mode 100644 index 43c7bc8bf784..000000000000 --- a/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h +++ /dev/null @@ -1,70 +0,0 @@ -/* linux/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h - * - * Copyright 2009 Samsung Electronics Co. - * Byungho Min - * - * S5PC1XX - GPIO register definitions - */ - -#ifndef __ASM_PLAT_S5PC1XX_REGS_GPIO_H -#define __ASM_PLAT_S5PC1XX_REGS_GPIO_H __FILE__ - -#include - -/* S5PC100 */ -#define S5PC100_GPIO_BASE S5PC1XX_VA_GPIO -#define S5PC100_GPA0_BASE (S5PC100_GPIO_BASE + 0x0000) -#define S5PC100_GPA1_BASE (S5PC100_GPIO_BASE + 0x0020) -#define S5PC100_GPB_BASE (S5PC100_GPIO_BASE + 0x0040) -#define S5PC100_GPC_BASE (S5PC100_GPIO_BASE + 0x0060) -#define S5PC100_GPD_BASE (S5PC100_GPIO_BASE + 0x0080) -#define S5PC100_GPE0_BASE (S5PC100_GPIO_BASE + 0x00A0) -#define S5PC100_GPE1_BASE (S5PC100_GPIO_BASE + 0x00C0) -#define S5PC100_GPF0_BASE (S5PC100_GPIO_BASE + 0x00E0) -#define S5PC100_GPF1_BASE (S5PC100_GPIO_BASE + 0x0100) -#define S5PC100_GPF2_BASE (S5PC100_GPIO_BASE + 0x0120) -#define S5PC100_GPF3_BASE (S5PC100_GPIO_BASE + 0x0140) -#define S5PC100_GPG0_BASE (S5PC100_GPIO_BASE + 0x0160) -#define S5PC100_GPG1_BASE (S5PC100_GPIO_BASE + 0x0180) -#define S5PC100_GPG2_BASE (S5PC100_GPIO_BASE + 0x01A0) -#define S5PC100_GPG3_BASE (S5PC100_GPIO_BASE + 0x01C0) -#define S5PC100_GPH0_BASE (S5PC100_GPIO_BASE + 0x0C00) -#define S5PC100_GPH1_BASE (S5PC100_GPIO_BASE + 0x0C20) -#define S5PC100_GPH2_BASE (S5PC100_GPIO_BASE + 0x0C40) -#define S5PC100_GPH3_BASE (S5PC100_GPIO_BASE + 0x0C60) -#define S5PC100_GPI_BASE (S5PC100_GPIO_BASE + 0x01E0) -#define S5PC100_GPJ0_BASE (S5PC100_GPIO_BASE + 0x0200) -#define S5PC100_GPJ1_BASE (S5PC100_GPIO_BASE + 0x0220) -#define S5PC100_GPJ2_BASE (S5PC100_GPIO_BASE + 0x0240) -#define S5PC100_GPJ3_BASE (S5PC100_GPIO_BASE + 0x0260) -#define S5PC100_GPJ4_BASE (S5PC100_GPIO_BASE + 0x0280) -#define S5PC100_GPK0_BASE (S5PC100_GPIO_BASE + 0x02A0) -#define S5PC100_GPK1_BASE (S5PC100_GPIO_BASE + 0x02C0) -#define S5PC100_GPK2_BASE (S5PC100_GPIO_BASE + 0x02E0) -#define S5PC100_GPK3_BASE (S5PC100_GPIO_BASE + 0x0300) -#define S5PC100_GPL0_BASE (S5PC100_GPIO_BASE + 0x0320) -#define S5PC100_GPL1_BASE (S5PC100_GPIO_BASE + 0x0340) -#define S5PC100_GPL2_BASE (S5PC100_GPIO_BASE + 0x0360) -#define S5PC100_GPL3_BASE (S5PC100_GPIO_BASE + 0x0380) -#define S5PC100_GPL4_BASE (S5PC100_GPIO_BASE + 0x03A0) -#define S5PC100_EINT_BASE (S5PC100_GPIO_BASE + 0x0E00) - -#define S5PC100_UHOST (S5PC100_GPIO_BASE + 0x0B68) -#define S5PC100_PDNEN (S5PC100_GPIO_BASE + 0x0F80) - -/* PDNEN */ -#define S5PC100_PDNEN_CFG_PDNEN (1 << 1) -#define S5PC100_PDNEN_CFG_AUTO (0 << 1) -#define S5PC100_PDNEN_POWERDOWN (1 << 0) -#define S5PC100_PDNEN_NORMAL (0 << 0) - -/* Common part */ -/* External interrupt base is same at both s5pc100 and s5pc110 */ -#define S5PC1XX_EINT_BASE (S5PC100_EINT_BASE) - -#define S5PC100_GPx_INPUT(__gpio) (0x0 << ((__gpio) * 4)) -#define S5PC100_GPx_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) -#define S5PC100_GPx_CONMASK(__gpio) (0xf << ((__gpio) * 4)) - -#endif /* __ASM_PLAT_S5PC1XX_REGS_GPIO_H */ - -- cgit v1.2.3-59-g8ed1b From c8bb9635f926aaf15987450c57af05e422874b92 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 18 May 2010 12:38:42 +0200 Subject: ARM: S5PC100: gpio.h cleanup This patch renames gpio related registers from s5pc1xx to s5pc100 to better match the plat-s5p framework style. GPIO_MP* defines now used anywhere thus has been removed. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Ben Dooks --- arch/arm/mach-s5pc100/include/mach/gpio.h | 95 ++++++++++++-------------- arch/arm/mach-s5pc100/include/mach/regs-gpio.h | 8 +-- 2 files changed, 46 insertions(+), 57 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s5pc100/include/mach/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h index 2c4cbe8ee6b7..29a8a12d9b4f 100644 --- a/arch/arm/mach-s5pc100/include/mach/gpio.h +++ b/arch/arm/mach-s5pc100/include/mach/gpio.h @@ -12,6 +12,9 @@ * published by the Free Software Foundation. */ +#ifndef __ASM_ARCH_GPIO_H +#define __ASM_ARCH_GPIO_H __FILE__ + #define gpio_get_value __gpio_get_value #define gpio_set_value __gpio_set_value #define gpio_cansleep __gpio_cansleep @@ -52,11 +55,6 @@ #define S5PC100_GPIO_L2_NR (8) #define S5PC100_GPIO_L3_NR (8) #define S5PC100_GPIO_L4_NR (8) -#define S5PC100_GPIO_MP00_NR (8) -#define S5PC100_GPIO_MP01_NR (8) -#define S5PC100_GPIO_MP02_NR (8) -#define S5PC100_GPIO_MP03_NR (8) -#define S5PC100_GPIO_MP04_NR (5) /* GPIO bank numbes */ @@ -65,50 +63,45 @@ * change from one gpio bank to another can be caught. */ -#define S5PC1XX_GPIO_NEXT(__gpio) \ +#define S5PC100_GPIO_NEXT(__gpio) \ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) -enum s3c_gpio_number { +enum s5p_gpio_number { S5PC100_GPIO_A0_START = 0, - S5PC100_GPIO_A1_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_A0), - S5PC100_GPIO_B_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_A1), - S5PC100_GPIO_C_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_B), - S5PC100_GPIO_D_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_C), - S5PC100_GPIO_E0_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_D), - S5PC100_GPIO_E1_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_E0), - S5PC100_GPIO_F0_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_E1), - S5PC100_GPIO_F1_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F0), - S5PC100_GPIO_F2_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F1), - S5PC100_GPIO_F3_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F2), - S5PC100_GPIO_G0_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F3), - S5PC100_GPIO_G1_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G0), - S5PC100_GPIO_G2_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G1), - S5PC100_GPIO_G3_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G2), - S5PC100_GPIO_H0_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G3), - S5PC100_GPIO_H1_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H0), - S5PC100_GPIO_H2_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H1), - S5PC100_GPIO_H3_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H2), - S5PC100_GPIO_I_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H3), - S5PC100_GPIO_J0_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_I), - S5PC100_GPIO_J1_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J0), - S5PC100_GPIO_J2_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J1), - S5PC100_GPIO_J3_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J2), - S5PC100_GPIO_J4_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J3), - S5PC100_GPIO_K0_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J4), - S5PC100_GPIO_K1_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K0), - S5PC100_GPIO_K2_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K1), - S5PC100_GPIO_K3_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K2), - S5PC100_GPIO_L0_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K3), - S5PC100_GPIO_L1_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L0), - S5PC100_GPIO_L2_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L1), - S5PC100_GPIO_L3_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L2), - S5PC100_GPIO_L4_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L3), - S5PC100_GPIO_MP00_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L4), - S5PC100_GPIO_MP01_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP00), - S5PC100_GPIO_MP02_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP01), - S5PC100_GPIO_MP03_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP02), - S5PC100_GPIO_MP04_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP03), - S5PC100_GPIO_END = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP04), + S5PC100_GPIO_A1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_A0), + S5PC100_GPIO_B_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_A1), + S5PC100_GPIO_C_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_B), + S5PC100_GPIO_D_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_C), + S5PC100_GPIO_E0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_D), + S5PC100_GPIO_E1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_E0), + S5PC100_GPIO_F0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_E1), + S5PC100_GPIO_F1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_F0), + S5PC100_GPIO_F2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_F1), + S5PC100_GPIO_F3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_F2), + S5PC100_GPIO_G0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_F3), + S5PC100_GPIO_G1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_G0), + S5PC100_GPIO_G2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_G1), + S5PC100_GPIO_G3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_G2), + S5PC100_GPIO_H0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_G3), + S5PC100_GPIO_H1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_H0), + S5PC100_GPIO_H2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_H1), + S5PC100_GPIO_H3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_H2), + S5PC100_GPIO_I_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_H3), + S5PC100_GPIO_J0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_I), + S5PC100_GPIO_J1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_J0), + S5PC100_GPIO_J2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_J1), + S5PC100_GPIO_J3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_J2), + S5PC100_GPIO_J4_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_J3), + S5PC100_GPIO_K0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_J4), + S5PC100_GPIO_K1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_K0), + S5PC100_GPIO_K2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_K1), + S5PC100_GPIO_K3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_K2), + S5PC100_GPIO_L0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_K3), + S5PC100_GPIO_L1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_L0), + S5PC100_GPIO_L2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_L1), + S5PC100_GPIO_L3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_L2), + S5PC100_GPIO_L4_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_L3), + S5PC100_GPIO_END = S5PC100_GPIO_NEXT(S5PC100_GPIO_L4), }; /* S5PC100 GPIO number definitions. */ @@ -146,17 +139,13 @@ enum s3c_gpio_number { #define S5PC100_GPL2(_nr) (S5PC100_GPIO_L2_START + (_nr)) #define S5PC100_GPL3(_nr) (S5PC100_GPIO_L3_START + (_nr)) #define S5PC100_GPL4(_nr) (S5PC100_GPIO_L4_START + (_nr)) -#define S5PC100_MP00(_nr) (S5PC100_GPIO_MP00_START + (_nr)) -#define S5PC100_MP01(_nr) (S5PC100_GPIO_MP01_START + (_nr)) -#define S5PC100_MP02(_nr) (S5PC100_GPIO_MP02_START + (_nr)) -#define S5PC100_MP03(_nr) (S5PC100_GPIO_MP03_START + (_nr)) -#define S5PC100_MP04(_nr) (S5PC100_GPIO_MP04_START + (_nr)) -#define S5PC100_MP05(_nr) (S5PC100_GPIO_MP05_START + (_nr)) -/* It used the end of the S5PC1XX gpios */ +/* It used the end of the S5PC100 gpios */ #define S3C_GPIO_END S5PC100_GPIO_END /* define the number of gpios we need to the one after the MP04() range */ #define ARCH_NR_GPIOS (S5PC100_GPIO_END + 1) #include + +#endif /* __ASM_ARCH_GPIO_H */ diff --git a/arch/arm/mach-s5pc100/include/mach/regs-gpio.h b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h index 43c7bc8bf784..68666913354c 100644 --- a/arch/arm/mach-s5pc100/include/mach/regs-gpio.h +++ b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h @@ -3,11 +3,11 @@ * Copyright 2009 Samsung Electronics Co. * Byungho Min * - * S5PC1XX - GPIO register definitions + * S5PC100 - GPIO register definitions */ -#ifndef __ASM_PLAT_S5PC1XX_REGS_GPIO_H -#define __ASM_PLAT_S5PC1XX_REGS_GPIO_H __FILE__ +#ifndef __ASM_MACH_S5PC100_REGS_GPIO_H +#define __ASM_MACH_S5PC100_REGS_GPIO_H __FILE__ #include @@ -66,5 +66,5 @@ #define S5PC100_GPx_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) #define S5PC100_GPx_CONMASK(__gpio) (0xf << ((__gpio) * 4)) -#endif /* __ASM_PLAT_S5PC1XX_REGS_GPIO_H */ +#endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */ -- cgit v1.2.3-59-g8ed1b From b884c0e07058478bff82b8edcecff4e2919fa361 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 18 May 2010 12:38:43 +0200 Subject: ARM: S5PC100: Move frame buffer helpers from plat-s5pc1xx to mach-s5pc100 Move frame buffer helpers from plat-s5pc1xx to mach-s5pc100. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Ben Dooks --- arch/arm/mach-s5pc100/Kconfig | 7 ++++- arch/arm/mach-s5pc100/Makefile | 1 + arch/arm/mach-s5pc100/setup-fb-24bpp.c | 48 ++++++++++++++++++++++++++++++++++ arch/arm/plat-s5pc1xx/Kconfig | 5 ---- arch/arm/plat-s5pc1xx/Makefile | 1 - arch/arm/plat-s5pc1xx/setup-fb-24bpp.c | 48 ---------------------------------- 6 files changed, 55 insertions(+), 55 deletions(-) create mode 100644 arch/arm/mach-s5pc100/setup-fb-24bpp.c delete mode 100644 arch/arm/plat-s5pc1xx/setup-fb-24bpp.c (limited to 'arch') diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig index 27ec167d2808..7d9b68c8fef5 100644 --- a/arch/arm/mach-s5pc100/Kconfig +++ b/arch/arm/mach-s5pc100/Kconfig @@ -12,6 +12,11 @@ config CPU_S5PC100 help Enable S5PC100 CPU support +config S5PC100_SETUP_FB_24BPP + bool + help + Common setup code for S5PC1XX with an 24bpp RGB display helper. + config S5PC100_SETUP_SDHCI bool select S5PC1XX_SETUP_SDHCI_GPIO @@ -28,7 +33,7 @@ config MACH_SMDKC100 select S3C_DEV_HSMMC2 select S5PC1XX_SETUP_I2C0 select S5PC1XX_SETUP_I2C1 - select S5PC1XX_SETUP_FB_24BPP + select S5PC100_SETUP_FB_24BPP select S5PC100_SETUP_SDHCI help Machine support for the Samsung SMDKC100 diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile index 4199ce2b161a..1d1276c29cff 100644 --- a/arch/arm/mach-s5pc100/Makefile +++ b/arch/arm/mach-s5pc100/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_S5PC100) += cpu.o gpiolib.o # Helper and device support +obj-$(CONFIG_S5PC100_SETUP_FB_24BPP) += setup-fb-24bpp.o obj-$(CONFIG_S5PC100_SETUP_SDHCI) += setup-sdhci.o # machine support diff --git a/arch/arm/mach-s5pc100/setup-fb-24bpp.c b/arch/arm/mach-s5pc100/setup-fb-24bpp.c new file mode 100644 index 000000000000..6eba6cb8e2f4 --- /dev/null +++ b/arch/arm/mach-s5pc100/setup-fb-24bpp.c @@ -0,0 +1,48 @@ +/* + * linux/arch/arm/mach-s5pc100/setup-fb-24bpp.c + * + * Copyright 2009 Samsung Electronics + * + * Base S5PC100 setup information for 24bpp LCD framebuffer + * + * 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 +#include +#include +#include + +#include +#include +#include +#include + +#define DISR_OFFSET 0x7008 + +void s5pc100_fb_gpio_setup_24bpp(void) +{ + unsigned int gpio = 0; + + for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + } + + for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + } + + for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + } + + for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + } +} diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig index 98bbaf9d2219..708f7a0de065 100644 --- a/arch/arm/plat-s5pc1xx/Kconfig +++ b/arch/arm/plat-s5pc1xx/Kconfig @@ -39,11 +39,6 @@ config CPU_S5PC100_CLOCK # platform specific device setup -config S5PC1XX_SETUP_FB_24BPP - bool - help - Common setup code for S5PC1XX with an 24bpp RGB display helper. - config S5PC1XX_SETUP_I2C0 bool default y diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile index 540fca5b4860..a5b90c0cc487 100644 --- a/arch/arm/plat-s5pc1xx/Makefile +++ b/arch/arm/plat-s5pc1xx/Makefile @@ -23,7 +23,6 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK) += s5pc100-clock.o # Device setup -obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o obj-$(CONFIG_S5PC1XX_SETUP_I2C0) += setup-i2c0.o obj-$(CONFIG_S5PC1XX_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5PC1XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o diff --git a/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c deleted file mode 100644 index b02c36fb10d1..000000000000 --- a/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * linux/arch/arm/plat-s5pc100/setup-fb-24bpp.c - * - * Copyright 2009 Samsung Electronics - * - * Base S5PC1XX setup information for 24bpp LCD framebuffer - * - * 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 -#include -#include -#include - -#include -#include -#include -#include - -#define DISR_OFFSET 0x7008 - -void s5pc100_fb_gpio_setup_24bpp(void) -{ - unsigned int gpio = 0; - - for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) { - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); - } - - for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) { - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); - } - - for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) { - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); - } - - for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) { - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); - } -} -- cgit v1.2.3-59-g8ed1b From 51ffd971edb2d5187007967c14712a8ed956c092 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 18 May 2010 12:38:44 +0200 Subject: ARM: S5PC100: Move i2c helpers from plat-s5pc1xx to mach-s5pc100 Move i2c helpers from plat-s5pc1xx to mach-s5pc100. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Ben Dooks --- arch/arm/mach-s5pc100/Kconfig | 8 ++++++-- arch/arm/mach-s5pc100/Makefile | 2 ++ arch/arm/mach-s5pc100/setup-i2c0.c | 30 ++++++++++++++++++++++++++++++ arch/arm/mach-s5pc100/setup-i2c1.c | 30 ++++++++++++++++++++++++++++++ arch/arm/plat-s5pc1xx/Kconfig | 14 -------------- arch/arm/plat-s5pc1xx/Makefile | 2 -- arch/arm/plat-s5pc1xx/setup-i2c0.c | 30 ------------------------------ arch/arm/plat-s5pc1xx/setup-i2c1.c | 30 ------------------------------ 8 files changed, 68 insertions(+), 78 deletions(-) create mode 100644 arch/arm/mach-s5pc100/setup-i2c0.c create mode 100644 arch/arm/mach-s5pc100/setup-i2c1.c delete mode 100644 arch/arm/plat-s5pc1xx/setup-i2c0.c delete mode 100644 arch/arm/plat-s5pc1xx/setup-i2c1.c (limited to 'arch') diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig index 7d9b68c8fef5..8593337784e1 100644 --- a/arch/arm/mach-s5pc100/Kconfig +++ b/arch/arm/mach-s5pc100/Kconfig @@ -23,6 +23,11 @@ config S5PC100_SETUP_SDHCI help Internal helper functions for S5PC100 based SDHCI systems +config S5PC100_SETUP_I2C1 + bool + help + Common setup code for i2c bus 1. + config MACH_SMDKC100 bool "SMDKC100" select CPU_S5PC100 @@ -31,9 +36,8 @@ config MACH_SMDKC100 select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 - select S5PC1XX_SETUP_I2C0 - select S5PC1XX_SETUP_I2C1 select S5PC100_SETUP_FB_24BPP + select S5PC100_SETUP_I2C1 select S5PC100_SETUP_SDHCI help Machine support for the Samsung SMDKC100 diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile index 1d1276c29cff..373bc546eae8 100644 --- a/arch/arm/mach-s5pc100/Makefile +++ b/arch/arm/mach-s5pc100/Makefile @@ -12,10 +12,12 @@ obj- := # Core support for S5PC100 system obj-$(CONFIG_CPU_S5PC100) += cpu.o gpiolib.o +obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o # Helper and device support obj-$(CONFIG_S5PC100_SETUP_FB_24BPP) += setup-fb-24bpp.o +obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5PC100_SETUP_SDHCI) += setup-sdhci.o # machine support diff --git a/arch/arm/mach-s5pc100/setup-i2c0.c b/arch/arm/mach-s5pc100/setup-i2c0.c new file mode 100644 index 000000000000..dd3174e6ecc5 --- /dev/null +++ b/arch/arm/mach-s5pc100/setup-i2c0.c @@ -0,0 +1,30 @@ +/* linux/arch/arm/mach-s5pc100/setup-i2c0.c + * + * Copyright 2009 Samsung Electronics Co. + * Byungho Min + * + * Base S5PC100 I2C bus 0 gpio configuration + * + * Based on plat-s3c64xx/setup-i2c0.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 +#include + +struct platform_device; /* don't need the contents */ + +#include +#include +#include + +void s3c_i2c0_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP); + s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP); +} diff --git a/arch/arm/mach-s5pc100/setup-i2c1.c b/arch/arm/mach-s5pc100/setup-i2c1.c new file mode 100644 index 000000000000..d1fec26b69ee --- /dev/null +++ b/arch/arm/mach-s5pc100/setup-i2c1.c @@ -0,0 +1,30 @@ +/* linux/arch/arm/mach-s5pc100/setup-i2c1.c + * + * Copyright 2009 Samsung Electronics Co. + * Byungho Min + * + * Base S5PC100 I2C bus 1 gpio configuration + * + * Based on plat-s3c64xx/setup-i2c1.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 +#include + +struct platform_device; /* don't need the contents */ + +#include +#include +#include + +void s3c_i2c1_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP); + s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP); +} diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig index 708f7a0de065..c7bd2bbda239 100644 --- a/arch/arm/plat-s5pc1xx/Kconfig +++ b/arch/arm/plat-s5pc1xx/Kconfig @@ -39,20 +39,6 @@ config CPU_S5PC100_CLOCK # platform specific device setup -config S5PC1XX_SETUP_I2C0 - bool - default y - help - Common setup code for i2c bus 0. - - Note, currently since i2c0 is always compiled, this setup helper - is always compiled with it. - -config S5PC1XX_SETUP_I2C1 - bool - help - Common setup code for i2c bus 1. - config S5PC1XX_SETUP_SDHCI_GPIO bool help diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile index a5b90c0cc487..9ce6409a9e02 100644 --- a/arch/arm/plat-s5pc1xx/Makefile +++ b/arch/arm/plat-s5pc1xx/Makefile @@ -23,6 +23,4 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK) += s5pc100-clock.o # Device setup -obj-$(CONFIG_S5PC1XX_SETUP_I2C0) += setup-i2c0.o -obj-$(CONFIG_S5PC1XX_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5PC1XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o diff --git a/arch/arm/plat-s5pc1xx/setup-i2c0.c b/arch/arm/plat-s5pc1xx/setup-i2c0.c deleted file mode 100644 index 5e4a7c3a231e..000000000000 --- a/arch/arm/plat-s5pc1xx/setup-i2c0.c +++ /dev/null @@ -1,30 +0,0 @@ -/* linux/arch/arm/plat-s5pc1xx/setup-i2c0.c - * - * Copyright 2009 Samsung Electronics Co. - * Byungho Min - * - * Base S5PC1XX I2C bus 0 gpio configuration - * - * Based on plat-s3c64xx/setup-i2c0.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 -#include - -struct platform_device; /* don't need the contents */ - -#include -#include -#include - -void s3c_i2c0_cfg_gpio(struct platform_device *dev) -{ - s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2)); - s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP); - s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2)); - s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP); -} diff --git a/arch/arm/plat-s5pc1xx/setup-i2c1.c b/arch/arm/plat-s5pc1xx/setup-i2c1.c deleted file mode 100644 index a0a8b4ae6ad8..000000000000 --- a/arch/arm/plat-s5pc1xx/setup-i2c1.c +++ /dev/null @@ -1,30 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c - * - * Copyright 2009 Samsung Electronics Co. - * Byungho Min - * - * Base S5PC1XX I2C bus 1 gpio configuration - * - * Based on plat-s3c64xx/setup-i2c1.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 -#include - -struct platform_device; /* don't need the contents */ - -#include -#include -#include - -void s3c_i2c1_cfg_gpio(struct platform_device *dev) -{ - s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2)); - s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP); - s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2)); - s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP); -} -- cgit v1.2.3-59-g8ed1b From 73e59b1d6b69f5ae02e3be5e2b3259c46d8bb27a Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Tue, 4 May 2010 13:12:41 +0200 Subject: ARM: SAMSUNG: Move mach/ts.h to plat/ts.h This moves mach-s3c2410/include/mach/ts.h to plat-samsung/include/plat/ts.h in order to prepare for s3c64xx support in the touchscreen driver. Signed-off-by: Maurus Cuelenaere Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/ts.h | 21 --------------------- arch/arm/mach-s3c2410/mach-h1940.c | 2 +- arch/arm/plat-s3c24xx/devs.c | 3 +-- arch/arm/plat-samsung/include/plat/ts.h | 21 +++++++++++++++++++++ drivers/input/touchscreen/s3c2410_ts.c | 2 +- 5 files changed, 24 insertions(+), 25 deletions(-) delete mode 100644 arch/arm/mach-s3c2410/include/mach/ts.h create mode 100644 arch/arm/plat-samsung/include/plat/ts.h (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/include/mach/ts.h b/arch/arm/mach-s3c2410/include/mach/ts.h deleted file mode 100644 index dc361700d695..000000000000 --- a/arch/arm/mach-s3c2410/include/mach/ts.h +++ /dev/null @@ -1,21 +0,0 @@ -/* linux/include/asm/arch-s3c2410/ts.h - * - * Copyright (c) 2005 Arnaud Patard - * - * 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. -*/ - -#ifndef __ASM_ARM_TS_H -#define __ASM_ARM_TS_H - -struct s3c2410_ts_mach_info { - int delay; - int presc; - int oversampling_shift; -}; - -extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *); - -#endif /* __ASM_ARM_TS_H */ diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index d2a2fad7db97..b1f7dbb3bb60 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include @@ -57,6 +56,7 @@ #include #include #include +#include static struct map_desc h1940_iodesc[] __initdata = { [0] = { diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index cd5b41d0b5a4..58583732b29a 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -39,8 +39,7 @@ #include #include #include - -#include +#include /* Serial port registrations */ diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h new file mode 100644 index 000000000000..8a51675f6b03 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/ts.h @@ -0,0 +1,21 @@ +/* arch/arm/plat-samsung/include/plat/ts.h + * + * Copyright (c) 2005 Arnaud Patard + * + * 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. +*/ + +#ifndef __ASM_ARM_TS_H +#define __ASM_ARM_TS_H + +struct s3c2410_ts_mach_info { + int delay; + int presc; + int oversampling_shift; +}; + +extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *); + +#endif /* __ASM_ARM_TS_H */ diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index 98a7d1279486..a2e122878f30 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -37,9 +37,9 @@ #include #include +#include #include -#include #define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)) -- cgit v1.2.3-59-g8ed1b From 909de0d67dbd9488d5f77bdcadcd34264fea3c02 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Tue, 4 May 2010 13:12:44 +0200 Subject: ARM: S3C64XX: Add touchscreen platform device definition This patch adds the touchscreen platform device definition for S3C64XX boards. Signed-off-by: Maurus Cuelenaere Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/Makefile | 1 + arch/arm/mach-s3c64xx/dev-ts.c | 61 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/plat-samsung/Kconfig | 6 +++++ 3 files changed, 68 insertions(+) create mode 100644 arch/arm/mach-s3c64xx/dev-ts.c (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index d78c3dd43a1a..a10f1fc6b023 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -58,3 +58,4 @@ obj-$(CONFIG_MACH_HMT) += mach-hmt.o obj-y += dev-uart.o obj-y += dev-audio.o obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o +obj-$(CONFIG_S3C64XX_DEV_TS) += dev-ts.o diff --git a/arch/arm/mach-s3c64xx/dev-ts.c b/arch/arm/mach-s3c64xx/dev-ts.c new file mode 100644 index 000000000000..17cc7934afbe --- /dev/null +++ b/arch/arm/mach-s3c64xx/dev-ts.c @@ -0,0 +1,61 @@ +/* linux/arch/arm/mach-s3c64xx/dev-ts.c + * + * Copyright (c) 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks , + * + * Adapted by Maurus Cuelenaere for s3c64xx + * + * S3C64XX series device definition for touchscreen device + * + * 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 +#include +#include + +#include +#include + +#include +#include + +static struct resource s3c_ts_resource[] = { + [0] = { + .start = S3C64XX_PA_ADC, + .end = S3C64XX_PA_ADC + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TC, + .end = IRQ_TC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_ts = { + .name = "s3c64xx-ts", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_ts_resource), + .resource = s3c_ts_resource, +}; + +void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd) +{ + struct s3c2410_ts_mach_info *npd; + + if (!pd) { + printk(KERN_ERR "%s: no platform data\n", __func__); + return; + } + + npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + + s3c_device_ts.dev.platform_data = npd; +} +EXPORT_SYMBOL(s3c24xx_ts_set_platdata); diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 711d5a4cce58..896b171bd430 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -206,6 +206,12 @@ config S3C64XX_DEV_SPI Compile in platform device definitions for S3C64XX's type SPI controllers. +config S3C64XX_DEV_TS + bool + help + Common in platform device definitions for S3C64XX touchscreen + device + # DMA config S3C_DMA -- cgit v1.2.3-59-g8ed1b From 5bfdca146edc558ae6b3bac6b05dc5b1f094fbf3 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Date: Tue, 18 May 2010 20:44:27 +0900 Subject: ARM: SAMSUNG: Implements cfg_gpio function for Samsung touchscreen This patch implements cfg_gpio function for Samsung touchscreen. And also modifies the H1940 machine respectively. Signed-off-by: Naveen Krishna Ch Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/Kconfig | 1 + arch/arm/mach-s3c2410/mach-h1940.c | 1 + arch/arm/plat-s3c24xx/Kconfig | 5 +++++ arch/arm/plat-s3c24xx/Makefile | 1 + arch/arm/plat-s3c24xx/setup-ts.c | 34 +++++++++++++++++++++++++++++++++ arch/arm/plat-samsung/include/plat/ts.h | 4 ++++ 6 files changed, 46 insertions(+) create mode 100644 arch/arm/plat-s3c24xx/setup-ts.c (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index a4c0b3fcdbba..7245a55795dc 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -77,6 +77,7 @@ config ARCH_H1940 select PM_H1940 if PM select S3C_DEV_USB_HOST select S3C_DEV_NAND + select S3C2410_SETUP_TS help Say Y here if you are using the HP IPAQ H1940 diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index b1f7dbb3bb60..779b45b3f80f 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -146,6 +146,7 @@ static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = { .delay = 10000, .presc = 49, .oversampling_shift = 2, + .cfg_gpio = s3c24xx_ts_cfg_gpio, }; /** diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index 3ce8f010b3c6..984bf66826d2 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig @@ -164,4 +164,9 @@ config S3C24XX_SIMTEC_AUDIO help Add audio devices for common Simtec S3C24XX boards +config S3C2410_SETUP_TS + bool + help + Compile in platform device definition for Samsung TouchScreen. + endif diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index 44aea8868f89..c2064c308719 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o # device specific setup and/or initialisation obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o +obj-$(CONFIG_S3C2410_SETUP_TS) += setup-ts.o # SPI gpio central GPIO functions diff --git a/arch/arm/plat-s3c24xx/setup-ts.c b/arch/arm/plat-s3c24xx/setup-ts.c new file mode 100644 index 000000000000..ed2638663675 --- /dev/null +++ b/arch/arm/plat-s3c24xx/setup-ts.c @@ -0,0 +1,34 @@ +/* linux/arch/arm/plat-s3c24xx/setup-ts.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Based on S3C24XX setup for i2c device + * + * 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 +#include + +struct platform_device; /* don't need the contents */ + +#include +#include + +/** + * s3c24xx_ts_cfg_gpio - configure gpio for s3c2410 systems + * + * Configure the GPIO for the S3C2410 system, where we have external FETs + * connected to the device (later systems such as the S3C2440 integrate + * these into the device). + */ +void s3c24xx_ts_cfg_gpio(struct platform_device *dev) +{ + s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON); + s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON); + s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON); + s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON); +} diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h index 8a51675f6b03..26fdb22e0fc2 100644 --- a/arch/arm/plat-samsung/include/plat/ts.h +++ b/arch/arm/plat-samsung/include/plat/ts.h @@ -14,8 +14,12 @@ struct s3c2410_ts_mach_info { int delay; int presc; int oversampling_shift; + void (*cfg_gpio)(struct platform_device *dev); }; extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *); +/* defined by architecture to configure gpio */ +extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev); + #endif /* __ASM_ARM_TS_H */ -- cgit v1.2.3-59-g8ed1b From 2b6c02abca5a04bf8d9f8a3b1976a5b10d317603 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 19 May 2010 14:36:28 +0900 Subject: ARM: SAMSUNG: Move s3c64xx dev-ts.c to plat-samsung and rename configuration Move the arch/arm/mach-s3c64xx/dev-ts.c file to arch/arm/plat-samsung and rename the Kconfig entry appropriately. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c64xx/dev-ts.c | 61 ------------------------------------------ arch/arm/plat-samsung/Kconfig | 5 ++-- arch/arm/plat-samsung/Makefile | 1 + arch/arm/plat-samsung/dev-ts.c | 61 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 64 deletions(-) delete mode 100644 arch/arm/mach-s3c64xx/dev-ts.c create mode 100644 arch/arm/plat-samsung/dev-ts.c (limited to 'arch') diff --git a/arch/arm/mach-s3c64xx/dev-ts.c b/arch/arm/mach-s3c64xx/dev-ts.c deleted file mode 100644 index 17cc7934afbe..000000000000 --- a/arch/arm/mach-s3c64xx/dev-ts.c +++ /dev/null @@ -1,61 +0,0 @@ -/* linux/arch/arm/mach-s3c64xx/dev-ts.c - * - * Copyright (c) 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks , - * - * Adapted by Maurus Cuelenaere for s3c64xx - * - * S3C64XX series device definition for touchscreen device - * - * 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 -#include -#include - -#include -#include - -#include -#include - -static struct resource s3c_ts_resource[] = { - [0] = { - .start = S3C64XX_PA_ADC, - .end = S3C64XX_PA_ADC + SZ_256 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TC, - .end = IRQ_TC, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device s3c_device_ts = { - .name = "s3c64xx-ts", - .id = -1, - .num_resources = ARRAY_SIZE(s3c_ts_resource), - .resource = s3c_ts_resource, -}; - -void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd) -{ - struct s3c2410_ts_mach_info *npd; - - if (!pd) { - printk(KERN_ERR "%s: no platform data\n", __func__); - return; - } - - npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL); - if (!npd) - printk(KERN_ERR "%s: no memory for platform data\n", __func__); - - s3c_device_ts.dev.platform_data = npd; -} -EXPORT_SYMBOL(s3c24xx_ts_set_platdata); diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 896b171bd430..229919e9744c 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -206,11 +206,10 @@ config S3C64XX_DEV_SPI Compile in platform device definitions for S3C64XX's type SPI controllers. -config S3C64XX_DEV_TS +config SAMSUNG_DEV_TS bool help - Common in platform device definitions for S3C64XX touchscreen - device + Common in platform device definitions for touchscreen device # DMA diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 7068af322e73..48288499a3b9 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o obj-$(CONFIG_SAMSUNG_DEV_ADC) += dev-adc.o +obj-$(CONFIG_SAMSUNG_DEV_TS) += dev-ts.o # DMA support diff --git a/arch/arm/plat-samsung/dev-ts.c b/arch/arm/plat-samsung/dev-ts.c new file mode 100644 index 000000000000..236ef8427d7d --- /dev/null +++ b/arch/arm/plat-samsung/dev-ts.c @@ -0,0 +1,61 @@ +/* linux/arch/arm/mach-s3c64xx/dev-ts.c + * + * Copyright (c) 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks , + * + * Adapted by Maurus Cuelenaere for s3c64xx + * + * S3C64XX series device definition for touchscreen device + * + * 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 +#include +#include + +#include +#include + +#include +#include + +static struct resource s3c_ts_resource[] = { + [0] = { + .start = SAMSUNG_PA_ADC, + .end = SAMSUNG_PA_ADC + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TC, + .end = IRQ_TC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_ts = { + .name = "s3c64xx-ts", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_ts_resource), + .resource = s3c_ts_resource, +}; + +void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd) +{ + struct s3c2410_ts_mach_info *npd; + + if (!pd) { + printk(KERN_ERR "%s: no platform data\n", __func__); + return; + } + + npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + + s3c_device_ts.dev.platform_data = npd; +} +EXPORT_SYMBOL(s3c24xx_ts_set_platdata); -- cgit v1.2.3-59-g8ed1b From 20c9d2c4ab8243a1c311248232954b2c1da3ba75 Mon Sep 17 00:00:00 2001 From: Kalle Jokiniemi Date: Tue, 11 May 2010 11:35:08 -0700 Subject: i2c-omap: add mpu wake up latency constraint in i2c While waiting for completion of the i2c transfer, the MPU could hit OFF mode and cause several msecs of delay that made i2c transfers fail more often. The extra delays and subsequent re-trys cause i2c clocks to be active more often. This has also an negative effect on power consumption. Created a mechanism for passing and using the constraint setting function in driver code. The used mpu wake up latency constraints are now set individually per bus, and they are calculated based on clock rate and fifo size. Thanks to Jarkko Nikula, Moiz Sonasath, Paul Walmsley, and Nishanth Menon for tuning out the details of this patch. Updates by Kevin as requested by Tony: - Remove omap_set_i2c_constraint_func() in favor of conditionally adding the flag in omap_i2c_add_bus() in order to keep all the OMAP conditional checking in a single location. - Update set_mpu_wkup_lat prototypes to match OMAP PM layer so OMAP PM function can be used directly in pdata. Cc: Moiz Sonasath Cc: Jarkko Nikula Cc: Paul Walmsley Cc: Nishanth Menon Signed-off-by: Kalle Jokiniemi Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren Signed-off-by: Ben Dooks --- arch/arm/plat-omap/i2c.c | 39 +++++++++++++++++++++++++++------------ drivers/i2c/busses/i2c-omap.c | 24 ++++++++++++++++++++---- include/linux/i2c-omap.h | 9 +++++++++ 3 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 include/linux/i2c-omap.h (limited to 'arch') diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 624e26298faa..f044b5927508 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -26,9 +26,12 @@ #include #include #include +#include + #include #include #include +#include #define OMAP_I2C_SIZE 0x3f #define OMAP1_I2C_BASE 0xfffb3800 @@ -70,14 +73,14 @@ static struct resource i2c_resources[][2] = { }, \ } -static u32 i2c_rate[ARRAY_SIZE(i2c_resources)]; +static struct omap_i2c_bus_platform_data i2c_pdata[ARRAY_SIZE(i2c_resources)]; static struct platform_device omap_i2c_devices[] = { - I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]), + I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]), #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) - I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_rate[1]), + I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_pdata[1]), #endif #if defined(CONFIG_ARCH_OMAP3) - I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_rate[2]), + I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_pdata[2]), #endif }; @@ -100,10 +103,12 @@ static int __init omap_i2c_nr_ports(void) static int __init omap_i2c_add_bus(int bus_id) { struct platform_device *pdev; + struct omap_i2c_bus_platform_data *pd; struct resource *res; resource_size_t base, irq; pdev = &omap_i2c_devices[bus_id - 1]; + pd = pdev->dev.platform_data; if (bus_id == 1) { res = pdev->resource; if (cpu_class_is_omap1()) { @@ -123,6 +128,15 @@ static int __init omap_i2c_add_bus(int bus_id) if (cpu_class_is_omap2()) omap2_i2c_mux_pins(bus_id); + /* + * When waiting for completion of a i2c transfer, we need to + * set a wake up latency constraint for the MPU. This is to + * ensure quick enough wakeup from idle, when transfer + * completes. + */ + if (cpu_is_omap34xx()) + pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat; + return platform_device_register(pdev); } @@ -146,8 +160,8 @@ static int __init omap_i2c_bus_setup(char *str) get_options(str, 3, ints); if (ints[0] < 2 || ints[1] < 1 || ints[1] > ports) return 0; - i2c_rate[ints[1] - 1] = ints[2]; - i2c_rate[ints[1] - 1] |= OMAP_I2C_CMDLINE_SETUP; + i2c_pdata[ints[1] - 1].clkrate = ints[2]; + i2c_pdata[ints[1] - 1].clkrate |= OMAP_I2C_CMDLINE_SETUP; return 1; } @@ -161,9 +175,9 @@ static int __init omap_register_i2c_bus_cmdline(void) { int i, err = 0; - for (i = 0; i < ARRAY_SIZE(i2c_rate); i++) - if (i2c_rate[i] & OMAP_I2C_CMDLINE_SETUP) { - i2c_rate[i] &= ~OMAP_I2C_CMDLINE_SETUP; + for (i = 0; i < ARRAY_SIZE(i2c_pdata); i++) + if (i2c_pdata[i].clkrate & OMAP_I2C_CMDLINE_SETUP) { + i2c_pdata[i].clkrate &= ~OMAP_I2C_CMDLINE_SETUP; err = omap_i2c_add_bus(i + 1); if (err) goto out; @@ -197,9 +211,10 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate, return err; } - if (!i2c_rate[bus_id - 1]) - i2c_rate[bus_id - 1] = clkrate; - i2c_rate[bus_id - 1] &= ~OMAP_I2C_CMDLINE_SETUP; + if (!i2c_pdata[bus_id - 1].clkrate) + i2c_pdata[bus_id - 1].clkrate = clkrate; + + i2c_pdata[bus_id - 1].clkrate &= ~OMAP_I2C_CMDLINE_SETUP; return omap_i2c_add_bus(bus_id); } diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 46111ff18133..42c0b9108c7f 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -38,6 +38,7 @@ #include #include #include +#include /* I2C controller revisions */ #define OMAP_I2C_REV_2 0x20 @@ -175,6 +176,9 @@ struct omap_i2c_dev { struct clk *fclk; /* Functional clock */ struct completion cmd_complete; struct resource *ioarea; + u32 latency; /* maximum mpu wkup latency */ + void (*set_mpu_wkup_lat)(struct device *dev, + long latency); u32 speed; /* Speed of bus in Khz */ u16 cmd_err; u8 *buf; @@ -603,8 +607,12 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, * REVISIT: We should abort the transfer on signals, but the bus goes * into arbitration and we're currently unable to recover from it. */ + if (dev->set_mpu_wkup_lat != NULL) + dev->set_mpu_wkup_lat(dev->dev, dev->latency); r = wait_for_completion_timeout(&dev->cmd_complete, OMAP_I2C_TIMEOUT); + if (dev->set_mpu_wkup_lat != NULL) + dev->set_mpu_wkup_lat(dev->dev, -1); dev->buf_len = 0; if (r < 0) return r; @@ -927,6 +935,7 @@ omap_i2c_probe(struct platform_device *pdev) struct omap_i2c_dev *dev; struct i2c_adapter *adap; struct resource *mem, *irq, *ioarea; + struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data; irq_handler_t isr; int r; u32 speed = 0; @@ -956,10 +965,13 @@ omap_i2c_probe(struct platform_device *pdev) goto err_release_region; } - if (pdev->dev.platform_data != NULL) - speed = *(u32 *)pdev->dev.platform_data; - else - speed = 100; /* Defualt speed */ + if (pdata != NULL) { + speed = pdata->clkrate; + dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat; + } else { + speed = 100; /* Default speed */ + dev->set_mpu_wkup_lat = NULL; + } dev->speed = speed; dev->idle = 1; @@ -1011,6 +1023,10 @@ omap_i2c_probe(struct platform_device *pdev) dev->fifo_size = (dev->fifo_size / 2); dev->b_hw = 1; /* Enable hardware fixes */ } + /* calculate wakeup latency constraint for MPU */ + if (dev->set_mpu_wkup_lat != NULL) + dev->latency = (1000000 * dev->fifo_size) / + (1000 * speed / 8); } /* reset ASAP, clearing any IRQs */ diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h new file mode 100644 index 000000000000..78ebf507ce56 --- /dev/null +++ b/include/linux/i2c-omap.h @@ -0,0 +1,9 @@ +#ifndef __I2C_OMAP_H__ +#define __I2C_OMAP_H__ + +struct omap_i2c_bus_platform_data { + u32 clkrate; + void (*set_mpu_wkup_lat)(struct device *dev, long set); +}; + +#endif -- cgit v1.2.3-59-g8ed1b From d22ae836d65f5b59ca91a14a7694e2b643c6cf63 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Mon, 10 May 2010 14:29:14 -0700 Subject: omap1: amsdelta: defconfig updates The patch provides the following ams_delta_defconfig updates: - explicitly select preemptable RCU, - replace outdated CONFIG_LBD and CONFIG_LSF options with CONFIG_LBDAF, - activate support for LCD contrast setting (new in 2.6.34), - turn off verbose bug reporting for smaller kernel. Created and tested against linux-2.6.34-rc3. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/configs/ams_delta_defconfig | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/ams_delta_defconfig b/arch/arm/configs/ams_delta_defconfig index 3b3a3775bbf4..1d0e8926a2f0 100644 --- a/arch/arm/configs/ams_delta_defconfig +++ b/arch/arm/configs/ams_delta_defconfig @@ -47,6 +47,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set +CONFIG_TREE_PREEMPT_RCU=y # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y @@ -95,9 +96,8 @@ CONFIG_KMOD=y # Block layer # CONFIG_BLOCK=y -# CONFIG_LBD is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # # IO Schedulers @@ -835,7 +835,8 @@ CONFIG_DAB=y # # Graphics support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y # # Display device support @@ -1283,7 +1284,7 @@ CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set -- cgit v1.2.3-59-g8ed1b From 39ecc703d19da2e40296d84d487f843c03f82d25 Mon Sep 17 00:00:00 2001 From: Viral Mehta Date: Mon, 10 May 2010 14:29:15 -0700 Subject: omap2: Add I2C bus 1 initialisation for 2430sdp Initialize isp1301 FS USB transceiver and add I2C bus1 initialization code for OMAP2430 SDP Signed-off-by: Viral Mehta Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-2430sdp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 01d113ff9fcf..85f5f33bed2f 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -174,9 +174,18 @@ static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = { }, }; +static struct i2c_board_info __initdata sdp2430_i2c1_boardinfo[] = { + { + I2C_BOARD_INFO("isp1301_omap", 0x2D), + .flags = I2C_CLIENT_WAKE, + .irq = OMAP_GPIO_IRQ(78), + }, +}; + static int __init omap2430_i2c_init(void) { - omap_register_i2c_bus(1, 400, NULL, 0); + omap_register_i2c_bus(1, 100, sdp2430_i2c1_boardinfo, + ARRAY_SIZE(sdp2430_i2c1_boardinfo)); omap_register_i2c_bus(2, 2600, sdp2430_i2c_boardinfo, ARRAY_SIZE(sdp2430_i2c_boardinfo)); return 0; -- cgit v1.2.3-59-g8ed1b From 9c68eb8197a07a157c72ae3f31877e53a44786c5 Mon Sep 17 00:00:00 2001 From: Viral Mehta Date: Mon, 10 May 2010 14:29:15 -0700 Subject: omap2: Add OHCI USB platform init for 2430 SDP Add platform init code for OHCI USB on OMAP2430 SDP Signed-off-by: Viral Mehta [tony@atomide.com: Updated subject to mention the board name] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-2430sdp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 85f5f33bed2f..a11a575745e4 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -207,6 +207,15 @@ static struct omap_musb_board_data musb_board_data = { .mode = MUSB_OTG, .power = 100, }; +static struct omap_usb_config sdp2430_usb_config __initdata = { + .otg = 1, +#ifdef CONFIG_USB_GADGET_OMAP + .hmc_mode = 0x0, +#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) + .hmc_mode = 0x1, +#endif + .pins[0] = 3, +}; static void __init omap_2430sdp_init(void) { @@ -217,6 +226,7 @@ static void __init omap_2430sdp_init(void) platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); omap_serial_init(); omap2_hsmmc_init(mmc); + omap_usb_init(&sdp2430_usb_config); usb_musb_init(&musb_board_data); board_smc91x_init(); -- cgit v1.2.3-59-g8ed1b From 4ab866d11ac14d2a55808d71d7c0ee4fea83265f Mon Sep 17 00:00:00 2001 From: Viral Mehta Date: Mon, 10 May 2010 14:29:15 -0700 Subject: omap2: select ARCH_OMAP_OTG for OMAP2430 SDP Configuration for OMAP2430 should select ARCH_OMAP_OTG just like it is done for OMAP2420 Signed-off-by: Viral Mehta Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 2455dcc744a0..99abac2a8c53 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -10,6 +10,7 @@ config ARCH_OMAP2420 config ARCH_OMAP2430 bool "OMAP2430 support" depends on ARCH_OMAP2 + select ARCH_OMAP_OTG config ARCH_OMAP3430 bool "OMAP3430 support" -- cgit v1.2.3-59-g8ed1b From 018e075c19d2a640cc64a07bb90916269bed57bb Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Mon, 10 May 2010 14:29:16 -0700 Subject: omap: Devkit8000: Add mux initialization Initialize multiplexed pins with correct mode. Signed-off-by: Thomas Weber Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-devkit8000.c | 155 +++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 47e3af2166d4..77022b588816 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -633,8 +633,163 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .reset_gpio_port[2] = -EINVAL }; +static struct omap_board_mux board_mux[] __initdata = { + /* nCS and IRQ for Devkit8000 ethernet */ + OMAP3_MUX(GPMC_NCS6, OMAP_MUX_MODE0), + OMAP3_MUX(ETK_D11, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP), + + /* McSPI 2*/ + OMAP3_MUX(MCSPI2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI2_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCSPI2_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI2_CS0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCSPI2_CS1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + + /* PENDOWN GPIO */ + OMAP3_MUX(ETK_D13, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + + /* mUSB */ + OMAP3_MUX(HSUSB0_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_STP, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(HSUSB0_DIR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_NXT, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* USB 1 */ + OMAP3_MUX(ETK_CTL, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), + OMAP3_MUX(ETK_D8, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D9, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D0, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D2, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D4, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D5, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D6, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D7, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + + /* MMC 1 */ + OMAP3_MUX(SDMMC1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* McBSP 2 */ + OMAP3_MUX(MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + + /* I2C 1 */ + OMAP3_MUX(I2C1_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(I2C1_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* I2C 2 */ + OMAP3_MUX(I2C2_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(I2C2_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* I2C 3 */ + OMAP3_MUX(I2C3_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(I2C3_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* I2C 4 */ + OMAP3_MUX(I2C4_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(I2C4_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* serial ports */ + OMAP3_MUX(MCBSP3_CLKX, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* DSS */ + OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + + /* expansion port */ + /* McSPI 1 */ + OMAP3_MUX(MCSPI1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI1_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI1_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI1_CS0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN), + OMAP3_MUX(MCSPI1_CS3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN), + + /* HDQ */ + OMAP3_MUX(HDQ_SIO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* McSPI4 */ + OMAP3_MUX(MCBSP1_CLKR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP1_DX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP1_DR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP1_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT_PULLUP), + + /* MMC 2 */ + OMAP3_MUX(SDMMC2_DAT4, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(SDMMC2_DAT5, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(SDMMC2_DAT6, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(SDMMC2_DAT7, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + + /* I2C3 */ + OMAP3_MUX(I2C3_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(I2C3_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + + OMAP3_MUX(GPMC_NCS7, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + OMAP3_MUX(GPMC_NCS3, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + + /* TPS IRQ */ + OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_WAKEUP_EN | \ + OMAP_PIN_INPUT_PULLUP), + + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; + static void __init devkit8000_init(void) { + omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); omap_serial_init(); omap_dm9000_init(); -- cgit v1.2.3-59-g8ed1b From a29b8204d22c9c634841f2474c0bc327f36d7be6 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Mon, 10 May 2010 14:29:16 -0700 Subject: omap: Devkit8000: Update default configuration This patch updates the new default configuration for the Devkit8000. Signed-off-by: Thomas Weber Signed-off-by: Tony Lindgren --- arch/arm/configs/devkit8000_defconfig | 157 ++++++++++++++++++++-------------- 1 file changed, 91 insertions(+), 66 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/devkit8000_defconfig b/arch/arm/configs/devkit8000_defconfig index 61a817e8cf81..c7a68202fa3f 100644 --- a/arch/arm/configs/devkit8000_defconfig +++ b/arch/arm/configs/devkit8000_defconfig @@ -1,13 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc6 -# Thu Feb 4 15:42:56 2010 +# Linux kernel version: 2.6.34-rc2 +# Wed Mar 24 13:27:25 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y @@ -19,7 +20,9 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_ARCH_HAS_CPUFREQ=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_ARM_L1_CACHE_SHIFT_6=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -60,11 +63,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -96,10 +94,14 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -170,7 +172,7 @@ CONFIG_INLINE_WRITE_UNLOCK=y CONFIG_INLINE_WRITE_UNLOCK_IRQ=y # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set # CONFIG_MUTEX_SPIN_ON_OWNER is not set -# CONFIG_FREEZER is not set +CONFIG_FREEZER=y # # System Type @@ -181,6 +183,7 @@ CONFIG_MMU=y # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set # CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set @@ -190,7 +193,6 @@ CONFIG_MMU=y # CONFIG_ARCH_STMP3XXX is not set # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set # CONFIG_ARCH_IOP33X is not set @@ -207,21 +209,26 @@ CONFIG_MMU=y # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set # CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set # CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_DAVINCI is not set CONFIG_ARCH_OMAP=y -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_U8500 is not set # # TI OMAP Implementations @@ -237,16 +244,20 @@ CONFIG_ARCH_OMAP3=y # OMAP Feature Selections # # CONFIG_OMAP_RESET_CLOCKS is not set -# CONFIG_OMAP_MUX is not set +CONFIG_OMAP_MUX=y +# CONFIG_OMAP_MUX_DEBUG is not set +CONFIG_OMAP_MUX_WARNINGS=y CONFIG_OMAP_MCBSP=y # CONFIG_OMAP_MBOX_FWK is not set # CONFIG_OMAP_MPU_TIMER is not set CONFIG_OMAP_32K_TIMER=y +# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set CONFIG_OMAP_32K_TIMER_HZ=128 CONFIG_OMAP_DM_TIMER=y # CONFIG_OMAP_PM_NONE is not set CONFIG_OMAP_PM_NOOP=y CONFIG_ARCH_OMAP3430=y +CONFIG_OMAP_PACKAGE_CUS=y # # OMAP Board Type @@ -295,6 +306,7 @@ CONFIG_ARM_THUMB=y # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_HAS_TLS_REG=y CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_CPU_HAS_PMU=y # CONFIG_ARM_ERRATA_430973 is not set # CONFIG_ARM_ERRATA_458693 is not set # CONFIG_ARM_ERRATA_460075 is not set @@ -387,7 +399,14 @@ CONFIG_HAVE_AOUT=y # # Power management options # -# CONFIG_PM is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +# CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y @@ -395,7 +414,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set @@ -666,6 +684,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -717,6 +736,7 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_AX88796 is not set # CONFIG_SMC91X is not set +# CONFIG_TI_DAVINCI_EMAC is not set CONFIG_DM9000=y CONFIG_DM9000_DEBUGLEVEL=4 CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y @@ -863,6 +883,7 @@ CONFIG_SERIAL_8250_RSA=y # CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -891,6 +912,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_OMAP=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -904,15 +926,9 @@ CONFIG_I2C_OMAP=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -944,10 +960,12 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set @@ -984,10 +1002,12 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # CONFIG_MFD_CORE=y +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_ASIC3 is not set # CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set CONFIG_TWL4030_CORE=y CONFIG_TWL4030_POWER=y @@ -998,22 +1018,25 @@ CONFIG_TWL4030_CODEC=y # CONFIG_MFD_TC6393XB is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_AB4500_CORE is not set CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set # CONFIG_REGULATOR_FIXED_VOLTAGE is not set # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set # CONFIG_REGULATOR_BQ24022 is not set # CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set # CONFIG_REGULATOR_MAX8660 is not set CONFIG_REGULATOR_TWL4030=y # CONFIG_REGULATOR_LP3971 is not set @@ -1072,7 +1095,6 @@ CONFIG_OMAP2_DSS_VENC=y CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0 CONFIG_FB_OMAP2=y CONFIG_FB_OMAP2_DEBUG_SUPPORT=y -# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set CONFIG_FB_OMAP2_NUM_FBS=3 # @@ -1080,7 +1102,9 @@ CONFIG_FB_OMAP2_NUM_FBS=3 # CONFIG_PANEL_GENERIC=y # CONFIG_PANEL_SHARP_LS037V7DW01 is not set -CONFIG_PANEL_INNOLUX_AT070TN83=y +# CONFIG_PANEL_SHARP_LQ043T1DG01 is not set +# CONFIG_PANEL_TOPPOLY_TDO35S is not set +# CONFIG_PANEL_TPO_TD043MTEA1 is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -1136,6 +1160,7 @@ CONFIG_SND_ARM=y CONFIG_SND_SPI=y CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set # CONFIG_SND_USB_CAIAQ is not set CONFIG_SND_SOC=y CONFIG_SND_OMAP_SOC=y @@ -1147,42 +1172,44 @@ CONFIG_SND_SOC_TWL4030=y # CONFIG_SOUND_PRIME is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y -CONFIG_HIDRAW=y +# CONFIG_HIDRAW is not set # # USB Input Devices # CONFIG_USB_HID=y # CONFIG_HID_PID is not set -CONFIG_USB_HIDDEV=y +# CONFIG_USB_HIDDEV is not set # # Special HID drivers # -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y +# CONFIG_HID_3M_PCT is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set # CONFIG_HID_DRAGONRISE is not set -CONFIG_HID_EZKEY=y +# CONFIG_HID_EZKEY is not set # CONFIG_HID_KYE is not set -CONFIG_HID_GYRATION=y +# CONFIG_HID_GYRATION is not set # CONFIG_HID_TWINHAN is not set # CONFIG_HID_KENSINGTON is not set -CONFIG_HID_LOGITECH=y -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MOSART is not set +# CONFIG_HID_MONTEREY is not set # CONFIG_HID_NTRIG is not set -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_SUNPLUS=y +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_STANTUM is not set +# CONFIG_HID_SUNPLUS is not set # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set # CONFIG_HID_TOPSEED is not set @@ -1193,7 +1220,7 @@ CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y -# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEBUG=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # @@ -1202,7 +1229,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # CONFIG_USB_DEVICEFS is not set # CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set +CONFIG_USB_OTG=y # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set CONFIG_USB_MON=y @@ -1230,15 +1257,15 @@ CONFIG_USB_MUSB_SOC=y # # OMAP 343x high speed USB support # -CONFIG_USB_MUSB_HOST=y +# CONFIG_USB_MUSB_HOST is not set # CONFIG_USB_MUSB_PERIPHERAL is not set -# CONFIG_USB_MUSB_OTG is not set -# CONFIG_USB_GADGET_MUSB_HDRC is not set +CONFIG_USB_MUSB_OTG=y +CONFIG_USB_GADGET_MUSB_HDRC=y CONFIG_USB_MUSB_HDRC_HCD=y # CONFIG_MUSB_PIO_ONLY is not set CONFIG_USB_INVENTRA_DMA=y # CONFIG_USB_TI_CPPI_DMA is not set -# CONFIG_USB_MUSB_DEBUG is not set +CONFIG_USB_MUSB_DEBUG=y # # USB Device Class drivers @@ -1291,7 +1318,6 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1304,9 +1330,8 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG is not set +CONFIG_USB_GADGET_DEBUG=y # CONFIG_USB_GADGET_DEBUG_FILES is not set CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_SELECTED=y @@ -1314,8 +1339,7 @@ CONFIG_USB_GADGET_SELECTED=y # CONFIG_USB_GADGET_ATMEL_USBA is not set # CONFIG_USB_GADGET_FSL_USB2 is not set # CONFIG_USB_GADGET_LH7A40X is not set -CONFIG_USB_GADGET_OMAP=y -CONFIG_USB_OMAP=y +# CONFIG_USB_GADGET_OMAP is not set # CONFIG_USB_GADGET_PXA25X is not set # CONFIG_USB_GADGET_R8A66597 is not set # CONFIG_USB_GADGET_PXA27X is not set @@ -1330,19 +1354,20 @@ CONFIG_USB_OMAP=y # CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set -# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_ZERO is not set -CONFIG_USB_AUDIO=m -CONFIG_USB_ETH=m -CONFIG_USB_ETH_RNDIS=y -CONFIG_USB_ETH_EEM=y -CONFIG_USB_GADGETFS=m +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=y +# CONFIG_USB_ETH_RNDIS is not set +# CONFIG_USB_ETH_EEM is not set +# CONFIG_USB_GADGETFS is not set # CONFIG_USB_FILE_STORAGE is not set # CONFIG_USB_MASS_STORAGE is not set -CONFIG_USB_G_SERIAL=m +# CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set -CONFIG_USB_G_PRINTER=m +# CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set # CONFIG_USB_G_MULTI is not set # @@ -1373,8 +1398,6 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=m # CONFIG_MMC_OMAP is not set CONFIG_MMC_OMAP_HS=y -# CONFIG_MMC_AT91 is not set -# CONFIG_MMC_ATMELMCI is not set CONFIG_MMC_SPI=m # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -1392,11 +1415,11 @@ CONFIG_LEDS_GPIO_PLATFORM=y # CONFIG_LEDS_REGULATOR is not set # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y # # LED Triggers # -CONFIG_LEDS_TRIGGERS=y # CONFIG_LEDS_TRIGGER_TIMER is not set CONFIG_LEDS_TRIGGER_HEARTBEAT=y # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set @@ -1580,6 +1603,7 @@ CONFIG_UBIFS_FS=y CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y # CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1606,6 +1630,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -- cgit v1.2.3-59-g8ed1b From 917336318ef1c2520b6898113dade12c401ea1a0 Mon Sep 17 00:00:00 2001 From: Sriram Date: Mon, 10 May 2010 14:29:16 -0700 Subject: can: ti_hecc: board specific hookup on AM3517EVM Add board specific hookup for TI HECC driver on AM3517 EVM Signed-off-by: Sriramakrishnan Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-am3517evm.c | 38 +++++++++++++++++++++++++++++++ arch/arm/mach-omap2/include/mach/am35xx.h | 9 ++++++++ 2 files changed, 47 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index c1c4389fbd8f..6ca0075026ff 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -292,6 +293,42 @@ static struct omap_board_mux board_mux[] __initdata = { #define board_mux NULL #endif + +static struct resource am3517_hecc_resources[] = { + { + .start = AM35XX_IPSS_HECC_BASE, + .end = AM35XX_IPSS_HECC_BASE + 0x3FFF, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_35XX_HECC0_IRQ, + .end = INT_35XX_HECC0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device am3517_hecc_device = { + .name = "ti_hecc", + .id = -1, + .num_resources = ARRAY_SIZE(am3517_hecc_resources), + .resource = am3517_hecc_resources, +}; + +static struct ti_hecc_platform_data am3517_evm_hecc_pdata = { + .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET, + .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET, + .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET, + .mbx_offset = AM35XX_HECC_MBOX_OFFSET, + .int_line = AM35XX_HECC_INT_LINE, + .version = AM35XX_HECC_VERSION, +}; + +static void am3517_evm_hecc_init(struct ti_hecc_platform_data *pdata) +{ + am3517_hecc_device.dev.platform_data = pdata; + platform_device_register(&am3517_hecc_device); +} + static void __init am3517_evm_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); @@ -305,6 +342,7 @@ static void __init am3517_evm_init(void) /* Configure GPIO for EHCI port */ omap_mux_init_gpio(57, OMAP_PIN_OUTPUT); usb_ehci_init(&ehci_pdata); + am3517_evm_hecc_init(&am3517_evm_hecc_pdata); /* DSS */ am3517_evm_display_init(); diff --git a/arch/arm/mach-omap2/include/mach/am35xx.h b/arch/arm/mach-omap2/include/mach/am35xx.h index a705f946fc46..0636263c2e7d 100644 --- a/arch/arm/mach-omap2/include/mach/am35xx.h +++ b/arch/arm/mach-omap2/include/mach/am35xx.h @@ -23,4 +23,13 @@ #define AM35XX_IPSS_HECC_BASE 0x5C050000 #define AM35XX_IPSS_VPFE_BASE 0x5C060000 + +/* HECC module specifc offset definitions */ +#define AM35XX_HECC_SCC_HECC_OFFSET (0x0) +#define AM35XX_HECC_SCC_RAM_OFFSET (0x3000) +#define AM35XX_HECC_RAM_OFFSET (0x3000) +#define AM35XX_HECC_MBOX_OFFSET (0x2000) +#define AM35XX_HECC_INT_LINE (0x0) +#define AM35XX_HECC_VERSION (0x1) + #endif /* __ASM_ARCH_AM35XX_H */ -- cgit v1.2.3-59-g8ed1b From e72b9b807247ea8e1e5c457b8c30d5ae9d53fedc Mon Sep 17 00:00:00 2001 From: Sriram Date: Mon, 10 May 2010 14:29:16 -0700 Subject: can: ti_hecc: Enable CAN support on AM3517 Modify the default kernel configuration on AM3517 to enable CAN. Signed-off-by: Sriramakrishnan Signed-off-by: Tony Lindgren --- arch/arm/configs/am3517_evm_defconfig | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/am3517_evm_defconfig b/arch/arm/configs/am3517_evm_defconfig index 66a10b50d938..c151d6e7c093 100644 --- a/arch/arm/configs/am3517_evm_defconfig +++ b/arch/arm/configs/am3517_evm_defconfig @@ -422,15 +422,29 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set +CONFIG_CAN=y +CONFIG_CAN_RAW=y +CONFIG_CAN_BCM=y + +# +# CAN Device Drivers +# +CONFIG_CAN_VCAN=y +CONFIG_CAN_DEV=y +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_TI_HECC=y +# CONFIG_CAN_SJA1000 is not set + +# +# CAN USB interfaces +# +# CONFIG_CAN_EMS_USB is not set +CONFIG_CAN_DEBUG_DEVICES=y # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set -CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -# CONFIG_WIRELESS_OLD_REGULATORY is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_LIB80211 is not set # -- cgit v1.2.3-59-g8ed1b From 39e799df2f504a160852342109d228abfe75fede Mon Sep 17 00:00:00 2001 From: Sriram Date: Mon, 10 May 2010 14:29:17 -0700 Subject: AM35xx EMAC: define submodule offsets Define offsets for EMAC sub modules. Signed-off-by: Sriramakrishnan Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/include/mach/am35xx.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/include/mach/am35xx.h b/arch/arm/mach-omap2/include/mach/am35xx.h index 0636263c2e7d..f1e13d1ca5e7 100644 --- a/arch/arm/mach-omap2/include/mach/am35xx.h +++ b/arch/arm/mach-omap2/include/mach/am35xx.h @@ -32,4 +32,13 @@ #define AM35XX_HECC_INT_LINE (0x0) #define AM35XX_HECC_VERSION (0x1) -#endif /* __ASM_ARCH_AM35XX_H */ +#define AM35XX_EMAC_CNTRL_OFFSET (0x10000) +#define AM35XX_EMAC_CNTRL_MOD_OFFSET (0x0) +#define AM35XX_EMAC_CNTRL_RAM_OFFSET (0x20000) +#define AM35XX_EMAC_MDIO_OFFSET (0x30000) +#define AM35XX_EMAC_CNTRL_RAM_SIZE (0x2000) +#define AM35XX_EMAC_RAM_ADDR (AM3517_EMAC_BASE + \ + AM3517_EMAC_CNTRL_RAM_OFFSET) +#define AM35XX_EMAC_HW_RAM_ADDR (0x01E20000) + +#endif /* __ASM_ARCH_AM35XX_H */ -- cgit v1.2.3-59-g8ed1b From 56881d28b2eed78665daa1d680014e9ebaf8c0e3 Mon Sep 17 00:00:00 2001 From: Sriram Date: Mon, 10 May 2010 14:29:17 -0700 Subject: AM35xx: Platform specific hookup for EMAC module Modified AM35xx EVM init sequence to handle EMAC initialization. Signed-off-by: Sriramakrishnan Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-am3517evm.c | 98 +++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 6ca0075026ff..02e209743e1f 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -31,11 +32,106 @@ #include #include +#include #include #include #include "mux.h" +#define AM35XX_EVM_PHY_MASK (0xF) +#define AM35XX_EVM_MDIO_FREQUENCY (1000000) + +static struct emac_platform_data am3517_evm_emac_pdata = { + .phy_mask = AM35XX_EVM_PHY_MASK, + .mdio_max_freq = AM35XX_EVM_MDIO_FREQUENCY, + .rmii_en = 1, +}; + +static struct resource am3517_emac_resources[] = { + { + .start = AM35XX_IPSS_EMAC_BASE, + .end = AM35XX_IPSS_EMAC_BASE + 0x3FFFF, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_35XX_EMAC_C0_RXTHRESH_IRQ, + .end = INT_35XX_EMAC_C0_RXTHRESH_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .start = INT_35XX_EMAC_C0_RX_PULSE_IRQ, + .end = INT_35XX_EMAC_C0_RX_PULSE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .start = INT_35XX_EMAC_C0_TX_PULSE_IRQ, + .end = INT_35XX_EMAC_C0_TX_PULSE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .start = INT_35XX_EMAC_C0_MISC_PULSE_IRQ, + .end = INT_35XX_EMAC_C0_MISC_PULSE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device am3517_emac_device = { + .name = "davinci_emac", + .id = -1, + .num_resources = ARRAY_SIZE(am3517_emac_resources), + .resource = am3517_emac_resources, +}; + +static void am3517_enable_ethernet_int(void) +{ + u32 regval; + + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); + regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR | + AM35XX_CPGMAC_C0_TX_PULSE_CLR | + AM35XX_CPGMAC_C0_MISC_PULSE_CLR | + AM35XX_CPGMAC_C0_RX_THRESH_CLR); + omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); +} + +static void am3517_disable_ethernet_int(void) +{ + u32 regval; + + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); + regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR | + AM35XX_CPGMAC_C0_TX_PULSE_CLR); + omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); +} + +void am3517_evm_ethernet_init(struct emac_platform_data *pdata) +{ + unsigned int regval; + + pdata->ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET; + pdata->ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET; + pdata->ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET; + pdata->mdio_reg_offset = AM35XX_EMAC_MDIO_OFFSET; + pdata->ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE; + pdata->version = EMAC_VERSION_2; + pdata->hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR; + pdata->interrupt_enable = am3517_enable_ethernet_int; + pdata->interrupt_disable = am3517_disable_ethernet_int; + am3517_emac_device.dev.platform_data = pdata; + platform_device_register(&am3517_emac_device); + + regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); + regval = regval & (~(AM35XX_CPGMACSS_SW_RST)); + omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); + regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); + + return ; +} + + + #define LCD_PANEL_PWR 176 #define LCD_PANEL_BKLIGHT_PWR 182 #define LCD_PANEL_PWM 181 @@ -351,6 +447,8 @@ static void __init am3517_evm_init(void) i2c_register_board_info(1, am3517evm_i2c_boardinfo, ARRAY_SIZE(am3517evm_i2c_boardinfo)); + /*Ethernet*/ + am3517_evm_ethernet_init(&am3517_evm_emac_pdata); } static void __init am3517_evm_map_io(void) -- cgit v1.2.3-59-g8ed1b From b98dd73c6cd13ff9a5576a845ca9c1e359fdb7d0 Mon Sep 17 00:00:00 2001 From: Sriram Date: Mon, 10 May 2010 14:29:17 -0700 Subject: OMAP3: clock data: Update name string for EMAC clocks The emac driver currently uses Davinci clock names for the module and phy clocks. Updated the omap3xxx_clks table to match the names used by the Davinci emac driver. Note that eventually the EMAC clocks should be renamed to be generic. Signed-off-by: Sriramakrishnan Acked-by: Paul Walmsley [tony@atomide.com: updated patch description to match the patch] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clock3xxx_data.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 9cba5560519b..6905eb7aa67c 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3472,8 +3472,8 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "ipss_ick", &ipss_ick, CK_AM35XX), CLK(NULL, "rmii_ck", &rmii_ck, CK_AM35XX), CLK(NULL, "pclk_ck", &pclk_ck, CK_AM35XX), - CLK("davinci_emac", "ick", &emac_ick, CK_AM35XX), - CLK("davinci_emac", "fck", &emac_fck, CK_AM35XX), + CLK("davinci_emac", "emac_clk", &emac_ick, CK_AM35XX), + CLK("davinci_emac", "phy_clk", &emac_fck, CK_AM35XX), CLK("vpfe-capture", "master", &vpfe_ick, CK_AM35XX), CLK("vpfe-capture", "slave", &vpfe_fck, CK_AM35XX), CLK("musb_hdrc", "ick", &hsotgusb_ick_am35xx, CK_AM35XX), -- cgit v1.2.3-59-g8ed1b From 38e473a84ecfe30c03eb68244533cc26cd52c06c Mon Sep 17 00:00:00 2001 From: Sriram Date: Mon, 10 May 2010 14:29:18 -0700 Subject: AM3517: defconfig update to enable EMAC support Update the default configuration for AM3517EVM to enable support for EMAC peripheral. Signed-off-by: Sriramakrishnan Signed-off-by: Tony Lindgren --- arch/arm/configs/am3517_evm_defconfig | 70 ++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/configs/am3517_evm_defconfig b/arch/arm/configs/am3517_evm_defconfig index c151d6e7c093..232f8eeb72e3 100644 --- a/arch/arm/configs/am3517_evm_defconfig +++ b/arch/arm/configs/am3517_evm_defconfig @@ -531,7 +531,75 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set # CONFIG_MD is not set -# CONFIG_NETDEVICES is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +CONFIG_TI_DAVINCI_EMAC=y +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set -- cgit v1.2.3-59-g8ed1b From 5c9a29ede210b59321a65bd692b7c37b758943e6 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Mon, 10 May 2010 14:29:18 -0700 Subject: omap: Overo: Add support for second ethernet port Some Overo add-on boards include a second ethernet port. This patch adds support for that second port. Signed-off-by: Steve Sakoman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-overo.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 8848c7c5ce48..79ac41400c21 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -63,6 +63,8 @@ #define OVERO_SMSC911X_CS 5 #define OVERO_SMSC911X_GPIO 176 +#define OVERO_SMSC911X2_CS 4 +#define OVERO_SMSC911X2_GPIO 65 #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) @@ -137,6 +139,16 @@ static struct resource overo_smsc911x_resources[] = { }, }; +static struct resource overo_smsc911x2_resources[] = { + { + .name = "smsc911x2-memory", + .flags = IORESOURCE_MEM, + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + static struct smsc911x_platform_config overo_smsc911x_config = { .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, @@ -146,7 +158,7 @@ static struct smsc911x_platform_config overo_smsc911x_config = { static struct platform_device overo_smsc911x_device = { .name = "smsc911x", - .id = -1, + .id = 0, .num_resources = ARRAY_SIZE(overo_smsc911x_resources), .resource = overo_smsc911x_resources, .dev = { -- cgit v1.2.3-59-g8ed1b From f2add1de55d577b9babe4812a710affb903b366b Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 10 May 2010 14:29:18 -0700 Subject: omap: rx51: Change the TWL4030 VMMC2 voltage constraints andsupply name I believe the VMMC2 constraints must be the same than with VAUX3. Older boards are using TWL4030 VMMC2 supply for internal MMC whereas newer are using VAUX3 that has more limited constraints defined in this same file. More over, the VMMC2 supply is used also for analog audio domain and the miminum analog voltage of the TLV320AIC34 codec is 2.7 V. To combine these two facts, the patch changes supply name to V28_A as the newer boards register VMMC2_30 for VAUX3 and uses the same constraints than VAUX3 since those constraints are ok for the TLV320AIC34. Signed-off-by: Jarkko Nikula Cc: Adrian Hunter Cc: Eduardo Valentin Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-rx51-peripherals.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 4377a4cf36eb..b803f47792a4 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -370,9 +370,9 @@ static struct regulator_init_data rx51_vmmc1 = { static struct regulator_init_data rx51_vmmc2 = { .constraints = { - .name = "VMMC2_30", - .min_uV = 1850000, - .max_uV = 3150000, + .name = "V28_A", + .min_uV = 2800000, + .max_uV = 3000000, .apply_uV = true, .valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY, -- cgit v1.2.3-59-g8ed1b From dabe929b590c0139aa5a18994d953a9eb201d626 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 10 May 2010 14:29:18 -0700 Subject: omap: rx51: Add i2c2 board_info with tlv320aic3x This makes possible to probe the audio codec and add another i2c2 components in the future. Fix also indentation for the first omap_register_i2c_bus. Signed-off-by: Jarkko Nikula Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-rx51-peripherals.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index b803f47792a4..3addfe646625 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -629,6 +629,12 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = { }, }; +static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = { + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + }, +}; + static int __init rx51_i2c_init(void) { if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) || @@ -639,8 +645,9 @@ static int __init rx51_i2c_init(void) rx51_twldata.vmmc2 = &rx51_vmmc2; } omap_register_i2c_bus(1, 2200, rx51_peripherals_i2c_board_info_1, - ARRAY_SIZE(rx51_peripherals_i2c_board_info_1)); - omap_register_i2c_bus(2, 100, NULL, 0); + ARRAY_SIZE(rx51_peripherals_i2c_board_info_1)); + omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2, + ARRAY_SIZE(rx51_peripherals_i2c_board_info_2)); omap_register_i2c_bus(3, 400, NULL, 0); return 0; } -- cgit v1.2.3-59-g8ed1b From 4cfcaef11fd32a27cee1bb5b7fcb741003db84a2 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 10 May 2010 14:29:19 -0700 Subject: omap: rx51: Add supplies for the tlv320aic3x codec driver Upcoming change to tlv320aic3x codec driver require four supplies. Implement this by connecting analogic supplies to TWL4030 VMMC2 and digital supplies to TWL4030 VIO. Signed-off-by: Jarkko Nikula Cc: Eduardo Valentin Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-rx51-peripherals.c | 60 ++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 3addfe646625..8179d55106d5 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -277,7 +277,7 @@ static struct regulator_consumer_supply rx51_vmmc1_supply = { .dev_name = "mmci-omap-hs.0", }; -static struct regulator_consumer_supply rx51_vmmc2_supply = { +static struct regulator_consumer_supply rx51_vaux3_supply = { .supply = "vmmc", .dev_name = "mmci-omap-hs.1", }; @@ -287,6 +287,35 @@ static struct regulator_consumer_supply rx51_vsim_supply = { .dev_name = "mmci-omap-hs.1", }; +static struct regulator_consumer_supply rx51_vmmc2_supplies[] = { + /* tlv320aic3x analog supplies */ + { + .supply = "AVDD", + .dev_name = "2-0018", + }, + { + .supply = "DRVDD", + .dev_name = "2-0018", + }, + /* Keep vmmc as last item. It is not iterated for newer boards */ + { + .supply = "vmmc", + .dev_name = "mmci-omap-hs.1", + }, +}; + +static struct regulator_consumer_supply rx51_vio_supplies[] = { + /* tlv320aic3x digital supplies */ + { + .supply = "IOVDD", + .dev_name = "2-0018" + }, + { + .supply = "DVDD", + .dev_name = "2-0018" + }, +}; + static struct regulator_init_data rx51_vaux1 = { .constraints = { .name = "V28", @@ -338,7 +367,7 @@ static struct regulator_init_data rx51_vaux3_mmc = { | REGULATOR_CHANGE_STATUS, }, .num_consumer_supplies = 1, - .consumer_supplies = &rx51_vmmc2_supply, + .consumer_supplies = &rx51_vaux3_supply, }; static struct regulator_init_data rx51_vaux4 = { @@ -380,8 +409,8 @@ static struct regulator_init_data rx51_vmmc2 = { | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &rx51_vmmc2_supply, + .num_consumer_supplies = ARRAY_SIZE(rx51_vmmc2_supplies), + .consumer_supplies = rx51_vmmc2_supplies, }; static struct regulator_init_data rx51_vsim = { @@ -411,6 +440,20 @@ static struct regulator_init_data rx51_vdac = { }, }; +static struct regulator_init_data rx51_vio = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(rx51_vio_supplies), + .consumer_supplies = rx51_vio_supplies, +}; + static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n) { /* FIXME this gpio setup is just a placeholder for now */ @@ -618,6 +661,7 @@ static struct twl4030_platform_data rx51_twldata __initdata = { .vmmc1 = &rx51_vmmc1, .vsim = &rx51_vsim, .vdac = &rx51_vdac, + .vio = &rx51_vio, }; static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = { @@ -638,12 +682,14 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = { static int __init rx51_i2c_init(void) { if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) || - system_rev >= SYSTEM_REV_B_USES_VAUX3) + system_rev >= SYSTEM_REV_B_USES_VAUX3) { rx51_twldata.vaux3 = &rx51_vaux3_mmc; - else { + /* Only older boards use VMMC2 for internal MMC */ + rx51_vmmc2.num_consumer_supplies--; + } else { rx51_twldata.vaux3 = &rx51_vaux3_cam; - rx51_twldata.vmmc2 = &rx51_vmmc2; } + rx51_twldata.vmmc2 = &rx51_vmmc2; omap_register_i2c_bus(1, 2200, rx51_peripherals_i2c_board_info_1, ARRAY_SIZE(rx51_peripherals_i2c_board_info_1)); omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2, -- cgit v1.2.3-59-g8ed1b From de997718b64df2f766736f23f8557da450b83a25 Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Mon, 10 May 2010 14:29:19 -0700 Subject: AM35x: fix UI card EHCI port and LCD dependency EHCI port on UI card and LCD share two pins (GPIO 181 and 182) thus they have to be mutually exclusive. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-am3517evm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 02e209743e1f..19b9e415710d 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -216,6 +216,8 @@ static int __init am3517_evm_i2c_init(void) static int lcd_enabled; static int dvi_enabled; +#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ + defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE) static void __init am3517_evm_display_init(void) { int r; @@ -259,6 +261,9 @@ err_2: err_1: gpio_free(LCD_PANEL_BKLIGHT_PWR); } +#else +static void __init am3517_evm_display_init(void) {} +#endif static int am3517_evm_panel_enable_lcd(struct omap_dss_device *dssdev) { @@ -372,7 +377,12 @@ static void __init am3517_evm_init_irq(void) static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, +#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ + defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE) + .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, +#else .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, +#endif .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, .phy_reset = true, -- cgit v1.2.3-59-g8ed1b From 754b8e653412106ff613f4750b197f807fcd8347 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 20 May 2010 11:02:43 -0700 Subject: OMAP1: Amstrad Delta: modify defconfig for external keyboardsupport The patch adds a CONFIG directive required for supporting the Amstrad Delta connected external keyboard by default. Created and tested against linux-omap master, commit 104a77440f05430f29f9d3f4ecb88c1536819585 dated 2010-04-27. Works on top of PATCH v4 4/5(7), "input: serio: add support for Amstrad Delta serial keyboard port". Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/configs/ams_delta_defconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/configs/ams_delta_defconfig b/arch/arm/configs/ams_delta_defconfig index 3b3a3775bbf4..ecf45fbff956 100644 --- a/arch/arm/configs/ams_delta_defconfig +++ b/arch/arm/configs/ams_delta_defconfig @@ -699,6 +699,7 @@ CONFIG_SERIO=y CONFIG_SERIO_SERPORT=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set +CONFIG_SERIO_AMS_DELTA=y # CONFIG_GAMEPORT is not set # -- cgit v1.2.3-59-g8ed1b From 0581b52e898f3f5472820940537d91d80895db5a Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 12 May 2010 11:48:47 +0300 Subject: OMAP: RX51: Add "vdds_sdi" supply voltage for SDI The SDI Display subsystem needs access to the vdds_sdi supply regulator. This is TWL4030's VAUX1 supply on RX-51. Signed-off-by: Roger Quadros Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/board-rx51-peripherals.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 8179d55106d5..966f5f84f2bd 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -316,6 +316,19 @@ static struct regulator_consumer_supply rx51_vio_supplies[] = { }, }; +#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) +extern struct platform_device rx51_display_device; +#endif + +static struct regulator_consumer_supply rx51_vaux1_consumers[] = { +#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) + { + .supply = "vdds_sdi", + .dev = &rx51_display_device.dev, + }, +#endif +}; + static struct regulator_init_data rx51_vaux1 = { .constraints = { .name = "V28", @@ -326,6 +339,8 @@ static struct regulator_init_data rx51_vaux1 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, + .num_consumer_supplies = ARRAY_SIZE(rx51_vaux1_consumers), + .consumer_supplies = rx51_vaux1_consumers, }; static struct regulator_init_data rx51_vaux2 = { -- cgit v1.2.3-59-g8ed1b From ada8d4a5e2ed9de8a5a58788c4b6a4c8103e0f8d Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 14 May 2010 12:05:25 -0700 Subject: OMAP2/3/4: DMA: disable channel interrupts in omap_init_dma() If we are softbooting another kernel using kexec, DMA controller state is not known when we are performing omap_init_dma(). It is possible that some DMA channels are already active. For example after kexec we get: <4>IRQ 0020 for non-allocated DMAchannel 5 <4>IRQ 0020 for non-allocated DMAchannel 5 <4>IRQ 0020 for non-allocated DMAchannel 5 <4>IRQ 0020 for non-allocated DMAchannel 5 <4>IRQ 0020 for non-allocated DMAchannel 5 To prevent any weird things happening, we disable all channel interrupts during init. Signed-off-by: Mika Westerberg Acked-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 1d959965ff52..ad42ec3592e5 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -709,6 +709,21 @@ static inline void omap2_enable_irq_lch(int lch) spin_unlock_irqrestore(&dma_chan_lock, flags); } +static inline void omap2_disable_irq_lch(int lch) +{ + u32 val; + unsigned long flags; + + if (!cpu_class_is_omap2()) + return; + + spin_lock_irqsave(&dma_chan_lock, flags); + val = dma_read(IRQENABLE_L0); + val &= ~(1 << lch); + dma_write(val, IRQENABLE_L0); + spin_unlock_irqrestore(&dma_chan_lock, flags); +} + int omap_request_dma(int dev_id, const char *dev_name, void (*callback)(int lch, u16 ch_status, void *data), void *data, int *dma_ch_out) @@ -807,14 +822,7 @@ void omap_free_dma(int lch) } if (cpu_class_is_omap2()) { - u32 val; - - spin_lock_irqsave(&dma_chan_lock, flags); - /* Disable interrupts */ - val = dma_read(IRQENABLE_L0); - val &= ~(1 << lch); - dma_write(val, IRQENABLE_L0); - spin_unlock_irqrestore(&dma_chan_lock, flags); + omap2_disable_irq_lch(lch); /* Clear the CSR register and IRQ status register */ dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch)); @@ -2107,6 +2115,9 @@ static int __init omap_init_dma(void) for (ch = 0; ch < dma_chan_count; ch++) { omap_clear_dma(ch); + if (cpu_class_is_omap2()) + omap2_disable_irq_lch(ch); + dma_chan[ch].dev_id = -1; dma_chan[ch].next_lch = -1; -- cgit v1.2.3-59-g8ed1b From ea221a6ae73c7696c60a52aefd8a7af0bb47033a Mon Sep 17 00:00:00 2001 From: manjugk manjugk Date: Fri, 14 May 2010 12:05:25 -0700 Subject: omap: DMA: Fix multi-line comments Multi line comments are fixed as per CodingStyle guidelines. Cc: Kevin Hilman Signed-off-by: Manjunatha GK Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index ad42ec3592e5..f7f571e7987e 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -501,7 +501,8 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) burst = 0x2; break; } - /* not supported by current hardware on OMAP1 + /* + * not supported by current hardware on OMAP1 * w |= (0x03 << 7); * fall through */ @@ -510,7 +511,8 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) burst = 0x3; break; } - /* OMAP1 don't support burst 16 + /* + * OMAP1 don't support burst 16 * fall through */ default: @@ -604,7 +606,8 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) burst = 0x3; break; } - /* OMAP1 don't support burst 16 + /* + * OMAP1 don't support burst 16 * fall through */ default: @@ -1285,8 +1288,10 @@ int omap_request_dma_chain(int dev_id, const char *dev_name, return -EINVAL; } - /* Allocate a queue to maintain the status of the channels - * in the chain */ + /* + * Allocate a queue to maintain the status of the channels + * in the chain + */ channels = kmalloc(sizeof(*channels) * no_of_chans, GFP_KERNEL); if (channels == NULL) { printk(KERN_ERR "omap_dma: No memory for channel queue\n"); @@ -1915,7 +1920,8 @@ static int omap2_dma_handle_ch(int ch) printk(KERN_INFO "DMA transaction error with device %d\n", dma_chan[ch].dev_id); if (cpu_class_is_omap2()) { - /* Errata: sDMA Channel is not disabled + /* + * Errata: sDMA Channel is not disabled * after a transaction error. So we explicitely * disable the channel */ -- cgit v1.2.3-59-g8ed1b From ed8303fc111e58530e22bd29b0d7e08dced75999 Mon Sep 17 00:00:00 2001 From: "stanley.miao" Date: Thu, 13 May 2010 12:39:30 +0000 Subject: omap: init the gpio pinmux for mmc There is two gpio for mmc use, one is for card detecting, another is used for checking write protect. Intialize its pinmux in case the bootloader doesn't set it. Signed-off-by: Stanley.Miao Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/devices.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 10f3a3c58cc0..3d30f22c4c88 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -591,6 +591,15 @@ static inline void omap_hsmmc_reset(void) {} static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, int controller_nr) { + if ((mmc_controller->slots[0].switch_pin > 0) && \ + (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) + omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, + OMAP_PIN_INPUT_PULLUP); + if ((mmc_controller->slots[0].gpio_wp > 0) && \ + (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) + omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, + OMAP_PIN_INPUT_PULLUP); + if (cpu_is_omap2420() && controller_nr == 0) { omap_cfg_reg(H18_24XX_MMC_CMD); omap_cfg_reg(H15_24XX_MMC_CLKI); -- cgit v1.2.3-59-g8ed1b From 03e7e170d6fdc5b6f75d1ab2cc1a6cb4f2b6b8c4 Mon Sep 17 00:00:00 2001 From: "stanley.miao" Date: Thu, 13 May 2010 12:39:31 +0000 Subject: omap: hsmmc: fix the hsmmc driver for am3517 AM3517 don't have the register OMAP343X_CONTROL_PBIAS_LITE and the regulators like "vmmc", so we set a noop "set_power" function for it. Signed-off-by: Stanley.Miao Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/hsmmc.c | 27 +++++++++++++++++++++------ arch/arm/plat-omap/include/plat/mmc.h | 4 ++++ 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 9ad229594b46..2d36f3afbd4e 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -139,6 +139,12 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot, } } +static int nop_mmc_set_power(struct device *dev, int slot, int power_on, + int vdd) +{ + return 0; +} + static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) @@ -216,11 +222,18 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) */ mmc->slots[0].ocr_mask = c->ocr_mask; + if (cpu_is_omap3517() || cpu_is_omap3505()) + mmc->slots[0].set_power = nop_mmc_set_power; + else + mmc->slots[0].features |= HSMMC_HAS_PBIAS; + switch (c->mmc) { case 1: - /* on-chip level shifting via PBIAS0/PBIAS1 */ - mmc->slots[0].before_set_reg = hsmmc1_before_set_reg; - mmc->slots[0].after_set_reg = hsmmc1_after_set_reg; + if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { + /* on-chip level shifting via PBIAS0/PBIAS1 */ + mmc->slots[0].before_set_reg = hsmmc1_before_set_reg; + mmc->slots[0].after_set_reg = hsmmc1_after_set_reg; + } /* Omap3630 HSMMC1 supports only 4-bit */ if (cpu_is_omap3630() && c->wires > 4) { @@ -235,9 +248,11 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) c->wires = 4; /* FALLTHROUGH */ case 3: - /* off-chip level shifting, or none */ - mmc->slots[0].before_set_reg = hsmmc23_before_set_reg; - mmc->slots[0].after_set_reg = NULL; + if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { + /* off-chip level shifting, or none */ + mmc->slots[0].before_set_reg = hsmmc23_before_set_reg; + mmc->slots[0].after_set_reg = NULL; + } break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index a1bac07c89eb..c835f1e994c6 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -102,6 +102,10 @@ struct omap_mmc_platform_data { /* Regulator off remapped to sleep */ unsigned vcc_aux_disable_is_sleep:1; + /* we can put the features above into this variable */ +#define HSMMC_HAS_PBIAS (1 << 0) + unsigned features; + int switch_pin; /* gpio (card detect) */ int gpio_wp; /* gpio (write protect) */ -- cgit v1.2.3-59-g8ed1b From b2aa5e5757b2fd33c47fc52dfd6d5b0dbcda6492 Mon Sep 17 00:00:00 2001 From: Abraham Arce Date: Fri, 14 May 2010 12:05:26 -0700 Subject: OMAP4: Ethernet: KS8851 Board Support Enable Micrel KS8851 SPI network chip for OMAP4430 Signed-off-by: Abraham Arce Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-4430sdp.c | 81 +++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index b88f28c5814b..be7a7868d210 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,75 @@ #include #include +#define ETH_KS8851_IRQ 34 +#define ETH_KS8851_POWER_ON 48 +#define ETH_KS8851_QUART 138 + +static struct spi_board_info sdp4430_spi_board_info[] __initdata = { + { + .modalias = "ks8851", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 24000000, + .irq = ETH_KS8851_IRQ, + }, +}; + +static int omap_ethernet_init(void) +{ + int status; + + /* Request of GPIO lines */ + + status = gpio_request(ETH_KS8851_POWER_ON, "eth_power"); + if (status) { + pr_err("Cannot request GPIO %d\n", ETH_KS8851_POWER_ON); + return status; + } + + status = gpio_request(ETH_KS8851_QUART, "quart"); + if (status) { + pr_err("Cannot request GPIO %d\n", ETH_KS8851_QUART); + goto error1; + } + + status = gpio_request(ETH_KS8851_IRQ, "eth_irq"); + if (status) { + pr_err("Cannot request GPIO %d\n", ETH_KS8851_IRQ); + goto error2; + } + + /* Configuration of requested GPIO lines */ + + status = gpio_direction_output(ETH_KS8851_POWER_ON, 1); + if (status) { + pr_err("Cannot set output GPIO %d\n", ETH_KS8851_IRQ); + goto error3; + } + + status = gpio_direction_output(ETH_KS8851_QUART, 1); + if (status) { + pr_err("Cannot set output GPIO %d\n", ETH_KS8851_QUART); + goto error3; + } + + status = gpio_direction_input(ETH_KS8851_IRQ); + if (status) { + pr_err("Cannot set input GPIO %d\n", ETH_KS8851_IRQ); + goto error3; + } + + return 0; + +error3: + gpio_free(ETH_KS8851_IRQ); +error2: + gpio_free(ETH_KS8851_QUART); +error1: + gpio_free(ETH_KS8851_POWER_ON); + return status; +} + static struct platform_device sdp4430_lcd_device = { .name = "sdp4430_lcd", .id = -1, @@ -113,6 +183,8 @@ static struct omap_musb_board_data musb_board_data = { static void __init omap_4430sdp_init(void) { + int status; + platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); omap_serial_init(); /* OMAP4 SDP uses internal transceiver so register nop transceiver */ @@ -120,6 +192,15 @@ static void __init omap_4430sdp_init(void) /* FIXME: allow multi-omap to boot until musb is updated for omap4 */ if (!cpu_is_omap44xx()) usb_musb_init(&musb_board_data); + + status = omap_ethernet_init(); + if (status) { + pr_err("Ethernet initialization failed: %d\n", status); + } else { + sdp4430_spi_board_info[0].irq = gpio_to_irq(ETH_KS8851_IRQ); + spi_register_board_info(sdp4430_spi_board_info, + ARRAY_SIZE(sdp4430_spi_board_info)); + } } static void __init omap_4430sdp_map_io(void) -- cgit v1.2.3-59-g8ed1b From 2e5f51a539194406566968d1b68f0bcd1112720d Mon Sep 17 00:00:00 2001 From: Abraham Arce Date: Fri, 14 May 2010 12:05:26 -0700 Subject: OMAP4: Networking: Defconfig Support Enable KS8851 SPI support + Networking Support - Packet Socket - TCP/IP Network Filesystems - NFS Client - Root Filesystem on NFS Signed-off-by: Abraham Arce Signed-off-by: Tony Lindgren --- arch/arm/configs/omap_4430sdp_defconfig | 57 +++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/omap_4430sdp_defconfig b/arch/arm/configs/omap_4430sdp_defconfig index a96bca290cd1..d87a349ed6f7 100644 --- a/arch/arm/configs/omap_4430sdp_defconfig +++ b/arch/arm/configs/omap_4430sdp_defconfig @@ -343,7 +343,34 @@ CONFIG_BINFMT_MISC=y # # CONFIG_PM is not set CONFIG_ARCH_SUSPEND_POSSIBLE=y -# CONFIG_NET is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_XFRM=y +CONFIG_INET=y +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_IPV6 is not set + +# +# Network testing +# +# CONFIG_WIRELESS is not set + # # Device Drivers @@ -386,6 +413,13 @@ CONFIG_HAVE_IDE=y # CONFIG_ATA is not set # CONFIG_MD is not set # CONFIG_PHONE is not set +CONFIG_NETDEVICES=y +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_KS8851=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set # # Input device support @@ -457,7 +491,13 @@ CONFIG_HW_RANDOM=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set -# CONFIG_SPI is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_OMAP24XX=y # # PPS support @@ -634,6 +674,19 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y # # Partition Types -- cgit v1.2.3-59-g8ed1b From fbc9be106e9f27450ea999da74bc24fad04cf41d Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 14 May 2010 12:05:26 -0700 Subject: omap4: Move SOC specific code from board file This patch moves OMAP4 soc specific code from 4430sdp board file. The change is necessary so that newer board support can be added with minimal changes. This will be also problematic for multi-board, multi-omap builds. Signed-off-by: Santosh Shilimkar Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/board-4430sdp.c | 47 +--------------- arch/arm/mach-omap2/include/mach/omap4-common.h | 26 +++++++++ arch/arm/mach-omap2/omap-smp.c | 2 +- arch/arm/mach-omap2/omap4-common.c | 72 +++++++++++++++++++++++++ arch/arm/plat-omap/common.c | 3 -- arch/arm/plat-omap/include/plat/common.h | 3 -- 7 files changed, 101 insertions(+), 54 deletions(-) create mode 100644 arch/arm/mach-omap2/include/mach/omap4-common.h create mode 100644 arch/arm/mach-omap2/omap4-common.c (limited to 'arch') diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 7d2cf0f714c0..203a414c3341 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -22,7 +22,7 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o # SMP support ONLY available for OMAP4 obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o -obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o +obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index be7a7868d210..6cce6f229799 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -30,8 +31,6 @@ #include #include #include -#include -#include #define ETH_KS8851_IRQ 34 #define ETH_KS8851_POWER_ON 48 @@ -119,50 +118,6 @@ static struct omap_board_config_kernel sdp4430_config[] __initdata = { { OMAP_TAG_LCD, &sdp4430_lcd_config }, }; -#ifdef CONFIG_CACHE_L2X0 -static int __init omap_l2_cache_init(void) -{ - extern void omap_smc1(u32 fn, u32 arg); - void __iomem *l2cache_base; - - /* To avoid code running on other OMAPs in - * multi-omap builds - */ - if (!cpu_is_omap44xx()) - return -ENODEV; - - /* Static mapping, never released */ - l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K); - BUG_ON(!l2cache_base); - - /* Enable PL310 L2 Cache controller */ - omap_smc1(0x102, 0x1); - - /* 32KB way size, 16-way associativity, - * parity disabled - */ - l2x0_init(l2cache_base, 0x0e050000, 0xc0000fff); - - return 0; -} -early_initcall(omap_l2_cache_init); -#endif - -static void __init gic_init_irq(void) -{ - void __iomem *base; - - /* Static mapping, never released */ - base = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); - BUG_ON(!base); - gic_dist_init(0, base, 29); - - /* Static mapping, never released */ - gic_cpu_base_addr = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); - BUG_ON(!gic_cpu_base_addr); - gic_cpu_init(0, gic_cpu_base_addr); -} - static void __init omap_4430sdp_init_irq(void) { omap_board_config = sdp4430_config; diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h new file mode 100644 index 000000000000..423af3a6dd31 --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/omap4-common.h @@ -0,0 +1,26 @@ +/* + * omap4-common.h: OMAP4 specific common header file + * + * Copyright (C) 2010 Texas Instruments, Inc. + * + * Author: + * Santosh Shilimkar + * + * 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. + */ +#ifndef OMAP_ARCH_OMAP4_COMMON_H +#define OMAP_ARCH_OMAP4_COMMON_H + +#ifdef CONFIG_CACHE_L2X0 +extern void __iomem *l2cache_base; +#endif + +extern void __iomem *gic_cpu_base_addr; +extern void __iomem *gic_dist_base_addr; + +extern void __init gic_init_irq(void); +extern void omap_smc1(u32 fn, u32 arg); + +#endif diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 38153e5fbca0..1cf52313759e 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include /* SCU base address */ static void __iomem *scu_base; diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c new file mode 100644 index 000000000000..13dc9794dcc2 --- /dev/null +++ b/arch/arm/mach-omap2/omap4-common.c @@ -0,0 +1,72 @@ +/* + * OMAP4 specific common source file. + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Author: + * Santosh Shilimkar + * + * + * 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 +#include +#include +#include + +#include +#include + +#include +#include + +#ifdef CONFIG_CACHE_L2X0 +void __iomem *l2cache_base; +#endif + +void __iomem *gic_cpu_base_addr; +void __iomem *gic_dist_base_addr; + + +void __init gic_init_irq(void) +{ + /* Static mapping, never released */ + gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); + BUG_ON(!gic_dist_base_addr); + gic_dist_init(0, gic_dist_base_addr, 29); + + /* Static mapping, never released */ + gic_cpu_base_addr = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); + BUG_ON(!gic_cpu_base_addr); + gic_cpu_init(0, gic_cpu_base_addr); +} + +#ifdef CONFIG_CACHE_L2X0 +static int __init omap_l2_cache_init(void) +{ + /* + * To avoid code running on other OMAPs in + * multi-omap builds + */ + if (!cpu_is_omap44xx()) + return -ENODEV; + + /* Static mapping, never released */ + l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K); + BUG_ON(!l2cache_base); + + /* Enable PL310 L2 Cache controller */ + omap_smc1(0x102, 0x1); + + /* + * 32KB way size, 16-way associativity, + * parity disabled + */ + l2x0_init(l2cache_base, 0x0e050000, 0xc0000fff); + + return 0; +} +early_initcall(omap_l2_cache_init); +#endif diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index f12f0e39ddf2..219c01e82bc5 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c @@ -47,9 +47,6 @@ struct omap_board_config_kernel *omap_board_config; int omap_board_config_size; -/* used by omap-smp.c and board-4430sdp.c */ -void __iomem *gic_cpu_base_addr; - static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out) { struct omap_board_config_kernel *kinfo = NULL; diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index 7556e271942e..d265018f5e6b 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -31,9 +31,6 @@ struct sys_timer; -/* used by omap-smp.c and board-4430sdp.c */ -extern void __iomem *gic_cpu_base_addr; - extern void omap_map_common_io(void); extern struct sys_timer omap_timer; -- cgit v1.2.3-59-g8ed1b From 9f09686864e16723b2998eefb3986196ba0bcf6b Mon Sep 17 00:00:00 2001 From: Charulatha V Date: Fri, 14 May 2010 12:05:27 -0700 Subject: omap: GPIO: Fix OMAP4 GPIO reg access issues Access to some of the OMAP4 GPIO registers are not properly handled. This patch fixes it. This patch is tested on 3430SDP and 4430SDP boards Signed-off-by: Charulatha V Acked-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/gpio.c | 59 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 955597fd6d35..dc2ac42d6319 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -138,7 +138,11 @@ #define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 #define OMAP4_GPIO_IRQWAKEN0 0x0044 #define OMAP4_GPIO_IRQWAKEN1 0x0048 -#define OMAP4_GPIO_SYSSTATUS 0x0104 +#define OMAP4_GPIO_SYSSTATUS 0x0114 +#define OMAP4_GPIO_IRQENABLE1 0x011c +#define OMAP4_GPIO_WAKE_EN 0x0120 +#define OMAP4_GPIO_IRQSTATUS2 0x0128 +#define OMAP4_GPIO_IRQENABLE2 0x012c #define OMAP4_GPIO_CTRL 0x0130 #define OMAP4_GPIO_OE 0x0134 #define OMAP4_GPIO_DATAIN 0x0138 @@ -149,6 +153,10 @@ #define OMAP4_GPIO_FALLINGDETECT 0x014c #define OMAP4_GPIO_DEBOUNCENABLE 0x0150 #define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 +#define OMAP4_GPIO_CLEARIRQENABLE1 0x0160 +#define OMAP4_GPIO_SETIRQENABLE1 0x0164 +#define OMAP4_GPIO_CLEARWKUENA 0x0180 +#define OMAP4_GPIO_SETWKUENA 0x0184 #define OMAP4_GPIO_CLEARDATAOUT 0x0190 #define OMAP4_GPIO_SETDATAOUT 0x0194 /* @@ -591,11 +599,15 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) reg += OMAP7XX_GPIO_DATA_OUTPUT; break; #endif -#ifdef CONFIG_ARCH_OMAP2PLUS +#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) case METHOD_GPIO_24XX: - case METHOD_GPIO_44XX: reg += OMAP24XX_GPIO_DATAOUT; break; +#endif +#ifdef CONFIG_ARCH_OMAP4 + case METHOD_GPIO_44XX: + reg += OMAP4_GPIO_DATAOUT; + break; #endif default: return -EINVAL; @@ -1213,11 +1225,17 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) #endif if (!cpu_class_is_omap1()) { if (!bank->mod_usage) { + void __iomem *reg = bank->base; u32 ctrl; - ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); - ctrl &= 0xFFFFFFFE; + + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + reg += OMAP24XX_GPIO_CTRL; + else if (cpu_is_omap44xx()) + reg += OMAP4_GPIO_CTRL; + ctrl = __raw_readl(reg); /* Module is enabled, clocks are not gated */ - __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL); + ctrl &= 0xFFFFFFFE; + __raw_writel(ctrl, reg); } bank->mod_usage |= 1 << offset; } @@ -1239,22 +1257,34 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) __raw_writel(1 << offset, reg); } #endif -#ifdef CONFIG_ARCH_OMAP2PLUS - if ((bank->method == METHOD_GPIO_24XX) || - (bank->method == METHOD_GPIO_44XX)) { +#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) + if (bank->method == METHOD_GPIO_24XX) { /* Disable wake-up during idle for dynamic tick */ void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; __raw_writel(1 << offset, reg); } +#endif +#ifdef CONFIG_ARCH_OMAP4 + if (bank->method == METHOD_GPIO_44XX) { + /* Disable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0; + __raw_writel(1 << offset, reg); + } #endif if (!cpu_class_is_omap1()) { bank->mod_usage &= ~(1 << offset); if (!bank->mod_usage) { + void __iomem *reg = bank->base; u32 ctrl; - ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); + + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + reg += OMAP24XX_GPIO_CTRL; + else if (cpu_is_omap44xx()) + reg += OMAP4_GPIO_CTRL; + ctrl = __raw_readl(reg); /* Module is disabled, clocks are gated */ ctrl |= 1; - __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL); + __raw_writel(ctrl, reg); } } _reset_gpio(bank, bank->chip.base + offset); @@ -1583,9 +1613,14 @@ static int gpio_is_input(struct gpio_bank *bank, int mask) reg += OMAP7XX_GPIO_DIR_CONTROL; break; case METHOD_GPIO_24XX: - case METHOD_GPIO_44XX: reg += OMAP24XX_GPIO_OE; break; + case METHOD_GPIO_44XX: + reg += OMAP4_GPIO_OE; + break; + default: + WARN_ONCE(1, "gpio_is_input: incorrect OMAP GPIO method"); + return -EINVAL; } return __raw_readl(reg) & mask; } -- cgit v1.2.3-59-g8ed1b From b91da669472a534328bf796a8c913f2d042ede76 Mon Sep 17 00:00:00 2001 From: "stanley.miao" Date: Thu, 13 May 2010 12:39:29 +0000 Subject: AM3517: rename the i2c boardinfo to make it more readable There are three i2c buses on am3517, and each i2c bus has several devices on it, so we can't name the i2c boardinfo structures with one of these devices. In order to make it more readable, now rename these three boardinfo structures based on i2c indexes. Signed-off-by: Stanley.Miao Acked-By: Vaibhav Hiremath Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-am3517evm.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 19b9e415710d..af383a876943 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -136,7 +136,7 @@ void am3517_evm_ethernet_init(struct emac_platform_data *pdata) #define LCD_PANEL_BKLIGHT_PWR 182 #define LCD_PANEL_PWM 181 -static struct i2c_board_info __initdata am3517evm_i2c_boardinfo[] = { +static struct i2c_board_info __initdata am3517evm_i2c1_boardinfo[] = { { I2C_BOARD_INFO("s35390a", 0x30), .type = "s35390a", @@ -166,7 +166,7 @@ static void __init am3517_evm_rtc_init(void) gpio_free(GPIO_RTCS35390A_IRQ); return; } - am3517evm_i2c_boardinfo[0].irq = gpio_to_irq(GPIO_RTCS35390A_IRQ); + am3517evm_i2c1_boardinfo[0].irq = gpio_to_irq(GPIO_RTCS35390A_IRQ); } /* @@ -177,7 +177,7 @@ static void __init am3517_evm_rtc_init(void) static struct pca953x_platform_data am3517evm_gpio_expander_info_0 = { .gpio_base = OMAP_MAX_GPIO_LINES, }; -static struct i2c_board_info __initdata am3517evm_tca6416_info_0[] = { +static struct i2c_board_info __initdata am3517evm_i2c2_boardinfo[] = { { I2C_BOARD_INFO("tca6416", 0x21), .platform_data = &am3517evm_gpio_expander_info_0, @@ -191,7 +191,7 @@ static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_1 = { static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_2 = { .gpio_base = OMAP_MAX_GPIO_LINES + 32, }; -static struct i2c_board_info __initdata am3517evm_ui_tca6416_info[] = { +static struct i2c_board_info __initdata am3517evm_i2c3_boardinfo[] = { { I2C_BOARD_INFO("tca6416", 0x20), .platform_data = &am3517evm_ui_gpio_expander_info_1, @@ -205,10 +205,10 @@ static struct i2c_board_info __initdata am3517evm_ui_tca6416_info[] = { static int __init am3517_evm_i2c_init(void) { omap_register_i2c_bus(1, 400, NULL, 0); - omap_register_i2c_bus(2, 400, am3517evm_tca6416_info_0, - ARRAY_SIZE(am3517evm_tca6416_info_0)); - omap_register_i2c_bus(3, 400, am3517evm_ui_tca6416_info, - ARRAY_SIZE(am3517evm_ui_tca6416_info)); + omap_register_i2c_bus(2, 400, am3517evm_i2c2_boardinfo, + ARRAY_SIZE(am3517evm_i2c2_boardinfo)); + omap_register_i2c_bus(3, 400, am3517evm_i2c3_boardinfo, + ARRAY_SIZE(am3517evm_i2c3_boardinfo)); return 0; } @@ -455,8 +455,8 @@ static void __init am3517_evm_init(void) /* RTC - S35390A */ am3517_evm_rtc_init(); - i2c_register_board_info(1, am3517evm_i2c_boardinfo, - ARRAY_SIZE(am3517evm_i2c_boardinfo)); + i2c_register_board_info(1, am3517evm_i2c1_boardinfo, + ARRAY_SIZE(am3517evm_i2c1_boardinfo)); /*Ethernet*/ am3517_evm_ethernet_init(&am3517_evm_emac_pdata); } -- cgit v1.2.3-59-g8ed1b From baeb73e8027b8a62b32c11afc3035cf6cc0927dd Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 12 May 2010 08:27:29 +0000 Subject: omap4: Add i2c board support on omap4430 sdp platform This patch adds the i2c board support for OMAP4430 SDP platform. Signed-off-by: Santosh Shilimkar Signed-off-by: Balaji T K Signed-off-by: Tony Lindgren --- arch/arm/configs/omap_4430sdp_defconfig | 46 ++++++++++++++++++++++++++++++++- arch/arm/mach-omap2/board-4430sdp.c | 14 +++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/omap_4430sdp_defconfig b/arch/arm/configs/omap_4430sdp_defconfig index d87a349ed6f7..a5553055f428 100644 --- a/arch/arm/configs/omap_4430sdp_defconfig +++ b/arch/arm/configs/omap_4430sdp_defconfig @@ -490,14 +490,58 @@ CONFIG_HW_RANDOM=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_OMAP=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y # # SPI Master Controller Drivers # +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set CONFIG_SPI_OMAP24XX=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set # # PPS support diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 6cce6f229799..41fed9235f81 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -135,11 +135,23 @@ static struct omap_musb_board_data musb_board_data = { .mode = MUSB_PERIPHERAL, .power = 100, }; - +static int __init omap4_i2c_init(void) +{ + /* + * Phoenix Audio IC needs I2C1 to + * start with 400 KHz or less + */ + omap_register_i2c_bus(1, 400, NULL, 0); + omap_register_i2c_bus(2, 400, NULL, 0); + omap_register_i2c_bus(3, 400, NULL, 0); + omap_register_i2c_bus(4, 400, NULL, 0); + return 0; +} static void __init omap_4430sdp_init(void) { int status; + omap4_i2c_init(); platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); omap_serial_init(); /* OMAP4 SDP uses internal transceiver so register nop transceiver */ -- cgit v1.2.3-59-g8ed1b From 6e30a7dbc946132525ca12ce16f0f2105096624a Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Wed, 12 May 2010 08:27:30 +0000 Subject: omap4: add i2c1 peripherals data This patch adds i2c1 peripherals data to omap4430 sdp board file. Signed-off-by: Rajendra Nayak Signed-off-by: Balaji T K Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-4430sdp.c | 177 +++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 41fed9235f81..921cde3d79e0 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -135,13 +137,186 @@ static struct omap_musb_board_data musb_board_data = { .mode = MUSB_PERIPHERAL, .power = 100, }; +static struct regulator_consumer_supply sdp4430_vmmc_supply[] = { + { + .supply = "vmmc", + }, + { + .supply = "vmmc", + }, + { + .supply = "vmmc", + }, + { + .supply = "vmmc", + }, + { + .supply = "vmmc", + }, +}; + +static struct regulator_init_data sdp4430_vaux1 = { + .constraints = { + .min_uV = 1000000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vaux2 = { + .constraints = { + .min_uV = 1200000, + .max_uV = 2800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vaux3 = { + .constraints = { + .min_uV = 1000000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +/* VMMC1 for MMC1 card */ +static struct regulator_init_data sdp4430_vmmc = { + .constraints = { + .min_uV = 1200000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 5, + .consumer_supplies = sdp4430_vmmc_supply, +}; + +static struct regulator_init_data sdp4430_vpp = { + .constraints = { + .min_uV = 1800000, + .max_uV = 2500000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vusim = { + .constraints = { + .min_uV = 1200000, + .max_uV = 2900000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vana = { + .constraints = { + .min_uV = 2100000, + .max_uV = 2100000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vcxio = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vdac = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vusb = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct twl4030_platform_data sdp4430_twldata = { + .irq_base = TWL6030_IRQ_BASE, + .irq_end = TWL6030_IRQ_END, + + /* Regulators */ + .vmmc = &sdp4430_vmmc, + .vpp = &sdp4430_vpp, + .vusim = &sdp4430_vusim, + .vana = &sdp4430_vana, + .vcxio = &sdp4430_vcxio, + .vdac = &sdp4430_vdac, + .vusb = &sdp4430_vusb, + .vaux1 = &sdp4430_vaux1, + .vaux2 = &sdp4430_vaux2, + .vaux3 = &sdp4430_vaux3, +}; + +static struct i2c_board_info __initdata sdp4430_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl6030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = OMAP44XX_IRQ_SYS_1N, + .platform_data = &sdp4430_twldata, + }, +}; static int __init omap4_i2c_init(void) { /* * Phoenix Audio IC needs I2C1 to * start with 400 KHz or less */ - omap_register_i2c_bus(1, 400, NULL, 0); + omap_register_i2c_bus(1, 400, sdp4430_i2c_boardinfo, + ARRAY_SIZE(sdp4430_i2c_boardinfo)); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, NULL, 0); omap_register_i2c_bus(4, 400, NULL, 0); -- cgit v1.2.3-59-g8ed1b From f9ea6cfb5a31d0addf9d1d8ed772bdc3a1c0dbd7 Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Wed, 12 May 2010 08:27:31 +0000 Subject: omap4: Enable RTC and regulator support This patch enables RTC and regulator support on omap4430 sdp platform. Also sync up the defconfig with latest kernel Signed-off-by: Balaji T K Signed-off-by: Santosh Shilimkar Signed-off-by: Tony Lindgren --- arch/arm/configs/omap_4430sdp_defconfig | 330 +++++++++++++++++++++++++++++--- 1 file changed, 302 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/omap_4430sdp_defconfig b/arch/arm/configs/omap_4430sdp_defconfig index a5553055f428..25e8d048fc1c 100644 --- a/arch/arm/configs/omap_4430sdp_defconfig +++ b/arch/arm/configs/omap_4430sdp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.32 -# Sun Dec 6 23:37:45 2009 +# Linux kernel version: 2.6.34-rc7 +# Wed May 12 12:26:05 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -9,6 +9,7 @@ CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_HAVE_PROC_CPU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -20,6 +21,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_ARCH_HAS_CPUFREQ=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -33,28 +35,33 @@ CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set # # RCU Subsystem # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -64,6 +71,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -85,10 +93,14 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y CONFIG_COMPAT_BRK=y @@ -127,14 +139,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y # CONFIG_FREEZER is not set # @@ -146,6 +185,7 @@ CONFIG_MMU=y # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set # CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set @@ -155,7 +195,6 @@ CONFIG_MMU=y # CONFIG_ARCH_STMP3XXX is not set # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set # CONFIG_ARCH_IOP33X is not set @@ -163,6 +202,7 @@ CONFIG_MMU=y # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set # CONFIG_ARCH_KIRKWOOD is not set # CONFIG_ARCH_LOKI is not set # CONFIG_ARCH_MV78XX0 is not set @@ -171,25 +211,32 @@ CONFIG_MMU=y # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set # CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set # CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_DAVINCI is not set CONFIG_ARCH_OMAP=y -# CONFIG_ARCH_BCMRING is not set # # TI OMAP Implementations # # CONFIG_ARCH_OMAP1 is not set +CONFIG_ARCH_OMAP2PLUS=y # CONFIG_ARCH_OMAP2 is not set # CONFIG_ARCH_OMAP3 is not set CONFIG_ARCH_OMAP4=y @@ -205,10 +252,6 @@ CONFIG_OMAP_MCBSP=y CONFIG_OMAP_32K_TIMER=y CONFIG_OMAP_32K_TIMER_HZ=128 CONFIG_OMAP_DM_TIMER=y -# CONFIG_OMAP_LL_DEBUG_UART1 is not set -# CONFIG_OMAP_LL_DEBUG_UART2 is not set -CONFIG_OMAP_LL_DEBUG_UART3=y -# CONFIG_OMAP_LL_DEBUG_NONE is not set # CONFIG_OMAP_PM_NONE is not set CONFIG_OMAP_PM_NOOP=y @@ -243,13 +286,16 @@ CONFIG_CPU_CP15_MMU=y # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_HAS_TLS_REG=y CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y CONFIG_CACHE_L2X0=y CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_CPU_HAS_PMU=y # CONFIG_ARM_ERRATA_430973 is not set # CONFIG_ARM_ERRATA_458693 is not set # CONFIG_ARM_ERRATA_460075 is not set CONFIG_PL310_ERRATA_588369=y CONFIG_ARM_GIC=y +CONFIG_COMMON_CLKDEV=y # # Bus support @@ -280,6 +326,7 @@ CONFIG_HZ=128 # CONFIG_THUMB2_KERNEL is not set CONFIG_AEABI=y CONFIG_OABI_COMPAT=y +CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set # CONFIG_HIGHMEM is not set @@ -294,8 +341,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # CONFIG_LEDS is not set @@ -349,28 +394,77 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y +# CONFIG_UNIX is not set CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_LRO=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set # CONFIG_WIRELESS is not set - +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -387,17 +481,24 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set # CONFIG_MTD is not set # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 # CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set # CONFIG_MG_DISK is not set # CONFIG_MISC_DEVICES is not set CONFIG_HAVE_IDE=y @@ -406,27 +507,65 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set # CONFIG_MD is not set -# CONFIG_PHONE is not set CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set CONFIG_KS8851=y +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + # # Input device support # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -479,8 +618,10 @@ CONFIG_SERIAL_8250_RSA=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -555,10 +696,17 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_TWL4030 is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -567,6 +715,9 @@ CONFIG_GPIOLIB=y # # SPI GPIO expanders: # +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set # # AC97 GPIO expanders: @@ -576,7 +727,15 @@ CONFIG_GPIOLIB=y # CONFIG_HWMON is not set # CONFIG_THERMAL is not set CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set CONFIG_OMAP_WATCHDOG=y +# CONFIG_TWL4030_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set CONFIG_SSB_POSSIBLE=y # @@ -588,15 +747,46 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_ASIC3 is not set # CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +CONFIG_TWL4030_CORE=y +# CONFIG_TWL4030_POWER is not set +# CONFIG_TWL4030_CODEC is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set # CONFIG_MFD_TC6393XB is not set -# CONFIG_REGULATOR is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +CONFIG_REGULATOR_TWL4030=y +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set # CONFIG_MEDIA_SUPPORT is not set # @@ -625,7 +815,72 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +CONFIG_RTC_DRV_TWL4030=y +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# # CONFIG_DMADEVICES is not set # CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set @@ -648,9 +903,10 @@ CONFIG_EXT3_FS=y CONFIG_JBD=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set +CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y @@ -659,7 +915,9 @@ CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QUOTA_DEBUG is not set CONFIG_QUOTA_TREE=y # CONFIG_QFMT_V1 is not set CONFIG_QFMT_V2=y @@ -708,6 +966,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -723,7 +982,9 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_ACL_SUPPORT=y @@ -731,6 +992,13 @@ CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -793,6 +1061,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set # # Kernel hacking @@ -847,13 +1116,11 @@ CONFIG_FRAME_POINTER=y # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set -# CONFIG_BRANCH_PROFILE_NONE is not set -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -862,6 +1129,7 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_LL is not set +# CONFIG_OC_ETM is not set # # Security options @@ -869,7 +1137,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # @@ -888,6 +1160,7 @@ CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set # CONFIG_CRYPTO_AUTHENC is not set @@ -986,3 +1259,4 @@ CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- cgit v1.2.3-59-g8ed1b From 2c9d103e1e6b0970fd45c82de205415a2ad86c8d Mon Sep 17 00:00:00 2001 From: kishore kadiyala Date: Tue, 4 May 2010 16:01:45 +0000 Subject: omap4: Adds Dummy Interface clock's for MMC controllers This patch adds dummy Interface clocks for MMC controllers Signed-off-by: Kishore Kadiyala Acked-by: Paul Walmsley Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clock44xx_data.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index a5c0c9c8e496..02804224517b 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -2675,6 +2675,11 @@ static struct omap_clk omap44xx_clks[] = { CLK("omap2_mcspi.2", "ick", &dummy_ck, CK_443X), CLK("omap2_mcspi.3", "ick", &dummy_ck, CK_443X), CLK("omap2_mcspi.4", "ick", &dummy_ck, CK_443X), + CLK("mmci-omap-hs.0", "ick", &dummy_ck, CK_443X), + CLK("mmci-omap-hs.1", "ick", &dummy_ck, CK_443X), + CLK("mmci-omap-hs.2", "ick", &dummy_ck, CK_443X), + CLK("mmci-omap-hs.3", "ick", &dummy_ck, CK_443X), + CLK("mmci-omap-hs.4", "ick", &dummy_ck, CK_443X), CLK(NULL, "uart1_ick", &dummy_ck, CK_443X), CLK(NULL, "uart2_ick", &dummy_ck, CK_443X), CLK(NULL, "uart3_ick", &dummy_ck, CK_443X), -- cgit v1.2.3-59-g8ed1b From 717c1fbf7c139c3c5d5920b29bdf196d07a40c8a Mon Sep 17 00:00:00 2001 From: kishore kadiyala Date: Sat, 15 May 2010 18:21:06 +0000 Subject: omap4: Adding hsmmc support to board file Adding support for MMC1 & MMC2 controllers of OMAP4430 SDP to board file. Signed-off-by: Kishore Kadiyala Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Makefile | 3 +- arch/arm/mach-omap2/board-4430sdp.c | 59 ++++++++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 203a414c3341..a79945349368 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -137,7 +137,8 @@ obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o \ hsmmc.o obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \ hsmmc.o -obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o +obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \ + hsmmc.o obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 921cde3d79e0..e4a5d66b83b8 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include "hsmmc.h" #define ETH_KS8851_IRQ 34 #define ETH_KS8851_POWER_ON 48 @@ -137,24 +139,66 @@ static struct omap_musb_board_data musb_board_data = { .mode = MUSB_PERIPHERAL, .power = 100, }; -static struct regulator_consumer_supply sdp4430_vmmc_supply[] = { - { - .supply = "vmmc", - }, + +static struct omap2_hsmmc_info mmc[] = { { - .supply = "vmmc", + .mmc = 1, + .wires = 8, + .gpio_wp = -EINVAL, }, { - .supply = "vmmc", + .mmc = 2, + .wires = 8, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + .nonremovable = true, }, + {} /* Terminator */ +}; + +static struct regulator_consumer_supply sdp4430_vmmc_supply[] = { { .supply = "vmmc", + .dev_name = "mmci-omap-hs.0", }, { .supply = "vmmc", + .dev_name = "mmci-omap-hs.1", }, }; +static int omap4_twl6030_hsmmc_late_init(struct device *dev) +{ + int ret = 0; + struct platform_device *pdev = container_of(dev, + struct platform_device, dev); + struct omap_mmc_platform_data *pdata = dev->platform_data; + + /* Setting MMC1 Card detect Irq */ + if (pdev->id == 0) + pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE + + MMCDETECT_INTR_OFFSET; + return ret; +} + +static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev) +{ + struct omap_mmc_platform_data *pdata = dev->platform_data; + + pdata->init = omap4_twl6030_hsmmc_late_init; +} + +static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) +{ + struct omap2_hsmmc_info *c; + + omap2_hsmmc_init(controllers); + for (c = controllers; c->mmc; c++) + omap4_twl6030_hsmmc_set_late_init(c->dev); + + return 0; +} + static struct regulator_init_data sdp4430_vaux1 = { .constraints = { .min_uV = 1000000, @@ -206,7 +250,7 @@ static struct regulator_init_data sdp4430_vmmc = { | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 5, + .num_consumer_supplies = 2, .consumer_supplies = sdp4430_vmmc_supply, }; @@ -329,6 +373,7 @@ static void __init omap_4430sdp_init(void) omap4_i2c_init(); platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); omap_serial_init(); + omap4_twl6030_hsmmc_init(mmc); /* OMAP4 SDP uses internal transceiver so register nop transceiver */ usb_nop_xceiv_register(); /* FIXME: allow multi-omap to boot until musb is updated for omap4 */ -- cgit v1.2.3-59-g8ed1b From c83c8e6cde35c51a120952f54b4e4ecda6fa58a5 Mon Sep 17 00:00:00 2001 From: kishore kadiyala Date: Sat, 15 May 2010 18:21:25 +0000 Subject: omap4: Adding PBIAS Configuration for MMC1 Controller In OMAP4, MMC1 PBIAS and its associated IO is software-controlled by CONTROL_PBIAS and CONTROL_MMC1 registers. This patch adds PBIAS configuration for MMC1 Controller during power-ON and power-OFF of regulator. Signed-off-by: Kishore Kadiyala Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/hsmmc.c | 97 ++++++++++++++++++++++++++++--- arch/arm/plat-omap/include/plat/control.h | 20 +++++++ 2 files changed, 108 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 2d36f3afbd4e..1ef54b036103 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -24,6 +24,7 @@ static u16 control_pbias_offset; static u16 control_devconf1_offset; +static u16 control_mmc1; #define HSMMC_NAME_LEN 9 @@ -42,7 +43,7 @@ static int hsmmc_get_context_loss(struct device *dev) #define hsmmc_get_context_loss NULL #endif -static void hsmmc1_before_set_reg(struct device *dev, int slot, +static void omap_hsmmc1_before_set_reg(struct device *dev, int slot, int power_on, int vdd) { u32 reg, prog_io; @@ -95,7 +96,7 @@ static void hsmmc1_before_set_reg(struct device *dev, int slot, } } -static void hsmmc1_after_set_reg(struct device *dev, int slot, +static void omap_hsmmc1_after_set_reg(struct device *dev, int slot, int power_on, int vdd) { u32 reg; @@ -119,6 +120,60 @@ static void hsmmc1_after_set_reg(struct device *dev, int slot, } } +static void omap4_hsmmc1_before_set_reg(struct device *dev, int slot, + int power_on, int vdd) +{ + u32 reg; + + /* + * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the + * card with Vcc regulator (from twl4030 or whatever). OMAP has both + * 1.8V and 3.0V modes, controlled by the PBIAS register. + * + * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which + * is most naturally TWL VSIM; those pins also use PBIAS. + * + * FIXME handle VMMC1A as needed ... + */ + reg = omap_ctrl_readl(control_pbias_offset); + reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ | OMAP4_MMC1_PWRDNZ | + OMAP4_USBC1_ICUSB_PWRDNZ); + omap_ctrl_writel(reg, control_pbias_offset); +} + +static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot, + int power_on, int vdd) +{ + u32 reg; + + if (power_on) { + reg = omap_ctrl_readl(control_pbias_offset); + reg |= OMAP4_MMC1_PBIASLITE_PWRDNZ; + if ((1 << vdd) <= MMC_VDD_165_195) + reg &= ~OMAP4_MMC1_PBIASLITE_VMODE; + else + reg |= OMAP4_MMC1_PBIASLITE_VMODE; + reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ | OMAP4_MMC1_PWRDNZ | + OMAP4_USBC1_ICUSB_PWRDNZ); + omap_ctrl_writel(reg, control_pbias_offset); + /* 4 microsec delay for comparator to generate an error*/ + udelay(4); + reg = omap_ctrl_readl(control_pbias_offset); + if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR) { + pr_err("Pbias Voltage is not same as LDO\n"); + /* Caution : On VMODE_ERROR Power Down MMC IO */ + reg &= ~(OMAP4_MMC1_PWRDNZ | OMAP4_USBC1_ICUSB_PWRDNZ); + omap_ctrl_writel(reg, control_pbias_offset); + } + } else { + reg = omap_ctrl_readl(control_pbias_offset); + reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ | + OMAP4_MMC1_PBIASLITE_VMODE | OMAP4_MMC1_PWRDNZ | + OMAP4_USBC1_ICUSB_PWRDNZ); + omap_ctrl_writel(reg, control_pbias_offset); + } +} + static void hsmmc23_before_set_reg(struct device *dev, int slot, int power_on, int vdd) { @@ -152,13 +207,28 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) struct omap2_hsmmc_info *c; int nr_hsmmc = ARRAY_SIZE(hsmmc_data); int i; + u32 reg; - if (cpu_is_omap2430()) { - control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; - control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; + if (!cpu_is_omap44xx()) { + if (cpu_is_omap2430()) { + control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; + control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; + } else { + control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; + control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; + } } else { - control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; - control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; + control_pbias_offset = OMAP44XX_CONTROL_PBIAS_LITE; + control_mmc1 = OMAP44XX_CONTROL_MMC1; + reg = omap_ctrl_readl(control_mmc1); + reg |= (OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP0 | + OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP1); + reg &= ~(OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP2 | + OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP3); + reg |= (OMAP4_CONTROL_SDMMC1_DR0_SPEEDCTRL | + OMAP4_CONTROL_SDMMC1_DR1_SPEEDCTRL | + OMAP4_CONTROL_SDMMC1_DR2_SPEEDCTRL); + omap_ctrl_writel(reg, control_mmc1); } for (c = controllers; c->mmc; c++) { @@ -231,8 +301,17 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) case 1: if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { /* on-chip level shifting via PBIAS0/PBIAS1 */ - mmc->slots[0].before_set_reg = hsmmc1_before_set_reg; - mmc->slots[0].after_set_reg = hsmmc1_after_set_reg; + if (cpu_is_omap44xx()) { + mmc->slots[0].before_set_reg = + omap4_hsmmc1_before_set_reg; + mmc->slots[0].after_set_reg = + omap4_hsmmc1_after_set_reg; + } else { + mmc->slots[0].before_set_reg = + omap_hsmmc1_before_set_reg; + mmc->slots[0].after_set_reg = + omap_hsmmc1_after_set_reg; + } } /* Omap3630 HSMMC1 supports only 4-bit */ diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/plat-omap/include/plat/control.h index a56deee97676..131bf405c2f6 100644 --- a/arch/arm/plat-omap/include/plat/control.h +++ b/arch/arm/plat-omap/include/plat/control.h @@ -207,6 +207,9 @@ /* 44xx control status register offset */ #define OMAP44XX_CONTROL_STATUS 0x2c4 +/* 44xx-only CONTROL_GENERAL register offsets */ +#define OMAP44XX_CONTROL_MMC1 0x628 +#define OMAP44XX_CONTROL_PBIAS_LITE 0x600 /* * REVISIT: This list of registers is not comprehensive - there are more * that should be added. @@ -252,6 +255,23 @@ #define OMAP2_PBIASLITEPWRDNZ0 (1 << 1) #define OMAP2_PBIASLITEVMODE0 (1 << 0) +/* CONTROL_PBIAS_LITE bits for OMAP4 */ +#define OMAP4_MMC1_PWRDNZ (1 << 26) +#define OMAP4_MMC1_PBIASLITE_HIZ_MODE (1 << 25) +#define OMAP4_MMC1_PBIASLITE_SUPPLY_HI_OUT (1 << 24) +#define OMAP4_MMC1_PBIASLITE_VMODE_ERROR (1 << 23) +#define OMAP4_MMC1_PBIASLITE_PWRDNZ (1 << 22) +#define OMAP4_MMC1_PBIASLITE_VMODE (1 << 21) +#define OMAP4_USBC1_ICUSB_PWRDNZ (1 << 20) + +#define OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP0 (1 << 31) +#define OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP1 (1 << 30) +#define OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP2 (1 << 29) +#define OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP3 (1 << 28) +#define OMAP4_CONTROL_SDMMC1_DR0_SPEEDCTRL (1 << 27) +#define OMAP4_CONTROL_SDMMC1_DR1_SPEEDCTRL (1 << 26) +#define OMAP4_CONTROL_SDMMC1_DR2_SPEEDCTRL (1 << 25) + /* CONTROL_PROG_IO1 bits */ #define OMAP3630_PRG_SDMMC1_SPEEDCTRL (1 << 20) -- cgit v1.2.3-59-g8ed1b From ebe6d428ed2ddbcbf4b60d2ef0a4a7023685bede Mon Sep 17 00:00:00 2001 From: kishore kadiyala Date: Sat, 15 May 2010 18:21:36 +0000 Subject: omap4: Enable HSMMC support Enables HSMMC support for OMAP4430 defconfig Signed-off-by: Kishore Kadiyala Signed-off-by: Tony Lindgren --- arch/arm/configs/omap_4430sdp_defconfig | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/configs/omap_4430sdp_defconfig b/arch/arm/configs/omap_4430sdp_defconfig index 25e8d048fc1c..1fb04567f6e1 100644 --- a/arch/arm/configs/omap_4430sdp_defconfig +++ b/arch/arm/configs/omap_4430sdp_defconfig @@ -810,7 +810,24 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_SOUND is not set # CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_OMAP is not set +CONFIG_MMC_OMAP_HS=y # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set -- cgit v1.2.3-59-g8ed1b From 9cbc34939c6d520a979cdb624a421204882a8ded Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 17 May 2010 14:39:09 +0800 Subject: omap3: Add support for OMAP3Stalker boards Add support for OMAP3Stalker boards Signed-off-by: Jason Lam Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 6 + arch/arm/mach-omap2/Makefile | 2 + arch/arm/mach-omap2/board-omap3stalker.c | 672 +++++++++++++++++++++++++++++++ 3 files changed, 680 insertions(+) create mode 100644 arch/arm/mach-omap2/board-omap3stalker.c (limited to 'arch') diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 99abac2a8c53..b31b6f123122 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -142,6 +142,12 @@ config MACH_IGEP0020 depends on ARCH_OMAP3 select OMAP_PACKAGE_CBB +config MACH_SBC3530 + bool "OMAP3 SBC STALKER board" + depends on ARCH_OMAP3 + select OMAP_PACKAGE_CUS + select OMAP_MUX + config MACH_OMAP_3630SDP bool "OMAP3630 SDP board" depends on ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index a79945349368..d28e9e5702a0 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -142,6 +142,8 @@ obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \ obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o +obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o \ + hsmmc.o # Platform specific device init code obj-y += usb-musb.o obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c new file mode 100644 index 000000000000..f848ba8dbc16 --- /dev/null +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -0,0 +1,672 @@ +/* + * linux/arch/arm/mach-omap2/board-omap3evm.c + * + * Copyright (C) 2008 Guangzhou EMA-Tech + * + * Modified from mach-omap2/board-omap3evm.c + * + * Initial code: Syed Mohammed Khasim + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "sdram-micron-mt46h32m32lf-6.h" +#include "mux.h" +#include "hsmmc.h" + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +#define OMAP3STALKER_ETHR_START 0x2c000000 +#define OMAP3STALKER_ETHR_SIZE 1024 +#define OMAP3STALKER_ETHR_GPIO_IRQ 19 +#define OMAP3STALKER_SMC911X_CS 5 + +static struct resource omap3stalker_smsc911x_resources[] = { + [0] = { + .start = OMAP3STALKER_ETHR_START, + .end = + (OMAP3STALKER_ETHR_START + OMAP3STALKER_ETHR_SIZE - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(OMAP3STALKER_ETHR_GPIO_IRQ), + .end = OMAP_GPIO_IRQ(OMAP3STALKER_ETHR_GPIO_IRQ), + .flags = (IORESOURCE_IRQ | IRQF_TRIGGER_LOW), + }, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .phy_interface = PHY_INTERFACE_MODE_MII, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS), +}; + +static struct platform_device omap3stalker_smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(omap3stalker_smsc911x_resources), + .resource = &omap3stalker_smsc911x_resources[0], + .dev = { + .platform_data = &smsc911x_config, + }, +}; + +static inline void __init omap3stalker_init_eth(void) +{ + int eth_cs; + struct clk *l3ck; + unsigned int rate; + + eth_cs = OMAP3STALKER_SMC911X_CS; + + l3ck = clk_get(NULL, "l3_ck"); + if (IS_ERR(l3ck)) + rate = 100000000; + else + rate = clk_get_rate(l3ck); + + omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP); + if (gpio_request(OMAP3STALKER_ETHR_GPIO_IRQ, "SMC911x irq") < 0) { + printk(KERN_ERR + "Failed to request GPIO%d for smc911x IRQ\n", + OMAP3STALKER_ETHR_GPIO_IRQ); + return; + } + + gpio_direction_input(OMAP3STALKER_ETHR_GPIO_IRQ); + + platform_device_register(&omap3stalker_smsc911x_device); +} + +#else +static inline void __init omap3stalker_init_eth(void) +{ + return; +} +#endif + +/* + * OMAP3 DSS control signals + */ + +#define DSS_ENABLE_GPIO 199 +#define LCD_PANEL_BKLIGHT_GPIO 210 +#define ENABLE_VPLL2_DEV_GRP 0xE0 + +static int lcd_enabled; +static int dvi_enabled; + +static void __init omap3_stalker_display_init(void) +{ + return; +} + +static int omap3_stalker_enable_lcd(struct omap_dss_device *dssdev) +{ + if (dvi_enabled) { + printk(KERN_ERR "cannot enable LCD, DVI is enabled\n"); + return -EINVAL; + } + gpio_set_value(DSS_ENABLE_GPIO, 1); + gpio_set_value(LCD_PANEL_BKLIGHT_GPIO, 1); + lcd_enabled = 1; + return 0; +} + +static void omap3_stalker_disable_lcd(struct omap_dss_device *dssdev) +{ + gpio_set_value(DSS_ENABLE_GPIO, 0); + gpio_set_value(LCD_PANEL_BKLIGHT_GPIO, 0); + lcd_enabled = 0; +} + +static struct omap_dss_device omap3_stalker_lcd_device = { + .name = "lcd", + .driver_name = "generic_panel", + .phy.dpi.data_lines = 24, + .type = OMAP_DISPLAY_TYPE_DPI, + .platform_enable = omap3_stalker_enable_lcd, + .platform_disable = omap3_stalker_disable_lcd, +}; + +static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev) +{ + return 0; +} + +static void omap3_stalker_disable_tv(struct omap_dss_device *dssdev) +{ +} + +static struct omap_dss_device omap3_stalker_tv_device = { + .name = "tv", + .driver_name = "venc", + .type = OMAP_DISPLAY_TYPE_VENC, +#if defined(CONFIG_OMAP2_VENC_OUT_TYPE_SVIDEO) + .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, +#elif defined(CONFIG_OMAP2_VENC_OUT_TYPE_COMPOSITE) + .u.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE, +#endif + .platform_enable = omap3_stalker_enable_tv, + .platform_disable = omap3_stalker_disable_tv, +}; + +static int omap3_stalker_enable_dvi(struct omap_dss_device *dssdev) +{ + if (lcd_enabled) { + printk(KERN_ERR "cannot enable DVI, LCD is enabled\n"); + return -EINVAL; + } + gpio_set_value(DSS_ENABLE_GPIO, 1); + dvi_enabled = 1; + return 0; +} + +static void omap3_stalker_disable_dvi(struct omap_dss_device *dssdev) +{ + gpio_set_value(DSS_ENABLE_GPIO, 0); + dvi_enabled = 0; +} + +static struct omap_dss_device omap3_stalker_dvi_device = { + .name = "dvi", + .driver_name = "generic_panel", + .type = OMAP_DISPLAY_TYPE_DPI, + .phy.dpi.data_lines = 24, + .platform_enable = omap3_stalker_enable_dvi, + .platform_disable = omap3_stalker_disable_dvi, +}; + +static struct omap_dss_device *omap3_stalker_dss_devices[] = { + &omap3_stalker_lcd_device, + &omap3_stalker_tv_device, + &omap3_stalker_dvi_device, +}; + +static struct omap_dss_board_info omap3_stalker_dss_data = { + .num_devices = ARRAY_SIZE(omap3_stalker_dss_devices), + .devices = omap3_stalker_dss_devices, + .default_device = &omap3_stalker_dvi_device, +}; + +static struct platform_device omap3_stalker_dss_device = { + .name = "omapdss", + .id = -1, + .dev = { + .platform_data = &omap3_stalker_dss_data, + }, +}; + +static struct regulator_consumer_supply omap3stalker_vmmc1_supply = { + .supply = "vmmc", +}; + +static struct regulator_consumer_supply omap3stalker_vsim_supply = { + .supply = "vmmc_aux", +}; + +/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ +static struct regulator_init_data omap3stalker_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &omap3stalker_vmmc1_supply, +}; + +/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ +static struct regulator_init_data omap3stalker_vsim = { + .constraints = { + .min_uV = 1800000, + .max_uV = 3000000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &omap3stalker_vsim_supply, +}; + +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + .wires = 4, + .gpio_cd = -EINVAL, + .gpio_wp = 23, + }, + {} /* Terminator */ +}; + +static struct gpio_keys_button gpio_buttons[] = { + { + .code = BTN_EXTRA, + .gpio = 18, + .desc = "user", + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data gpio_key_info = { + .buttons = gpio_buttons, + .nbuttons = ARRAY_SIZE(gpio_buttons), +}; + +static struct platform_device keys_gpio = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &gpio_key_info, + }, +}; + +static struct gpio_led gpio_leds[] = { + { + .name = "stalker:D8:usr0", + .default_trigger = "default-on", + .gpio = 126, + }, + { + .name = "stalker:D9:usr1", + .default_trigger = "default-on", + .gpio = 127, + }, + { + .name = "stalker:D3:mmc0", + .gpio = -EINVAL, /* gets replaced */ + .active_low = true, + .default_trigger = "mmc0", + }, + { + .name = "stalker:D4:heartbeat", + .gpio = -EINVAL, /* gets replaced */ + .active_low = true, + .default_trigger = "heartbeat", + }, +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct platform_device leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &gpio_led_info, + }, +}; + +static int +omap3stalker_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + omap_mux_init_gpio(23, OMAP_PIN_INPUT); + mmc[0].gpio_cd = gpio + 0; + omap2_hsmmc_init(mmc); + + /* link regulators to MMC adapters */ + omap3stalker_vmmc1_supply.dev = mmc[0].dev; + omap3stalker_vsim_supply.dev = mmc[0].dev; + + /* + * Most GPIOs are for USB OTG. Some are mostly sent to + * the P2 connector; notably LEDA for the LCD backlight. + */ + + /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */ + gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL"); + gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); + + /* gpio + 7 == DVI Enable */ + gpio_request(gpio + 7, "EN_DVI"); + gpio_direction_output(gpio + 7, 0); + + /* TWL4030_GPIO_MAX + 1 == ledB (out, mmc0) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; + /* GPIO + 13 == ledsync (out, heartbeat) */ + gpio_leds[3].gpio = gpio + 13; + + platform_device_register(&leds_gpio); + return 0; +} + +static struct twl4030_gpio_platform_data omap3stalker_gpio_data = { + .gpio_base = OMAP_MAX_GPIO_LINES, + .irq_base = TWL4030_GPIO_IRQ_BASE, + .irq_end = TWL4030_GPIO_IRQ_END, + .use_leds = true, + .setup = omap3stalker_twl_gpio_setup, +}; + +static struct twl4030_usb_data omap3stalker_usb_data = { + .usb_mode = T2_USB_MODE_ULPI, +}; + +static int board_keymap[] = { + KEY(0, 0, KEY_LEFT), + KEY(0, 1, KEY_DOWN), + KEY(0, 2, KEY_ENTER), + KEY(0, 3, KEY_M), + + KEY(1, 0, KEY_RIGHT), + KEY(1, 1, KEY_UP), + KEY(1, 2, KEY_I), + KEY(1, 3, KEY_N), + + KEY(2, 0, KEY_A), + KEY(2, 1, KEY_E), + KEY(2, 2, KEY_J), + KEY(2, 3, KEY_O), + + KEY(3, 0, KEY_B), + KEY(3, 1, KEY_F), + KEY(3, 2, KEY_K), + KEY(3, 3, KEY_P) +}; + +static struct matrix_keymap_data board_map_data = { + .keymap = board_keymap, + .keymap_size = ARRAY_SIZE(board_keymap), +}; + +static struct twl4030_keypad_data omap3stalker_kp_data = { + .keymap_data = &board_map_data, + .rows = 4, + .cols = 4, + .rep = 1, +}; + +static struct twl4030_madc_platform_data omap3stalker_madc_data = { + .irq_line = 1, +}; + +static struct twl4030_codec_audio_data omap3stalker_audio_data = { + .audio_mclk = 26000000, +}; + +static struct twl4030_codec_data omap3stalker_codec_data = { + .audio_mclk = 26000000, + .audio = &omap3stalker_audio_data, +}; + +static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply = { + .supply = "vdda_dac", + .dev = &omap3_stalker_dss_device.dev, +}; + +/* VDAC for DSS driving S-Video */ +static struct regulator_init_data omap3_stalker_vdac = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &omap3_stalker_vdda_dac_supply, +}; + +/* VPLL2 for digital video outputs */ +static struct regulator_consumer_supply omap3_stalker_vpll2_supply = { + .supply = "vdds_dsi", + .dev = &omap3_stalker_lcd_device.dev, +}; + +static struct regulator_init_data omap3_stalker_vpll2 = { + .constraints = { + .name = "VDVI", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &omap3_stalker_vpll2_supply, +}; + +static struct twl4030_platform_data omap3stalker_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, + + /* platform_data for children goes here */ + .keypad = &omap3stalker_kp_data, + .madc = &omap3stalker_madc_data, + .usb = &omap3stalker_usb_data, + .gpio = &omap3stalker_gpio_data, + .codec = &omap3stalker_codec_data, + .vdac = &omap3_stalker_vdac, + .vpll2 = &omap3_stalker_vpll2, +}; + +static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &omap3stalker_twldata, + }, +}; + +static struct at24_platform_data fram_info = { + .byte_len = (64 * 1024) / 8, + .page_size = 8192, + .flags = AT24_FLAG_ADDR16 | AT24_FLAG_IRUGO, +}; + +static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo3[] = { + { + I2C_BOARD_INFO("24c64", 0x50), + .flags = I2C_CLIENT_WAKE, + .platform_data = &fram_info, + }, +}; + +static int __init omap3_stalker_i2c_init(void) +{ + /* + * REVISIT: These entries can be set in omap3evm_twl_data + * after a merge with MFD tree + */ + omap3stalker_twldata.vmmc1 = &omap3stalker_vmmc1; + omap3stalker_twldata.vsim = &omap3stalker_vsim; + + omap_register_i2c_bus(1, 2600, omap3stalker_i2c_boardinfo, + ARRAY_SIZE(omap3stalker_i2c_boardinfo)); + omap_register_i2c_bus(2, 400, NULL, 0); + omap_register_i2c_bus(3, 400, omap3stalker_i2c_boardinfo3, + ARRAY_SIZE(omap3stalker_i2c_boardinfo3)); + return 0; +} + +#define OMAP3_STALKER_TS_GPIO 175 +static void ads7846_dev_init(void) +{ + if (gpio_request(OMAP3_STALKER_TS_GPIO, "ADS7846 pendown") < 0) + printk(KERN_ERR "can't get ads7846 pen down GPIO\n"); + + gpio_direction_input(OMAP3_STALKER_TS_GPIO); + + omap_set_gpio_debounce(OMAP3_STALKER_TS_GPIO, 1); + omap_set_gpio_debounce_time(OMAP3_STALKER_TS_GPIO, 0xa); +} + +static int ads7846_get_pendown_state(void) +{ + return !gpio_get_value(OMAP3_STALKER_TS_GPIO); +} + +static struct ads7846_platform_data ads7846_config = { + .x_max = 0x0fff, + .y_max = 0x0fff, + .x_plate_ohms = 180, + .pressure_max = 255, + .debounce_max = 10, + .debounce_tol = 3, + .debounce_rep = 1, + .get_pendown_state = ads7846_get_pendown_state, + .keep_vref_on = 1, + .settle_delay_usecs = 150, +}; + +static struct omap2_mcspi_device_config ads7846_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +struct spi_board_info omap3stalker_spi_board_info[] = { + [0] = { + .modalias = "ads7846", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, + .irq = OMAP_GPIO_IRQ(OMAP3_STALKER_TS_GPIO), + .platform_data = &ads7846_config, + }, +}; + +static struct omap_board_config_kernel omap3_stalker_config[] __initdata = { +}; + +static void __init omap3_stalker_init_irq(void) +{ + omap_board_config = omap3_stalker_config; + omap_board_config_size = ARRAY_SIZE(omap3_stalker_config); + omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL); + omap_init_irq(); +#ifdef CONFIG_OMAP_32K_TIMER + omap2_gp_clockevent_set_gptimer(12); +#endif + omap_gpio_init(); +} + +static struct platform_device *omap3_stalker_devices[] __initdata = { + &omap3_stalker_dss_device, + &keys_gpio, +}; + +static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { + .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, + .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, + + .phy_reset = true, + .reset_gpio_port[0] = -EINVAL, + .reset_gpio_port[1] = 21, + .reset_gpio_port[2] = -EINVAL, +}; + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | + OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE), + OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | + OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE), + {.reg_offset = OMAP_MUX_TERMINATOR}, +}; +#else +#define board_mux NULL +#endif + +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + +static void __init omap3_stalker_init(void) +{ + omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); + + omap3_stalker_i2c_init(); + + platform_add_devices(omap3_stalker_devices, + ARRAY_SIZE(omap3_stalker_devices)); + + spi_register_board_info(omap3stalker_spi_board_info, + ARRAY_SIZE(omap3stalker_spi_board_info)); + + omap_serial_init(); + usb_musb_init(&musb_board_data); + usb_ehci_init(&ehci_pdata); + ads7846_dev_init(); + + omap_mux_init_gpio(21, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(18, OMAP_PIN_INPUT_PULLUP); + + omap3stalker_init_eth(); + omap3_stalker_display_init(); +/* Ensure SDRC pins are mux'd for self-refresh */ + omap_mux_init_signal("sdr_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT); +} + +static void __init omap3_stalker_map_io(void) +{ + omap2_set_globals_343x(); + omap34xx_map_common_io(); +} + +MACHINE_START(SBC3530, "OMAP3 STALKER") + /* Maintainer: Jason Lam -lzg@ema-tech.com */ + .phys_io = 0x48000000, + .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = omap3_stalker_map_io, + .init_irq = omap3_stalker_init_irq, + .init_machine = omap3_stalker_init, + .timer = &omap_timer, +MACHINE_END -- cgit v1.2.3-59-g8ed1b From b20f01031772e90ba5ee95966f7cfe58760fbc95 Mon Sep 17 00:00:00 2001 From: Jason Lam Date: Wed, 3 Mar 2010 05:48:51 +0000 Subject: omap3: Add OMAP3 Stalker board LK-S defconfig Add OMAP3 Stalker board LK-S defconfig. Signed-off-by: Jason Lam Signed-off-by: Tony Lindgren --- arch/arm/configs/omap3_stalker_lks_defconfig | 1691 ++++++++++++++++++++++++++ 1 file changed, 1691 insertions(+) create mode 100644 arch/arm/configs/omap3_stalker_lks_defconfig (limited to 'arch') diff --git a/arch/arm/configs/omap3_stalker_lks_defconfig b/arch/arm/configs/omap3_stalker_lks_defconfig new file mode 100644 index 000000000000..83365f075cea --- /dev/null +++ b/arch/arm/configs/omap3_stalker_lks_defconfig @@ -0,0 +1,1691 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.34-rc7 +# Mon May 17 16:57:28 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPUFREQ=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +CONFIG_ARCH_OMAP=y + +# +# TI OMAP Implementations +# +CONFIG_ARCH_OMAP_OTG=y +# CONFIG_ARCH_OMAP1 is not set +CONFIG_ARCH_OMAP2PLUS=y +# CONFIG_ARCH_OMAP2 is not set +CONFIG_ARCH_OMAP3=y +# CONFIG_ARCH_OMAP4 is not set + +# +# OMAP Feature Selections +# +CONFIG_OMAP_RESET_CLOCKS=y +CONFIG_OMAP_MUX=y +# CONFIG_OMAP_MUX_DEBUG is not set +CONFIG_OMAP_MUX_WARNINGS=y +# CONFIG_OMAP_MCBSP is not set +# CONFIG_OMAP_MBOX_FWK is not set +# CONFIG_OMAP_MPU_TIMER is not set +CONFIG_OMAP_32K_TIMER=y +# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set +CONFIG_OMAP_32K_TIMER_HZ=128 +CONFIG_OMAP_DM_TIMER=y +# CONFIG_OMAP_PM_NONE is not set +CONFIG_OMAP_PM_NOOP=y +CONFIG_ARCH_OMAP3430=y +CONFIG_OMAP_PACKAGE_CUS=y + +# +# OMAP Board Type +# +# CONFIG_MACH_OMAP3_BEAGLE is not set +# CONFIG_MACH_DEVKIT8000 is not set +# CONFIG_MACH_OMAP_LDP is not set +# CONFIG_MACH_OVERO is not set +# CONFIG_MACH_OMAP3EVM is not set +# CONFIG_MACH_OMAP3517EVM is not set +# CONFIG_MACH_OMAP3_PANDORA is not set +# CONFIG_MACH_OMAP3_TOUCHBOOK is not set +# CONFIG_MACH_OMAP_3430SDP is not set +# CONFIG_MACH_NOKIA_RX51 is not set +# CONFIG_MACH_OMAP_ZOOM2 is not set +# CONFIG_MACH_OMAP_ZOOM3 is not set +# CONFIG_MACH_CM_T35 is not set +# CONFIG_MACH_IGEP0020 is not set +CONFIG_MACH_SBC3530=y +# CONFIG_MACH_OMAP_3630SDP is not set +# CONFIG_OMAP3_EMU is not set +# CONFIG_OMAP3_SDRC_AC_TIMING is not set + +# +# Processor Type +# +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_CPU_HAS_PMU=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=128 +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_ADVANCED_DEBUG is not set +# CONFIG_PM_VERBOSE is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +# CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +# CONFIG_MTD_NAND_OMAP2 is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_ONENAND=y +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +# CONFIG_MTD_ONENAND_GENERIC is not set +CONFIG_MTD_ONENAND_OMAP2=y +# CONFIG_MTD_ONENAND_OTP is not set +# CONFIG_MTD_ONENAND_2X_PROGRAM is not set +# CONFIG_MTD_ONENAND_SIM is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_TI_DAVINCI_EMAC is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +CONFIG_SMSC911X=y +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +CONFIG_KEYBOARD_TWL4030=y +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=y +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_OMAP=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_OMAP24XX=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +CONFIG_GPIO_TWL4030=y +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_OMAP_WATCHDOG=y +# CONFIG_TWL4030_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +CONFIG_TWL4030_CORE=y +# CONFIG_TWL4030_POWER is not set +# CONFIG_TWL4030_CODEC is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +CONFIG_REGULATOR_TWL4030=y +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +# CONFIG_FB is not set +# CONFIG_OMAP2_DSS is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +# CONFIG_HID_3M_PCT is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MOSART is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_STANTUM is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SOC=y + +# +# OMAP 343x high speed USB support +# +# CONFIG_USB_MUSB_HOST is not set +# CONFIG_USB_MUSB_PERIPHERAL is not set +CONFIG_USB_MUSB_OTG=y +CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_USB_MUSB_HDRC_HCD=y +# CONFIG_MUSB_PIO_ONLY is not set +CONFIG_USB_INVENTRA_DMA=y +# CONFIG_USB_TI_CPPI_DMA is not set +# CONFIG_USB_MUSB_DEBUG is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +CONFIG_USB_TEST=y +# CONFIG_USB_ISIGHTFW is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +# CONFIG_USB_ZERO_HNPTEST is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_ISP1301_OMAP is not set +# CONFIG_USB_ULPI is not set +CONFIG_TWL4030_USB=y +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_OMAP is not set +CONFIG_MMC_OMAP_HS=y +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QUOTA_DEBUG is not set +CONFIG_QUOTA_TREE=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +# CONFIG_EARLY_PRINTK is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- cgit v1.2.3-59-g8ed1b From 1f6e57ba77b91c826453a435b6ac87d2f889ebc6 Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Thu, 13 May 2010 05:32:27 +0000 Subject: omap3: update omap3_defconfig - Update the omap3_defconfig to sync up with the generated .config - Increase CONFIG_LOG_BUF_SHIFT to 16 to allow the entire boot log to be captured (useful when using boot time tracer, for example) Signed-off-by: Anand Gadiyar Signed-off-by: Tony Lindgren --- arch/arm/configs/omap3_defconfig | 116 ++++++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 37 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap3_defconfig index 1efb833147c2..0eb1bc9d04c5 100644 --- a/arch/arm/configs/omap3_defconfig +++ b/arch/arm/configs/omap3_defconfig @@ -1,13 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc5 -# Tue Jan 26 11:05:31 2010 +# Linux kernel version: 2.6.34-rc7 +# Thu May 13 10:54:43 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y @@ -19,7 +20,9 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_ARCH_HAS_CPUFREQ=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_ARM_L1_CACHE_SHIFT_6=y CONFIG_OPROFILE_ARMV6=y CONFIG_OPROFILE_ARM11_CORE=y CONFIG_OPROFILE_ARMV7=y @@ -63,12 +66,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set +CONFIG_LOG_BUF_SHIFT=16 # CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -100,17 +98,21 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # +CONFIG_PERF_EVENTS=y +# CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y @@ -189,6 +191,7 @@ CONFIG_MMU=y # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set # CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set @@ -198,7 +201,6 @@ CONFIG_MMU=y # CONFIG_ARCH_STMP3XXX is not set # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set # CONFIG_ARCH_IOP33X is not set @@ -215,21 +217,26 @@ CONFIG_MMU=y # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set # CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set # CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_DAVINCI is not set CONFIG_ARCH_OMAP=y -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_U8500 is not set # # TI OMAP Implementations @@ -254,6 +261,7 @@ CONFIG_OMAP_MCBSP=y # CONFIG_OMAP_MBOX_FWK is not set # CONFIG_OMAP_MPU_TIMER is not set CONFIG_OMAP_32K_TIMER=y +# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set CONFIG_OMAP_32K_TIMER_HZ=128 CONFIG_OMAP_DM_TIMER=y # CONFIG_OMAP_PM_NONE is not set @@ -331,11 +339,16 @@ CONFIG_ARM_THUMBEE=y # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_HAS_TLS_REG=y +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_CACHE_L2X0=y CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_CPU_HAS_PMU=y # CONFIG_ARM_ERRATA_411920 is not set # CONFIG_ARM_ERRATA_430973 is not set # CONFIG_ARM_ERRATA_458693 is not set # CONFIG_ARM_ERRATA_460075 is not set +# CONFIG_PL310_ERRATA_588369 is not set CONFIG_ARM_GIC=y CONFIG_COMMON_CLKDEV=y @@ -369,6 +382,7 @@ CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set # CONFIG_HIGHMEM is not set +CONFIG_HW_PERF_EVENTS=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -444,6 +458,7 @@ CONFIG_BINFMT_MISC=y # CONFIG_PM=y CONFIG_PM_DEBUG=y +# CONFIG_PM_ADVANCED_DEBUG is not set # CONFIG_PM_VERBOSE is not set CONFIG_CAN_PM_TRACE=y CONFIG_PM_SLEEP=y @@ -452,6 +467,7 @@ CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y @@ -459,7 +475,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y @@ -545,7 +560,6 @@ CONFIG_NETFILTER_ADVANCED=y # # CONFIG_NET_PKTGEN is not set # CONFIG_NET_TCPPROBE is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -585,7 +599,7 @@ CONFIG_CFG80211=y # CONFIG_CFG80211_REG_DEBUG is not set CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set -CONFIG_WIRELESS_OLD_REGULATORY=y +# CONFIG_CFG80211_INTERNAL_REGDB is not set CONFIG_CFG80211_WEXT=y CONFIG_WIRELESS_EXT_SYSFS=y CONFIG_LIB80211=y @@ -677,7 +691,6 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_ARM_INTEGRATOR is not set -CONFIG_MTD_OMAP_NOR=y # CONFIG_MTD_PLATRAM is not set # @@ -755,6 +768,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_DS1682 is not set # CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set @@ -774,6 +788,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -840,12 +855,14 @@ CONFIG_SMSC_PHY=y # CONFIG_NATIONAL_PHY is not set # CONFIG_STE10XP is not set # CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_AX88796 is not set CONFIG_SMC91X=y +# CONFIG_TI_DAVINCI_EMAC is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set # CONFIG_ETHOC is not set @@ -882,6 +899,7 @@ CONFIG_LIBERTAS_USB=y CONFIG_LIBERTAS_SDIO=y # CONFIG_LIBERTAS_SPI is not set CONFIG_LIBERTAS_DEBUG=y +# CONFIG_LIBERTAS_MESH is not set # CONFIG_P54_COMMON is not set # CONFIG_RT2X00 is not set # CONFIG_WL12XX is not set @@ -903,6 +921,7 @@ CONFIG_USB_NET_AX8817X=y CONFIG_USB_NET_CDCETHER=y # CONFIG_USB_NET_CDC_EEM is not set # CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set # CONFIG_USB_NET_SMSC95XX is not set # CONFIG_USB_NET_GL620A is not set CONFIG_USB_NET_NET1080=y @@ -918,6 +937,8 @@ CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y CONFIG_USB_NET_ZAURUS=y # CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -1013,6 +1034,7 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set CONFIG_INPUT_TWL4030_PWRBUTTON=y +# CONFIG_INPUT_TWL4030_VIBRA is not set # CONFIG_INPUT_UINPUT is not set # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set @@ -1056,6 +1078,7 @@ CONFIG_SERIAL_8250_RSA=y # CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -1084,6 +1107,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_OMAP=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -1097,15 +1121,9 @@ CONFIG_I2C_OMAP=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -1137,10 +1155,12 @@ CONFIG_GPIO_SYSFS=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set @@ -1205,10 +1225,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set @@ -1271,6 +1292,7 @@ CONFIG_WATCHDOG=y # CONFIG_SOFT_WATCHDOG is not set CONFIG_OMAP_WATCHDOG=y CONFIG_TWL4030_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set # # USB-based Watchdog Cards @@ -1287,10 +1309,12 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # CONFIG_MFD_CORE=y +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_ASIC3 is not set # CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set CONFIG_MENELAUS=y CONFIG_TWL4030_CORE=y @@ -1302,22 +1326,25 @@ CONFIG_TWL4030_CODEC=y # CONFIG_MFD_TC6393XB is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_AB4500_CORE is not set CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set # CONFIG_REGULATOR_FIXED_VOLTAGE is not set # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set # CONFIG_REGULATOR_BQ24022 is not set # CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set # CONFIG_REGULATOR_MAX8660 is not set CONFIG_REGULATOR_TWL4030=y # CONFIG_REGULATOR_LP3971 is not set @@ -1334,9 +1361,9 @@ CONFIG_FB=y CONFIG_FIRMWARE_EDID=y # CONFIG_FB_DDC is not set # CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set @@ -1364,6 +1391,7 @@ CONFIG_FB_OMAP_LCD_VGA=y # CONFIG_OMAP2_DSS is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y +# CONFIG_LCD_L4F00242T03 is not set # CONFIG_LCD_LMS283GF05 is not set # CONFIG_LCD_LTV350QV is not set # CONFIG_LCD_ILI9320 is not set @@ -1441,6 +1469,7 @@ CONFIG_SND_ARM=y CONFIG_SND_SPI=y CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=y +# CONFIG_SND_USB_UA101 is not set # CONFIG_SND_USB_CAIAQ is not set CONFIG_SND_SOC=y CONFIG_SND_OMAP_SOC=y @@ -1472,6 +1501,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set # CONFIG_HID_A4TECH is not set # CONFIG_HID_APPLE is not set # CONFIG_HID_BELKIN is not set @@ -1485,13 +1515,18 @@ CONFIG_USB_HID=y # CONFIG_HID_TWINHAN is not set # CONFIG_HID_KENSINGTON is not set # CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MAGICMOUSE is not set # CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MOSART is not set # CONFIG_HID_MONTEREY is not set # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set # CONFIG_HID_PANTHERLORD is not set # CONFIG_HID_PETALYNX is not set +# CONFIG_HID_QUANTA is not set # CONFIG_HID_SAMSUNG is not set # CONFIG_HID_SONY is not set +# CONFIG_HID_STANTUM is not set # CONFIG_HID_SUNPLUS is not set # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1537,6 +1572,10 @@ CONFIG_USB_MON=y CONFIG_USB_MUSB_HDRC=y CONFIG_USB_MUSB_SOC=y +# +# OMAP 243x high speed USB support +# + # # OMAP 343x high speed USB support # @@ -1601,7 +1640,6 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1614,7 +1652,6 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_IOWARRIOR is not set CONFIG_USB_TEST=y # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DEBUG=y CONFIG_USB_GADGET_DEBUG_FILES=y @@ -1652,6 +1689,7 @@ CONFIG_USB_ZERO=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set # CONFIG_USB_G_MULTI is not set # @@ -1681,8 +1719,6 @@ CONFIG_SDIO_UART=y # CONFIG_MMC_SDHCI is not set CONFIG_MMC_OMAP=y CONFIG_MMC_OMAP_HS=y -# CONFIG_MMC_AT91 is not set -# CONFIG_MMC_ATMELMCI is not set # CONFIG_MMC_SPI is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -1700,11 +1736,11 @@ CONFIG_LEDS_GPIO_PLATFORM=y # CONFIG_LEDS_REGULATOR is not set # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y # # LED Triggers # -CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set @@ -1792,6 +1828,11 @@ CONFIG_RTC_DRV_TWL4030=y # # CONFIG_STAGING is not set +# +# CBUS support +# +# CONFIG_CBUS is not set + # # File systems # @@ -1820,6 +1861,7 @@ CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y # CONFIG_QUOTA_NETLINK_INTERFACE is not set CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QUOTA_DEBUG is not set CONFIG_QUOTA_TREE=y # CONFIG_QFMT_V1 is not set CONFIG_QFMT_V2=y @@ -1891,6 +1933,7 @@ CONFIG_UBIFS_FS=y CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y # CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1918,6 +1961,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -2018,6 +2062,7 @@ CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_PROVE_LOCKING=y +# CONFIG_PROVE_RCU is not set CONFIG_LOCKDEP=y CONFIG_LOCK_STAT=y # CONFIG_DEBUG_LOCKDEP is not set @@ -2047,13 +2092,9 @@ CONFIG_DEBUG_INFO=y # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y # CONFIG_FUNCTION_TRACER is not set @@ -2193,7 +2234,7 @@ CONFIG_CRYPTO_LZO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y -CONFIG_BINARY_PRINTF=y +# CONFIG_BINARY_PRINTF is not set # # Library routines @@ -2216,3 +2257,4 @@ CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y -- cgit v1.2.3-59-g8ed1b From c8f626fe1c7e6de983b0c3b6375da69ded3313b6 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 17 May 2010 17:05:29 -0700 Subject: omap3: Add stalker board to omap3_defconfig Add stalker board to omap3_defconfig Signed-off-by: Tony Lindgren --- arch/arm/configs/omap3_defconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap3_defconfig index 0eb1bc9d04c5..94dfcf0aa674 100644 --- a/arch/arm/configs/omap3_defconfig +++ b/arch/arm/configs/omap3_defconfig @@ -303,6 +303,7 @@ CONFIG_MACH_OMAP_ZOOM2=y CONFIG_MACH_OMAP_ZOOM3=y CONFIG_MACH_CM_T35=y CONFIG_MACH_IGEP0020=y +CONFIG_MACH_SBC3530=y CONFIG_MACH_OMAP_3630SDP=y CONFIG_MACH_OMAP_4430SDP=y # CONFIG_OMAP3_EMU is not set -- cgit v1.2.3-59-g8ed1b From 5838bb674907a57525936bfd5652eb998c433315 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 20 May 2010 12:31:04 -0600 Subject: OMAP1 clock: fix section mismatch on clk_init remove the section annotation from omap1_clk_disable_unused() to kill the section mismatch warning. Signed-off-by: Felipe Balbi Signed-off-by: Paul Walmsley --- arch/arm/mach-omap1/clock.c | 2 +- arch/arm/mach-omap1/clock.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index e0aec1007a0d..6bbb1b8b8294 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -578,7 +578,7 @@ int omap1_clk_set_rate(struct clk *clk, unsigned long rate) #ifdef CONFIG_OMAP_RESET_CLOCKS -void __init omap1_clk_disable_unused(struct clk *clk) +void omap1_clk_disable_unused(struct clk *clk) { __u32 regval32; diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index a4190afb8614..75d0d7d90bff 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h @@ -39,7 +39,7 @@ extern long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate); extern unsigned long omap1_watchdog_recalc(struct clk *clk); #ifdef CONFIG_OMAP_RESET_CLOCKS -extern void __init omap1_clk_disable_unused(struct clk *clk); +extern void omap1_clk_disable_unused(struct clk *clk); #else #define omap1_clk_disable_unused NULL #endif -- cgit v1.2.3-59-g8ed1b From f38ca10a79a0cd9902b8a470901951354802faa1 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 20 May 2010 12:31:04 -0600 Subject: OMAP2 PRCM: convert OMAP2 PRCM macros to the _SHIFT/_MASK suffixes Fix all of the remaining OMAP2 PRCM register shift/bitmask macros that did not use the _SHIFT/_MASK suffixes to use them. This makes the use of these macros consistent. It is intended to reduce error, as code can be inspected visually by reviewers to ensure that bitshifts and bitmasks are used in the appropriate places. Signed-off-by: Paul Walmsley Cc: Kevin Hilman --- arch/arm/mach-omap2/clkt2xxx_apll.c | 4 +- arch/arm/mach-omap2/clock2420_data.c | 4 +- arch/arm/mach-omap2/clock2430_data.c | 6 +- arch/arm/mach-omap2/clockdomain.c | 4 +- arch/arm/mach-omap2/cm-regbits-24xx.h | 236 ++++++++++++++++----------------- arch/arm/mach-omap2/pm24xx.c | 107 +++++++-------- arch/arm/mach-omap2/prm-regbits-24xx.h | 120 ++++++++--------- 7 files changed, 241 insertions(+), 240 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c index 43d7246ce335..66e01acfd585 100644 --- a/arch/arm/mach-omap2/clkt2xxx_apll.c +++ b/arch/arm/mach-omap2/clkt2xxx_apll.c @@ -70,12 +70,12 @@ static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask) static int omap2_clk_apll96_enable(struct clk *clk) { - return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL); + return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL_MASK); } static int omap2_clk_apll54_enable(struct clk *clk) { - return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL); + return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL_MASK); } /* Stop APLL */ diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index d932b142d0b6..1381e767ce31 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -177,7 +177,7 @@ static struct clk func_54m_ck = { .clkdm_name = "wkup_clkdm", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_54M_SOURCE, + .clksel_mask = OMAP24XX_54M_SOURCE_MASK, .clksel = func_54m_clksel, .recalc = &omap2_clksel_recalc, }; @@ -223,7 +223,7 @@ static struct clk func_48m_ck = { .clkdm_name = "wkup_clkdm", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_48M_SOURCE, + .clksel_mask = OMAP24XX_48M_SOURCE_MASK, .clksel = func_48m_clksel, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index 0438b6e4f51a..1aac22709dfe 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -177,7 +177,7 @@ static struct clk func_54m_ck = { .clkdm_name = "wkup_clkdm", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_54M_SOURCE, + .clksel_mask = OMAP24XX_54M_SOURCE_MASK, .clksel = func_54m_clksel, .recalc = &omap2_clksel_recalc, }; @@ -214,7 +214,7 @@ static struct clk func_96m_ck = { .clkdm_name = "wkup_clkdm", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP2430_96M_SOURCE, + .clksel_mask = OMAP2430_96M_SOURCE_MASK, .clksel = func_96m_clksel, .recalc = &omap2_clksel_recalc, }; @@ -244,7 +244,7 @@ static struct clk func_48m_ck = { .clkdm_name = "wkup_clkdm", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_48M_SOURCE, + .clksel_mask = OMAP24XX_48M_SOURCE_MASK, .clksel = func_48m_clksel, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 6e568ec995ee..5d80cb897489 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -809,7 +809,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm) if (cpu_is_omap24xx()) { - cm_set_mod_reg_bits(OMAP24XX_FORCESTATE, + cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL); } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { @@ -853,7 +853,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm) if (cpu_is_omap24xx()) { - cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE, + cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL); } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { diff --git a/arch/arm/mach-omap2/cm-regbits-24xx.h b/arch/arm/mach-omap2/cm-regbits-24xx.h index 297a2fe634ea..da51cc3ed7eb 100644 --- a/arch/arm/mach-omap2/cm-regbits-24xx.h +++ b/arch/arm/mach-omap2/cm-regbits-24xx.h @@ -20,43 +20,43 @@ /* CM_FCLKEN1_CORE and CM_ICLKEN1_CORE shared bits */ #define OMAP24XX_EN_CAM_SHIFT 31 -#define OMAP24XX_EN_CAM (1 << 31) +#define OMAP24XX_EN_CAM_MASK (1 << 31) #define OMAP24XX_EN_WDT4_SHIFT 29 -#define OMAP24XX_EN_WDT4 (1 << 29) +#define OMAP24XX_EN_WDT4_MASK (1 << 29) #define OMAP2420_EN_WDT3_SHIFT 28 -#define OMAP2420_EN_WDT3 (1 << 28) +#define OMAP2420_EN_WDT3_MASK (1 << 28) #define OMAP24XX_EN_MSPRO_SHIFT 27 -#define OMAP24XX_EN_MSPRO (1 << 27) +#define OMAP24XX_EN_MSPRO_MASK (1 << 27) #define OMAP24XX_EN_FAC_SHIFT 25 -#define OMAP24XX_EN_FAC (1 << 25) +#define OMAP24XX_EN_FAC_MASK (1 << 25) #define OMAP2420_EN_EAC_SHIFT 24 -#define OMAP2420_EN_EAC (1 << 24) +#define OMAP2420_EN_EAC_MASK (1 << 24) #define OMAP24XX_EN_HDQ_SHIFT 23 -#define OMAP24XX_EN_HDQ (1 << 23) +#define OMAP24XX_EN_HDQ_MASK (1 << 23) #define OMAP2420_EN_I2C2_SHIFT 20 -#define OMAP2420_EN_I2C2 (1 << 20) +#define OMAP2420_EN_I2C2_MASK (1 << 20) #define OMAP2420_EN_I2C1_SHIFT 19 -#define OMAP2420_EN_I2C1 (1 << 19) +#define OMAP2420_EN_I2C1_MASK (1 << 19) /* CM_FCLKEN2_CORE and CM_ICLKEN2_CORE shared bits */ #define OMAP2430_EN_MCBSP5_SHIFT 5 -#define OMAP2430_EN_MCBSP5 (1 << 5) +#define OMAP2430_EN_MCBSP5_MASK (1 << 5) #define OMAP2430_EN_MCBSP4_SHIFT 4 -#define OMAP2430_EN_MCBSP4 (1 << 4) +#define OMAP2430_EN_MCBSP4_MASK (1 << 4) #define OMAP2430_EN_MCBSP3_SHIFT 3 -#define OMAP2430_EN_MCBSP3 (1 << 3) +#define OMAP2430_EN_MCBSP3_MASK (1 << 3) #define OMAP24XX_EN_SSI_SHIFT 1 -#define OMAP24XX_EN_SSI (1 << 1) +#define OMAP24XX_EN_SSI_MASK (1 << 1) /* CM_FCLKEN_WKUP and CM_ICLKEN_WKUP shared bits */ #define OMAP24XX_EN_MPU_WDT_SHIFT 3 -#define OMAP24XX_EN_MPU_WDT (1 << 3) +#define OMAP24XX_EN_MPU_WDT_MASK (1 << 3) /* Bits specific to each register */ /* CM_IDLEST_MPU */ /* 2430 only */ -#define OMAP2430_ST_MPU (1 << 0) +#define OMAP2430_ST_MPU_MASK (1 << 0) /* CM_CLKSEL_MPU */ #define OMAP24XX_CLKSEL_MPU_SHIFT 0 @@ -68,46 +68,46 @@ /* CM_FCLKEN1_CORE specific bits*/ #define OMAP24XX_EN_TV_SHIFT 2 -#define OMAP24XX_EN_TV (1 << 2) +#define OMAP24XX_EN_TV_MASK (1 << 2) #define OMAP24XX_EN_DSS2_SHIFT 1 -#define OMAP24XX_EN_DSS2 (1 << 1) +#define OMAP24XX_EN_DSS2_MASK (1 << 1) #define OMAP24XX_EN_DSS1_SHIFT 0 -#define OMAP24XX_EN_DSS1 (1 << 0) +#define OMAP24XX_EN_DSS1_MASK (1 << 0) /* CM_FCLKEN2_CORE specific bits */ #define OMAP2430_EN_I2CHS2_SHIFT 20 -#define OMAP2430_EN_I2CHS2 (1 << 20) +#define OMAP2430_EN_I2CHS2_MASK (1 << 20) #define OMAP2430_EN_I2CHS1_SHIFT 19 -#define OMAP2430_EN_I2CHS1 (1 << 19) +#define OMAP2430_EN_I2CHS1_MASK (1 << 19) #define OMAP2430_EN_MMCHSDB2_SHIFT 17 -#define OMAP2430_EN_MMCHSDB2 (1 << 17) +#define OMAP2430_EN_MMCHSDB2_MASK (1 << 17) #define OMAP2430_EN_MMCHSDB1_SHIFT 16 -#define OMAP2430_EN_MMCHSDB1 (1 << 16) +#define OMAP2430_EN_MMCHSDB1_MASK (1 << 16) /* CM_ICLKEN1_CORE specific bits */ #define OMAP24XX_EN_MAILBOXES_SHIFT 30 -#define OMAP24XX_EN_MAILBOXES (1 << 30) +#define OMAP24XX_EN_MAILBOXES_MASK (1 << 30) #define OMAP24XX_EN_DSS_SHIFT 0 -#define OMAP24XX_EN_DSS (1 << 0) +#define OMAP24XX_EN_DSS_MASK (1 << 0) /* CM_ICLKEN2_CORE specific bits */ /* CM_ICLKEN3_CORE */ /* 2430 only */ #define OMAP2430_EN_SDRC_SHIFT 2 -#define OMAP2430_EN_SDRC (1 << 2) +#define OMAP2430_EN_SDRC_MASK (1 << 2) /* CM_ICLKEN4_CORE */ #define OMAP24XX_EN_PKA_SHIFT 4 -#define OMAP24XX_EN_PKA (1 << 4) +#define OMAP24XX_EN_PKA_MASK (1 << 4) #define OMAP24XX_EN_AES_SHIFT 3 -#define OMAP24XX_EN_AES (1 << 3) +#define OMAP24XX_EN_AES_MASK (1 << 3) #define OMAP24XX_EN_RNG_SHIFT 2 -#define OMAP24XX_EN_RNG (1 << 2) +#define OMAP24XX_EN_RNG_MASK (1 << 2) #define OMAP24XX_EN_SHA_SHIFT 1 -#define OMAP24XX_EN_SHA (1 << 1) +#define OMAP24XX_EN_SHA_MASK (1 << 1) #define OMAP24XX_EN_DES_SHIFT 0 -#define OMAP24XX_EN_DES (1 << 0) +#define OMAP24XX_EN_DES_MASK (1 << 0) /* CM_IDLEST1_CORE specific bits */ #define OMAP24XX_ST_MAILBOXES_SHIFT 30 @@ -138,9 +138,9 @@ /* CM_IDLEST2_CORE */ #define OMAP2430_ST_MCBSP5_SHIFT 5 #define OMAP2430_ST_MCBSP5_MASK (1 << 5) -#define OMAP2430_ST_MCBSP4_SHIFT 4 +#define OMAP2430_ST_MCBSP4_SHIFT 4 #define OMAP2430_ST_MCBSP4_MASK (1 << 4) -#define OMAP2430_ST_MCBSP3_SHIFT 3 +#define OMAP2430_ST_MCBSP3_SHIFT 3 #define OMAP2430_ST_MCBSP3_MASK (1 << 3) #define OMAP24XX_ST_SSI_SHIFT 1 #define OMAP24XX_ST_SSI_MASK (1 << 1) @@ -162,62 +162,62 @@ #define OMAP24XX_ST_DES_MASK (1 << 0) /* CM_AUTOIDLE1_CORE */ -#define OMAP24XX_AUTO_CAM (1 << 31) -#define OMAP24XX_AUTO_MAILBOXES (1 << 30) -#define OMAP24XX_AUTO_WDT4 (1 << 29) -#define OMAP2420_AUTO_WDT3 (1 << 28) -#define OMAP24XX_AUTO_MSPRO (1 << 27) -#define OMAP2420_AUTO_MMC (1 << 26) -#define OMAP24XX_AUTO_FAC (1 << 25) -#define OMAP2420_AUTO_EAC (1 << 24) -#define OMAP24XX_AUTO_HDQ (1 << 23) -#define OMAP24XX_AUTO_UART2 (1 << 22) -#define OMAP24XX_AUTO_UART1 (1 << 21) -#define OMAP24XX_AUTO_I2C2 (1 << 20) -#define OMAP24XX_AUTO_I2C1 (1 << 19) -#define OMAP24XX_AUTO_MCSPI2 (1 << 18) -#define OMAP24XX_AUTO_MCSPI1 (1 << 17) -#define OMAP24XX_AUTO_MCBSP2 (1 << 16) -#define OMAP24XX_AUTO_MCBSP1 (1 << 15) -#define OMAP24XX_AUTO_GPT12 (1 << 14) -#define OMAP24XX_AUTO_GPT11 (1 << 13) -#define OMAP24XX_AUTO_GPT10 (1 << 12) -#define OMAP24XX_AUTO_GPT9 (1 << 11) -#define OMAP24XX_AUTO_GPT8 (1 << 10) -#define OMAP24XX_AUTO_GPT7 (1 << 9) -#define OMAP24XX_AUTO_GPT6 (1 << 8) -#define OMAP24XX_AUTO_GPT5 (1 << 7) -#define OMAP24XX_AUTO_GPT4 (1 << 6) -#define OMAP24XX_AUTO_GPT3 (1 << 5) -#define OMAP24XX_AUTO_GPT2 (1 << 4) -#define OMAP2420_AUTO_VLYNQ (1 << 3) -#define OMAP24XX_AUTO_DSS (1 << 0) +#define OMAP24XX_AUTO_CAM_MASK (1 << 31) +#define OMAP24XX_AUTO_MAILBOXES_MASK (1 << 30) +#define OMAP24XX_AUTO_WDT4_MASK (1 << 29) +#define OMAP2420_AUTO_WDT3_MASK (1 << 28) +#define OMAP24XX_AUTO_MSPRO_MASK (1 << 27) +#define OMAP2420_AUTO_MMC_MASK (1 << 26) +#define OMAP24XX_AUTO_FAC_MASK (1 << 25) +#define OMAP2420_AUTO_EAC_MASK (1 << 24) +#define OMAP24XX_AUTO_HDQ_MASK (1 << 23) +#define OMAP24XX_AUTO_UART2_MASK (1 << 22) +#define OMAP24XX_AUTO_UART1_MASK (1 << 21) +#define OMAP24XX_AUTO_I2C2_MASK (1 << 20) +#define OMAP24XX_AUTO_I2C1_MASK (1 << 19) +#define OMAP24XX_AUTO_MCSPI2_MASK (1 << 18) +#define OMAP24XX_AUTO_MCSPI1_MASK (1 << 17) +#define OMAP24XX_AUTO_MCBSP2_MASK (1 << 16) +#define OMAP24XX_AUTO_MCBSP1_MASK (1 << 15) +#define OMAP24XX_AUTO_GPT12_MASK (1 << 14) +#define OMAP24XX_AUTO_GPT11_MASK (1 << 13) +#define OMAP24XX_AUTO_GPT10_MASK (1 << 12) +#define OMAP24XX_AUTO_GPT9_MASK (1 << 11) +#define OMAP24XX_AUTO_GPT8_MASK (1 << 10) +#define OMAP24XX_AUTO_GPT7_MASK (1 << 9) +#define OMAP24XX_AUTO_GPT6_MASK (1 << 8) +#define OMAP24XX_AUTO_GPT5_MASK (1 << 7) +#define OMAP24XX_AUTO_GPT4_MASK (1 << 6) +#define OMAP24XX_AUTO_GPT3_MASK (1 << 5) +#define OMAP24XX_AUTO_GPT2_MASK (1 << 4) +#define OMAP2420_AUTO_VLYNQ_MASK (1 << 3) +#define OMAP24XX_AUTO_DSS_MASK (1 << 0) /* CM_AUTOIDLE2_CORE */ -#define OMAP2430_AUTO_MDM_INTC (1 << 11) -#define OMAP2430_AUTO_GPIO5 (1 << 10) -#define OMAP2430_AUTO_MCSPI3 (1 << 9) -#define OMAP2430_AUTO_MMCHS2 (1 << 8) -#define OMAP2430_AUTO_MMCHS1 (1 << 7) -#define OMAP2430_AUTO_USBHS (1 << 6) -#define OMAP2430_AUTO_MCBSP5 (1 << 5) -#define OMAP2430_AUTO_MCBSP4 (1 << 4) -#define OMAP2430_AUTO_MCBSP3 (1 << 3) -#define OMAP24XX_AUTO_UART3 (1 << 2) -#define OMAP24XX_AUTO_SSI (1 << 1) -#define OMAP24XX_AUTO_USB (1 << 0) +#define OMAP2430_AUTO_MDM_INTC_MASK (1 << 11) +#define OMAP2430_AUTO_GPIO5_MASK (1 << 10) +#define OMAP2430_AUTO_MCSPI3_MASK (1 << 9) +#define OMAP2430_AUTO_MMCHS2_MASK (1 << 8) +#define OMAP2430_AUTO_MMCHS1_MASK (1 << 7) +#define OMAP2430_AUTO_USBHS_MASK (1 << 6) +#define OMAP2430_AUTO_MCBSP5_MASK (1 << 5) +#define OMAP2430_AUTO_MCBSP4_MASK (1 << 4) +#define OMAP2430_AUTO_MCBSP3_MASK (1 << 3) +#define OMAP24XX_AUTO_UART3_MASK (1 << 2) +#define OMAP24XX_AUTO_SSI_MASK (1 << 1) +#define OMAP24XX_AUTO_USB_MASK (1 << 0) /* CM_AUTOIDLE3_CORE */ -#define OMAP24XX_AUTO_SDRC (1 << 2) -#define OMAP24XX_AUTO_GPMC (1 << 1) -#define OMAP24XX_AUTO_SDMA (1 << 0) +#define OMAP24XX_AUTO_SDRC_MASK (1 << 2) +#define OMAP24XX_AUTO_GPMC_MASK (1 << 1) +#define OMAP24XX_AUTO_SDMA_MASK (1 << 0) /* CM_AUTOIDLE4_CORE */ -#define OMAP24XX_AUTO_PKA (1 << 4) -#define OMAP24XX_AUTO_AES (1 << 3) -#define OMAP24XX_AUTO_RNG (1 << 2) -#define OMAP24XX_AUTO_SHA (1 << 1) -#define OMAP24XX_AUTO_DES (1 << 0) +#define OMAP24XX_AUTO_PKA_MASK (1 << 4) +#define OMAP24XX_AUTO_AES_MASK (1 << 3) +#define OMAP24XX_AUTO_RNG_MASK (1 << 2) +#define OMAP24XX_AUTO_SHA_MASK (1 << 1) +#define OMAP24XX_AUTO_DES_MASK (1 << 0) /* CM_CLKSEL1_CORE */ #define OMAP24XX_CLKSEL_USB_SHIFT 25 @@ -269,9 +269,9 @@ /* CM_FCLKEN_GFX */ #define OMAP24XX_EN_3D_SHIFT 2 -#define OMAP24XX_EN_3D (1 << 2) +#define OMAP24XX_EN_3D_MASK (1 << 2) #define OMAP24XX_EN_2D_SHIFT 1 -#define OMAP24XX_EN_2D (1 << 1) +#define OMAP24XX_EN_2D_MASK (1 << 1) /* CM_ICLKEN_GFX specific bits */ @@ -287,13 +287,13 @@ /* CM_ICLKEN_WKUP specific bits */ #define OMAP2430_EN_ICR_SHIFT 6 -#define OMAP2430_EN_ICR (1 << 6) +#define OMAP2430_EN_ICR_MASK (1 << 6) #define OMAP24XX_EN_OMAPCTRL_SHIFT 5 -#define OMAP24XX_EN_OMAPCTRL (1 << 5) +#define OMAP24XX_EN_OMAPCTRL_MASK (1 << 5) #define OMAP24XX_EN_WDT1_SHIFT 4 -#define OMAP24XX_EN_WDT1 (1 << 4) +#define OMAP24XX_EN_WDT1_MASK (1 << 4) #define OMAP24XX_EN_32KSYNC_SHIFT 1 -#define OMAP24XX_EN_32KSYNC (1 << 1) +#define OMAP24XX_EN_32KSYNC_MASK (1 << 1) /* CM_IDLEST_WKUP specific bits */ #define OMAP2430_ST_ICR_SHIFT 6 @@ -308,12 +308,12 @@ #define OMAP24XX_ST_32KSYNC_MASK (1 << 1) /* CM_AUTOIDLE_WKUP */ -#define OMAP24XX_AUTO_OMAPCTRL (1 << 5) -#define OMAP24XX_AUTO_WDT1 (1 << 4) -#define OMAP24XX_AUTO_MPU_WDT (1 << 3) -#define OMAP24XX_AUTO_GPIOS (1 << 2) -#define OMAP24XX_AUTO_32KSYNC (1 << 1) -#define OMAP24XX_AUTO_GPT1 (1 << 0) +#define OMAP24XX_AUTO_OMAPCTRL_MASK (1 << 5) +#define OMAP24XX_AUTO_WDT1_MASK (1 << 4) +#define OMAP24XX_AUTO_MPU_WDT_MASK (1 << 3) +#define OMAP24XX_AUTO_GPIOS_MASK (1 << 2) +#define OMAP24XX_AUTO_32KSYNC_MASK (1 << 1) +#define OMAP24XX_AUTO_GPT1_MASK (1 << 0) /* CM_CLKSEL_WKUP */ #define OMAP24XX_CLKSEL_GPT1_SHIFT 0 @@ -328,12 +328,12 @@ #define OMAP24XX_EN_DPLL_MASK (0x3 << 0) /* CM_IDLEST_CKGEN */ -#define OMAP24XX_ST_54M_APLL (1 << 9) -#define OMAP24XX_ST_96M_APLL (1 << 8) -#define OMAP24XX_ST_54M_CLK (1 << 6) -#define OMAP24XX_ST_12M_CLK (1 << 5) -#define OMAP24XX_ST_48M_CLK (1 << 4) -#define OMAP24XX_ST_96M_CLK (1 << 2) +#define OMAP24XX_ST_54M_APLL_MASK (1 << 9) +#define OMAP24XX_ST_96M_APLL_MASK (1 << 8) +#define OMAP24XX_ST_54M_CLK_MASK (1 << 6) +#define OMAP24XX_ST_12M_CLK_MASK (1 << 5) +#define OMAP24XX_ST_48M_CLK_MASK (1 << 4) +#define OMAP24XX_ST_96M_CLK_MASK (1 << 2) #define OMAP24XX_ST_CORE_CLK_SHIFT 0 #define OMAP24XX_ST_CORE_CLK_MASK (0x3 << 0) @@ -355,11 +355,11 @@ #define OMAP24XX_DPLL_DIV_SHIFT 8 #define OMAP24XX_DPLL_DIV_MASK (0xf << 8) #define OMAP24XX_54M_SOURCE_SHIFT 5 -#define OMAP24XX_54M_SOURCE (1 << 5) +#define OMAP24XX_54M_SOURCE_MASK (1 << 5) #define OMAP2430_96M_SOURCE_SHIFT 4 -#define OMAP2430_96M_SOURCE (1 << 4) +#define OMAP2430_96M_SOURCE_MASK (1 << 4) #define OMAP24XX_48M_SOURCE_SHIFT 3 -#define OMAP24XX_48M_SOURCE (1 << 3) +#define OMAP24XX_48M_SOURCE_MASK (1 << 3) #define OMAP2430_ALTCLK_SOURCE_SHIFT 0 #define OMAP2430_ALTCLK_SOURCE_MASK (0x7 << 0) @@ -369,29 +369,29 @@ /* CM_FCLKEN_DSP */ #define OMAP2420_EN_IVA_COP_SHIFT 10 -#define OMAP2420_EN_IVA_COP (1 << 10) +#define OMAP2420_EN_IVA_COP_MASK (1 << 10) #define OMAP2420_EN_IVA_MPU_SHIFT 8 -#define OMAP2420_EN_IVA_MPU (1 << 8) +#define OMAP2420_EN_IVA_MPU_MASK (1 << 8) #define OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT 0 -#define OMAP24XX_CM_FCLKEN_DSP_EN_DSP (1 << 0) +#define OMAP24XX_CM_FCLKEN_DSP_EN_DSP_MASK (1 << 0) /* CM_ICLKEN_DSP */ #define OMAP2420_EN_DSP_IPI_SHIFT 1 -#define OMAP2420_EN_DSP_IPI (1 << 1) +#define OMAP2420_EN_DSP_IPI_MASK (1 << 1) /* CM_IDLEST_DSP */ -#define OMAP2420_ST_IVA (1 << 8) -#define OMAP2420_ST_IPI (1 << 1) -#define OMAP24XX_ST_DSP (1 << 0) +#define OMAP2420_ST_IVA_MASK (1 << 8) +#define OMAP2420_ST_IPI_MASK (1 << 1) +#define OMAP24XX_ST_DSP_MASK (1 << 0) /* CM_AUTOIDLE_DSP */ -#define OMAP2420_AUTO_DSP_IPI (1 << 1) +#define OMAP2420_AUTO_DSP_IPI_MASK (1 << 1) /* CM_CLKSEL_DSP */ -#define OMAP2420_SYNC_IVA (1 << 13) +#define OMAP2420_SYNC_IVA_MASK (1 << 13) #define OMAP2420_CLKSEL_IVA_SHIFT 8 #define OMAP2420_CLKSEL_IVA_MASK (0x1f << 8) -#define OMAP24XX_SYNC_DSP (1 << 7) +#define OMAP24XX_SYNC_DSP_MASK (1 << 7) #define OMAP24XX_CLKSEL_DSP_IF_SHIFT 5 #define OMAP24XX_CLKSEL_DSP_IF_MASK (0x3 << 5) #define OMAP24XX_CLKSEL_DSP_SHIFT 0 @@ -406,24 +406,24 @@ /* CM_FCLKEN_MDM */ /* 2430 only */ #define OMAP2430_EN_OSC_SHIFT 1 -#define OMAP2430_EN_OSC (1 << 1) +#define OMAP2430_EN_OSC_MASK (1 << 1) /* CM_ICLKEN_MDM */ /* 2430 only */ #define OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT 0 -#define OMAP2430_CM_ICLKEN_MDM_EN_MDM (1 << 0) +#define OMAP2430_CM_ICLKEN_MDM_EN_MDM_MASK (1 << 0) /* CM_IDLEST_MDM specific bits */ /* 2430 only */ /* CM_AUTOIDLE_MDM */ /* 2430 only */ -#define OMAP2430_AUTO_OSC (1 << 1) -#define OMAP2430_AUTO_MDM (1 << 0) +#define OMAP2430_AUTO_OSC_MASK (1 << 1) +#define OMAP2430_AUTO_MDM_MASK (1 << 0) /* CM_CLKSEL_MDM */ /* 2430 only */ -#define OMAP2430_SYNC_MDM (1 << 4) +#define OMAP2430_SYNC_MDM_MASK (1 << 4) #define OMAP2430_CLKSEL_MDM_SHIFT 0 #define OMAP2430_CLKSEL_MDM_MASK (0xf << 0) diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 7816c4e84a32..b8c9e900a679 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -170,7 +170,7 @@ static int omap2_i2c_active(void) u32 l; l = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); - return l & (OMAP2420_EN_I2C2 | OMAP2420_EN_I2C1); + return l & (OMAP2420_EN_I2C2_MASK | OMAP2420_EN_I2C1_MASK); } static int sti_console_enabled; @@ -183,7 +183,7 @@ static int omap2_allow_mpu_retention(void) l = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); if (l & (OMAP2420_EN_MMC | OMAP24XX_EN_UART2 | OMAP24XX_EN_UART1 | OMAP24XX_EN_MCSPI2 | - OMAP24XX_EN_MCSPI1 | OMAP24XX_EN_DSS1)) + OMAP24XX_EN_MCSPI1 | OMAP24XX_EN_DSS1_MASK)) return 0; /* Check for UART3. */ l = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2); @@ -351,7 +351,7 @@ static void __init prcm_setup_regs(void) struct powerdomain *pwrdm; /* Enable autoidle */ - prm_write_mod_reg(OMAP24XX_AUTOIDLE, OCP_MOD, + prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD, OMAP2_PRCM_SYSCONFIG_OFFSET); /* @@ -390,53 +390,54 @@ static void __init prcm_setup_regs(void) clkdm_add_wkdep(mpu_clkdm, wkup_clkdm); /* Enable clock autoidle for all domains */ - cm_write_mod_reg(OMAP24XX_AUTO_CAM | - OMAP24XX_AUTO_MAILBOXES | - OMAP24XX_AUTO_WDT4 | - OMAP2420_AUTO_WDT3 | - OMAP24XX_AUTO_MSPRO | - OMAP2420_AUTO_MMC | - OMAP24XX_AUTO_FAC | - OMAP2420_AUTO_EAC | - OMAP24XX_AUTO_HDQ | - OMAP24XX_AUTO_UART2 | - OMAP24XX_AUTO_UART1 | - OMAP24XX_AUTO_I2C2 | - OMAP24XX_AUTO_I2C1 | - OMAP24XX_AUTO_MCSPI2 | - OMAP24XX_AUTO_MCSPI1 | - OMAP24XX_AUTO_MCBSP2 | - OMAP24XX_AUTO_MCBSP1 | - OMAP24XX_AUTO_GPT12 | - OMAP24XX_AUTO_GPT11 | - OMAP24XX_AUTO_GPT10 | - OMAP24XX_AUTO_GPT9 | - OMAP24XX_AUTO_GPT8 | - OMAP24XX_AUTO_GPT7 | - OMAP24XX_AUTO_GPT6 | - OMAP24XX_AUTO_GPT5 | - OMAP24XX_AUTO_GPT4 | - OMAP24XX_AUTO_GPT3 | - OMAP24XX_AUTO_GPT2 | - OMAP2420_AUTO_VLYNQ | - OMAP24XX_AUTO_DSS, + cm_write_mod_reg(OMAP24XX_AUTO_CAM_MASK | + OMAP24XX_AUTO_MAILBOXES_MASK | + OMAP24XX_AUTO_WDT4_MASK | + OMAP2420_AUTO_WDT3_MASK | + OMAP24XX_AUTO_MSPRO_MASK | + OMAP2420_AUTO_MMC_MASK | + OMAP24XX_AUTO_FAC_MASK | + OMAP2420_AUTO_EAC_MASK | + OMAP24XX_AUTO_HDQ_MASK | + OMAP24XX_AUTO_UART2_MASK | + OMAP24XX_AUTO_UART1_MASK | + OMAP24XX_AUTO_I2C2_MASK | + OMAP24XX_AUTO_I2C1_MASK | + OMAP24XX_AUTO_MCSPI2_MASK | + OMAP24XX_AUTO_MCSPI1_MASK | + OMAP24XX_AUTO_MCBSP2_MASK | + OMAP24XX_AUTO_MCBSP1_MASK | + OMAP24XX_AUTO_GPT12_MASK | + OMAP24XX_AUTO_GPT11_MASK | + OMAP24XX_AUTO_GPT10_MASK | + OMAP24XX_AUTO_GPT9_MASK | + OMAP24XX_AUTO_GPT8_MASK | + OMAP24XX_AUTO_GPT7_MASK | + OMAP24XX_AUTO_GPT6_MASK | + OMAP24XX_AUTO_GPT5_MASK | + OMAP24XX_AUTO_GPT4_MASK | + OMAP24XX_AUTO_GPT3_MASK | + OMAP24XX_AUTO_GPT2_MASK | + OMAP2420_AUTO_VLYNQ_MASK | + OMAP24XX_AUTO_DSS_MASK, CORE_MOD, CM_AUTOIDLE1); - cm_write_mod_reg(OMAP24XX_AUTO_UART3 | - OMAP24XX_AUTO_SSI | - OMAP24XX_AUTO_USB, + cm_write_mod_reg(OMAP24XX_AUTO_UART3_MASK | + OMAP24XX_AUTO_SSI_MASK | + OMAP24XX_AUTO_USB_MASK, CORE_MOD, CM_AUTOIDLE2); - cm_write_mod_reg(OMAP24XX_AUTO_SDRC | - OMAP24XX_AUTO_GPMC | - OMAP24XX_AUTO_SDMA, + cm_write_mod_reg(OMAP24XX_AUTO_SDRC_MASK | + OMAP24XX_AUTO_GPMC_MASK | + OMAP24XX_AUTO_SDMA_MASK, CORE_MOD, CM_AUTOIDLE3); - cm_write_mod_reg(OMAP24XX_AUTO_PKA | - OMAP24XX_AUTO_AES | - OMAP24XX_AUTO_RNG | - OMAP24XX_AUTO_SHA | - OMAP24XX_AUTO_DES, + cm_write_mod_reg(OMAP24XX_AUTO_PKA_MASK | + OMAP24XX_AUTO_AES_MASK | + OMAP24XX_AUTO_RNG_MASK | + OMAP24XX_AUTO_SHA_MASK | + OMAP24XX_AUTO_DES_MASK, CORE_MOD, OMAP24XX_CM_AUTOIDLE4); - cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI, OMAP24XX_DSP_MOD, CM_AUTOIDLE); + cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI_MASK, OMAP24XX_DSP_MOD, + CM_AUTOIDLE); /* Put DPLL and both APLLs into autoidle mode */ cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) | @@ -444,12 +445,12 @@ static void __init prcm_setup_regs(void) (0x03 << OMAP24XX_AUTO_54M_SHIFT), PLL_MOD, CM_AUTOIDLE); - cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL | - OMAP24XX_AUTO_WDT1 | - OMAP24XX_AUTO_MPU_WDT | - OMAP24XX_AUTO_GPIOS | - OMAP24XX_AUTO_32KSYNC | - OMAP24XX_AUTO_GPT1, + cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL_MASK | + OMAP24XX_AUTO_WDT1_MASK | + OMAP24XX_AUTO_MPU_WDT_MASK | + OMAP24XX_AUTO_GPIOS_MASK | + OMAP24XX_AUTO_32KSYNC_MASK | + OMAP24XX_AUTO_GPT1_MASK, WKUP_MOD, CM_AUTOIDLE); /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk @@ -460,9 +461,9 @@ static void __init prcm_setup_regs(void) /* Configure automatic voltage transition */ prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTSETUP_OFFSET); - prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT | + prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT_MASK | (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) | - OMAP24XX_MEMRETCTRL | + OMAP24XX_MEMRETCTRL_MASK | (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) | (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT), OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTCTRL_OFFSET); diff --git a/arch/arm/mach-omap2/prm-regbits-24xx.h b/arch/arm/mach-omap2/prm-regbits-24xx.h index 4002051c20b9..0b188ffa710e 100644 --- a/arch/arm/mach-omap2/prm-regbits-24xx.h +++ b/arch/arm/mach-omap2/prm-regbits-24xx.h @@ -19,14 +19,14 @@ /* Bits shared between registers */ /* PRCM_IRQSTATUS_MPU, PM_IRQSTATUS_DSP, PRCM_IRQSTATUS_IVA shared bits */ -#define OMAP24XX_VOLTTRANS_ST (1 << 2) -#define OMAP24XX_WKUP2_ST (1 << 1) -#define OMAP24XX_WKUP1_ST (1 << 0) +#define OMAP24XX_VOLTTRANS_ST_MASK (1 << 2) +#define OMAP24XX_WKUP2_ST_MASK (1 << 1) +#define OMAP24XX_WKUP1_ST_MASK (1 << 0) /* PRCM_IRQENABLE_MPU, PM_IRQENABLE_DSP, PRCM_IRQENABLE_IVA shared bits */ -#define OMAP24XX_VOLTTRANS_EN (1 << 2) -#define OMAP24XX_WKUP2_EN (1 << 1) -#define OMAP24XX_WKUP1_EN (1 << 0) +#define OMAP24XX_VOLTTRANS_EN_MASK (1 << 2) +#define OMAP24XX_WKUP2_EN_MASK (1 << 1) +#define OMAP24XX_WKUP1_EN_MASK (1 << 0) /* PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_DSP, PM_WKDEP_MDM shared bits */ #define OMAP24XX_EN_MPU_SHIFT 1 @@ -40,16 +40,16 @@ */ #define OMAP24XX_MEMONSTATE_SHIFT 10 #define OMAP24XX_MEMONSTATE_MASK (0x3 << 10) -#define OMAP24XX_MEMRETSTATE (1 << 3) +#define OMAP24XX_MEMRETSTATE_MASK (1 << 3) /* PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSP, PM_PWSTCTRL_MDM shared bits */ -#define OMAP24XX_FORCESTATE (1 << 18) +#define OMAP24XX_FORCESTATE_MASK (1 << 18) /* * PM_PWSTST_CORE, PM_PWSTST_GFX, PM_PWSTST_MPU, PM_PWSTST_DSP, * PM_PWSTST_MDM shared bits */ -#define OMAP24XX_CLKACTIVITY (1 << 19) +#define OMAP24XX_CLKACTIVITY_MASK (1 << 19) /* PM_PWSTST_MPU, PM_PWSTST_CORE, PM_PWSTST_DSP shared bits */ #define OMAP24XX_LASTSTATEENTERED_SHIFT 4 @@ -71,26 +71,26 @@ #define OMAP24XX_REV_MASK (0xff << 0) /* PRCM_SYSCONFIG */ -#define OMAP24XX_AUTOIDLE (1 << 0) +#define OMAP24XX_AUTOIDLE_MASK (1 << 0) /* PRCM_IRQSTATUS_MPU specific bits */ -#define OMAP2430_DPLL_RECAL_ST (1 << 6) -#define OMAP24XX_TRANSITION_ST (1 << 5) -#define OMAP24XX_EVGENOFF_ST (1 << 4) -#define OMAP24XX_EVGENON_ST (1 << 3) +#define OMAP2430_DPLL_RECAL_ST_MASK (1 << 6) +#define OMAP24XX_TRANSITION_ST_MASK (1 << 5) +#define OMAP24XX_EVGENOFF_ST_MASK (1 << 4) +#define OMAP24XX_EVGENON_ST_MASK (1 << 3) /* PRCM_IRQENABLE_MPU specific bits */ -#define OMAP2430_DPLL_RECAL_EN (1 << 6) -#define OMAP24XX_TRANSITION_EN (1 << 5) -#define OMAP24XX_EVGENOFF_EN (1 << 4) -#define OMAP24XX_EVGENON_EN (1 << 3) +#define OMAP2430_DPLL_RECAL_EN_MASK (1 << 6) +#define OMAP24XX_TRANSITION_EN_MASK (1 << 5) +#define OMAP24XX_EVGENOFF_EN_MASK (1 << 4) +#define OMAP24XX_EVGENON_EN_MASK (1 << 3) /* PRCM_VOLTCTRL */ -#define OMAP24XX_AUTO_EXTVOLT (1 << 15) -#define OMAP24XX_FORCE_EXTVOLT (1 << 14) +#define OMAP24XX_AUTO_EXTVOLT_MASK (1 << 15) +#define OMAP24XX_FORCE_EXTVOLT_MASK (1 << 14) #define OMAP24XX_SETOFF_LEVEL_SHIFT 12 #define OMAP24XX_SETOFF_LEVEL_MASK (0x3 << 12) -#define OMAP24XX_MEMRETCTRL (1 << 8) +#define OMAP24XX_MEMRETCTRL_MASK (1 << 8) #define OMAP24XX_SETRET_LEVEL_SHIFT 6 #define OMAP24XX_SETRET_LEVEL_MASK (0x3 << 6) #define OMAP24XX_VOLT_LEVEL_SHIFT 0 @@ -104,13 +104,13 @@ /* PRCM_CLKOUT_CTRL */ #define OMAP2420_CLKOUT2_EN_SHIFT 15 -#define OMAP2420_CLKOUT2_EN (1 << 15) +#define OMAP2420_CLKOUT2_EN_MASK (1 << 15) #define OMAP2420_CLKOUT2_DIV_SHIFT 11 #define OMAP2420_CLKOUT2_DIV_MASK (0x7 << 11) #define OMAP2420_CLKOUT2_SOURCE_SHIFT 8 #define OMAP2420_CLKOUT2_SOURCE_MASK (0x3 << 8) #define OMAP24XX_CLKOUT_EN_SHIFT 7 -#define OMAP24XX_CLKOUT_EN (1 << 7) +#define OMAP24XX_CLKOUT_EN_MASK (1 << 7) #define OMAP24XX_CLKOUT_DIV_SHIFT 3 #define OMAP24XX_CLKOUT_DIV_MASK (0x7 << 3) #define OMAP24XX_CLKOUT_SOURCE_SHIFT 0 @@ -118,25 +118,25 @@ /* PRCM_CLKEMUL_CTRL */ #define OMAP24XX_EMULATION_EN_SHIFT 0 -#define OMAP24XX_EMULATION_EN (1 << 0) +#define OMAP24XX_EMULATION_EN_MASK (1 << 0) /* PRCM_CLKCFG_CTRL */ -#define OMAP24XX_VALID_CONFIG (1 << 0) +#define OMAP24XX_VALID_CONFIG_MASK (1 << 0) /* PRCM_CLKCFG_STATUS */ -#define OMAP24XX_CONFIG_STATUS (1 << 0) +#define OMAP24XX_CONFIG_STATUS_MASK (1 << 0) /* PRCM_VOLTSETUP specific bits */ /* PRCM_CLKSSETUP specific bits */ /* PRCM_POLCTRL */ -#define OMAP2420_CLKOUT2_POL (1 << 10) -#define OMAP24XX_CLKOUT_POL (1 << 9) -#define OMAP24XX_CLKREQ_POL (1 << 8) -#define OMAP2430_USE_POWEROK (1 << 2) -#define OMAP2430_POWEROK_POL (1 << 1) -#define OMAP24XX_EXTVOL_POL (1 << 0) +#define OMAP2420_CLKOUT2_POL_MASK (1 << 10) +#define OMAP24XX_CLKOUT_POL_MASK (1 << 9) +#define OMAP24XX_CLKREQ_POL_MASK (1 << 8) +#define OMAP2430_USE_POWEROK_MASK (1 << 2) +#define OMAP2430_POWEROK_POL_MASK (1 << 1) +#define OMAP24XX_EXTVOL_POL_MASK (1 << 0) /* RM_RSTST_MPU specific bits */ /* 2430 calls GLOBALWMPU_RST "GLOBALWARM_RST" instead */ @@ -154,7 +154,7 @@ /* PM_EVEGENOFFTIM_MPU specific bits */ /* PM_PWSTCTRL_MPU specific bits */ -#define OMAP2430_FORCESTATE (1 << 18) +#define OMAP2430_FORCESTATE_MASK (1 << 18) /* PM_PWSTST_MPU specific bits */ /* INTRANSITION, CLKACTIVITY, POWERSTATE, MEMSTATEST are 2430 only */ @@ -168,21 +168,21 @@ /* PM_WKST2_CORE specific bits */ /* PM_WKDEP_CORE specific bits*/ -#define OMAP2430_PM_WKDEP_CORE_EN_MDM (1 << 5) -#define OMAP24XX_PM_WKDEP_CORE_EN_GFX (1 << 3) -#define OMAP24XX_PM_WKDEP_CORE_EN_DSP (1 << 2) +#define OMAP2430_PM_WKDEP_CORE_EN_MDM_MASK (1 << 5) +#define OMAP24XX_PM_WKDEP_CORE_EN_GFX_MASK (1 << 3) +#define OMAP24XX_PM_WKDEP_CORE_EN_DSP_MASK (1 << 2) /* PM_PWSTCTRL_CORE specific bits */ -#define OMAP24XX_MEMORYCHANGE (1 << 20) +#define OMAP24XX_MEMORYCHANGE_MASK (1 << 20) #define OMAP24XX_MEM3ONSTATE_SHIFT 14 #define OMAP24XX_MEM3ONSTATE_MASK (0x3 << 14) #define OMAP24XX_MEM2ONSTATE_SHIFT 12 #define OMAP24XX_MEM2ONSTATE_MASK (0x3 << 12) #define OMAP24XX_MEM1ONSTATE_SHIFT 10 #define OMAP24XX_MEM1ONSTATE_MASK (0x3 << 10) -#define OMAP24XX_MEM3RETSTATE (1 << 5) -#define OMAP24XX_MEM2RETSTATE (1 << 4) -#define OMAP24XX_MEM1RETSTATE (1 << 3) +#define OMAP24XX_MEM3RETSTATE_MASK (1 << 5) +#define OMAP24XX_MEM2RETSTATE_MASK (1 << 4) +#define OMAP24XX_MEM1RETSTATE_MASK (1 << 3) /* PM_PWSTST_CORE specific bits */ #define OMAP24XX_MEM3STATEST_SHIFT 14 @@ -193,10 +193,10 @@ #define OMAP24XX_MEM1STATEST_MASK (0x3 << 10) /* RM_RSTCTRL_GFX */ -#define OMAP24XX_GFX_RST (1 << 0) +#define OMAP24XX_GFX_RST_MASK (1 << 0) /* RM_RSTST_GFX specific bits */ -#define OMAP24XX_GFX_SW_RST (1 << 4) +#define OMAP24XX_GFX_SW_RST_MASK (1 << 4) /* PM_PWSTCTRL_GFX specific bits */ @@ -209,25 +209,25 @@ /* RM_RSTST_WKUP specific bits */ /* 2430 calls EXTWMPU_RST "EXTWARM_RST" and GLOBALWMPU_RST "GLOBALWARM_RST" */ -#define OMAP24XX_EXTWMPU_RST (1 << 6) -#define OMAP24XX_SECU_WD_RST (1 << 5) -#define OMAP24XX_MPU_WD_RST (1 << 4) -#define OMAP24XX_SECU_VIOL_RST (1 << 3) +#define OMAP24XX_EXTWMPU_RST_MASK (1 << 6) +#define OMAP24XX_SECU_WD_RST_MASK (1 << 5) +#define OMAP24XX_MPU_WD_RST_MASK (1 << 4) +#define OMAP24XX_SECU_VIOL_RST_MASK (1 << 3) /* PM_WKEN_WKUP specific bits */ /* PM_WKST_WKUP specific bits */ /* RM_RSTCTRL_DSP */ -#define OMAP2420_RST_IVA (1 << 8) -#define OMAP24XX_RST2_DSP (1 << 1) -#define OMAP24XX_RST1_DSP (1 << 0) +#define OMAP2420_RST_IVA_MASK (1 << 8) +#define OMAP24XX_RST2_DSP_MASK (1 << 1) +#define OMAP24XX_RST1_DSP_MASK (1 << 0) /* RM_RSTST_DSP specific bits */ /* 2430 calls GLOBALWMPU_RST "GLOBALWARM_RST" */ -#define OMAP2420_IVA_SW_RST (1 << 8) -#define OMAP24XX_DSP_SW_RST2 (1 << 5) -#define OMAP24XX_DSP_SW_RST1 (1 << 4) +#define OMAP2420_IVA_SW_RST_MASK (1 << 8) +#define OMAP24XX_DSP_SW_RST2_MASK (1 << 5) +#define OMAP24XX_DSP_SW_RST1_MASK (1 << 4) /* PM_WKDEP_DSP specific bits */ @@ -235,7 +235,7 @@ /* 2430 only: MEMONSTATE, MEMRETSTATE */ #define OMAP2420_MEMIONSTATE_SHIFT 12 #define OMAP2420_MEMIONSTATE_MASK (0x3 << 12) -#define OMAP2420_MEMIRETSTATE (1 << 4) +#define OMAP2420_MEMIRETSTATE_MASK (1 << 4) /* PM_PWSTST_DSP specific bits */ /* MEMSTATEST is 2430 only */ @@ -248,18 +248,18 @@ /* RM_RSTCTRL_MDM */ /* 2430 only */ -#define OMAP2430_PWRON1_MDM (1 << 1) -#define OMAP2430_RST1_MDM (1 << 0) +#define OMAP2430_PWRON1_MDM_MASK (1 << 1) +#define OMAP2430_RST1_MDM_MASK (1 << 0) /* RM_RSTST_MDM specific bits */ /* 2430 only */ -#define OMAP2430_MDM_SECU_VIOL (1 << 6) -#define OMAP2430_MDM_SW_PWRON1 (1 << 5) -#define OMAP2430_MDM_SW_RST1 (1 << 4) +#define OMAP2430_MDM_SECU_VIOL_MASK (1 << 6) +#define OMAP2430_MDM_SW_PWRON1_MASK (1 << 5) +#define OMAP2430_MDM_SW_RST1_MASK (1 << 4) /* PM_WKEN_MDM */ /* 2430 only */ -#define OMAP2430_PM_WKEN_MDM_EN_MDM (1 << 0) +#define OMAP2430_PM_WKEN_MDM_EN_MDM_MASK (1 << 0) /* PM_WKST_MDM specific bits */ /* 2430 only */ @@ -269,7 +269,7 @@ /* PM_PWSTCTRL_MDM specific bits */ /* 2430 only */ -#define OMAP2430_KILLDOMAINWKUP (1 << 19) +#define OMAP2430_KILLDOMAINWKUP_MASK (1 << 19) /* PM_PWSTST_MDM specific bits */ /* 2430 only */ -- cgit v1.2.3-59-g8ed1b From 2bc4ef71c5a3b6986b452d6c530777974d11ef4a Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 18 May 2010 18:47:24 -0600 Subject: OMAP3 PRCM: convert OMAP3 PRCM macros to the _SHIFT/_MASK suffixes Fix all of the remaining OMAP3 PRCM register shift/bitmask macros that did not use the _SHIFT/_MASK suffixes to use them. This makes the use of these macros consistent. It is intended to reduce error, as code can be inspected visually by reviewers to ensure that bitshifts and bitmasks are used in the appropriate places. Signed-off-by: Paul Walmsley Cc: Kevin Hilman --- arch/arm/mach-omap2/cm-regbits-34xx.h | 222 ++++++++++---------- arch/arm/mach-omap2/control.c | 7 +- arch/arm/mach-omap2/pm34xx.c | 178 ++++++++-------- arch/arm/mach-omap2/powerdomain.c | 24 ++- arch/arm/mach-omap2/prm-regbits-34xx.h | 360 ++++++++++++++++----------------- 5 files changed, 398 insertions(+), 393 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index a3a3ca07e383..fe82b79d5f3b 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -21,15 +21,15 @@ /* CM_FCLKEN1_CORE and CM_ICLKEN1_CORE shared bits */ #define OMAP3430ES2_EN_MMC3_MASK (1 << 30) #define OMAP3430ES2_EN_MMC3_SHIFT 30 -#define OMAP3430_EN_MSPRO (1 << 23) +#define OMAP3430_EN_MSPRO_MASK (1 << 23) #define OMAP3430_EN_MSPRO_SHIFT 23 -#define OMAP3430_EN_HDQ (1 << 22) +#define OMAP3430_EN_HDQ_MASK (1 << 22) #define OMAP3430_EN_HDQ_SHIFT 22 -#define OMAP3430ES1_EN_FSHOSTUSB (1 << 5) +#define OMAP3430ES1_EN_FSHOSTUSB_MASK (1 << 5) #define OMAP3430ES1_EN_FSHOSTUSB_SHIFT 5 -#define OMAP3430ES1_EN_D2D (1 << 3) +#define OMAP3430ES1_EN_D2D_MASK (1 << 3) #define OMAP3430ES1_EN_D2D_SHIFT 3 -#define OMAP3430_EN_SSI (1 << 0) +#define OMAP3430_EN_SSI_MASK (1 << 0) #define OMAP3430_EN_SSI_SHIFT 0 /* CM_FCLKEN3_CORE and CM_ICLKEN3_CORE shared bits */ @@ -37,19 +37,19 @@ #define OMAP3430ES2_EN_USBTLL_MASK (1 << 2) /* CM_FCLKEN_WKUP and CM_ICLKEN_WKUP shared bits */ -#define OMAP3430_EN_WDT2 (1 << 5) +#define OMAP3430_EN_WDT2_MASK (1 << 5) #define OMAP3430_EN_WDT2_SHIFT 5 /* CM_ICLKEN_CAM, CM_FCLKEN_CAM shared bits */ -#define OMAP3430_EN_CAM (1 << 0) +#define OMAP3430_EN_CAM_MASK (1 << 0) #define OMAP3430_EN_CAM_SHIFT 0 /* CM_FCLKEN_PER, CM_ICLKEN_PER shared bits */ -#define OMAP3430_EN_WDT3 (1 << 12) +#define OMAP3430_EN_WDT3_MASK (1 << 12) #define OMAP3430_EN_WDT3_SHIFT 12 /* CM_CLKSEL2_EMU, CM_CLKSEL3_EMU shared bits */ -#define OMAP3430_OVERRIDE_ENABLE (1 << 19) +#define OMAP3430_OVERRIDE_ENABLE_MASK (1 << 19) /* Bits specific to each register */ @@ -69,7 +69,7 @@ #define OMAP3430_EN_IVA2_DPLL_MASK (0x7 << 0) /* CM_IDLEST_IVA2 */ -#define OMAP3430_ST_IVA2 (1 << 0) +#define OMAP3430_ST_IVA2_MASK (1 << 0) /* CM_IDLEST_PLL_IVA2 */ #define OMAP3430_ST_IVA2_CLK_SHIFT 0 @@ -114,7 +114,7 @@ #define OMAP3430_EN_MPU_DPLL_MASK (0x7 << 0) /* CM_IDLEST_MPU */ -#define OMAP3430_ST_MPU (1 << 0) +#define OMAP3430_ST_MPU_MASK (1 << 0) /* CM_IDLEST_PLL_MPU */ #define OMAP3430_ST_MPU_CLK_SHIFT 0 @@ -145,50 +145,50 @@ #define OMAP3430_CLKACTIVITY_MPU_MASK (1 << 0) /* CM_FCLKEN1_CORE specific bits */ -#define OMAP3430_EN_MODEM (1 << 31) +#define OMAP3430_EN_MODEM_MASK (1 << 31) #define OMAP3430_EN_MODEM_SHIFT 31 /* CM_ICLKEN1_CORE specific bits */ -#define OMAP3430_EN_ICR (1 << 29) +#define OMAP3430_EN_ICR_MASK (1 << 29) #define OMAP3430_EN_ICR_SHIFT 29 -#define OMAP3430_EN_AES2 (1 << 28) +#define OMAP3430_EN_AES2_MASK (1 << 28) #define OMAP3430_EN_AES2_SHIFT 28 -#define OMAP3430_EN_SHA12 (1 << 27) +#define OMAP3430_EN_SHA12_MASK (1 << 27) #define OMAP3430_EN_SHA12_SHIFT 27 -#define OMAP3430_EN_DES2 (1 << 26) +#define OMAP3430_EN_DES2_MASK (1 << 26) #define OMAP3430_EN_DES2_SHIFT 26 -#define OMAP3430ES1_EN_FAC (1 << 8) +#define OMAP3430ES1_EN_FAC_MASK (1 << 8) #define OMAP3430ES1_EN_FAC_SHIFT 8 -#define OMAP3430_EN_MAILBOXES (1 << 7) +#define OMAP3430_EN_MAILBOXES_MASK (1 << 7) #define OMAP3430_EN_MAILBOXES_SHIFT 7 -#define OMAP3430_EN_OMAPCTRL (1 << 6) +#define OMAP3430_EN_OMAPCTRL_MASK (1 << 6) #define OMAP3430_EN_OMAPCTRL_SHIFT 6 -#define OMAP3430_EN_SAD2D (1 << 3) +#define OMAP3430_EN_SAD2D_MASK (1 << 3) #define OMAP3430_EN_SAD2D_SHIFT 3 -#define OMAP3430_EN_SDRC (1 << 1) +#define OMAP3430_EN_SDRC_MASK (1 << 1) #define OMAP3430_EN_SDRC_SHIFT 1 /* AM35XX specific CM_ICLKEN1_CORE bits */ #define AM35XX_EN_IPSS_MASK (1 << 4) #define AM35XX_EN_IPSS_SHIFT 4 -#define AM35XX_EN_UART4_MASK (1 << 23) +#define AM35XX_EN_UART4_MASK (1 << 23) #define AM35XX_EN_UART4_SHIFT 23 /* CM_ICLKEN2_CORE */ -#define OMAP3430_EN_PKA (1 << 4) +#define OMAP3430_EN_PKA_MASK (1 << 4) #define OMAP3430_EN_PKA_SHIFT 4 -#define OMAP3430_EN_AES1 (1 << 3) +#define OMAP3430_EN_AES1_MASK (1 << 3) #define OMAP3430_EN_AES1_SHIFT 3 -#define OMAP3430_EN_RNG (1 << 2) +#define OMAP3430_EN_RNG_MASK (1 << 2) #define OMAP3430_EN_RNG_SHIFT 2 -#define OMAP3430_EN_SHA11 (1 << 1) +#define OMAP3430_EN_SHA11_MASK (1 << 1) #define OMAP3430_EN_SHA11_SHIFT 1 -#define OMAP3430_EN_DES1 (1 << 0) +#define OMAP3430_EN_DES1_MASK (1 << 0) #define OMAP3430_EN_DES1_SHIFT 0 /* CM_ICLKEN3_CORE */ #define OMAP3430_EN_MAD2D_SHIFT 3 -#define OMAP3430_EN_MAD2D (1 << 3) +#define OMAP3430_EN_MAD2D_MASK (1 << 3) /* CM_FCLKEN3_CORE specific bits */ #define OMAP3430ES2_EN_TS_SHIFT 1 @@ -249,79 +249,79 @@ #define OMAP3430ES2_ST_CPEFUSE_MASK (1 << 0) /* CM_AUTOIDLE1_CORE */ -#define OMAP3430_AUTO_MODEM (1 << 31) +#define OMAP3430_AUTO_MODEM_MASK (1 << 31) #define OMAP3430_AUTO_MODEM_SHIFT 31 -#define OMAP3430ES2_AUTO_MMC3 (1 << 30) +#define OMAP3430ES2_AUTO_MMC3_MASK (1 << 30) #define OMAP3430ES2_AUTO_MMC3_SHIFT 30 -#define OMAP3430ES2_AUTO_ICR (1 << 29) +#define OMAP3430ES2_AUTO_ICR_MASK (1 << 29) #define OMAP3430ES2_AUTO_ICR_SHIFT 29 -#define OMAP3430_AUTO_AES2 (1 << 28) +#define OMAP3430_AUTO_AES2_MASK (1 << 28) #define OMAP3430_AUTO_AES2_SHIFT 28 -#define OMAP3430_AUTO_SHA12 (1 << 27) +#define OMAP3430_AUTO_SHA12_MASK (1 << 27) #define OMAP3430_AUTO_SHA12_SHIFT 27 -#define OMAP3430_AUTO_DES2 (1 << 26) +#define OMAP3430_AUTO_DES2_MASK (1 << 26) #define OMAP3430_AUTO_DES2_SHIFT 26 -#define OMAP3430_AUTO_MMC2 (1 << 25) +#define OMAP3430_AUTO_MMC2_MASK (1 << 25) #define OMAP3430_AUTO_MMC2_SHIFT 25 -#define OMAP3430_AUTO_MMC1 (1 << 24) +#define OMAP3430_AUTO_MMC1_MASK (1 << 24) #define OMAP3430_AUTO_MMC1_SHIFT 24 -#define OMAP3430_AUTO_MSPRO (1 << 23) +#define OMAP3430_AUTO_MSPRO_MASK (1 << 23) #define OMAP3430_AUTO_MSPRO_SHIFT 23 -#define OMAP3430_AUTO_HDQ (1 << 22) +#define OMAP3430_AUTO_HDQ_MASK (1 << 22) #define OMAP3430_AUTO_HDQ_SHIFT 22 -#define OMAP3430_AUTO_MCSPI4 (1 << 21) +#define OMAP3430_AUTO_MCSPI4_MASK (1 << 21) #define OMAP3430_AUTO_MCSPI4_SHIFT 21 -#define OMAP3430_AUTO_MCSPI3 (1 << 20) +#define OMAP3430_AUTO_MCSPI3_MASK (1 << 20) #define OMAP3430_AUTO_MCSPI3_SHIFT 20 -#define OMAP3430_AUTO_MCSPI2 (1 << 19) +#define OMAP3430_AUTO_MCSPI2_MASK (1 << 19) #define OMAP3430_AUTO_MCSPI2_SHIFT 19 -#define OMAP3430_AUTO_MCSPI1 (1 << 18) +#define OMAP3430_AUTO_MCSPI1_MASK (1 << 18) #define OMAP3430_AUTO_MCSPI1_SHIFT 18 -#define OMAP3430_AUTO_I2C3 (1 << 17) +#define OMAP3430_AUTO_I2C3_MASK (1 << 17) #define OMAP3430_AUTO_I2C3_SHIFT 17 -#define OMAP3430_AUTO_I2C2 (1 << 16) +#define OMAP3430_AUTO_I2C2_MASK (1 << 16) #define OMAP3430_AUTO_I2C2_SHIFT 16 -#define OMAP3430_AUTO_I2C1 (1 << 15) +#define OMAP3430_AUTO_I2C1_MASK (1 << 15) #define OMAP3430_AUTO_I2C1_SHIFT 15 -#define OMAP3430_AUTO_UART2 (1 << 14) +#define OMAP3430_AUTO_UART2_MASK (1 << 14) #define OMAP3430_AUTO_UART2_SHIFT 14 -#define OMAP3430_AUTO_UART1 (1 << 13) +#define OMAP3430_AUTO_UART1_MASK (1 << 13) #define OMAP3430_AUTO_UART1_SHIFT 13 -#define OMAP3430_AUTO_GPT11 (1 << 12) +#define OMAP3430_AUTO_GPT11_MASK (1 << 12) #define OMAP3430_AUTO_GPT11_SHIFT 12 -#define OMAP3430_AUTO_GPT10 (1 << 11) +#define OMAP3430_AUTO_GPT10_MASK (1 << 11) #define OMAP3430_AUTO_GPT10_SHIFT 11 -#define OMAP3430_AUTO_MCBSP5 (1 << 10) +#define OMAP3430_AUTO_MCBSP5_MASK (1 << 10) #define OMAP3430_AUTO_MCBSP5_SHIFT 10 -#define OMAP3430_AUTO_MCBSP1 (1 << 9) +#define OMAP3430_AUTO_MCBSP1_MASK (1 << 9) #define OMAP3430_AUTO_MCBSP1_SHIFT 9 -#define OMAP3430ES1_AUTO_FAC (1 << 8) +#define OMAP3430ES1_AUTO_FAC_MASK (1 << 8) #define OMAP3430ES1_AUTO_FAC_SHIFT 8 -#define OMAP3430_AUTO_MAILBOXES (1 << 7) +#define OMAP3430_AUTO_MAILBOXES_MASK (1 << 7) #define OMAP3430_AUTO_MAILBOXES_SHIFT 7 -#define OMAP3430_AUTO_OMAPCTRL (1 << 6) +#define OMAP3430_AUTO_OMAPCTRL_MASK (1 << 6) #define OMAP3430_AUTO_OMAPCTRL_SHIFT 6 -#define OMAP3430ES1_AUTO_FSHOSTUSB (1 << 5) +#define OMAP3430ES1_AUTO_FSHOSTUSB_MASK (1 << 5) #define OMAP3430ES1_AUTO_FSHOSTUSB_SHIFT 5 -#define OMAP3430_AUTO_HSOTGUSB (1 << 4) +#define OMAP3430_AUTO_HSOTGUSB_MASK (1 << 4) #define OMAP3430_AUTO_HSOTGUSB_SHIFT 4 -#define OMAP3430ES1_AUTO_D2D (1 << 3) +#define OMAP3430ES1_AUTO_D2D_MASK (1 << 3) #define OMAP3430ES1_AUTO_D2D_SHIFT 3 -#define OMAP3430_AUTO_SAD2D (1 << 3) +#define OMAP3430_AUTO_SAD2D_MASK (1 << 3) #define OMAP3430_AUTO_SAD2D_SHIFT 3 -#define OMAP3430_AUTO_SSI (1 << 0) +#define OMAP3430_AUTO_SSI_MASK (1 << 0) #define OMAP3430_AUTO_SSI_SHIFT 0 /* CM_AUTOIDLE2_CORE */ -#define OMAP3430_AUTO_PKA (1 << 4) +#define OMAP3430_AUTO_PKA_MASK (1 << 4) #define OMAP3430_AUTO_PKA_SHIFT 4 -#define OMAP3430_AUTO_AES1 (1 << 3) +#define OMAP3430_AUTO_AES1_MASK (1 << 3) #define OMAP3430_AUTO_AES1_SHIFT 3 -#define OMAP3430_AUTO_RNG (1 << 2) +#define OMAP3430_AUTO_RNG_MASK (1 << 2) #define OMAP3430_AUTO_RNG_SHIFT 2 -#define OMAP3430_AUTO_SHA11 (1 << 1) +#define OMAP3430_AUTO_SHA11_MASK (1 << 1) #define OMAP3430_AUTO_SHA11_SHIFT 1 -#define OMAP3430_AUTO_DES1 (1 << 0) +#define OMAP3430_AUTO_DES1_MASK (1 << 0) #define OMAP3430_AUTO_DES1_SHIFT 0 /* CM_AUTOIDLE3_CORE */ @@ -331,7 +331,7 @@ #define OMAP3430ES2_AUTO_USBTLL_SHIFT 2 #define OMAP3430ES2_AUTO_USBTLL_MASK (1 << 2) #define OMAP3430_AUTO_MAD2D_SHIFT 3 -#define OMAP3430_AUTO_MAD2D (1 << 3) +#define OMAP3430_AUTO_MAD2D_MASK (1 << 3) /* CM_CLKSEL_CORE */ #define OMAP3430_CLKSEL_SSI_SHIFT 8 @@ -366,9 +366,9 @@ #define OMAP3430_CLKACTIVITY_L3_MASK (1 << 0) /* CM_FCLKEN_GFX */ -#define OMAP3430ES1_EN_3D (1 << 2) +#define OMAP3430ES1_EN_3D_MASK (1 << 2) #define OMAP3430ES1_EN_3D_SHIFT 2 -#define OMAP3430ES1_EN_2D (1 << 1) +#define OMAP3430ES1_EN_2D_MASK (1 << 1) #define OMAP3430ES1_EN_2D_SHIFT 1 /* CM_ICLKEN_GFX specific bits */ @@ -416,9 +416,9 @@ #define OMAP3430ES2_EN_USIMOCP_MASK (1 << 9) /* CM_ICLKEN_WKUP specific bits */ -#define OMAP3430_EN_WDT1 (1 << 4) +#define OMAP3430_EN_WDT1_MASK (1 << 4) #define OMAP3430_EN_WDT1_SHIFT 4 -#define OMAP3430_EN_32KSYNC (1 << 2) +#define OMAP3430_EN_32KSYNC_MASK (1 << 2) #define OMAP3430_EN_32KSYNC_SHIFT 2 /* CM_IDLEST_WKUP specific bits */ @@ -432,19 +432,19 @@ #define OMAP3430_ST_32KSYNC_MASK (1 << 2) /* CM_AUTOIDLE_WKUP */ -#define OMAP3430ES2_AUTO_USIMOCP (1 << 9) +#define OMAP3430ES2_AUTO_USIMOCP_MASK (1 << 9) #define OMAP3430ES2_AUTO_USIMOCP_SHIFT 9 -#define OMAP3430_AUTO_WDT2 (1 << 5) +#define OMAP3430_AUTO_WDT2_MASK (1 << 5) #define OMAP3430_AUTO_WDT2_SHIFT 5 -#define OMAP3430_AUTO_WDT1 (1 << 4) +#define OMAP3430_AUTO_WDT1_MASK (1 << 4) #define OMAP3430_AUTO_WDT1_SHIFT 4 -#define OMAP3430_AUTO_GPIO1 (1 << 3) +#define OMAP3430_AUTO_GPIO1_MASK (1 << 3) #define OMAP3430_AUTO_GPIO1_SHIFT 3 -#define OMAP3430_AUTO_32KSYNC (1 << 2) +#define OMAP3430_AUTO_32KSYNC_MASK (1 << 2) #define OMAP3430_AUTO_32KSYNC_SHIFT 2 -#define OMAP3430_AUTO_GPT12 (1 << 1) +#define OMAP3430_AUTO_GPT12_MASK (1 << 1) #define OMAP3430_AUTO_GPT12_SHIFT 1 -#define OMAP3430_AUTO_GPT1 (1 << 0) +#define OMAP3430_AUTO_GPT1_MASK (1 << 0) #define OMAP3430_AUTO_GPT1_SHIFT 0 /* CM_CLKSEL_WKUP */ @@ -479,7 +479,7 @@ #define OMAP3430_EN_CORE_DPLL_MASK (0x7 << 0) /* CM_CLKEN2_PLL */ -#define OMAP3430ES2_EN_PERIPH2_DPLL_LPMODE_SHIFT 10 +#define OMAP3430ES2_EN_PERIPH2_DPLL_LPMODE_SHIFT 10 #define OMAP3430ES2_PERIPH2_DPLL_RAMPTIME_MASK (0x3 << 8) #define OMAP3430ES2_PERIPH2_DPLL_FREQSEL_SHIFT 4 #define OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK (0xf << 4) @@ -488,10 +488,10 @@ #define OMAP3430ES2_EN_PERIPH2_DPLL_MASK (0x7 << 0) /* CM_IDLEST_CKGEN */ -#define OMAP3430_ST_54M_CLK (1 << 5) -#define OMAP3430_ST_12M_CLK (1 << 4) -#define OMAP3430_ST_48M_CLK (1 << 3) -#define OMAP3430_ST_96M_CLK (1 << 2) +#define OMAP3430_ST_54M_CLK_MASK (1 << 5) +#define OMAP3430_ST_12M_CLK_MASK (1 << 4) +#define OMAP3430_ST_48M_CLK_MASK (1 << 3) +#define OMAP3430_ST_96M_CLK_MASK (1 << 2) #define OMAP3430_ST_PERIPH_CLK_SHIFT 1 #define OMAP3430_ST_PERIPH_CLK_MASK (1 << 1) #define OMAP3430_ST_CORE_CLK_SHIFT 0 @@ -558,22 +558,22 @@ /* CM_CLKOUT_CTRL */ #define OMAP3430_CLKOUT2_EN_SHIFT 7 -#define OMAP3430_CLKOUT2_EN (1 << 7) +#define OMAP3430_CLKOUT2_EN_MASK (1 << 7) #define OMAP3430_CLKOUT2_DIV_SHIFT 3 #define OMAP3430_CLKOUT2_DIV_MASK (0x7 << 3) #define OMAP3430_CLKOUT2SOURCE_SHIFT 0 #define OMAP3430_CLKOUT2SOURCE_MASK (0x3 << 0) /* CM_FCLKEN_DSS */ -#define OMAP3430_EN_TV (1 << 2) +#define OMAP3430_EN_TV_MASK (1 << 2) #define OMAP3430_EN_TV_SHIFT 2 -#define OMAP3430_EN_DSS2 (1 << 1) +#define OMAP3430_EN_DSS2_MASK (1 << 1) #define OMAP3430_EN_DSS2_SHIFT 1 -#define OMAP3430_EN_DSS1 (1 << 0) +#define OMAP3430_EN_DSS1_MASK (1 << 0) #define OMAP3430_EN_DSS1_SHIFT 0 /* CM_ICLKEN_DSS */ -#define OMAP3430_CM_ICLKEN_DSS_EN_DSS (1 << 0) +#define OMAP3430_CM_ICLKEN_DSS_EN_DSS_MASK (1 << 0) #define OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT 0 /* CM_IDLEST_DSS */ @@ -585,7 +585,7 @@ #define OMAP3430ES1_ST_DSS_MASK (1 << 0) /* CM_AUTOIDLE_DSS */ -#define OMAP3430_AUTO_DSS (1 << 0) +#define OMAP3430_AUTO_DSS_MASK (1 << 0) #define OMAP3430_AUTO_DSS_SHIFT 0 /* CM_CLKSEL_DSS */ @@ -607,16 +607,16 @@ #define OMAP3430_CLKACTIVITY_DSS_MASK (1 << 0) /* CM_FCLKEN_CAM specific bits */ -#define OMAP3430_EN_CSI2 (1 << 1) +#define OMAP3430_EN_CSI2_MASK (1 << 1) #define OMAP3430_EN_CSI2_SHIFT 1 /* CM_ICLKEN_CAM specific bits */ /* CM_IDLEST_CAM */ -#define OMAP3430_ST_CAM (1 << 0) +#define OMAP3430_ST_CAM_MASK (1 << 0) /* CM_AUTOIDLE_CAM */ -#define OMAP3430_AUTO_CAM (1 << 0) +#define OMAP3430_AUTO_CAM_MASK (1 << 0) #define OMAP3430_AUTO_CAM_SHIFT 0 /* CM_CLKSEL_CAM */ @@ -649,41 +649,41 @@ #define OMAP3430_ST_MCBSP2_MASK (1 << 0) /* CM_AUTOIDLE_PER */ -#define OMAP3430_AUTO_GPIO6 (1 << 17) +#define OMAP3430_AUTO_GPIO6_MASK (1 << 17) #define OMAP3430_AUTO_GPIO6_SHIFT 17 -#define OMAP3430_AUTO_GPIO5 (1 << 16) +#define OMAP3430_AUTO_GPIO5_MASK (1 << 16) #define OMAP3430_AUTO_GPIO5_SHIFT 16 -#define OMAP3430_AUTO_GPIO4 (1 << 15) +#define OMAP3430_AUTO_GPIO4_MASK (1 << 15) #define OMAP3430_AUTO_GPIO4_SHIFT 15 -#define OMAP3430_AUTO_GPIO3 (1 << 14) +#define OMAP3430_AUTO_GPIO3_MASK (1 << 14) #define OMAP3430_AUTO_GPIO3_SHIFT 14 -#define OMAP3430_AUTO_GPIO2 (1 << 13) +#define OMAP3430_AUTO_GPIO2_MASK (1 << 13) #define OMAP3430_AUTO_GPIO2_SHIFT 13 -#define OMAP3430_AUTO_WDT3 (1 << 12) +#define OMAP3430_AUTO_WDT3_MASK (1 << 12) #define OMAP3430_AUTO_WDT3_SHIFT 12 -#define OMAP3430_AUTO_UART3 (1 << 11) +#define OMAP3430_AUTO_UART3_MASK (1 << 11) #define OMAP3430_AUTO_UART3_SHIFT 11 -#define OMAP3430_AUTO_GPT9 (1 << 10) +#define OMAP3430_AUTO_GPT9_MASK (1 << 10) #define OMAP3430_AUTO_GPT9_SHIFT 10 -#define OMAP3430_AUTO_GPT8 (1 << 9) +#define OMAP3430_AUTO_GPT8_MASK (1 << 9) #define OMAP3430_AUTO_GPT8_SHIFT 9 -#define OMAP3430_AUTO_GPT7 (1 << 8) +#define OMAP3430_AUTO_GPT7_MASK (1 << 8) #define OMAP3430_AUTO_GPT7_SHIFT 8 -#define OMAP3430_AUTO_GPT6 (1 << 7) +#define OMAP3430_AUTO_GPT6_MASK (1 << 7) #define OMAP3430_AUTO_GPT6_SHIFT 7 -#define OMAP3430_AUTO_GPT5 (1 << 6) +#define OMAP3430_AUTO_GPT5_MASK (1 << 6) #define OMAP3430_AUTO_GPT5_SHIFT 6 -#define OMAP3430_AUTO_GPT4 (1 << 5) +#define OMAP3430_AUTO_GPT4_MASK (1 << 5) #define OMAP3430_AUTO_GPT4_SHIFT 5 -#define OMAP3430_AUTO_GPT3 (1 << 4) +#define OMAP3430_AUTO_GPT3_MASK (1 << 4) #define OMAP3430_AUTO_GPT3_SHIFT 4 -#define OMAP3430_AUTO_GPT2 (1 << 3) +#define OMAP3430_AUTO_GPT2_MASK (1 << 3) #define OMAP3430_AUTO_GPT2_SHIFT 3 -#define OMAP3430_AUTO_MCBSP4 (1 << 2) +#define OMAP3430_AUTO_MCBSP4_MASK (1 << 2) #define OMAP3430_AUTO_MCBSP4_SHIFT 2 -#define OMAP3430_AUTO_MCBSP3 (1 << 1) +#define OMAP3430_AUTO_MCBSP3_MASK (1 << 1) #define OMAP3430_AUTO_MCBSP3_SHIFT 1 -#define OMAP3430_AUTO_MCBSP2 (1 << 0) +#define OMAP3430_AUTO_MCBSP2_MASK (1 << 0) #define OMAP3430_AUTO_MCBSP2_SHIFT 0 /* CM_CLKSEL_PER */ @@ -705,7 +705,7 @@ #define OMAP3430_CLKSEL_GPT2_SHIFT 0 /* CM_SLEEPDEP_PER specific bits */ -#define OMAP3430_CM_SLEEPDEP_PER_EN_IVA2 (1 << 2) +#define OMAP3430_CM_SLEEPDEP_PER_EN_IVA2_MASK (1 << 2) /* CM_CLKSTCTRL_PER */ #define OMAP3430_CLKTRCTRL_PER_SHIFT 0 @@ -755,10 +755,10 @@ #define OMAP3430_PERIPH_DPLL_EMU_DIV_MASK (0x7f << 0) /* CM_POLCTRL */ -#define OMAP3430_CLKOUT2_POL (1 << 0) +#define OMAP3430_CLKOUT2_POL_MASK (1 << 0) /* CM_IDLEST_NEON */ -#define OMAP3430_ST_NEON (1 << 0) +#define OMAP3430_ST_NEON_MASK (1 << 0) /* CM_CLKSTCTRL_NEON */ #define OMAP3430_CLKTRCTRL_NEON_SHIFT 0 diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index 43f8a33655d4..a8d20eef2306 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -194,11 +194,12 @@ void omap3_clear_scratchpad_contents(void) u32 offset = 0; v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM); if (prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) & - OMAP3430_GLOBAL_COLD_RST) { + OMAP3430_GLOBAL_COLD_RST_MASK) { for ( ; offset <= max_offset; offset += 0x4) __raw_writel(0x0, (v_addr + offset)); - prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST, OMAP3430_GR_MOD, - OMAP3_PRM_RSTST_OFFSET); + prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK, + OMAP3430_GR_MOD, + OMAP3_PRM_RSTST_OFFSET); } } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 24c1966f935e..dd09d80ea3eb 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -94,19 +94,20 @@ static void omap3_enable_io_chain(void) int timeout = 0; if (omap_rev() >= OMAP3430_REV_ES3_1) { - prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN, WKUP_MOD, PM_WKEN); + prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); /* Do a readback to assure write has been done */ prm_read_mod_reg(WKUP_MOD, PM_WKEN); while (!(prm_read_mod_reg(WKUP_MOD, PM_WKST) & - OMAP3430_ST_IO_CHAIN)) { + OMAP3430_ST_IO_CHAIN_MASK)) { timeout++; if (timeout > 1000) { printk(KERN_ERR "Wake up daisy chain " "activation failed.\n"); return; } - prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN, + prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD, PM_WKST); } } @@ -115,7 +116,8 @@ static void omap3_enable_io_chain(void) static void omap3_disable_io_chain(void) { if (omap_rev() >= OMAP3430_REV_ES3_1) - prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN, WKUP_MOD, PM_WKEN); + prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); } static void omap3_core_save_context(void) @@ -278,7 +280,8 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) irqstatus_mpu &= irqenable_mpu; do { - if (irqstatus_mpu & (OMAP3430_WKUP_ST | OMAP3430_IO_ST)) { + if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK | + OMAP3430_IO_ST_MASK)) { c = _prcm_int_handle_wakeup(); /* @@ -384,7 +387,7 @@ void omap_sram_idle(void) core_next_state = pwrdm_read_next_pwrst(core_pwrdm); if (per_next_state < PWRDM_POWER_ON || core_next_state < PWRDM_POWER_ON) { - prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); + prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); omap3_enable_io_chain(); } @@ -458,7 +461,7 @@ void omap_sram_idle(void) omap_uart_resume_idle(0); omap_uart_resume_idle(1); if (core_next_state == PWRDM_POWER_OFF) - prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF, + prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, OMAP3430_GR_MOD, OMAP3_PRM_VOLTCTRL_OFFSET); } @@ -476,9 +479,8 @@ void omap_sram_idle(void) } /* Disable IO-PAD and IO-CHAIN wakeup */ - if (per_next_state < PWRDM_POWER_ON || - core_next_state < PWRDM_POWER_ON) { - prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); + if (core_next_state < PWRDM_POWER_ON) { + prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); omap3_disable_io_chain(); } @@ -699,9 +701,9 @@ static void __init omap3_iva_idle(void) return; /* Reset IVA2 */ - prm_write_mod_reg(OMAP3430_RST1_IVA2 | - OMAP3430_RST2_IVA2 | - OMAP3430_RST3_IVA2, + prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK | + OMAP3430_RST2_IVA2_MASK | + OMAP3430_RST3_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); /* Enable IVA2 clock */ @@ -719,9 +721,9 @@ static void __init omap3_iva_idle(void) cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN); /* Reset IVA2 */ - prm_write_mod_reg(OMAP3430_RST1_IVA2 | - OMAP3430_RST2_IVA2 | - OMAP3430_RST3_IVA2, + prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK | + OMAP3430_RST2_IVA2_MASK | + OMAP3430_RST3_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); } @@ -743,8 +745,8 @@ static void __init omap3_d2d_idle(void) omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK); /* reset modem */ - prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON | - OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST, + prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK | + OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK, CORE_MOD, OMAP2_RM_RSTCTRL); prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL); } @@ -770,97 +772,97 @@ static void __init prcm_setup_regs(void) * Note that in the long run this should be done by clockfw */ cm_write_mod_reg( - OMAP3430_AUTO_MODEM | - OMAP3430ES2_AUTO_MMC3 | - OMAP3430ES2_AUTO_ICR | - OMAP3430_AUTO_AES2 | - OMAP3430_AUTO_SHA12 | - OMAP3430_AUTO_DES2 | - OMAP3430_AUTO_MMC2 | - OMAP3430_AUTO_MMC1 | - OMAP3430_AUTO_MSPRO | - OMAP3430_AUTO_HDQ | - OMAP3430_AUTO_MCSPI4 | - OMAP3430_AUTO_MCSPI3 | - OMAP3430_AUTO_MCSPI2 | - OMAP3430_AUTO_MCSPI1 | - OMAP3430_AUTO_I2C3 | - OMAP3430_AUTO_I2C2 | - OMAP3430_AUTO_I2C1 | - OMAP3430_AUTO_UART2 | - OMAP3430_AUTO_UART1 | - OMAP3430_AUTO_GPT11 | - OMAP3430_AUTO_GPT10 | - OMAP3430_AUTO_MCBSP5 | - OMAP3430_AUTO_MCBSP1 | - OMAP3430ES1_AUTO_FAC | /* This is es1 only */ - OMAP3430_AUTO_MAILBOXES | - OMAP3430_AUTO_OMAPCTRL | - OMAP3430ES1_AUTO_FSHOSTUSB | - OMAP3430_AUTO_HSOTGUSB | - OMAP3430_AUTO_SAD2D | - OMAP3430_AUTO_SSI, + OMAP3430_AUTO_MODEM_MASK | + OMAP3430ES2_AUTO_MMC3_MASK | + OMAP3430ES2_AUTO_ICR_MASK | + OMAP3430_AUTO_AES2_MASK | + OMAP3430_AUTO_SHA12_MASK | + OMAP3430_AUTO_DES2_MASK | + OMAP3430_AUTO_MMC2_MASK | + OMAP3430_AUTO_MMC1_MASK | + OMAP3430_AUTO_MSPRO_MASK | + OMAP3430_AUTO_HDQ_MASK | + OMAP3430_AUTO_MCSPI4_MASK | + OMAP3430_AUTO_MCSPI3_MASK | + OMAP3430_AUTO_MCSPI2_MASK | + OMAP3430_AUTO_MCSPI1_MASK | + OMAP3430_AUTO_I2C3_MASK | + OMAP3430_AUTO_I2C2_MASK | + OMAP3430_AUTO_I2C1_MASK | + OMAP3430_AUTO_UART2_MASK | + OMAP3430_AUTO_UART1_MASK | + OMAP3430_AUTO_GPT11_MASK | + OMAP3430_AUTO_GPT10_MASK | + OMAP3430_AUTO_MCBSP5_MASK | + OMAP3430_AUTO_MCBSP1_MASK | + OMAP3430ES1_AUTO_FAC_MASK | /* This is es1 only */ + OMAP3430_AUTO_MAILBOXES_MASK | + OMAP3430_AUTO_OMAPCTRL_MASK | + OMAP3430ES1_AUTO_FSHOSTUSB_MASK | + OMAP3430_AUTO_HSOTGUSB_MASK | + OMAP3430_AUTO_SAD2D_MASK | + OMAP3430_AUTO_SSI_MASK, CORE_MOD, CM_AUTOIDLE1); cm_write_mod_reg( - OMAP3430_AUTO_PKA | - OMAP3430_AUTO_AES1 | - OMAP3430_AUTO_RNG | - OMAP3430_AUTO_SHA11 | - OMAP3430_AUTO_DES1, + OMAP3430_AUTO_PKA_MASK | + OMAP3430_AUTO_AES1_MASK | + OMAP3430_AUTO_RNG_MASK | + OMAP3430_AUTO_SHA11_MASK | + OMAP3430_AUTO_DES1_MASK, CORE_MOD, CM_AUTOIDLE2); if (omap_rev() > OMAP3430_REV_ES1_0) { cm_write_mod_reg( - OMAP3430_AUTO_MAD2D | - OMAP3430ES2_AUTO_USBTLL, + OMAP3430_AUTO_MAD2D_MASK | + OMAP3430ES2_AUTO_USBTLL_MASK, CORE_MOD, CM_AUTOIDLE3); } cm_write_mod_reg( - OMAP3430_AUTO_WDT2 | - OMAP3430_AUTO_WDT1 | - OMAP3430_AUTO_GPIO1 | - OMAP3430_AUTO_32KSYNC | - OMAP3430_AUTO_GPT12 | - OMAP3430_AUTO_GPT1 , + OMAP3430_AUTO_WDT2_MASK | + OMAP3430_AUTO_WDT1_MASK | + OMAP3430_AUTO_GPIO1_MASK | + OMAP3430_AUTO_32KSYNC_MASK | + OMAP3430_AUTO_GPT12_MASK | + OMAP3430_AUTO_GPT1_MASK, WKUP_MOD, CM_AUTOIDLE); cm_write_mod_reg( - OMAP3430_AUTO_DSS, + OMAP3430_AUTO_DSS_MASK, OMAP3430_DSS_MOD, CM_AUTOIDLE); cm_write_mod_reg( - OMAP3430_AUTO_CAM, + OMAP3430_AUTO_CAM_MASK, OMAP3430_CAM_MOD, CM_AUTOIDLE); cm_write_mod_reg( - OMAP3430_AUTO_GPIO6 | - OMAP3430_AUTO_GPIO5 | - OMAP3430_AUTO_GPIO4 | - OMAP3430_AUTO_GPIO3 | - OMAP3430_AUTO_GPIO2 | - OMAP3430_AUTO_WDT3 | - OMAP3430_AUTO_UART3 | - OMAP3430_AUTO_GPT9 | - OMAP3430_AUTO_GPT8 | - OMAP3430_AUTO_GPT7 | - OMAP3430_AUTO_GPT6 | - OMAP3430_AUTO_GPT5 | - OMAP3430_AUTO_GPT4 | - OMAP3430_AUTO_GPT3 | - OMAP3430_AUTO_GPT2 | - OMAP3430_AUTO_MCBSP4 | - OMAP3430_AUTO_MCBSP3 | - OMAP3430_AUTO_MCBSP2, + OMAP3430_AUTO_GPIO6_MASK | + OMAP3430_AUTO_GPIO5_MASK | + OMAP3430_AUTO_GPIO4_MASK | + OMAP3430_AUTO_GPIO3_MASK | + OMAP3430_AUTO_GPIO2_MASK | + OMAP3430_AUTO_WDT3_MASK | + OMAP3430_AUTO_UART3_MASK | + OMAP3430_AUTO_GPT9_MASK | + OMAP3430_AUTO_GPT8_MASK | + OMAP3430_AUTO_GPT7_MASK | + OMAP3430_AUTO_GPT6_MASK | + OMAP3430_AUTO_GPT5_MASK | + OMAP3430_AUTO_GPT4_MASK | + OMAP3430_AUTO_GPT3_MASK | + OMAP3430_AUTO_GPT2_MASK | + OMAP3430_AUTO_MCBSP4_MASK | + OMAP3430_AUTO_MCBSP3_MASK | + OMAP3430_AUTO_MCBSP2_MASK, OMAP3430_PER_MOD, CM_AUTOIDLE); if (omap_rev() > OMAP3430_REV_ES1_0) { cm_write_mod_reg( - OMAP3430ES2_AUTO_USBHOST, + OMAP3430ES2_AUTO_USBHOST_MASK, OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE); } @@ -895,7 +897,7 @@ static void __init prcm_setup_regs(void) OMAP3_PRM_CLKSRC_CTRL_OFFSET); /* setup wakup source */ - prm_write_mod_reg(OMAP3430_EN_IO | OMAP3430_EN_GPIO1 | + prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1 | OMAP3430_EN_GPT1 | OMAP3430_EN_GPT12, WKUP_MOD, PM_WKEN); /* No need to write EN_IO, that is always enabled */ @@ -904,11 +906,11 @@ static void __init prcm_setup_regs(void) WKUP_MOD, OMAP3430_PM_MPUGRPSEL); /* For some reason IO doesn't generate wakeup event even if * it is selected to mpu wakeup goup */ - prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN, + prm_write_mod_reg(OMAP3430_IO_EN_MASK | OMAP3430_WKUP_EN_MASK, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); /* Enable PM_WKEN to support DSS LPR */ - prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS, + prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK, OMAP3430_DSS_MOD, PM_WKEN); /* Enable wakeups in PER */ @@ -919,9 +921,9 @@ static void __init prcm_setup_regs(void) OMAP3430_EN_MCBSP4, OMAP3430_PER_MOD, PM_WKEN); /* and allow them to wake up MPU */ - prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 | - OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 | - OMAP3430_GRPSEL_GPIO6 | OMAP3430_EN_UART3 | + prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2_MASK | OMAP3430_EN_GPIO3 | + OMAP3430_GRPSEL_GPIO4_MASK | OMAP3430_EN_GPIO5 | + OMAP3430_GRPSEL_GPIO6_MASK | OMAP3430_EN_UART3 | OMAP3430_EN_MCBSP2 | OMAP3430_EN_MCBSP3 | OMAP3430_EN_MCBSP4, OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL); diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index ebfce7d1a5d3..637fdfe7acd4 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -64,10 +64,10 @@ static u16 pwrstst_reg_offs; #define OMAP_MEM4_ONSTATE_MASK OMAP4430_OCP_NRET_BANK_ONSTATE_MASK /* OMAP3 and OMAP4 Memory Retstate Masks (common across all power domains) */ -#define OMAP_MEM0_RETSTATE_MASK OMAP3430_SHAREDL1CACHEFLATRETSTATE -#define OMAP_MEM1_RETSTATE_MASK OMAP3430_L1FLATMEMRETSTATE -#define OMAP_MEM2_RETSTATE_MASK OMAP3430_SHAREDL2CACHEFLATRETSTATE -#define OMAP_MEM3_RETSTATE_MASK OMAP3430_L2FLATMEMRETSTATE +#define OMAP_MEM0_RETSTATE_MASK OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK +#define OMAP_MEM1_RETSTATE_MASK OMAP3430_L1FLATMEMRETSTATE_MASK +#define OMAP_MEM2_RETSTATE_MASK OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK +#define OMAP_MEM3_RETSTATE_MASK OMAP3430_L2FLATMEMRETSTATE_MASK #define OMAP_MEM4_RETSTATE_MASK OMAP4430_OCP_NRET_BANK_RETSTATE_MASK /* OMAP3 and OMAP4 Memory Status bits */ @@ -511,6 +511,8 @@ int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) */ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) { + u32 v; + if (!pwrdm) return -EINVAL; @@ -526,9 +528,9 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) * but the type of value returned is the same for each * powerdomain. */ - prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE, - (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)), - pwrdm->prcm_offs, pwrstctrl_reg_offs); + v = pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE_MASK); + prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE_MASK, v, + pwrdm->prcm_offs, pwrstctrl_reg_offs); return 0; } @@ -676,8 +678,8 @@ int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) if (!pwrdm) return -EINVAL; - return prm_read_mod_bits_shift(pwrdm->prcm_offs, - pwrstst_reg_offs, OMAP3430_LOGICSTATEST); + return prm_read_mod_bits_shift(pwrdm->prcm_offs, pwrstst_reg_offs, + OMAP3430_LOGICSTATEST_MASK); } /** @@ -700,7 +702,7 @@ int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) * powerdomain. */ return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST, - OMAP3430_LASTLOGICSTATEENTERED); + OMAP3430_LASTLOGICSTATEENTERED_MASK); } /** @@ -723,7 +725,7 @@ int pwrdm_read_logic_retst(struct powerdomain *pwrdm) * powerdomain. */ return prm_read_mod_bits_shift(pwrdm->prcm_offs, pwrstctrl_reg_offs, - OMAP3430_LOGICSTATEST); + OMAP3430_LOGICSTATEST_MASK); } /** diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h index 8f21bae6dc1c..7fd6023edf96 100644 --- a/arch/arm/mach-omap2/prm-regbits-34xx.h +++ b/arch/arm/mach-omap2/prm-regbits-34xx.h @@ -35,10 +35,10 @@ #define OMAP3430_ERRORGAIN_MASK (0xff << 16) #define OMAP3430_INITVOLTAGE_SHIFT 8 #define OMAP3430_INITVOLTAGE_MASK (0xff << 8) -#define OMAP3430_TIMEOUTEN (1 << 3) -#define OMAP3430_INITVDD (1 << 2) -#define OMAP3430_FORCEUPDATE (1 << 1) -#define OMAP3430_VPENABLE (1 << 0) +#define OMAP3430_TIMEOUTEN_MASK (1 << 3) +#define OMAP3430_INITVDD_MASK (1 << 2) +#define OMAP3430_FORCEUPDATE_MASK (1 << 1) +#define OMAP3430_VPENABLE_MASK (1 << 0) /* PRM_VP1_VSTEPMIN, PRM_VP2_VSTEPMIN shared bits */ #define OMAP3430_SMPSWAITTIMEMIN_SHIFT 8 @@ -65,53 +65,53 @@ #define OMAP3430_VPVOLTAGE_MASK (0xff << 0) /* PRM_VP1_STATUS, PRM_VP2_STATUS shared bits */ -#define OMAP3430_VPINIDLE (1 << 0) +#define OMAP3430_VPINIDLE_MASK (1 << 0) /* PM_WKDEP_IVA2, PM_WKDEP_MPU shared bits */ #define OMAP3430_EN_PER_SHIFT 7 #define OMAP3430_EN_PER_MASK (1 << 7) /* PM_PWSTCTRL_IVA2, PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE shared bits */ -#define OMAP3430_MEMORYCHANGE (1 << 3) +#define OMAP3430_MEMORYCHANGE_MASK (1 << 3) /* PM_PWSTST_IVA2, PM_PWSTST_CORE shared bits */ -#define OMAP3430_LOGICSTATEST (1 << 2) +#define OMAP3430_LOGICSTATEST_MASK (1 << 2) /* PM_PREPWSTST_IVA2, PM_PREPWSTST_CORE shared bits */ -#define OMAP3430_LASTLOGICSTATEENTERED (1 << 2) +#define OMAP3430_LASTLOGICSTATEENTERED_MASK (1 << 2) /* * PM_PREPWSTST_IVA2, PM_PREPWSTST_MPU, PM_PREPWSTST_CORE, * PM_PREPWSTST_GFX, PM_PREPWSTST_DSS, PM_PREPWSTST_CAM, * PM_PREPWSTST_PER, PM_PREPWSTST_NEON shared bits */ -#define OMAP3430_LASTPOWERSTATEENTERED_SHIFT 0 -#define OMAP3430_LASTPOWERSTATEENTERED_MASK (0x3 << 0) +#define OMAP3430_LASTPOWERSTATEENTERED_SHIFT 0 +#define OMAP3430_LASTPOWERSTATEENTERED_MASK (0x3 << 0) /* PRM_IRQSTATUS_IVA2, PRM_IRQSTATUS_MPU shared bits */ -#define OMAP3430_WKUP_ST (1 << 0) +#define OMAP3430_WKUP_ST_MASK (1 << 0) /* PRM_IRQENABLE_IVA2, PRM_IRQENABLE_MPU shared bits */ -#define OMAP3430_WKUP_EN (1 << 0) +#define OMAP3430_WKUP_EN_MASK (1 << 0) /* PM_MPUGRPSEL1_CORE, PM_IVA2GRPSEL1_CORE shared bits */ -#define OMAP3430_GRPSEL_MMC2 (1 << 25) -#define OMAP3430_GRPSEL_MMC1 (1 << 24) -#define OMAP3430_GRPSEL_MCSPI4 (1 << 21) -#define OMAP3430_GRPSEL_MCSPI3 (1 << 20) -#define OMAP3430_GRPSEL_MCSPI2 (1 << 19) -#define OMAP3430_GRPSEL_MCSPI1 (1 << 18) -#define OMAP3430_GRPSEL_I2C3 (1 << 17) -#define OMAP3430_GRPSEL_I2C2 (1 << 16) -#define OMAP3430_GRPSEL_I2C1 (1 << 15) -#define OMAP3430_GRPSEL_UART2 (1 << 14) -#define OMAP3430_GRPSEL_UART1 (1 << 13) -#define OMAP3430_GRPSEL_GPT11 (1 << 12) -#define OMAP3430_GRPSEL_GPT10 (1 << 11) -#define OMAP3430_GRPSEL_MCBSP5 (1 << 10) -#define OMAP3430_GRPSEL_MCBSP1 (1 << 9) -#define OMAP3430_GRPSEL_HSOTGUSB (1 << 4) -#define OMAP3430_GRPSEL_D2D (1 << 3) +#define OMAP3430_GRPSEL_MMC2_MASK (1 << 25) +#define OMAP3430_GRPSEL_MMC1_MASK (1 << 24) +#define OMAP3430_GRPSEL_MCSPI4_MASK (1 << 21) +#define OMAP3430_GRPSEL_MCSPI3_MASK (1 << 20) +#define OMAP3430_GRPSEL_MCSPI2_MASK (1 << 19) +#define OMAP3430_GRPSEL_MCSPI1_MASK (1 << 18) +#define OMAP3430_GRPSEL_I2C3_MASK (1 << 17) +#define OMAP3430_GRPSEL_I2C2_MASK (1 << 16) +#define OMAP3430_GRPSEL_I2C1_MASK (1 << 15) +#define OMAP3430_GRPSEL_UART2_MASK (1 << 14) +#define OMAP3430_GRPSEL_UART1_MASK (1 << 13) +#define OMAP3430_GRPSEL_GPT11_MASK (1 << 12) +#define OMAP3430_GRPSEL_GPT10_MASK (1 << 11) +#define OMAP3430_GRPSEL_MCBSP5_MASK (1 << 10) +#define OMAP3430_GRPSEL_MCBSP1_MASK (1 << 9) +#define OMAP3430_GRPSEL_HSOTGUSB_MASK (1 << 4) +#define OMAP3430_GRPSEL_D2D_MASK (1 << 3) /* * PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSS, PM_PWSTCTRL_CAM, @@ -119,49 +119,49 @@ */ #define OMAP3430_MEMONSTATE_SHIFT 16 #define OMAP3430_MEMONSTATE_MASK (0x3 << 16) -#define OMAP3430_MEMRETSTATE (1 << 8) +#define OMAP3430_MEMRETSTATE_MASK (1 << 8) /* PM_MPUGRPSEL_PER, PM_IVA2GRPSEL_PER shared bits */ -#define OMAP3430_GRPSEL_GPIO6 (1 << 17) -#define OMAP3430_GRPSEL_GPIO5 (1 << 16) -#define OMAP3430_GRPSEL_GPIO4 (1 << 15) -#define OMAP3430_GRPSEL_GPIO3 (1 << 14) -#define OMAP3430_GRPSEL_GPIO2 (1 << 13) -#define OMAP3430_GRPSEL_UART3 (1 << 11) -#define OMAP3430_GRPSEL_GPT9 (1 << 10) -#define OMAP3430_GRPSEL_GPT8 (1 << 9) -#define OMAP3430_GRPSEL_GPT7 (1 << 8) -#define OMAP3430_GRPSEL_GPT6 (1 << 7) -#define OMAP3430_GRPSEL_GPT5 (1 << 6) -#define OMAP3430_GRPSEL_GPT4 (1 << 5) -#define OMAP3430_GRPSEL_GPT3 (1 << 4) -#define OMAP3430_GRPSEL_GPT2 (1 << 3) -#define OMAP3430_GRPSEL_MCBSP4 (1 << 2) -#define OMAP3430_GRPSEL_MCBSP3 (1 << 1) -#define OMAP3430_GRPSEL_MCBSP2 (1 << 0) +#define OMAP3430_GRPSEL_GPIO6_MASK (1 << 17) +#define OMAP3430_GRPSEL_GPIO5_MASK (1 << 16) +#define OMAP3430_GRPSEL_GPIO4_MASK (1 << 15) +#define OMAP3430_GRPSEL_GPIO3_MASK (1 << 14) +#define OMAP3430_GRPSEL_GPIO2_MASK (1 << 13) +#define OMAP3430_GRPSEL_UART3_MASK (1 << 11) +#define OMAP3430_GRPSEL_GPT9_MASK (1 << 10) +#define OMAP3430_GRPSEL_GPT8_MASK (1 << 9) +#define OMAP3430_GRPSEL_GPT7_MASK (1 << 8) +#define OMAP3430_GRPSEL_GPT6_MASK (1 << 7) +#define OMAP3430_GRPSEL_GPT5_MASK (1 << 6) +#define OMAP3430_GRPSEL_GPT4_MASK (1 << 5) +#define OMAP3430_GRPSEL_GPT3_MASK (1 << 4) +#define OMAP3430_GRPSEL_GPT2_MASK (1 << 3) +#define OMAP3430_GRPSEL_MCBSP4_MASK (1 << 2) +#define OMAP3430_GRPSEL_MCBSP3_MASK (1 << 1) +#define OMAP3430_GRPSEL_MCBSP2_MASK (1 << 0) /* PM_MPUGRPSEL_WKUP, PM_IVA2GRPSEL_WKUP shared bits */ -#define OMAP3430_GRPSEL_IO (1 << 8) -#define OMAP3430_GRPSEL_SR2 (1 << 7) -#define OMAP3430_GRPSEL_SR1 (1 << 6) -#define OMAP3430_GRPSEL_GPIO1 (1 << 3) -#define OMAP3430_GRPSEL_GPT12 (1 << 1) -#define OMAP3430_GRPSEL_GPT1 (1 << 0) +#define OMAP3430_GRPSEL_IO_MASK (1 << 8) +#define OMAP3430_GRPSEL_SR2_MASK (1 << 7) +#define OMAP3430_GRPSEL_SR1_MASK (1 << 6) +#define OMAP3430_GRPSEL_GPIO1_MASK (1 << 3) +#define OMAP3430_GRPSEL_GPT12_MASK (1 << 1) +#define OMAP3430_GRPSEL_GPT1_MASK (1 << 0) /* Bits specific to each register */ /* RM_RSTCTRL_IVA2 */ -#define OMAP3430_RST3_IVA2 (1 << 2) -#define OMAP3430_RST2_IVA2 (1 << 1) -#define OMAP3430_RST1_IVA2 (1 << 0) +#define OMAP3430_RST3_IVA2_MASK (1 << 2) +#define OMAP3430_RST2_IVA2_MASK (1 << 1) +#define OMAP3430_RST1_IVA2_MASK (1 << 0) /* RM_RSTST_IVA2 specific bits */ -#define OMAP3430_EMULATION_VSEQ_RST (1 << 13) -#define OMAP3430_EMULATION_VHWA_RST (1 << 12) -#define OMAP3430_EMULATION_IVA2_RST (1 << 11) -#define OMAP3430_IVA2_SW_RST3 (1 << 10) -#define OMAP3430_IVA2_SW_RST2 (1 << 9) -#define OMAP3430_IVA2_SW_RST1 (1 << 8) +#define OMAP3430_EMULATION_VSEQ_RST_MASK (1 << 13) +#define OMAP3430_EMULATION_VHWA_RST_MASK (1 << 12) +#define OMAP3430_EMULATION_IVA2_RST_MASK (1 << 11) +#define OMAP3430_IVA2_SW_RST3_MASK (1 << 10) +#define OMAP3430_IVA2_SW_RST2_MASK (1 << 9) +#define OMAP3430_IVA2_SW_RST1_MASK (1 << 8) /* PM_WKDEP_IVA2 specific bits */ @@ -174,10 +174,10 @@ #define OMAP3430_L1FLATMEMONSTATE_MASK (0x3 << 18) #define OMAP3430_SHAREDL1CACHEFLATONSTATE_SHIFT 16 #define OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK (0x3 << 16) -#define OMAP3430_L2FLATMEMRETSTATE (1 << 11) -#define OMAP3430_SHAREDL2CACHEFLATRETSTATE (1 << 10) -#define OMAP3430_L1FLATMEMRETSTATE (1 << 9) -#define OMAP3430_SHAREDL1CACHEFLATRETSTATE (1 << 8) +#define OMAP3430_L2FLATMEMRETSTATE_MASK (1 << 11) +#define OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK (1 << 10) +#define OMAP3430_L1FLATMEMRETSTATE_MASK (1 << 9) +#define OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK (1 << 8) /* PM_PWSTST_IVA2 specific bits */ #define OMAP3430_L2FLATMEMSTATEST_SHIFT 10 @@ -200,12 +200,12 @@ #define OMAP3430_LASTSHAREDL1CACHEFLATSTATEENTERED_MASK (0x3 << 4) /* PRM_IRQSTATUS_IVA2 specific bits */ -#define OMAP3430_PRM_IRQSTATUS_IVA2_IVA2_DPLL_ST (1 << 2) -#define OMAP3430_FORCEWKUP_ST (1 << 1) +#define OMAP3430_PRM_IRQSTATUS_IVA2_IVA2_DPLL_ST_MASK (1 << 2) +#define OMAP3430_FORCEWKUP_ST_MASK (1 << 1) /* PRM_IRQENABLE_IVA2 specific bits */ -#define OMAP3430_PRM_IRQENABLE_IVA2_IVA2_DPLL_RECAL_EN (1 << 2) -#define OMAP3430_FORCEWKUP_EN (1 << 1) +#define OMAP3430_PRM_IRQENABLE_IVA2_IVA2_DPLL_RECAL_EN_MASK (1 << 2) +#define OMAP3430_FORCEWKUP_EN_MASK (1 << 1) /* PRM_REVISION specific bits */ @@ -213,70 +213,70 @@ /* PRM_IRQSTATUS_MPU specific bits */ #define OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT 25 -#define OMAP3430ES2_SND_PERIPH_DPLL_ST (1 << 25) -#define OMAP3430_VC_TIMEOUTERR_ST (1 << 24) -#define OMAP3430_VC_RAERR_ST (1 << 23) -#define OMAP3430_VC_SAERR_ST (1 << 22) -#define OMAP3430_VP2_TRANXDONE_ST (1 << 21) -#define OMAP3430_VP2_EQVALUE_ST (1 << 20) -#define OMAP3430_VP2_NOSMPSACK_ST (1 << 19) -#define OMAP3430_VP2_MAXVDD_ST (1 << 18) -#define OMAP3430_VP2_MINVDD_ST (1 << 17) -#define OMAP3430_VP2_OPPCHANGEDONE_ST (1 << 16) -#define OMAP3430_VP1_TRANXDONE_ST (1 << 15) -#define OMAP3430_VP1_EQVALUE_ST (1 << 14) -#define OMAP3430_VP1_NOSMPSACK_ST (1 << 13) -#define OMAP3430_VP1_MAXVDD_ST (1 << 12) -#define OMAP3430_VP1_MINVDD_ST (1 << 11) -#define OMAP3430_VP1_OPPCHANGEDONE_ST (1 << 10) -#define OMAP3430_IO_ST (1 << 9) -#define OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST (1 << 8) +#define OMAP3430ES2_SND_PERIPH_DPLL_ST_MASK (1 << 25) +#define OMAP3430_VC_TIMEOUTERR_ST_MASK (1 << 24) +#define OMAP3430_VC_RAERR_ST_MASK (1 << 23) +#define OMAP3430_VC_SAERR_ST_MASK (1 << 22) +#define OMAP3430_VP2_TRANXDONE_ST_MASK (1 << 21) +#define OMAP3430_VP2_EQVALUE_ST_MASK (1 << 20) +#define OMAP3430_VP2_NOSMPSACK_ST_MASK (1 << 19) +#define OMAP3430_VP2_MAXVDD_ST_MASK (1 << 18) +#define OMAP3430_VP2_MINVDD_ST_MASK (1 << 17) +#define OMAP3430_VP2_OPPCHANGEDONE_ST_MASK (1 << 16) +#define OMAP3430_VP1_TRANXDONE_ST_MASK (1 << 15) +#define OMAP3430_VP1_EQVALUE_ST_MASK (1 << 14) +#define OMAP3430_VP1_NOSMPSACK_ST_MASK (1 << 13) +#define OMAP3430_VP1_MAXVDD_ST_MASK (1 << 12) +#define OMAP3430_VP1_MINVDD_ST_MASK (1 << 11) +#define OMAP3430_VP1_OPPCHANGEDONE_ST_MASK (1 << 10) +#define OMAP3430_IO_ST_MASK (1 << 9) +#define OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_MASK (1 << 8) #define OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT 8 -#define OMAP3430_MPU_DPLL_ST (1 << 7) +#define OMAP3430_MPU_DPLL_ST_MASK (1 << 7) #define OMAP3430_MPU_DPLL_ST_SHIFT 7 -#define OMAP3430_PERIPH_DPLL_ST (1 << 6) +#define OMAP3430_PERIPH_DPLL_ST_MASK (1 << 6) #define OMAP3430_PERIPH_DPLL_ST_SHIFT 6 -#define OMAP3430_CORE_DPLL_ST (1 << 5) +#define OMAP3430_CORE_DPLL_ST_MASK (1 << 5) #define OMAP3430_CORE_DPLL_ST_SHIFT 5 -#define OMAP3430_TRANSITION_ST (1 << 4) -#define OMAP3430_EVGENOFF_ST (1 << 3) -#define OMAP3430_EVGENON_ST (1 << 2) -#define OMAP3430_FS_USB_WKUP_ST (1 << 1) +#define OMAP3430_TRANSITION_ST_MASK (1 << 4) +#define OMAP3430_EVGENOFF_ST_MASK (1 << 3) +#define OMAP3430_EVGENON_ST_MASK (1 << 2) +#define OMAP3430_FS_USB_WKUP_ST_MASK (1 << 1) /* PRM_IRQENABLE_MPU specific bits */ #define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT 25 -#define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN (1 << 25) -#define OMAP3430_VC_TIMEOUTERR_EN (1 << 24) -#define OMAP3430_VC_RAERR_EN (1 << 23) -#define OMAP3430_VC_SAERR_EN (1 << 22) -#define OMAP3430_VP2_TRANXDONE_EN (1 << 21) -#define OMAP3430_VP2_EQVALUE_EN (1 << 20) -#define OMAP3430_VP2_NOSMPSACK_EN (1 << 19) -#define OMAP3430_VP2_MAXVDD_EN (1 << 18) -#define OMAP3430_VP2_MINVDD_EN (1 << 17) -#define OMAP3430_VP2_OPPCHANGEDONE_EN (1 << 16) -#define OMAP3430_VP1_TRANXDONE_EN (1 << 15) -#define OMAP3430_VP1_EQVALUE_EN (1 << 14) -#define OMAP3430_VP1_NOSMPSACK_EN (1 << 13) -#define OMAP3430_VP1_MAXVDD_EN (1 << 12) -#define OMAP3430_VP1_MINVDD_EN (1 << 11) -#define OMAP3430_VP1_OPPCHANGEDONE_EN (1 << 10) -#define OMAP3430_IO_EN (1 << 9) -#define OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN (1 << 8) +#define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_MASK (1 << 25) +#define OMAP3430_VC_TIMEOUTERR_EN_MASK (1 << 24) +#define OMAP3430_VC_RAERR_EN_MASK (1 << 23) +#define OMAP3430_VC_SAERR_EN_MASK (1 << 22) +#define OMAP3430_VP2_TRANXDONE_EN_MASK (1 << 21) +#define OMAP3430_VP2_EQVALUE_EN_MASK (1 << 20) +#define OMAP3430_VP2_NOSMPSACK_EN_MASK (1 << 19) +#define OMAP3430_VP2_MAXVDD_EN_MASK (1 << 18) +#define OMAP3430_VP2_MINVDD_EN_MASK (1 << 17) +#define OMAP3430_VP2_OPPCHANGEDONE_EN_MASK (1 << 16) +#define OMAP3430_VP1_TRANXDONE_EN_MASK (1 << 15) +#define OMAP3430_VP1_EQVALUE_EN_MASK (1 << 14) +#define OMAP3430_VP1_NOSMPSACK_EN_MASK (1 << 13) +#define OMAP3430_VP1_MAXVDD_EN_MASK (1 << 12) +#define OMAP3430_VP1_MINVDD_EN_MASK (1 << 11) +#define OMAP3430_VP1_OPPCHANGEDONE_EN_MASK (1 << 10) +#define OMAP3430_IO_EN_MASK (1 << 9) +#define OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_MASK (1 << 8) #define OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT 8 -#define OMAP3430_MPU_DPLL_RECAL_EN (1 << 7) +#define OMAP3430_MPU_DPLL_RECAL_EN_MASK (1 << 7) #define OMAP3430_MPU_DPLL_RECAL_EN_SHIFT 7 -#define OMAP3430_PERIPH_DPLL_RECAL_EN (1 << 6) +#define OMAP3430_PERIPH_DPLL_RECAL_EN_MASK (1 << 6) #define OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT 6 -#define OMAP3430_CORE_DPLL_RECAL_EN (1 << 5) +#define OMAP3430_CORE_DPLL_RECAL_EN_MASK (1 << 5) #define OMAP3430_CORE_DPLL_RECAL_EN_SHIFT 5 -#define OMAP3430_TRANSITION_EN (1 << 4) -#define OMAP3430_EVGENOFF_EN (1 << 3) -#define OMAP3430_EVGENON_EN (1 << 2) -#define OMAP3430_FS_USB_WKUP_EN (1 << 1) +#define OMAP3430_TRANSITION_EN_MASK (1 << 4) +#define OMAP3430_EVGENOFF_EN_MASK (1 << 3) +#define OMAP3430_EVGENON_EN_MASK (1 << 2) +#define OMAP3430_FS_USB_WKUP_EN_MASK (1 << 1) /* RM_RSTST_MPU specific bits */ -#define OMAP3430_EMULATION_MPU_RST (1 << 11) +#define OMAP3430_EMULATION_MPU_RST_MASK (1 << 11) /* PM_WKDEP_MPU specific bits */ #define OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT 5 @@ -289,7 +289,7 @@ #define OMAP3430_OFFLOADMODE_MASK (0x3 << 3) #define OMAP3430_ONLOADMODE_SHIFT 1 #define OMAP3430_ONLOADMODE_MASK (0x3 << 1) -#define OMAP3430_ENABLE (1 << 0) +#define OMAP3430_ENABLE_MASK (1 << 0) /* PM_EVGENONTIM_MPU */ #define OMAP3430_ONTIMEVAL_SHIFT 0 @@ -302,32 +302,32 @@ /* PM_PWSTCTRL_MPU specific bits */ #define OMAP3430_L2CACHEONSTATE_SHIFT 16 #define OMAP3430_L2CACHEONSTATE_MASK (0x3 << 16) -#define OMAP3430_L2CACHERETSTATE (1 << 8) -#define OMAP3430_LOGICL1CACHERETSTATE (1 << 2) +#define OMAP3430_L2CACHERETSTATE_MASK (1 << 8) +#define OMAP3430_LOGICL1CACHERETSTATE_MASK (1 << 2) /* PM_PWSTST_MPU specific bits */ #define OMAP3430_L2CACHESTATEST_SHIFT 6 #define OMAP3430_L2CACHESTATEST_MASK (0x3 << 6) -#define OMAP3430_LOGICL1CACHESTATEST (1 << 2) +#define OMAP3430_LOGICL1CACHESTATEST_MASK (1 << 2) /* PM_PREPWSTST_MPU specific bits */ #define OMAP3430_LASTL2CACHESTATEENTERED_SHIFT 6 #define OMAP3430_LASTL2CACHESTATEENTERED_MASK (0x3 << 6) -#define OMAP3430_LASTLOGICL1CACHESTATEENTERED (1 << 2) +#define OMAP3430_LASTLOGICL1CACHESTATEENTERED_MASK (1 << 2) /* RM_RSTCTRL_CORE */ -#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON (1 << 1) -#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST (1 << 0) +#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK (1 << 1) +#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK (1 << 0) /* RM_RSTST_CORE specific bits */ -#define OMAP3430_MODEM_SECURITY_VIOL_RST (1 << 10) -#define OMAP3430_RM_RSTST_CORE_MODEM_SW_RSTPWRON (1 << 9) -#define OMAP3430_RM_RSTST_CORE_MODEM_SW_RST (1 << 8) +#define OMAP3430_MODEM_SECURITY_VIOL_RST_MASK (1 << 10) +#define OMAP3430_RM_RSTST_CORE_MODEM_SW_RSTPWRON_MASK (1 << 9) +#define OMAP3430_RM_RSTST_CORE_MODEM_SW_RST_MASK (1 << 8) /* PM_WKEN1_CORE specific bits */ /* PM_MPUGRPSEL1_CORE specific bits */ -#define OMAP3430_GRPSEL_FSHOSTUSB (1 << 5) +#define OMAP3430_GRPSEL_FSHOSTUSB_MASK (1 << 5) /* PM_IVA2GRPSEL1_CORE specific bits */ @@ -338,8 +338,8 @@ #define OMAP3430_MEM2ONSTATE_MASK (0x3 << 18) #define OMAP3430_MEM1ONSTATE_SHIFT 16 #define OMAP3430_MEM1ONSTATE_MASK (0x3 << 16) -#define OMAP3430_MEM2RETSTATE (1 << 9) -#define OMAP3430_MEM1RETSTATE (1 << 8) +#define OMAP3430_MEM2RETSTATE_MASK (1 << 9) +#define OMAP3430_MEM1RETSTATE_MASK (1 << 8) /* PM_PWSTST_CORE specific bits */ #define OMAP3430_MEM2STATEST_SHIFT 6 @@ -356,7 +356,7 @@ /* RM_RSTST_GFX specific bits */ /* PM_WKDEP_GFX specific bits */ -#define OMAP3430_PM_WKDEP_GFX_EN_IVA2 (1 << 2) +#define OMAP3430_PM_WKDEP_GFX_EN_IVA2_MASK (1 << 2) /* PM_PWSTCTRL_GFX specific bits */ @@ -365,33 +365,33 @@ /* PM_PREPWSTST_GFX specific bits */ /* PM_WKEN_WKUP specific bits */ -#define OMAP3430_EN_IO_CHAIN (1 << 16) -#define OMAP3430_EN_IO (1 << 8) -#define OMAP3430_EN_GPIO1 (1 << 3) +#define OMAP3430_EN_IO_CHAIN_MASK (1 << 16) +#define OMAP3430_EN_IO_MASK (1 << 8) +#define OMAP3430_EN_GPIO1_MASK (1 << 3) /* PM_MPUGRPSEL_WKUP specific bits */ /* PM_IVA2GRPSEL_WKUP specific bits */ /* PM_WKST_WKUP specific bits */ -#define OMAP3430_ST_IO_CHAIN (1 << 16) -#define OMAP3430_ST_IO (1 << 8) +#define OMAP3430_ST_IO_CHAIN_MASK (1 << 16) +#define OMAP3430_ST_IO_MASK (1 << 8) /* PRM_CLKSEL */ #define OMAP3430_SYS_CLKIN_SEL_SHIFT 0 #define OMAP3430_SYS_CLKIN_SEL_MASK (0x7 << 0) /* PRM_CLKOUT_CTRL */ -#define OMAP3430_CLKOUT_EN (1 << 7) +#define OMAP3430_CLKOUT_EN_MASK (1 << 7) #define OMAP3430_CLKOUT_EN_SHIFT 7 /* RM_RSTST_DSS specific bits */ /* PM_WKEN_DSS */ -#define OMAP3430_PM_WKEN_DSS_EN_DSS (1 << 0) +#define OMAP3430_PM_WKEN_DSS_EN_DSS_MASK (1 << 0) /* PM_WKDEP_DSS specific bits */ -#define OMAP3430_PM_WKDEP_DSS_EN_IVA2 (1 << 2) +#define OMAP3430_PM_WKDEP_DSS_EN_IVA2_MASK (1 << 2) /* PM_PWSTCTRL_DSS specific bits */ @@ -402,7 +402,7 @@ /* RM_RSTST_CAM specific bits */ /* PM_WKDEP_CAM specific bits */ -#define OMAP3430_PM_WKDEP_CAM_EN_IVA2 (1 << 2) +#define OMAP3430_PM_WKDEP_CAM_EN_IVA2_MASK (1 << 2) /* PM_PWSTCTRL_CAM specific bits */ @@ -424,7 +424,7 @@ /* PM_WKST_PER specific bits */ /* PM_WKDEP_PER specific bits */ -#define OMAP3430_PM_WKDEP_PER_EN_IVA2 (1 << 2) +#define OMAP3430_PM_WKDEP_PER_EN_IVA2_MASK (1 << 2) /* PM_PWSTCTRL_PER specific bits */ @@ -467,26 +467,26 @@ /* PRM_VC_CMD_VAL_1 specific bits */ /* PRM_VC_CH_CONF */ -#define OMAP3430_CMD1 (1 << 20) -#define OMAP3430_RACEN1 (1 << 19) -#define OMAP3430_RAC1 (1 << 18) -#define OMAP3430_RAV1 (1 << 17) -#define OMAP3430_PRM_VC_CH_CONF_SA1 (1 << 16) -#define OMAP3430_CMD0 (1 << 4) -#define OMAP3430_RACEN0 (1 << 3) -#define OMAP3430_RAC0 (1 << 2) -#define OMAP3430_RAV0 (1 << 1) -#define OMAP3430_PRM_VC_CH_CONF_SA0 (1 << 0) +#define OMAP3430_CMD1_MASK (1 << 20) +#define OMAP3430_RACEN1_MASK (1 << 19) +#define OMAP3430_RAC1_MASK (1 << 18) +#define OMAP3430_RAV1_MASK (1 << 17) +#define OMAP3430_PRM_VC_CH_CONF_SA1_MASK (1 << 16) +#define OMAP3430_CMD0_MASK (1 << 4) +#define OMAP3430_RACEN0_MASK (1 << 3) +#define OMAP3430_RAC0_MASK (1 << 2) +#define OMAP3430_RAV0_MASK (1 << 1) +#define OMAP3430_PRM_VC_CH_CONF_SA0_MASK (1 << 0) /* PRM_VC_I2C_CFG */ -#define OMAP3430_HSMASTER (1 << 5) -#define OMAP3430_SREN (1 << 4) -#define OMAP3430_HSEN (1 << 3) +#define OMAP3430_HSMASTER_MASK (1 << 5) +#define OMAP3430_SREN_MASK (1 << 4) +#define OMAP3430_HSEN_MASK (1 << 3) #define OMAP3430_MCODE_SHIFT 0 #define OMAP3430_MCODE_MASK (0x7 << 0) /* PRM_VC_BYPASS_VAL */ -#define OMAP3430_VALID (1 << 24) +#define OMAP3430_VALID_MASK (1 << 24) #define OMAP3430_DATA_SHIFT 16 #define OMAP3430_DATA_MASK (0xff << 16) #define OMAP3430_REGADDR_SHIFT 8 @@ -495,8 +495,8 @@ #define OMAP3430_SLAVEADDR_MASK (0x7f << 0) /* PRM_RSTCTRL */ -#define OMAP3430_RST_DPLL3 (1 << 2) -#define OMAP3430_RST_GS (1 << 1) +#define OMAP3430_RST_DPLL3_MASK (1 << 2) +#define OMAP3430_RST_GS_MASK (1 << 1) /* PRM_RSTTIME */ #define OMAP3430_RSTTIME2_SHIFT 8 @@ -505,23 +505,23 @@ #define OMAP3430_RSTTIME1_MASK (0xff << 0) /* PRM_RSTST */ -#define OMAP3430_ICECRUSHER_RST (1 << 10) -#define OMAP3430_ICEPICK_RST (1 << 9) -#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST (1 << 8) -#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST (1 << 7) -#define OMAP3430_EXTERNAL_WARM_RST (1 << 6) -#define OMAP3430_SECURE_WD_RST (1 << 5) -#define OMAP3430_MPU_WD_RST (1 << 4) -#define OMAP3430_SECURITY_VIOL_RST (1 << 3) -#define OMAP3430_GLOBAL_SW_RST (1 << 1) -#define OMAP3430_GLOBAL_COLD_RST (1 << 0) +#define OMAP3430_ICECRUSHER_RST_MASK (1 << 10) +#define OMAP3430_ICEPICK_RST_MASK (1 << 9) +#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST_MASK (1 << 8) +#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST_MASK (1 << 7) +#define OMAP3430_EXTERNAL_WARM_RST_MASK (1 << 6) +#define OMAP3430_SECURE_WD_RST_MASK (1 << 5) +#define OMAP3430_MPU_WD_RST_MASK (1 << 4) +#define OMAP3430_SECURITY_VIOL_RST_MASK (1 << 3) +#define OMAP3430_GLOBAL_SW_RST_MASK (1 << 1) +#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0) /* PRM_VOLTCTRL */ -#define OMAP3430_SEL_VMODE (1 << 4) -#define OMAP3430_SEL_OFF (1 << 3) -#define OMAP3430_AUTO_OFF (1 << 2) -#define OMAP3430_AUTO_RET (1 << 1) -#define OMAP3430_AUTO_SLEEP (1 << 0) +#define OMAP3430_SEL_VMODE_MASK (1 << 4) +#define OMAP3430_SEL_OFF_MASK (1 << 3) +#define OMAP3430_AUTO_OFF_MASK (1 << 2) +#define OMAP3430_AUTO_RET_MASK (1 << 1) +#define OMAP3430_AUTO_SLEEP_MASK (1 << 0) /* PRM_SRAM_PCHARGE */ #define OMAP3430_PCHARGE_TIME_SHIFT 0 @@ -550,10 +550,10 @@ #define OMAP3430_SETUP_TIME_MASK (0xffff << 0) /* PRM_POLCTRL */ -#define OMAP3430_OFFMODE_POL (1 << 3) -#define OMAP3430_CLKOUT_POL (1 << 2) -#define OMAP3430_CLKREQ_POL (1 << 1) -#define OMAP3430_EXTVOL_POL (1 << 0) +#define OMAP3430_OFFMODE_POL_MASK (1 << 3) +#define OMAP3430_CLKOUT_POL_MASK (1 << 2) +#define OMAP3430_CLKREQ_POL_MASK (1 << 1) +#define OMAP3430_EXTVOL_POL_MASK (1 << 0) /* PRM_VOLTSETUP2 */ #define OMAP3430_OFFMODESETUPTIME_SHIFT 0 -- cgit v1.2.3-59-g8ed1b From 2fd0f75cb3413105ed10041c719346ccb710fbc6 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 18 May 2010 18:40:23 -0600 Subject: OMAP2+ PRCM: convert remaining PRCM macros to the _SHIFT/_MASK suffixes Fix all of the remaining PRCM register shift/bitmask macros that did not use the _SHIFT/_MASK suffixes to use them. This makes the use of these macros consistent. It is intended to reduce error, as code can be inspected visually by reviewers to ensure that bitshifts and bitmasks are used in the appropriate places. Signed-off-by: Paul Walmsley Cc: Kevin Hilman --- arch/arm/mach-omap2/cm.h | 5 +- arch/arm/mach-omap2/pm24xx.c | 21 +++--- arch/arm/mach-omap2/pm34xx.c | 30 ++++---- arch/arm/mach-omap2/powerdomain.c | 2 +- arch/arm/mach-omap2/prcm-common.h | 146 +++++++++++++++++++------------------- arch/arm/mach-omap2/prcm.c | 4 +- arch/arm/mach-omap2/prm.h | 18 ++--- 7 files changed, 114 insertions(+), 112 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 94728b1ee3c4..b6ab183212df 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -134,10 +134,11 @@ static inline u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) /* CM_ICLKEN_GFX */ #define OMAP_EN_GFX_SHIFT 0 -#define OMAP_EN_GFX (1 << 0) +#define OMAP_EN_GFX_MASK (1 << 0) /* CM_IDLEST_GFX */ -#define OMAP_ST_GFX (1 << 0) +#define OMAP_ST_GFX_MASK (1 << 0) + /* CM_IDLEST indicator */ #define OMAP24XX_CM_IDLEST_VAL 0 diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index b8c9e900a679..e321281ab6e1 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -70,8 +70,8 @@ static int omap2_fclks_active(void) f2 = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2); /* Ignore UART clocks. These are handled by UART core (serial.c) */ - f1 &= ~(OMAP24XX_EN_UART1 | OMAP24XX_EN_UART2); - f2 &= ~OMAP24XX_EN_UART3; + f1 &= ~(OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_UART2_MASK); + f2 &= ~OMAP24XX_EN_UART3_MASK; if (f1 | f2) return 1; @@ -181,13 +181,13 @@ static int omap2_allow_mpu_retention(void) /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */ l = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); - if (l & (OMAP2420_EN_MMC | OMAP24XX_EN_UART2 | - OMAP24XX_EN_UART1 | OMAP24XX_EN_MCSPI2 | - OMAP24XX_EN_MCSPI1 | OMAP24XX_EN_DSS1_MASK)) + if (l & (OMAP2420_EN_MMC_MASK | OMAP24XX_EN_UART2_MASK | + OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_MCSPI2_MASK | + OMAP24XX_EN_MCSPI1_MASK | OMAP24XX_EN_DSS1_MASK)) return 0; /* Check for UART3. */ l = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2); - if (l & OMAP24XX_EN_UART3) + if (l & OMAP24XX_EN_UART3_MASK) return 0; if (sti_console_enabled) return 0; @@ -215,12 +215,12 @@ static void omap2_enter_mpu_retention(void) /* Try to enter MPU retention */ prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) | - OMAP_LOGICRETSTATE, + OMAP_LOGICRETSTATE_MASK, MPU_MOD, OMAP2_PM_PWSTCTRL); } else { /* Block MPU retention */ - prm_write_mod_reg(OMAP_LOGICRETSTATE, MPU_MOD, + prm_write_mod_reg(OMAP_LOGICRETSTATE_MASK, MPU_MOD, OMAP2_PM_PWSTCTRL); only_idle = 1; } @@ -288,7 +288,8 @@ static int omap2_pm_suspend(void) u32 wken_wkup, mir1; wken_wkup = prm_read_mod_reg(WKUP_MOD, PM_WKEN); - prm_write_mod_reg(wken_wkup & ~OMAP24XX_EN_GPT1, WKUP_MOD, PM_WKEN); + wken_wkup &= ~OMAP24XX_EN_GPT1_MASK; + prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN); /* Mask GPT1 */ mir1 = omap_readl(0x480fe0a4); @@ -469,7 +470,7 @@ static void __init prcm_setup_regs(void) OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTCTRL_OFFSET); /* Enable wake-up events */ - prm_write_mod_reg(OMAP24XX_EN_GPIOS | OMAP24XX_EN_GPT1, + prm_write_mod_reg(OMAP24XX_EN_GPIOS_MASK | OMAP24XX_EN_GPT1_MASK, WKUP_MOD, PM_WKEN); } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index dd09d80ea3eb..b2c299d9f428 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -867,7 +867,7 @@ static void __init prcm_setup_regs(void) CM_AUTOIDLE); } - omap_ctrl_writel(OMAP3430_AUTOIDLE, OMAP2_CONTROL_SYSCONFIG); + omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG); /* * Set all plls to autoidle. This is needed until autoidle is @@ -897,12 +897,12 @@ static void __init prcm_setup_regs(void) OMAP3_PRM_CLKSRC_CTRL_OFFSET); /* setup wakup source */ - prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1 | - OMAP3430_EN_GPT1 | OMAP3430_EN_GPT12, + prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1_MASK | + OMAP3430_EN_GPT1_MASK | OMAP3430_EN_GPT12_MASK, WKUP_MOD, PM_WKEN); /* No need to write EN_IO, that is always enabled */ - prm_write_mod_reg(OMAP3430_EN_GPIO1 | OMAP3430_EN_GPT1 | - OMAP3430_EN_GPT12, + prm_write_mod_reg(OMAP3430_EN_GPIO1_MASK | OMAP3430_EN_GPT1_MASK | + OMAP3430_EN_GPT12_MASK, WKUP_MOD, OMAP3430_PM_MPUGRPSEL); /* For some reason IO doesn't generate wakeup event even if * it is selected to mpu wakeup goup */ @@ -914,18 +914,18 @@ static void __init prcm_setup_regs(void) OMAP3430_DSS_MOD, PM_WKEN); /* Enable wakeups in PER */ - prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 | - OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 | - OMAP3430_EN_GPIO6 | OMAP3430_EN_UART3 | - OMAP3430_EN_MCBSP2 | OMAP3430_EN_MCBSP3 | - OMAP3430_EN_MCBSP4, + prm_write_mod_reg(OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK | + OMAP3430_EN_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK | + OMAP3430_EN_GPIO6_MASK | OMAP3430_EN_UART3_MASK | + OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK | + OMAP3430_EN_MCBSP4_MASK, OMAP3430_PER_MOD, PM_WKEN); /* and allow them to wake up MPU */ - prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2_MASK | OMAP3430_EN_GPIO3 | - OMAP3430_GRPSEL_GPIO4_MASK | OMAP3430_EN_GPIO5 | - OMAP3430_GRPSEL_GPIO6_MASK | OMAP3430_EN_UART3 | - OMAP3430_EN_MCBSP2 | OMAP3430_EN_MCBSP3 | - OMAP3430_EN_MCBSP4, + prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK | + OMAP3430_GRPSEL_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK | + OMAP3430_GRPSEL_GPIO6_MASK | OMAP3430_EN_UART3_MASK | + OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK | + OMAP3430_EN_MCBSP4_MASK, OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL); /* Don't attach IVA interrupts */ diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 637fdfe7acd4..4a91d38d7b1a 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -1004,7 +1004,7 @@ int pwrdm_wait_transition(struct powerdomain *pwrdm) /* XXX Is this udelay() value meaningful? */ while ((prm_read_mod_reg(pwrdm->prcm_offs, pwrstst_reg_offs) & - OMAP_INTRANSITION) && + OMAP_INTRANSITION_MASK) && (c++ < PWRDM_TRANSITION_BAILOUT)) udelay(1); diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 90f603d434c6..ed2379f38db8 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -132,63 +132,63 @@ /* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */ #define OMAP2420_EN_MMC_SHIFT 26 -#define OMAP2420_EN_MMC (1 << 26) +#define OMAP2420_EN_MMC_MASK (1 << 26) #define OMAP24XX_EN_UART2_SHIFT 22 -#define OMAP24XX_EN_UART2 (1 << 22) +#define OMAP24XX_EN_UART2_MASK (1 << 22) #define OMAP24XX_EN_UART1_SHIFT 21 -#define OMAP24XX_EN_UART1 (1 << 21) +#define OMAP24XX_EN_UART1_MASK (1 << 21) #define OMAP24XX_EN_MCSPI2_SHIFT 18 -#define OMAP24XX_EN_MCSPI2 (1 << 18) +#define OMAP24XX_EN_MCSPI2_MASK (1 << 18) #define OMAP24XX_EN_MCSPI1_SHIFT 17 -#define OMAP24XX_EN_MCSPI1 (1 << 17) +#define OMAP24XX_EN_MCSPI1_MASK (1 << 17) #define OMAP24XX_EN_MCBSP2_SHIFT 16 -#define OMAP24XX_EN_MCBSP2 (1 << 16) +#define OMAP24XX_EN_MCBSP2_MASK (1 << 16) #define OMAP24XX_EN_MCBSP1_SHIFT 15 -#define OMAP24XX_EN_MCBSP1 (1 << 15) +#define OMAP24XX_EN_MCBSP1_MASK (1 << 15) #define OMAP24XX_EN_GPT12_SHIFT 14 -#define OMAP24XX_EN_GPT12 (1 << 14) +#define OMAP24XX_EN_GPT12_MASK (1 << 14) #define OMAP24XX_EN_GPT11_SHIFT 13 -#define OMAP24XX_EN_GPT11 (1 << 13) +#define OMAP24XX_EN_GPT11_MASK (1 << 13) #define OMAP24XX_EN_GPT10_SHIFT 12 -#define OMAP24XX_EN_GPT10 (1 << 12) +#define OMAP24XX_EN_GPT10_MASK (1 << 12) #define OMAP24XX_EN_GPT9_SHIFT 11 -#define OMAP24XX_EN_GPT9 (1 << 11) +#define OMAP24XX_EN_GPT9_MASK (1 << 11) #define OMAP24XX_EN_GPT8_SHIFT 10 -#define OMAP24XX_EN_GPT8 (1 << 10) +#define OMAP24XX_EN_GPT8_MASK (1 << 10) #define OMAP24XX_EN_GPT7_SHIFT 9 -#define OMAP24XX_EN_GPT7 (1 << 9) +#define OMAP24XX_EN_GPT7_MASK (1 << 9) #define OMAP24XX_EN_GPT6_SHIFT 8 -#define OMAP24XX_EN_GPT6 (1 << 8) +#define OMAP24XX_EN_GPT6_MASK (1 << 8) #define OMAP24XX_EN_GPT5_SHIFT 7 -#define OMAP24XX_EN_GPT5 (1 << 7) +#define OMAP24XX_EN_GPT5_MASK (1 << 7) #define OMAP24XX_EN_GPT4_SHIFT 6 -#define OMAP24XX_EN_GPT4 (1 << 6) +#define OMAP24XX_EN_GPT4_MASK (1 << 6) #define OMAP24XX_EN_GPT3_SHIFT 5 -#define OMAP24XX_EN_GPT3 (1 << 5) +#define OMAP24XX_EN_GPT3_MASK (1 << 5) #define OMAP24XX_EN_GPT2_SHIFT 4 -#define OMAP24XX_EN_GPT2 (1 << 4) +#define OMAP24XX_EN_GPT2_MASK (1 << 4) #define OMAP2420_EN_VLYNQ_SHIFT 3 -#define OMAP2420_EN_VLYNQ (1 << 3) +#define OMAP2420_EN_VLYNQ_MASK (1 << 3) /* CM_FCLKEN2_CORE, CM_ICLKEN2_CORE, PM_WKEN2_CORE shared bits */ #define OMAP2430_EN_GPIO5_SHIFT 10 -#define OMAP2430_EN_GPIO5 (1 << 10) +#define OMAP2430_EN_GPIO5_MASK (1 << 10) #define OMAP2430_EN_MCSPI3_SHIFT 9 -#define OMAP2430_EN_MCSPI3 (1 << 9) +#define OMAP2430_EN_MCSPI3_MASK (1 << 9) #define OMAP2430_EN_MMCHS2_SHIFT 8 -#define OMAP2430_EN_MMCHS2 (1 << 8) +#define OMAP2430_EN_MMCHS2_MASK (1 << 8) #define OMAP2430_EN_MMCHS1_SHIFT 7 -#define OMAP2430_EN_MMCHS1 (1 << 7) +#define OMAP2430_EN_MMCHS1_MASK (1 << 7) #define OMAP24XX_EN_UART3_SHIFT 2 -#define OMAP24XX_EN_UART3 (1 << 2) +#define OMAP24XX_EN_UART3_MASK (1 << 2) #define OMAP24XX_EN_USB_SHIFT 0 -#define OMAP24XX_EN_USB (1 << 0) +#define OMAP24XX_EN_USB_MASK (1 << 0) /* CM_ICLKEN2_CORE, PM_WKEN2_CORE shared bits */ #define OMAP2430_EN_MDM_INTC_SHIFT 11 -#define OMAP2430_EN_MDM_INTC (1 << 11) +#define OMAP2430_EN_MDM_INTC_MASK (1 << 11) #define OMAP2430_EN_USBHS_SHIFT 6 -#define OMAP2430_EN_USBHS (1 << 6) +#define OMAP2430_EN_USBHS_MASK (1 << 6) /* CM_IDLEST1_CORE, PM_WKST1_CORE shared bits */ #define OMAP2420_ST_MMC_SHIFT 26 @@ -246,9 +246,9 @@ /* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */ #define OMAP24XX_EN_GPIOS_SHIFT 2 -#define OMAP24XX_EN_GPIOS (1 << 2) +#define OMAP24XX_EN_GPIOS_MASK (1 << 2) #define OMAP24XX_EN_GPT1_SHIFT 0 -#define OMAP24XX_EN_GPT1 (1 << 0) +#define OMAP24XX_EN_GPT1_MASK (1 << 0) /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */ #define OMAP24XX_ST_GPIOS_SHIFT (1 << 2) @@ -267,47 +267,47 @@ #define OMAP3430_REV_MASK (0xff << 0) /* CM_SYSCONFIG, PRM_SYSCONFIG shared bits */ -#define OMAP3430_AUTOIDLE (1 << 0) +#define OMAP3430_AUTOIDLE_MASK (1 << 0) /* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */ -#define OMAP3430_EN_MMC2 (1 << 25) +#define OMAP3430_EN_MMC2_MASK (1 << 25) #define OMAP3430_EN_MMC2_SHIFT 25 -#define OMAP3430_EN_MMC1 (1 << 24) +#define OMAP3430_EN_MMC1_MASK (1 << 24) #define OMAP3430_EN_MMC1_SHIFT 24 -#define OMAP3430_EN_MCSPI4 (1 << 21) +#define OMAP3430_EN_MCSPI4_MASK (1 << 21) #define OMAP3430_EN_MCSPI4_SHIFT 21 -#define OMAP3430_EN_MCSPI3 (1 << 20) +#define OMAP3430_EN_MCSPI3_MASK (1 << 20) #define OMAP3430_EN_MCSPI3_SHIFT 20 -#define OMAP3430_EN_MCSPI2 (1 << 19) +#define OMAP3430_EN_MCSPI2_MASK (1 << 19) #define OMAP3430_EN_MCSPI2_SHIFT 19 -#define OMAP3430_EN_MCSPI1 (1 << 18) +#define OMAP3430_EN_MCSPI1_MASK (1 << 18) #define OMAP3430_EN_MCSPI1_SHIFT 18 -#define OMAP3430_EN_I2C3 (1 << 17) +#define OMAP3430_EN_I2C3_MASK (1 << 17) #define OMAP3430_EN_I2C3_SHIFT 17 -#define OMAP3430_EN_I2C2 (1 << 16) +#define OMAP3430_EN_I2C2_MASK (1 << 16) #define OMAP3430_EN_I2C2_SHIFT 16 -#define OMAP3430_EN_I2C1 (1 << 15) +#define OMAP3430_EN_I2C1_MASK (1 << 15) #define OMAP3430_EN_I2C1_SHIFT 15 -#define OMAP3430_EN_UART2 (1 << 14) +#define OMAP3430_EN_UART2_MASK (1 << 14) #define OMAP3430_EN_UART2_SHIFT 14 -#define OMAP3430_EN_UART1 (1 << 13) +#define OMAP3430_EN_UART1_MASK (1 << 13) #define OMAP3430_EN_UART1_SHIFT 13 -#define OMAP3430_EN_GPT11 (1 << 12) +#define OMAP3430_EN_GPT11_MASK (1 << 12) #define OMAP3430_EN_GPT11_SHIFT 12 -#define OMAP3430_EN_GPT10 (1 << 11) +#define OMAP3430_EN_GPT10_MASK (1 << 11) #define OMAP3430_EN_GPT10_SHIFT 11 -#define OMAP3430_EN_MCBSP5 (1 << 10) +#define OMAP3430_EN_MCBSP5_MASK (1 << 10) #define OMAP3430_EN_MCBSP5_SHIFT 10 -#define OMAP3430_EN_MCBSP1 (1 << 9) +#define OMAP3430_EN_MCBSP1_MASK (1 << 9) #define OMAP3430_EN_MCBSP1_SHIFT 9 -#define OMAP3430_EN_FSHOSTUSB (1 << 5) +#define OMAP3430_EN_FSHOSTUSB_MASK (1 << 5) #define OMAP3430_EN_FSHOSTUSB_SHIFT 5 -#define OMAP3430_EN_D2D (1 << 3) +#define OMAP3430_EN_D2D_MASK (1 << 3) #define OMAP3430_EN_D2D_SHIFT 3 /* CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */ -#define OMAP3430_EN_HSOTGUSB (1 << 4) -#define OMAP3430_EN_HSOTGUSB_SHIFT 4 +#define OMAP3430_EN_HSOTGUSB_MASK (1 << 4) +#define OMAP3430_EN_HSOTGUSB_SHIFT 4 /* PM_WKST1_CORE, CM_IDLEST1_CORE shared bits */ #define OMAP3430_ST_MMC2_SHIFT 25 @@ -352,21 +352,21 @@ #define OMAP3430_ST_D2D_MASK (1 << 3) /* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */ -#define OMAP3430_EN_GPIO1 (1 << 3) +#define OMAP3430_EN_GPIO1_MASK (1 << 3) #define OMAP3430_EN_GPIO1_SHIFT 3 -#define OMAP3430_EN_GPT12 (1 << 1) +#define OMAP3430_EN_GPT12_MASK (1 << 1) #define OMAP3430_EN_GPT12_SHIFT 1 -#define OMAP3430_EN_GPT1 (1 << 0) +#define OMAP3430_EN_GPT1_MASK (1 << 0) #define OMAP3430_EN_GPT1_SHIFT 0 /* CM_FCLKEN_WKUP, PM_WKEN_WKUP shared bits */ -#define OMAP3430_EN_SR2 (1 << 7) +#define OMAP3430_EN_SR2_MASK (1 << 7) #define OMAP3430_EN_SR2_SHIFT 7 -#define OMAP3430_EN_SR1 (1 << 6) +#define OMAP3430_EN_SR1_MASK (1 << 6) #define OMAP3430_EN_SR1_SHIFT 6 /* CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */ -#define OMAP3430_EN_GPT12 (1 << 1) +#define OMAP3430_EN_GPT12_MASK (1 << 1) #define OMAP3430_EN_GPT12_SHIFT 1 /* CM_IDLEST_WKUP, PM_WKST_WKUP shared bits */ @@ -386,47 +386,47 @@ * CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_GFX, * PM_WKDEP_DSS, PM_WKDEP_CAM, PM_WKDEP_PER, PM_WKDEP_NEON shared bits */ -#define OMAP3430_EN_MPU (1 << 1) +#define OMAP3430_EN_MPU_MASK (1 << 1) #define OMAP3430_EN_MPU_SHIFT 1 /* CM_FCLKEN_PER, CM_ICLKEN_PER, PM_WKEN_PER shared bits */ -#define OMAP3430_EN_GPIO6 (1 << 17) +#define OMAP3430_EN_GPIO6_MASK (1 << 17) #define OMAP3430_EN_GPIO6_SHIFT 17 -#define OMAP3430_EN_GPIO5 (1 << 16) +#define OMAP3430_EN_GPIO5_MASK (1 << 16) #define OMAP3430_EN_GPIO5_SHIFT 16 -#define OMAP3430_EN_GPIO4 (1 << 15) +#define OMAP3430_EN_GPIO4_MASK (1 << 15) #define OMAP3430_EN_GPIO4_SHIFT 15 -#define OMAP3430_EN_GPIO3 (1 << 14) +#define OMAP3430_EN_GPIO3_MASK (1 << 14) #define OMAP3430_EN_GPIO3_SHIFT 14 -#define OMAP3430_EN_GPIO2 (1 << 13) +#define OMAP3430_EN_GPIO2_MASK (1 << 13) #define OMAP3430_EN_GPIO2_SHIFT 13 -#define OMAP3430_EN_UART3 (1 << 11) +#define OMAP3430_EN_UART3_MASK (1 << 11) #define OMAP3430_EN_UART3_SHIFT 11 -#define OMAP3430_EN_GPT9 (1 << 10) +#define OMAP3430_EN_GPT9_MASK (1 << 10) #define OMAP3430_EN_GPT9_SHIFT 10 -#define OMAP3430_EN_GPT8 (1 << 9) +#define OMAP3430_EN_GPT8_MASK (1 << 9) #define OMAP3430_EN_GPT8_SHIFT 9 -#define OMAP3430_EN_GPT7 (1 << 8) +#define OMAP3430_EN_GPT7_MASK (1 << 8) #define OMAP3430_EN_GPT7_SHIFT 8 -#define OMAP3430_EN_GPT6 (1 << 7) +#define OMAP3430_EN_GPT6_MASK (1 << 7) #define OMAP3430_EN_GPT6_SHIFT 7 -#define OMAP3430_EN_GPT5 (1 << 6) +#define OMAP3430_EN_GPT5_MASK (1 << 6) #define OMAP3430_EN_GPT5_SHIFT 6 -#define OMAP3430_EN_GPT4 (1 << 5) +#define OMAP3430_EN_GPT4_MASK (1 << 5) #define OMAP3430_EN_GPT4_SHIFT 5 -#define OMAP3430_EN_GPT3 (1 << 4) +#define OMAP3430_EN_GPT3_MASK (1 << 4) #define OMAP3430_EN_GPT3_SHIFT 4 -#define OMAP3430_EN_GPT2 (1 << 3) +#define OMAP3430_EN_GPT2_MASK (1 << 3) #define OMAP3430_EN_GPT2_SHIFT 3 /* CM_FCLKEN_PER, CM_ICLKEN_PER, PM_WKEN_PER, PM_WKST_PER shared bits */ /* XXX Possible TI documentation bug: should the PM_WKST_PER EN_* bits * be ST_* bits instead? */ -#define OMAP3430_EN_MCBSP4 (1 << 2) +#define OMAP3430_EN_MCBSP4_MASK (1 << 2) #define OMAP3430_EN_MCBSP4_SHIFT 2 -#define OMAP3430_EN_MCBSP3 (1 << 1) +#define OMAP3430_EN_MCBSP3_MASK (1 << 1) #define OMAP3430_EN_MCBSP3_SHIFT 1 -#define OMAP3430_EN_MCBSP2 (1 << 0) +#define OMAP3430_EN_MCBSP2_MASK (1 << 0) #define OMAP3430_EN_MCBSP2_SHIFT 0 /* CM_IDLEST_PER, PM_WKST_PER shared bits */ diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index 07a60f1204ca..c20137497c92 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -158,10 +158,10 @@ void omap_prcm_arch_reset(char mode, const char *cmd) WARN_ON(1); if (cpu_is_omap24xx() || cpu_is_omap34xx()) - prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, + prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs, OMAP2_RM_RSTCTRL); if (cpu_is_omap44xx()) - prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, + prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs, OMAP4_RM_RSTCTRL); } diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 5fba2aa8932c..7bffb6e39d79 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -284,7 +284,7 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) #define OMAP_OFFLOADMODE_MASK (0x3 << 3) #define OMAP_ONLOADMODE_SHIFT 1 #define OMAP_ONLOADMODE_MASK (0x3 << 1) -#define OMAP_ENABLE (1 << 0) +#define OMAP_ENABLE_MASK (1 << 0) /* PRM_RSTTIME */ /* Named RM_RSTTIME_WKUP on the 24xx */ @@ -296,8 +296,8 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) /* PRM_RSTCTRL */ /* Named RM_RSTCTRL_WKUP on the 24xx */ /* 2420 calls RST_DPLL3 'RST_DPLL' */ -#define OMAP_RST_DPLL3 (1 << 2) -#define OMAP_RST_GS (1 << 1) +#define OMAP_RST_DPLL3_MASK (1 << 2) +#define OMAP_RST_GS_MASK (1 << 1) /* @@ -316,7 +316,7 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) * PM_PWSTST_DSS, PM_PWSTST_CAM, PM_PWSTST_PER, PM_PWSTST_EMU, * PM_PWSTST_NEON */ -#define OMAP_INTRANSITION (1 << 20) +#define OMAP_INTRANSITION_MASK (1 << 20) /* @@ -338,7 +338,7 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) * 3430: RM_RSTST_IVA2, RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSS, * RM_RSTST_CAM, RM_RSTST_PER, RM_RSTST_NEON */ -#define OMAP_COREDOMAINWKUP_RST (1 << 3) +#define OMAP_COREDOMAINWKUP_RST_MASK (1 << 3) /* * 24XX: RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSP @@ -347,7 +347,7 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) * * 3430: RM_RSTST_CORE, RM_RSTST_EMU */ -#define OMAP_DOMAINWKUP_RST (1 << 2) +#define OMAP_DOMAINWKUP_RST_MASK (1 << 2) /* * 24XX: RM_RSTST_MPU, RM_RSTST_WKUP, RM_RSTST_DSP @@ -357,8 +357,8 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) * * 3430: RM_RSTST_CORE, RM_RSTST_EMU */ -#define OMAP_GLOBALWARM_RST (1 << 1) -#define OMAP_GLOBALCOLD_RST (1 << 0) +#define OMAP_GLOBALWARM_RST_MASK (1 << 1) +#define OMAP_GLOBALCOLD_RST_MASK (1 << 0) /* * 24XX: PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_CORE, PM_WKDEP_DSP @@ -382,7 +382,7 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) * PM_PWSTCTRL_DSS, PM_PWSTCTRL_CAM, PM_PWSTCTRL_PER, * PM_PWSTCTRL_NEON */ -#define OMAP_LOGICRETSTATE (1 << 2) +#define OMAP_LOGICRETSTATE_MASK (1 << 2) /* * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX, -- cgit v1.2.3-59-g8ed1b From 275f675c24a16ea45cc78bc03ff73fd06be8bffb Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 18 May 2010 18:40:23 -0600 Subject: OMAP3: PM: PM_MPUGRPSEL writes should use GRPSEL macros, not EN macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Writes to the PM_*GRPSEL registers should use _GRPSEL_ macros, not _EN_ macros, to match the TRM and guard against inadvertent error. This patch should not cause any functional change. Signed-off-by: Paul Walmsley Cc: Kevin Hilman Cc: Jouni Högander --- arch/arm/mach-omap2/pm34xx.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index b2c299d9f428..2e967716cc3f 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -901,8 +901,9 @@ static void __init prcm_setup_regs(void) OMAP3430_EN_GPT1_MASK | OMAP3430_EN_GPT12_MASK, WKUP_MOD, PM_WKEN); /* No need to write EN_IO, that is always enabled */ - prm_write_mod_reg(OMAP3430_EN_GPIO1_MASK | OMAP3430_EN_GPT1_MASK | - OMAP3430_EN_GPT12_MASK, + prm_write_mod_reg(OMAP3430_GRPSEL_GPIO1_MASK | + OMAP3430_GRPSEL_GPT1_MASK | + OMAP3430_GRPSEL_GPT12_MASK, WKUP_MOD, OMAP3430_PM_MPUGRPSEL); /* For some reason IO doesn't generate wakeup event even if * it is selected to mpu wakeup goup */ @@ -921,11 +922,15 @@ static void __init prcm_setup_regs(void) OMAP3430_EN_MCBSP4_MASK, OMAP3430_PER_MOD, PM_WKEN); /* and allow them to wake up MPU */ - prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK | - OMAP3430_GRPSEL_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK | - OMAP3430_GRPSEL_GPIO6_MASK | OMAP3430_EN_UART3_MASK | - OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK | - OMAP3430_EN_MCBSP4_MASK, + prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2_MASK | + OMAP3430_GRPSEL_GPIO3_MASK | + OMAP3430_GRPSEL_GPIO4_MASK | + OMAP3430_GRPSEL_GPIO5_MASK | + OMAP3430_GRPSEL_GPIO6_MASK | + OMAP3430_GRPSEL_UART3_MASK | + OMAP3430_GRPSEL_MCBSP2_MASK | + OMAP3430_GRPSEL_MCBSP3_MASK | + OMAP3430_GRPSEL_MCBSP4_MASK, OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL); /* Don't attach IVA interrupts */ -- cgit v1.2.3-59-g8ed1b From d74b4949714741f4c58cd1801a6a92737b89a61c Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 18 May 2010 18:40:24 -0600 Subject: OMAP2+ clock: remove DEFAULT_RATE clksel_rate flag The DEFAULT_RATE clksel_rate flag is essentially useless. It was set on some of the lowest divisors, which, when switching to a much higher-rate parent, could have potentially resulted in rates that exceeded the hardware specifications for downstream clocks in the window between the clk_set_parent(), and a subsequent clk_set_rate(). It seems much safer to just remove the flag and always use the highest available divisor (resulting in the lowest possible rate) after the switch, and this patch does so. Ideally, it would be best to first attempt to switch to a divisor that matches the clock's rate with the previous parent, if at all possible. But that is a project for some other day or some other person. The parent changing code is rarely used. Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clkt_clksel.c | 57 +++++++++++++++-------- arch/arm/mach-omap2/clock2420_data.c | 46 +++++++++---------- arch/arm/mach-omap2/clock2430_data.c | 48 ++++++++++---------- arch/arm/mach-omap2/clock3xxx_data.c | 80 ++++++++++++++++----------------- arch/arm/mach-omap2/clock_common_data.c | 6 +-- arch/arm/plat-omap/include/plat/clock.h | 13 +++--- 6 files changed, 135 insertions(+), 115 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c index e50812dd03fd..9a23aebeea7e 100644 --- a/arch/arm/mach-omap2/clkt_clksel.c +++ b/arch/arm/mach-omap2/clkt_clksel.c @@ -67,38 +67,61 @@ static const struct clksel *_omap2_get_clksel_by_parent(struct clk *clk, return clks; } -/* - * Converts encoded control register address into a full address - * On error, the return value (parent_div) will be 0. +/** + * _omap2_clksel_get_src_field - find the new clksel divisor to use + * @src_clk: planned new parent struct clk * + * @clk: struct clk * that is being reparented + * @field_val: pointer to a u32 to contain the register data for the divisor + * + * Given an intended new parent struct clk * @src_clk, and the struct + * clk * @clk to the clock that is being reparented, find the + * appropriate rate divisor for the new clock (returned as the return + * value), and the corresponding register bitfield data to program to + * reach that divisor (returned in the u32 pointed to by @field_val). + * Returns 0 on error, or returns the newly-selected divisor upon + * success (in this latter case, the corresponding register bitfield + * value is passed back in the variable pointed to by @field_val) */ -static u32 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk, - u32 *field_val) +static u8 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk, + u32 *field_val) { const struct clksel *clks; - const struct clksel_rate *clkr; + const struct clksel_rate *clkr, *max_clkr; + u8 max_div = 0; clks = _omap2_get_clksel_by_parent(clk, src_clk); if (!clks) return 0; + /* + * Find the highest divisor (e.g., the one resulting in the + * lowest rate) to use as the default. This should avoid + * clock rates that are too high for the device. XXX A better + * solution here would be to try to determine if there is a + * divisor matching the original clock rate before the parent + * switch, and if it cannot be found, to fall back to the + * highest divisor. + */ for (clkr = clks->rates; clkr->div; clkr++) { - if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE) - break; /* Found the default rate for this platform */ + if (!(clkr->flags & cpu_mask)) + continue; + + if (clkr->div > max_div) { + max_div = clkr->div; + max_clkr = clkr; + } } - if (!clkr->div) { - printk(KERN_ERR "clock: Could not find default rate for " + if (max_div == 0) { + WARN(1, "clock: Could not find divisor for " "clock %s parent %s\n", clk->name, src_clk->parent->name); return 0; } - /* Should never happen. Add a clksel mask to the struct clk. */ - WARN_ON(clk->clksel_mask == 0); + *field_val = max_clkr->val; - *field_val = clkr->val; - - return clkr->div; + return max_div; } @@ -177,8 +200,6 @@ unsigned long omap2_clksel_recalc(struct clk *clk) * * Finds 'best' divider value in an array based on the source and target * rates. The divider array must be sorted with smallest divider first. - * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT, - * they are only settable as part of virtual_prcm set. * * Returns the rounded clock rate or returns 0xffffffff on error. */ @@ -380,7 +401,7 @@ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent) { u32 field_val, v, parent_div; - if (!clk->clksel) + if (!clk->clksel || !clk->clksel_mask) return -EINVAL; parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val); diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index 1381e767ce31..23bc981574f6 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -155,12 +155,12 @@ static struct clk apll54_ck = { /* func_54m_ck */ static const struct clksel_rate func_54m_apll54_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 }, }; static const struct clksel_rate func_54m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 0 }, }; @@ -201,12 +201,12 @@ static struct clk func_96m_ck = { /* func_48m_ck */ static const struct clksel_rate func_48m_apll96_rates[] = { - { .div = 2, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 2, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 }, }; static const struct clksel_rate func_48m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 0 }, }; @@ -256,22 +256,22 @@ static struct clk wdt1_osc_ck = { * flags fields, which mark them as 2420-only. */ static const struct clksel_rate common_clkout_src_core_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 } }; static const struct clksel_rate common_clkout_src_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 0 } }; static const struct clksel_rate common_clkout_src_96m_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 2, .flags = RATE_IN_24XX }, { .div = 0 } }; static const struct clksel_rate common_clkout_src_54m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 3, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -300,7 +300,7 @@ static struct clk sys_clkout_src = { }; static const struct clksel_rate common_clkout_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 2, .val = 1, .flags = RATE_IN_24XX }, { .div = 4, .val = 2, .flags = RATE_IN_24XX }, { .div = 8, .val = 3, .flags = RATE_IN_24XX }, @@ -384,7 +384,7 @@ static struct clk emul_ck = { * */ static const struct clksel_rate mpu_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 4, .val = 4, .flags = RATE_IN_242X }, { .div = 6, .val = 6, .flags = RATE_IN_242X }, @@ -420,7 +420,7 @@ static struct clk mpu_ck = { /* Control cpu */ * routed into a synchronizer and out of clocks abc. */ static const struct clksel_rate dsp_fck_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 3, .val = 3, .flags = RATE_IN_24XX }, { .div = 4, .val = 4, .flags = RATE_IN_24XX }, @@ -450,7 +450,7 @@ static struct clk dsp_fck = { /* DSP interface clock */ static const struct clksel_rate dsp_irate_ick_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 0 }, }; @@ -532,7 +532,7 @@ static struct clk iva1_mpu_int_ifck = { static const struct clksel_rate core_l3_core_rates[] = { { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 2, .val = 2, .flags = RATE_IN_242X }, - { .div = 4, .val = 4, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 4, .val = 4, .flags = RATE_IN_24XX }, { .div = 6, .val = 6, .flags = RATE_IN_24XX }, { .div = 8, .val = 8, .flags = RATE_IN_242X }, { .div = 12, .val = 12, .flags = RATE_IN_242X }, @@ -559,7 +559,7 @@ static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */ /* usb_l4_ick */ static const struct clksel_rate usb_l4_ick_core_l3_rates[] = { { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 4, .val = 4, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -591,7 +591,7 @@ static struct clk usb_l4_ick = { /* FS-USB interface clock */ * this domain. */ static const struct clksel_rate l4_core_l3_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -622,7 +622,7 @@ static struct clk l4_ck = { /* used both as an ick and fck */ */ static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = { { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 3, .val = 3, .flags = RATE_IN_24XX }, { .div = 4, .val = 4, .flags = RATE_IN_24XX }, { .div = 6, .val = 6, .flags = RATE_IN_242X }, @@ -730,7 +730,7 @@ static struct clk gfx_ick = { /* XXX Add RATE_NOT_VALIDATED */ static const struct clksel_rate dss1_fck_sys_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -744,7 +744,7 @@ static const struct clksel_rate dss1_fck_core_rates[] = { { .div = 8, .val = 8, .flags = RATE_IN_24XX }, { .div = 9, .val = 9, .flags = RATE_IN_24XX }, { .div = 12, .val = 12, .flags = RATE_IN_24XX }, - { .div = 16, .val = 16, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 16, .val = 16, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -779,12 +779,12 @@ static struct clk dss1_fck = { }; static const struct clksel_rate dss2_fck_sys_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 } }; static const struct clksel_rate dss2_fck_48m_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -825,7 +825,7 @@ static struct clk dss_54m_fck = { /* Alt clk used in power management */ * functional clock parents. */ static const struct clksel_rate gpt_alt_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 2, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -1588,7 +1588,7 @@ static struct clk vlynq_ick = { }; static const struct clksel_rate vlynq_fck_96m_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_242X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_242X }, { .div = 0 } }; @@ -1601,7 +1601,7 @@ static const struct clksel_rate vlynq_fck_core_rates[] = { { .div = 8, .val = 8, .flags = RATE_IN_242X }, { .div = 9, .val = 9, .flags = RATE_IN_242X }, { .div = 12, .val = 12, .flags = RATE_IN_242X }, - { .div = 16, .val = 16, .flags = RATE_IN_242X | DEFAULT_RATE }, + { .div = 16, .val = 16, .flags = RATE_IN_242X }, { .div = 18, .val = 18, .flags = RATE_IN_242X }, { .div = 0 } }; diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index 1aac22709dfe..2df50d97deb2 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -155,12 +155,12 @@ static struct clk apll54_ck = { /* func_54m_ck */ static const struct clksel_rate func_54m_apll54_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 }, }; static const struct clksel_rate func_54m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 0 }, }; @@ -192,12 +192,12 @@ static struct clk core_ck = { /* func_96m_ck */ static const struct clksel_rate func_96m_apll96_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 }, }; static const struct clksel_rate func_96m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_243X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_243X }, { .div = 0 }, }; @@ -222,12 +222,12 @@ static struct clk func_96m_ck = { /* func_48m_ck */ static const struct clksel_rate func_48m_apll96_rates[] = { - { .div = 2, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 2, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 }, }; static const struct clksel_rate func_48m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 0 }, }; @@ -277,22 +277,22 @@ static struct clk wdt1_osc_ck = { * flags fields, which mark them as 2420-only. */ static const struct clksel_rate common_clkout_src_core_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 } }; static const struct clksel_rate common_clkout_src_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 0 } }; static const struct clksel_rate common_clkout_src_96m_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 2, .flags = RATE_IN_24XX }, { .div = 0 } }; static const struct clksel_rate common_clkout_src_54m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 3, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -321,7 +321,7 @@ static struct clk sys_clkout_src = { }; static const struct clksel_rate common_clkout_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 2, .val = 1, .flags = RATE_IN_24XX }, { .div = 4, .val = 2, .flags = RATE_IN_24XX }, { .div = 8, .val = 3, .flags = RATE_IN_24XX }, @@ -369,7 +369,7 @@ static struct clk emul_ck = { * */ static const struct clksel_rate mpu_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 0 }, }; @@ -402,7 +402,7 @@ static struct clk mpu_ck = { /* Control cpu */ * routed into a synchronizer and out of clocks abc. */ static const struct clksel_rate dsp_fck_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 3, .val = 3, .flags = RATE_IN_24XX }, { .div = 4, .val = 4, .flags = RATE_IN_24XX }, @@ -429,7 +429,7 @@ static struct clk dsp_fck = { /* DSP interface clock */ static const struct clksel_rate dsp_irate_ick_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 3, .val = 3, .flags = RATE_IN_243X }, { .div = 0 }, @@ -481,7 +481,7 @@ static struct clk iva2_1_ick = { */ static const struct clksel_rate core_l3_core_rates[] = { { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 4, .val = 4, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 4, .val = 4, .flags = RATE_IN_24XX }, { .div = 6, .val = 6, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -505,7 +505,7 @@ static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */ /* usb_l4_ick */ static const struct clksel_rate usb_l4_ick_core_l3_rates[] = { { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 4, .val = 4, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -537,7 +537,7 @@ static struct clk usb_l4_ick = { /* FS-USB interface clock */ * this domain. */ static const struct clksel_rate l4_core_l3_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -568,7 +568,7 @@ static struct clk l4_ck = { /* used both as an ick and fck */ */ static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = { { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, { .div = 3, .val = 3, .flags = RATE_IN_24XX }, { .div = 4, .val = 4, .flags = RATE_IN_24XX }, { .div = 5, .val = 5, .flags = RATE_IN_243X }, @@ -673,7 +673,7 @@ static struct clk gfx_ick = { */ static const struct clksel_rate mdm_ick_core_rates[] = { { .div = 1, .val = 1, .flags = RATE_IN_243X }, - { .div = 4, .val = 4, .flags = RATE_IN_243X | DEFAULT_RATE }, + { .div = 4, .val = 4, .flags = RATE_IN_243X }, { .div = 6, .val = 6, .flags = RATE_IN_243X }, { .div = 9, .val = 9, .flags = RATE_IN_243X }, { .div = 0 } @@ -718,7 +718,7 @@ static struct clk mdm_osc_ck = { /* XXX Add RATE_NOT_VALIDATED */ static const struct clksel_rate dss1_fck_sys_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -732,7 +732,7 @@ static const struct clksel_rate dss1_fck_core_rates[] = { { .div = 8, .val = 8, .flags = RATE_IN_24XX }, { .div = 9, .val = 9, .flags = RATE_IN_24XX }, { .div = 12, .val = 12, .flags = RATE_IN_24XX }, - { .div = 16, .val = 16, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 16, .val = 16, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -767,12 +767,12 @@ static struct clk dss1_fck = { }; static const struct clksel_rate dss2_fck_sys_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, { .div = 0 } }; static const struct clksel_rate dss2_fck_48m_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, { .div = 0 } }; @@ -813,7 +813,7 @@ static struct clk dss_54m_fck = { /* Alt clk used in power management */ * functional clock parents. */ static const struct clksel_rate gpt_alt_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, + { .div = 1, .val = 2, .flags = RATE_IN_24XX }, { .div = 0 } }; diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 6905eb7aa67c..80a12acdf9f8 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -110,32 +110,32 @@ static struct clk virt_38_4m_ck = { }; static const struct clksel_rate osc_sys_12m_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate osc_sys_13m_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate osc_sys_16_8m_rates[] = { - { .div = 1, .val = 5, .flags = RATE_IN_3430ES2 | DEFAULT_RATE }, + { .div = 1, .val = 5, .flags = RATE_IN_3430ES2 }, { .div = 0 } }; static const struct clksel_rate osc_sys_19_2m_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 2, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate osc_sys_26m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 3, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate osc_sys_38_4m_rates[] = { - { .div = 1, .val = 4, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 4, .flags = RATE_IN_343X }, { .div = 0 } }; @@ -163,7 +163,7 @@ static struct clk osc_sys_ck = { }; static const struct clksel_rate div2_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 2, .val = 2, .flags = RATE_IN_343X }, { .div = 0 } }; @@ -213,7 +213,7 @@ static struct clk sys_clkout1 = { /* CM CLOCKS */ static const struct clksel_rate div16_dpll_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 2, .val = 2, .flags = RATE_IN_343X }, { .div = 3, .val = 3, .flags = RATE_IN_343X }, { .div = 4, .val = 4, .flags = RATE_IN_343X }, @@ -233,7 +233,7 @@ static const struct clksel_rate div16_dpll_rates[] = { }; static const struct clksel_rate div32_dpll4_rates_3630[] = { - { .div = 1, .val = 1, .flags = RATE_IN_36XX | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_36XX }, { .div = 2, .val = 2, .flags = RATE_IN_36XX }, { .div = 3, .val = 3, .flags = RATE_IN_36XX }, { .div = 4, .val = 4, .flags = RATE_IN_36XX }, @@ -450,7 +450,7 @@ static struct clk dpll3_x2_ck = { }; static const struct clksel_rate div31_dpll3_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 2, .val = 2, .flags = RATE_IN_343X }, { .div = 3, .val = 3, .flags = RATE_IN_3430ES2 }, { .div = 4, .val = 4, .flags = RATE_IN_3430ES2 }, @@ -698,7 +698,7 @@ static struct clk omap_192m_alwon_fck = { static const struct clksel_rate omap_96m_alwon_fck_rates[] = { { .div = 1, .val = 1, .flags = RATE_IN_36XX }, - { .div = 2, .val = 2, .flags = RATE_IN_36XX | DEFAULT_RATE }, + { .div = 2, .val = 2, .flags = RATE_IN_36XX }, { .div = 0 } }; @@ -708,12 +708,12 @@ static const struct clksel omap_96m_alwon_fck_clksel[] = { }; static const struct clksel_rate omap_96m_dpll_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate omap_96m_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 0 } }; @@ -799,12 +799,12 @@ static struct clk dpll4_m3x2_ck = { }; static const struct clksel_rate omap_54m_d4m3x2_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate omap_54m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 0 } }; @@ -825,12 +825,12 @@ static struct clk omap_54m_fck = { }; static const struct clksel_rate omap_48m_cm96m_rates[] = { - { .div = 2, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 2, .val = 0, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate omap_48m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 0 } }; @@ -1049,22 +1049,22 @@ static struct clk dpll5_m2_ck = { /* CM EXTERNAL CLOCK OUTPUTS */ static const struct clksel_rate clkout2_src_core_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate clkout2_src_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate clkout2_src_96m_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 2, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate clkout2_src_54m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 3, .flags = RATE_IN_343X }, { .div = 0 } }; @@ -1090,7 +1090,7 @@ static struct clk clkout2_src_ck = { }; static const struct clksel_rate sys_clkout2_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_343X }, { .div = 2, .val = 1, .flags = RATE_IN_343X }, { .div = 4, .val = 2, .flags = RATE_IN_343X }, { .div = 8, .val = 3, .flags = RATE_IN_343X }, @@ -1125,7 +1125,7 @@ static struct clk corex2_fck = { /* DPLL power domain clock controls */ static const struct clksel_rate div4_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 2, .val = 2, .flags = RATE_IN_343X }, { .div = 4, .val = 4, .flags = RATE_IN_343X }, { .div = 0 } @@ -1161,7 +1161,7 @@ static struct clk mpu_ck = { /* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */ static const struct clksel_rate arm_fck_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_343X }, { .div = 2, .val = 1, .flags = RATE_IN_343X }, { .div = 0 }, }; @@ -1333,25 +1333,25 @@ static struct clk gfx_cg2_ck = { static const struct clksel_rate sgx_core_rates[] = { { .div = 2, .val = 5, .flags = RATE_IN_36XX }, - { .div = 3, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 3, .val = 0, .flags = RATE_IN_343X }, { .div = 4, .val = 1, .flags = RATE_IN_343X }, { .div = 6, .val = 2, .flags = RATE_IN_343X }, { .div = 0 }, }; static const struct clksel_rate sgx_192m_rates[] = { - { .div = 1, .val = 4, .flags = RATE_IN_36XX | DEFAULT_RATE }, + { .div = 1, .val = 4, .flags = RATE_IN_36XX }, { .div = 0 }, }; static const struct clksel_rate sgx_corex2_rates[] = { - { .div = 3, .val = 6, .flags = RATE_IN_36XX | DEFAULT_RATE }, + { .div = 3, .val = 6, .flags = RATE_IN_36XX }, { .div = 5, .val = 7, .flags = RATE_IN_36XX }, { .div = 0 }, }; static const struct clksel_rate sgx_96m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 3, .flags = RATE_IN_343X }, { .div = 0 }, }; @@ -1576,12 +1576,12 @@ static struct clk i2c1_fck = { * MCBSP 2, 3, 4 get their 96MHz clock from per_96m_fck. */ static const struct clksel_rate common_mcbsp_96m_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_343X }, { .div = 0 } }; static const struct clksel_rate common_mcbsp_mcbsp_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 0 } }; @@ -1714,7 +1714,7 @@ static struct clk hdq_fck = { /* DPLL3-derived clock */ static const struct clksel_rate ssi_ssr_corex2_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 2, .val = 2, .flags = RATE_IN_343X }, { .div = 3, .val = 3, .flags = RATE_IN_343X }, { .div = 4, .val = 4, .flags = RATE_IN_343X }, @@ -2353,7 +2353,7 @@ static struct clk usbhost_ick = { /* WKUP */ static const struct clksel_rate usim_96m_rates[] = { - { .div = 2, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 2, .val = 3, .flags = RATE_IN_343X }, { .div = 4, .val = 4, .flags = RATE_IN_343X }, { .div = 8, .val = 5, .flags = RATE_IN_343X }, { .div = 10, .val = 6, .flags = RATE_IN_343X }, @@ -2361,7 +2361,7 @@ static const struct clksel_rate usim_96m_rates[] = { }; static const struct clksel_rate usim_120m_rates[] = { - { .div = 4, .val = 7, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 4, .val = 7, .flags = RATE_IN_343X }, { .div = 8, .val = 8, .flags = RATE_IN_343X }, { .div = 16, .val = 9, .flags = RATE_IN_343X }, { .div = 20, .val = 10, .flags = RATE_IN_343X }, @@ -2951,22 +2951,22 @@ static struct clk mcbsp4_fck = { /* More information: ARM Cortex-A8 Technical Reference Manual, sect 10.1 */ static const struct clksel_rate emu_src_sys_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_343X }, { .div = 0 }, }; static const struct clksel_rate emu_src_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 0 }, }; static const struct clksel_rate emu_src_per_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 2, .flags = RATE_IN_343X }, { .div = 0 }, }; static const struct clksel_rate emu_src_mpu_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 3, .flags = RATE_IN_343X }, { .div = 0 }, }; @@ -2995,7 +2995,7 @@ static struct clk emu_src_ck = { }; static const struct clksel_rate pclk_emu_rates[] = { - { .div = 2, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 2, .val = 2, .flags = RATE_IN_343X }, { .div = 3, .val = 3, .flags = RATE_IN_343X }, { .div = 4, .val = 4, .flags = RATE_IN_343X }, { .div = 6, .val = 6, .flags = RATE_IN_343X }, @@ -3019,7 +3019,7 @@ static struct clk pclk_fck = { }; static const struct clksel_rate pclkx2_emu_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 2, .val = 2, .flags = RATE_IN_343X }, { .div = 3, .val = 3, .flags = RATE_IN_343X }, { .div = 0 }, @@ -3069,7 +3069,7 @@ static struct clk traceclk_src_fck = { }; static const struct clksel_rate traceclk_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_343X }, { .div = 2, .val = 2, .flags = RATE_IN_343X }, { .div = 4, .val = 4, .flags = RATE_IN_343X }, { .div = 0 }, diff --git a/arch/arm/mach-omap2/clock_common_data.c b/arch/arm/mach-omap2/clock_common_data.c index f69096b88cdb..6f96dc4ef254 100644 --- a/arch/arm/mach-omap2/clock_common_data.c +++ b/arch/arm/mach-omap2/clock_common_data.c @@ -20,18 +20,18 @@ /* clksel_rate data common to 24xx/343x */ const struct clksel_rate gpt_32k_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX | RATE_IN_343X }, { .div = 0 } }; const struct clksel_rate gpt_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X }, { .div = 0 } }; const struct clksel_rate gfx_l3_rates[] = { { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX | RATE_IN_343X }, { .div = 3, .val = 3, .flags = RATE_IN_243X | RATE_IN_343X }, { .div = 4, .val = 4, .flags = RATE_IN_243X | RATE_IN_343X }, { .div = 0 } diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index 34f7fa9ad4c0..9c551d676c63 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -196,13 +196,12 @@ extern struct clk dummy_ck; #define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */ /* Clksel_rate flags */ -#define DEFAULT_RATE (1 << 0) -#define RATE_IN_242X (1 << 1) -#define RATE_IN_243X (1 << 2) -#define RATE_IN_343X (1 << 3) /* rates common to all 343X */ -#define RATE_IN_3430ES2 (1 << 4) /* 3430ES2 rates only */ -#define RATE_IN_36XX (1 << 5) -#define RATE_IN_4430 (1 << 6) +#define RATE_IN_242X (1 << 0) +#define RATE_IN_243X (1 << 1) +#define RATE_IN_343X (1 << 2) /* rates common to all 343X */ +#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */ +#define RATE_IN_36XX (1 << 4) +#define RATE_IN_4430 (1 << 5) #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) -- cgit v1.2.3-59-g8ed1b From 435699db6a3d81bfd36d25150177399a4f6048d5 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 18 May 2010 18:40:24 -0600 Subject: OMAP2+ clock: clean up clkt_clksel.c This patch cleans up arch/arm/mach-omap2/clkt_clksel.c. It: - makes several functions static that are not called outside the file; - adds documentation; - makes some code paths easier to read (hopefully), by breaking up compound statements and removing redundant checks; - converts some pr_err()s that indicate clock tree data problems into WARN()s, so they are more likely to be noticed; - and moves omap2_clk_round_rate() back into mach-omap2/clock.c, its proper home, since it is not clksel-specific. Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clkt_clksel.c | 423 ++++++++++++++++++++++---------------- arch/arm/mach-omap2/clock.c | 9 + arch/arm/mach-omap2/clock.h | 11 +- 3 files changed, 266 insertions(+), 177 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c index 9a23aebeea7e..a781cd6795a4 100644 --- a/arch/arm/mach-omap2/clkt_clksel.c +++ b/arch/arm/mach-omap2/clkt_clksel.c @@ -12,8 +12,26 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * XXX At some point these clksel clocks should be split into - * "divider" clocks and "mux" clocks to better match the hardware. + * + * clksel clocks are clocks that do not have a fixed parent, or that + * can divide their parent's rate, or possibly both at the same time, based + * on the contents of a hardware register bitfield. + * + * All of the various mux and divider settings can be encoded into + * struct clksel* data structures, and then these can be autogenerated + * from some hardware database for each new chip generation. This + * should avoid the need to write, review, and validate a lot of new + * clock code for each new chip, since it can be exported from the SoC + * design flow. This is now done on OMAP4. + * + * The fusion of mux and divider clocks is a software creation. In + * hardware reality, the multiplexer (parent selection) and the + * divider exist separately. XXX At some point these clksel clocks + * should be split into "divider" clocks and "mux" clocks to better + * match the hardware. + * + * (The name "clksel" comes from the name of the corresponding + * register field in the OMAP2/3 family of SoCs.) * * XXX Currently these clocks are only used in the OMAP2/3/4 code, but * many of the OMAP1 clocks should be convertible to use this @@ -29,14 +47,11 @@ #include #include "clock.h" -#include "cm.h" -#include "cm-regbits-24xx.h" -#include "cm-regbits-34xx.h" /* Private functions */ /** - * _omap2_get_clksel_by_parent - return clksel struct for a given clk & parent + * _get_clksel_by_parent() - return clksel struct for a given clk & parent * @clk: OMAP struct clk ptr to inspect * @src_clk: OMAP struct clk ptr of the parent clk to search for * @@ -44,23 +59,19 @@ * the element associated with the supplied parent clock address. * Returns a pointer to the struct clksel on success or NULL on error. */ -static const struct clksel *_omap2_get_clksel_by_parent(struct clk *clk, - struct clk *src_clk) +static const struct clksel *_get_clksel_by_parent(struct clk *clk, + struct clk *src_clk) { const struct clksel *clks; - if (!clk->clksel) - return NULL; - - for (clks = clk->clksel; clks->parent; clks++) { + for (clks = clk->clksel; clks->parent; clks++) if (clks->parent == src_clk) break; /* Found the requested parent */ - } if (!clks->parent) { - printk(KERN_ERR "clock: Could not find parent clock %s in " - "clksel array of clock %s\n", src_clk->name, - clk->name); + /* This indicates a data problem */ + WARN(1, "clock: Could not find parent clock %s in clksel array " + "of clock %s\n", src_clk->name, clk->name); return NULL; } @@ -68,7 +79,7 @@ static const struct clksel *_omap2_get_clksel_by_parent(struct clk *clk, } /** - * _omap2_clksel_get_src_field - find the new clksel divisor to use + * _get_div_and_fieldval() - find the new clksel divisor and field value to use * @src_clk: planned new parent struct clk * * @clk: struct clk * that is being reparented * @field_val: pointer to a u32 to contain the register data for the divisor @@ -82,14 +93,14 @@ static const struct clksel *_omap2_get_clksel_by_parent(struct clk *clk, * success (in this latter case, the corresponding register bitfield * value is passed back in the variable pointed to by @field_val) */ -static u8 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk, - u32 *field_val) +static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk, + u32 *field_val) { const struct clksel *clks; const struct clksel_rate *clkr, *max_clkr; u8 max_div = 0; - clks = _omap2_get_clksel_by_parent(clk, src_clk); + clks = _get_clksel_by_parent(clk, src_clk); if (!clks) return 0; @@ -113,9 +124,9 @@ static u8 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk, } if (max_div == 0) { - WARN(1, "clock: Could not find divisor for " - "clock %s parent %s\n", clk->name, - src_clk->parent->name); + /* This indicates an error in the clksel data */ + WARN(1, "clock: Could not find divisor for clock %s parent %s" + "\n", clk->name, src_clk->parent->name); return 0; } @@ -124,82 +135,141 @@ static u8 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk, return max_div; } +/** + * _write_clksel_reg() - program a clock's clksel register in hardware + * @clk: struct clk * to program + * @v: clksel bitfield value to program (with LSB at bit 0) + * + * Shift the clksel register bitfield value @v to its appropriate + * location in the clksel register and write it in. This function + * will ensure that the write to the clksel_reg reaches its + * destination before returning -- important since PRM and CM register + * accesses can be quite slow compared to ARM cycles -- but does not + * take into account any time the hardware might take to switch the + * clock source. + */ +static void _write_clksel_reg(struct clk *clk, u32 field_val) +{ + u32 v; -/* Public functions */ + v = __raw_readl(clk->clksel_reg); + v &= ~clk->clksel_mask; + v |= field_val << __ffs(clk->clksel_mask); + __raw_writel(v, clk->clksel_reg); + + v = __raw_readl(clk->clksel_reg); /* OCP barrier */ +} /** - * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware - * @clk: OMAP clock struct ptr to use + * _clksel_to_divisor() - turn clksel field value into integer divider + * @clk: OMAP struct clk to use + * @field_val: register field value to find * - * Given a pointer to a source-selectable struct clk, read the hardware - * register and determine what its parent is currently set to. Update the - * clk->parent field with the appropriate clk ptr. + * Given a struct clk of a rate-selectable clksel clock, and a register field + * value to search for, find the corresponding clock divisor. The register + * field value should be pre-masked and shifted down so the LSB is at bit 0 + * before calling. Returns 0 on error or returns the actual integer divisor + * upon success. */ -void omap2_init_clksel_parent(struct clk *clk) +static u32 _clksel_to_divisor(struct clk *clk, u32 field_val) { const struct clksel *clks; const struct clksel_rate *clkr; - u32 r, found = 0; - if (!clk->clksel) - return; + clks = _get_clksel_by_parent(clk, clk->parent); + if (!clks) + return 0; - r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; - r >>= __ffs(clk->clksel_mask); + for (clkr = clks->rates; clkr->div; clkr++) { + if (!(clkr->flags & cpu_mask)) + continue; - for (clks = clk->clksel; clks->parent && !found; clks++) { - for (clkr = clks->rates; clkr->div && !found; clkr++) { - if ((clkr->flags & cpu_mask) && (clkr->val == r)) { - if (clk->parent != clks->parent) { - pr_debug("clock: inited %s parent " - "to %s (was %s)\n", - clk->name, clks->parent->name, - ((clk->parent) ? - clk->parent->name : "NULL")); - clk_reparent(clk, clks->parent); - }; - found = 1; - } - } + if (clkr->val == field_val) + break; } - if (!found) - printk(KERN_ERR "clock: init parent: could not find " - "regval %0x for clock %s\n", r, clk->name); + if (!clkr->div) { + /* This indicates a data error */ + WARN(1, "clock: Could not find fieldval %d for clock %s parent " + "%s\n", field_val, clk->name, clk->parent->name); + return 0; + } - return; + return clkr->div; } -/* - * Used for clocks that are part of CLKSEL_xyz governed clocks. - * REVISIT: Maybe change to use clk->enable() functions like on omap1? +/** + * _divisor_to_clksel() - turn clksel integer divisor into a field value + * @clk: OMAP struct clk to use + * @div: integer divisor to search for + * + * Given a struct clk of a rate-selectable clksel clock, and a clock + * divisor, find the corresponding register field value. Returns the + * register field value _before_ left-shifting (i.e., LSB is at bit + * 0); or returns 0xFFFFFFFF (~0) upon error. */ -unsigned long omap2_clksel_recalc(struct clk *clk) +static u32 _divisor_to_clksel(struct clk *clk, u32 div) { - unsigned long rate; - u32 div = 0; + const struct clksel *clks; + const struct clksel_rate *clkr; - pr_debug("clock: recalc'ing clksel clk %s\n", clk->name); + /* should never happen */ + WARN_ON(div == 0); - div = omap2_clksel_get_divisor(clk); - if (div == 0) - return clk->rate; + clks = _get_clksel_by_parent(clk, clk->parent); + if (!clks) + return ~0; - rate = clk->parent->rate / div; + for (clkr = clks->rates; clkr->div; clkr++) { + if (!(clkr->flags & cpu_mask)) + continue; - pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div); + if (clkr->div == div) + break; + } - return rate; + if (!clkr->div) { + pr_err("clock: Could not find divisor %d for clock %s parent " + "%s\n", div, clk->name, clk->parent->name); + return ~0; + } + + return clkr->val; } /** - * omap2_clksel_round_rate_div - find divisor for the given clock and rate + * _read_divisor() - get current divisor applied to parent clock (from hdwr) + * @clk: OMAP struct clk to use. + * + * Read the current divisor register value for @clk that is programmed + * into the hardware, convert it into the actual divisor value, and + * return it; or return 0 on error. + */ +static u32 _read_divisor(struct clk *clk) +{ + u32 v; + + if (!clk->clksel || !clk->clksel_mask) + return 0; + + v = __raw_readl(clk->clksel_reg); + v &= clk->clksel_mask; + v >>= __ffs(clk->clksel_mask); + + return _clksel_to_divisor(clk, v); +} + +/* Public functions */ + +/** + * omap2_clksel_round_rate_div() - find divisor for the given clock and rate * @clk: OMAP struct clk to use * @target_rate: desired clock rate * @new_div: ptr to where we should store the divisor * * Finds 'best' divider value in an array based on the source and target * rates. The divider array must be sorted with smallest divider first. + * This function is also used by the DPLL3 M2 divider code. * * Returns the rounded clock rate or returns 0xffffffff on error. */ @@ -211,12 +281,15 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, const struct clksel_rate *clkr; u32 last_div = 0; + if (!clk->clksel || !clk->clksel_mask) + return ~0; + pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n", clk->name, target_rate); *new_div = 1; - clks = _omap2_get_clksel_by_parent(clk, clk->parent); + clks = _get_clksel_by_parent(clk, clk->parent); if (!clks) return ~0; @@ -252,168 +325,174 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, return clk->parent->rate / clkr->div; } -/** - * omap2_clksel_round_rate - find rounded rate for the given clock and rate - * @clk: OMAP struct clk to use - * @target_rate: desired clock rate - * - * Compatibility wrapper for OMAP clock framework - * Finds best target rate based on the source clock and possible dividers. - * rates. The divider array must be sorted with smallest divider first. - * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT, - * they are only settable as part of virtual_prcm set. - * - * Returns the rounded clock rate or returns 0xffffffff on error. +/* + * Clocktype interface functions to the OMAP clock code + * (i.e., those used in struct clk field function pointers, etc.) */ -long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate) -{ - u32 new_div; - - return omap2_clksel_round_rate_div(clk, target_rate, &new_div); -} - - -/* Given a clock and a rate apply a clock specific rounding function */ -long omap2_clk_round_rate(struct clk *clk, unsigned long rate) -{ - if (clk->round_rate) - return clk->round_rate(clk, rate); - - return clk->rate; -} /** - * omap2_clksel_to_divisor() - turn clksel field value into integer divider - * @clk: OMAP struct clk to use - * @field_val: register field value to find + * omap2_init_clksel_parent() - set a clksel clk's parent field from the hdwr + * @clk: OMAP clock struct ptr to use * - * Given a struct clk of a rate-selectable clksel clock, and a register field - * value to search for, find the corresponding clock divisor. The register - * field value should be pre-masked and shifted down so the LSB is at bit 0 - * before calling. Returns 0 on error + * Given a pointer @clk to a source-selectable struct clk, read the + * hardware register and determine what its parent is currently set + * to. Update @clk's .parent field with the appropriate clk ptr. No + * return value. */ -u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val) +void omap2_init_clksel_parent(struct clk *clk) { const struct clksel *clks; const struct clksel_rate *clkr; + u32 r, found = 0; - clks = _omap2_get_clksel_by_parent(clk, clk->parent); - if (!clks) - return 0; + if (!clk->clksel || !clk->clksel_mask) + return; - for (clkr = clks->rates; clkr->div; clkr++) { - if ((clkr->flags & cpu_mask) && (clkr->val == field_val)) - break; - } + r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; + r >>= __ffs(clk->clksel_mask); - if (!clkr->div) { - printk(KERN_ERR "clock: Could not find fieldval %d for " - "clock %s parent %s\n", field_val, clk->name, - clk->parent->name); - return 0; + for (clks = clk->clksel; clks->parent && !found; clks++) { + for (clkr = clks->rates; clkr->div && !found; clkr++) { + if (!(clkr->flags & cpu_mask)) + continue; + + if (clkr->val == r) { + if (clk->parent != clks->parent) { + pr_debug("clock: inited %s parent " + "to %s (was %s)\n", + clk->name, clks->parent->name, + ((clk->parent) ? + clk->parent->name : "NULL")); + clk_reparent(clk, clks->parent); + }; + found = 1; + } + } } - return clkr->div; + /* This indicates a data error */ + WARN(!found, "clock: %s: init parent: could not find regval %0x\n", + clk->name, r); + + return; } /** - * omap2_divisor_to_clksel() - turn clksel integer divisor into a field value - * @clk: OMAP struct clk to use - * @div: integer divisor to search for + * omap2_clksel_recalc() - function ptr to pass via struct clk .recalc field + * @clk: struct clk * * - * Given a struct clk of a rate-selectable clksel clock, and a clock divisor, - * find the corresponding register field value. The return register value is - * the value before left-shifting. Returns ~0 on error + * This function is intended to be called only by the clock framework. + * Each clksel clock should have its struct clk .recalc field set to this + * function. Returns the clock's current rate, based on its parent's rate + * and its current divisor setting in the hardware. */ -u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) +unsigned long omap2_clksel_recalc(struct clk *clk) { - const struct clksel *clks; - const struct clksel_rate *clkr; + unsigned long rate; + u32 div = 0; - /* should never happen */ - WARN_ON(div == 0); + div = _read_divisor(clk); + if (div == 0) + return clk->rate; - clks = _omap2_get_clksel_by_parent(clk, clk->parent); - if (!clks) - return ~0; + rate = clk->parent->rate / div; - for (clkr = clks->rates; clkr->div; clkr++) { - if ((clkr->flags & cpu_mask) && (clkr->div == div)) - break; - } + pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n", clk->name, + rate, div); - if (!clkr->div) { - printk(KERN_ERR "clock: Could not find divisor %d for " - "clock %s parent %s\n", div, clk->name, - clk->parent->name); - return ~0; - } - - return clkr->val; + return rate; } /** - * omap2_clksel_get_divisor - get current divider applied to parent clock. - * @clk: OMAP struct clk to use. + * omap2_clksel_round_rate() - find rounded rate for the given clock and rate + * @clk: OMAP struct clk to use + * @target_rate: desired clock rate + * + * This function is intended to be called only by the clock framework. + * Finds best target rate based on the source clock and possible dividers. + * rates. The divider array must be sorted with smallest divider first. * - * Returns the integer divisor upon success or 0 on error. + * Returns the rounded clock rate or returns 0xffffffff on error. */ -u32 omap2_clksel_get_divisor(struct clk *clk) +long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate) { - u32 v; - - if (!clk->clksel_mask) - return 0; - - v = __raw_readl(clk->clksel_reg) & clk->clksel_mask; - v >>= __ffs(clk->clksel_mask); + u32 new_div; - return omap2_clksel_to_divisor(clk, v); + return omap2_clksel_round_rate_div(clk, target_rate, &new_div); } +/** + * omap2_clksel_set_rate() - program clock rate in hardware + * @clk: struct clk * to program rate + * @rate: target rate to program + * + * This function is intended to be called only by the clock framework. + * Program @clk's rate to @rate in the hardware. The clock can be + * either enabled or disabled when this happens, although if the clock + * is enabled, some downstream devices may glitch or behave + * unpredictably when the clock rate is changed - this depends on the + * hardware. This function does not currently check the usecount of + * the clock, so if multiple drivers are using the clock, and the rate + * is changed, they will all be affected without any notification. + * Returns -EINVAL upon error, or 0 upon success. + */ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) { - u32 v, field_val, validrate, new_div = 0; + u32 field_val, validrate, new_div = 0; - if (!clk->clksel_mask) + if (!clk->clksel || !clk->clksel_mask) return -EINVAL; validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); if (validrate != rate) return -EINVAL; - field_val = omap2_divisor_to_clksel(clk, new_div); + field_val = _divisor_to_clksel(clk, new_div); if (field_val == ~0) return -EINVAL; - v = __raw_readl(clk->clksel_reg); - v &= ~clk->clksel_mask; - v |= field_val << __ffs(clk->clksel_mask); - __raw_writel(v, clk->clksel_reg); - v = __raw_readl(clk->clksel_reg); /* OCP barrier */ + _write_clksel_reg(clk, field_val); clk->rate = clk->parent->rate / new_div; + pr_debug("clock: %s: set rate to %ld\n", clk->name, clk->rate); + return 0; } +/* + * Clksel parent setting function - not passed in struct clk function + * pointer - instead, the OMAP clock code currently assumes that any + * parent-setting clock is a clksel clock, and calls + * omap2_clksel_set_parent() by default + */ + +/** + * omap2_clksel_set_parent() - change a clock's parent clock + * @clk: struct clk * of the child clock + * @new_parent: struct clk * of the new parent clock + * + * This function is intended to be called only by the clock framework. + * Change the parent clock of clock @clk to @new_parent. This is + * intended to be used while @clk is disabled. This function does not + * currently check the usecount of the clock, so if multiple drivers + * are using the clock, and the parent is changed, they will all be + * affected without any notification. Returns -EINVAL upon error, or + * 0 upon success. + */ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent) { - u32 field_val, v, parent_div; + u32 field_val = 0; + u32 parent_div; if (!clk->clksel || !clk->clksel_mask) return -EINVAL; - parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val); + parent_div = _get_div_and_fieldval(new_parent, clk, &field_val); if (!parent_div) return -EINVAL; - /* Set new source value (previous dividers if any in effect) */ - v = __raw_readl(clk->clksel_reg); - v &= ~clk->clksel_mask; - v |= field_val << __ffs(clk->clksel_mask); - __raw_writel(v, clk->clksel_reg); - v = __raw_readl(clk->clksel_reg); /* OCP barrier */ + _write_clksel_reg(clk, field_val); clk_reparent(clk, new_parent); @@ -423,7 +502,7 @@ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent) if (parent_div > 0) clk->rate /= parent_div; - pr_debug("clock: set parent of %s to %s (new rate %ld)\n", + pr_debug("clock: %s: set parent to %s (new rate %ld)\n", clk->name, clk->parent->name, clk->rate); return 0; diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index a6d0b34b7990..605f531783a8 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -334,6 +334,15 @@ oce_err1: return ret; } +/* Given a clock and a rate apply a clock specific rounding function */ +long omap2_clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (clk->round_rate) + return clk->round_rate(clk, rate); + + return clk->rate; +} + /* Set the clock rate for a clock source */ int omap2_clk_set_rate(struct clk *clk, unsigned long rate) { diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index ad8a1f7c1afc..a535c7a2a62a 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -73,19 +73,20 @@ void omap2_clk_disable_unused(struct clk *clk); #define omap2_clk_disable_unused NULL #endif -unsigned long omap2_clksel_recalc(struct clk *clk); void omap2_init_clk_clkdm(struct clk *clk); -void omap2_init_clksel_parent(struct clk *clk); -u32 omap2_clksel_get_divisor(struct clk *clk); + +/* clkt_clksel.c public functions */ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, u32 *new_div); -u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val); -u32 omap2_divisor_to_clksel(struct clk *clk, u32 div); +void omap2_init_clksel_parent(struct clk *clk); +unsigned long omap2_clksel_recalc(struct clk *clk); long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate); int omap2_clksel_set_rate(struct clk *clk, unsigned long rate); int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent); + u32 omap2_get_dpll_rate(struct clk *clk); void omap2_init_dpll_parent(struct clk *clk); + int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name); -- cgit v1.2.3-59-g8ed1b From 63405360fc8973d28e1c7c0f8e0fc77338a6ce23 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 18 May 2010 18:40:25 -0600 Subject: OMAP3 clock: rename RATE_IN_343X, RATE_IN_3430ES2 to match reality Rename the RATE_IN_343X clksel_rate.rate flag to be RATE_IN_3XXX, to reflect that these rates are valid on all OMAP3 platforms, not just 343X. Also rename the RATE_IN_OMAP3430ES2 clksel_rate.rate flag to be RATE_IN_OMAP3430ES2PLUS, to reflect that these flags are valid on all OMAP3 platforms after 3430ES2. This patch should not result in any functional changes. Signed-off-by: Paul Walmsley Cc: Richard Woodruff Cc: Rajendra Nayak Cc: Ranjith Lohithakshan --- arch/arm/mach-omap2/clock3xxx_data.c | 237 ++++++++++++++++---------------- arch/arm/mach-omap2/clock_common_data.c | 12 +- arch/arm/plat-omap/include/plat/clock.h | 3 +- 3 files changed, 127 insertions(+), 125 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 80a12acdf9f8..1c564c982270 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -110,32 +110,32 @@ static struct clk virt_38_4m_ck = { }; static const struct clksel_rate osc_sys_12m_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X }, + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate osc_sys_13m_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate osc_sys_16_8m_rates[] = { - { .div = 1, .val = 5, .flags = RATE_IN_3430ES2 }, + { .div = 1, .val = 5, .flags = RATE_IN_3430ES2PLUS }, { .div = 0 } }; static const struct clksel_rate osc_sys_19_2m_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_343X }, + { .div = 1, .val = 2, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate osc_sys_26m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X }, + { .div = 1, .val = 3, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate osc_sys_38_4m_rates[] = { - { .div = 1, .val = 4, .flags = RATE_IN_343X }, + { .div = 1, .val = 4, .flags = RATE_IN_3XXX }, { .div = 0 } }; @@ -163,8 +163,8 @@ static struct clk osc_sys_ck = { }; static const struct clksel_rate div2_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, { .div = 0 } }; @@ -213,22 +213,22 @@ static struct clk sys_clkout1 = { /* CM CLOCKS */ static const struct clksel_rate div16_dpll_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 3, .val = 3, .flags = RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, - { .div = 5, .val = 5, .flags = RATE_IN_343X }, - { .div = 6, .val = 6, .flags = RATE_IN_343X }, - { .div = 7, .val = 7, .flags = RATE_IN_343X }, - { .div = 8, .val = 8, .flags = RATE_IN_343X }, - { .div = 9, .val = 9, .flags = RATE_IN_343X }, - { .div = 10, .val = 10, .flags = RATE_IN_343X }, - { .div = 11, .val = 11, .flags = RATE_IN_343X }, - { .div = 12, .val = 12, .flags = RATE_IN_343X }, - { .div = 13, .val = 13, .flags = RATE_IN_343X }, - { .div = 14, .val = 14, .flags = RATE_IN_343X }, - { .div = 15, .val = 15, .flags = RATE_IN_343X }, - { .div = 16, .val = 16, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 3, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_3XXX }, + { .div = 5, .val = 5, .flags = RATE_IN_3XXX }, + { .div = 6, .val = 6, .flags = RATE_IN_3XXX }, + { .div = 7, .val = 7, .flags = RATE_IN_3XXX }, + { .div = 8, .val = 8, .flags = RATE_IN_3XXX }, + { .div = 9, .val = 9, .flags = RATE_IN_3XXX }, + { .div = 10, .val = 10, .flags = RATE_IN_3XXX }, + { .div = 11, .val = 11, .flags = RATE_IN_3XXX }, + { .div = 12, .val = 12, .flags = RATE_IN_3XXX }, + { .div = 13, .val = 13, .flags = RATE_IN_3XXX }, + { .div = 14, .val = 14, .flags = RATE_IN_3XXX }, + { .div = 15, .val = 15, .flags = RATE_IN_3XXX }, + { .div = 16, .val = 16, .flags = RATE_IN_3XXX }, { .div = 0 } }; @@ -450,37 +450,37 @@ static struct clk dpll3_x2_ck = { }; static const struct clksel_rate div31_dpll3_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 3, .val = 3, .flags = RATE_IN_3430ES2 }, - { .div = 4, .val = 4, .flags = RATE_IN_3430ES2 }, - { .div = 5, .val = 5, .flags = RATE_IN_3430ES2 }, - { .div = 6, .val = 6, .flags = RATE_IN_3430ES2 }, - { .div = 7, .val = 7, .flags = RATE_IN_3430ES2 }, - { .div = 8, .val = 8, .flags = RATE_IN_3430ES2 }, - { .div = 9, .val = 9, .flags = RATE_IN_3430ES2 }, - { .div = 10, .val = 10, .flags = RATE_IN_3430ES2 }, - { .div = 11, .val = 11, .flags = RATE_IN_3430ES2 }, - { .div = 12, .val = 12, .flags = RATE_IN_3430ES2 }, - { .div = 13, .val = 13, .flags = RATE_IN_3430ES2 }, - { .div = 14, .val = 14, .flags = RATE_IN_3430ES2 }, - { .div = 15, .val = 15, .flags = RATE_IN_3430ES2 }, - { .div = 16, .val = 16, .flags = RATE_IN_3430ES2 }, - { .div = 17, .val = 17, .flags = RATE_IN_3430ES2 }, - { .div = 18, .val = 18, .flags = RATE_IN_3430ES2 }, - { .div = 19, .val = 19, .flags = RATE_IN_3430ES2 }, - { .div = 20, .val = 20, .flags = RATE_IN_3430ES2 }, - { .div = 21, .val = 21, .flags = RATE_IN_3430ES2 }, - { .div = 22, .val = 22, .flags = RATE_IN_3430ES2 }, - { .div = 23, .val = 23, .flags = RATE_IN_3430ES2 }, - { .div = 24, .val = 24, .flags = RATE_IN_3430ES2 }, - { .div = 25, .val = 25, .flags = RATE_IN_3430ES2 }, - { .div = 26, .val = 26, .flags = RATE_IN_3430ES2 }, - { .div = 27, .val = 27, .flags = RATE_IN_3430ES2 }, - { .div = 28, .val = 28, .flags = RATE_IN_3430ES2 }, - { .div = 29, .val = 29, .flags = RATE_IN_3430ES2 }, - { .div = 30, .val = 30, .flags = RATE_IN_3430ES2 }, - { .div = 31, .val = 31, .flags = RATE_IN_3430ES2 }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 3, .val = 3, .flags = RATE_IN_3430ES2PLUS }, + { .div = 4, .val = 4, .flags = RATE_IN_3430ES2PLUS }, + { .div = 5, .val = 5, .flags = RATE_IN_3430ES2PLUS }, + { .div = 6, .val = 6, .flags = RATE_IN_3430ES2PLUS }, + { .div = 7, .val = 7, .flags = RATE_IN_3430ES2PLUS }, + { .div = 8, .val = 8, .flags = RATE_IN_3430ES2PLUS }, + { .div = 9, .val = 9, .flags = RATE_IN_3430ES2PLUS }, + { .div = 10, .val = 10, .flags = RATE_IN_3430ES2PLUS }, + { .div = 11, .val = 11, .flags = RATE_IN_3430ES2PLUS }, + { .div = 12, .val = 12, .flags = RATE_IN_3430ES2PLUS }, + { .div = 13, .val = 13, .flags = RATE_IN_3430ES2PLUS }, + { .div = 14, .val = 14, .flags = RATE_IN_3430ES2PLUS }, + { .div = 15, .val = 15, .flags = RATE_IN_3430ES2PLUS }, + { .div = 16, .val = 16, .flags = RATE_IN_3430ES2PLUS }, + { .div = 17, .val = 17, .flags = RATE_IN_3430ES2PLUS }, + { .div = 18, .val = 18, .flags = RATE_IN_3430ES2PLUS }, + { .div = 19, .val = 19, .flags = RATE_IN_3430ES2PLUS }, + { .div = 20, .val = 20, .flags = RATE_IN_3430ES2PLUS }, + { .div = 21, .val = 21, .flags = RATE_IN_3430ES2PLUS }, + { .div = 22, .val = 22, .flags = RATE_IN_3430ES2PLUS }, + { .div = 23, .val = 23, .flags = RATE_IN_3430ES2PLUS }, + { .div = 24, .val = 24, .flags = RATE_IN_3430ES2PLUS }, + { .div = 25, .val = 25, .flags = RATE_IN_3430ES2PLUS }, + { .div = 26, .val = 26, .flags = RATE_IN_3430ES2PLUS }, + { .div = 27, .val = 27, .flags = RATE_IN_3430ES2PLUS }, + { .div = 28, .val = 28, .flags = RATE_IN_3430ES2PLUS }, + { .div = 29, .val = 29, .flags = RATE_IN_3430ES2PLUS }, + { .div = 30, .val = 30, .flags = RATE_IN_3430ES2PLUS }, + { .div = 31, .val = 31, .flags = RATE_IN_3430ES2PLUS }, { .div = 0 }, }; @@ -708,12 +708,12 @@ static const struct clksel omap_96m_alwon_fck_clksel[] = { }; static const struct clksel_rate omap_96m_dpll_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X }, + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate omap_96m_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, { .div = 0 } }; @@ -799,12 +799,12 @@ static struct clk dpll4_m3x2_ck = { }; static const struct clksel_rate omap_54m_d4m3x2_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X }, + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate omap_54m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, { .div = 0 } }; @@ -825,12 +825,12 @@ static struct clk omap_54m_fck = { }; static const struct clksel_rate omap_48m_cm96m_rates[] = { - { .div = 2, .val = 0, .flags = RATE_IN_343X }, + { .div = 2, .val = 0, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate omap_48m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, { .div = 0 } }; @@ -1049,22 +1049,22 @@ static struct clk dpll5_m2_ck = { /* CM EXTERNAL CLOCK OUTPUTS */ static const struct clksel_rate clkout2_src_core_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X }, + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate clkout2_src_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate clkout2_src_96m_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_343X }, + { .div = 1, .val = 2, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate clkout2_src_54m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X }, + { .div = 1, .val = 3, .flags = RATE_IN_3XXX }, { .div = 0 } }; @@ -1090,11 +1090,11 @@ static struct clk clkout2_src_ck = { }; static const struct clksel_rate sys_clkout2_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X }, - { .div = 2, .val = 1, .flags = RATE_IN_343X }, - { .div = 4, .val = 2, .flags = RATE_IN_343X }, - { .div = 8, .val = 3, .flags = RATE_IN_343X }, - { .div = 16, .val = 4, .flags = RATE_IN_343X }, + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 8, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 16, .val = 4, .flags = RATE_IN_3XXX }, { .div = 0 }, }; @@ -1125,9 +1125,9 @@ static struct clk corex2_fck = { /* DPLL power domain clock controls */ static const struct clksel_rate div4_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_3XXX }, { .div = 0 } }; @@ -1161,8 +1161,8 @@ static struct clk mpu_ck = { /* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */ static const struct clksel_rate arm_fck_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X }, - { .div = 2, .val = 1, .flags = RATE_IN_343X }, + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 1, .flags = RATE_IN_3XXX }, { .div = 0 }, }; @@ -1333,9 +1333,9 @@ static struct clk gfx_cg2_ck = { static const struct clksel_rate sgx_core_rates[] = { { .div = 2, .val = 5, .flags = RATE_IN_36XX }, - { .div = 3, .val = 0, .flags = RATE_IN_343X }, - { .div = 4, .val = 1, .flags = RATE_IN_343X }, - { .div = 6, .val = 2, .flags = RATE_IN_343X }, + { .div = 3, .val = 0, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 6, .val = 2, .flags = RATE_IN_3XXX }, { .div = 0 }, }; @@ -1351,7 +1351,7 @@ static const struct clksel_rate sgx_corex2_rates[] = { }; static const struct clksel_rate sgx_96m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X }, + { .div = 1, .val = 3, .flags = RATE_IN_3XXX }, { .div = 0 }, }; @@ -1576,12 +1576,12 @@ static struct clk i2c1_fck = { * MCBSP 2, 3, 4 get their 96MHz clock from per_96m_fck. */ static const struct clksel_rate common_mcbsp_96m_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X }, + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, { .div = 0 } }; static const struct clksel_rate common_mcbsp_mcbsp_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, { .div = 0 } }; @@ -1714,12 +1714,12 @@ static struct clk hdq_fck = { /* DPLL3-derived clock */ static const struct clksel_rate ssi_ssr_corex2_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 3, .val = 3, .flags = RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, - { .div = 6, .val = 6, .flags = RATE_IN_343X }, - { .div = 8, .val = 8, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 3, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_3XXX }, + { .div = 6, .val = 6, .flags = RATE_IN_3XXX }, + { .div = 8, .val = 8, .flags = RATE_IN_3XXX }, { .div = 0 } }; @@ -2353,18 +2353,18 @@ static struct clk usbhost_ick = { /* WKUP */ static const struct clksel_rate usim_96m_rates[] = { - { .div = 2, .val = 3, .flags = RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, - { .div = 8, .val = 5, .flags = RATE_IN_343X }, - { .div = 10, .val = 6, .flags = RATE_IN_343X }, + { .div = 2, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_3XXX }, + { .div = 8, .val = 5, .flags = RATE_IN_3XXX }, + { .div = 10, .val = 6, .flags = RATE_IN_3XXX }, { .div = 0 }, }; static const struct clksel_rate usim_120m_rates[] = { - { .div = 4, .val = 7, .flags = RATE_IN_343X }, - { .div = 8, .val = 8, .flags = RATE_IN_343X }, - { .div = 16, .val = 9, .flags = RATE_IN_343X }, - { .div = 20, .val = 10, .flags = RATE_IN_343X }, + { .div = 4, .val = 7, .flags = RATE_IN_3XXX }, + { .div = 8, .val = 8, .flags = RATE_IN_3XXX }, + { .div = 16, .val = 9, .flags = RATE_IN_3XXX }, + { .div = 20, .val = 10, .flags = RATE_IN_3XXX }, { .div = 0 }, }; @@ -2951,22 +2951,22 @@ static struct clk mcbsp4_fck = { /* More information: ARM Cortex-A8 Technical Reference Manual, sect 10.1 */ static const struct clksel_rate emu_src_sys_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X }, + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, { .div = 0 }, }; static const struct clksel_rate emu_src_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, { .div = 0 }, }; static const struct clksel_rate emu_src_per_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_343X }, + { .div = 1, .val = 2, .flags = RATE_IN_3XXX }, { .div = 0 }, }; static const struct clksel_rate emu_src_mpu_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X }, + { .div = 1, .val = 3, .flags = RATE_IN_3XXX }, { .div = 0 }, }; @@ -2995,10 +2995,10 @@ static struct clk emu_src_ck = { }; static const struct clksel_rate pclk_emu_rates[] = { - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 3, .val = 3, .flags = RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, - { .div = 6, .val = 6, .flags = RATE_IN_343X }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 3, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_3XXX }, + { .div = 6, .val = 6, .flags = RATE_IN_3XXX }, { .div = 0 }, }; @@ -3019,9 +3019,9 @@ static struct clk pclk_fck = { }; static const struct clksel_rate pclkx2_emu_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 3, .val = 3, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 3, .val = 3, .flags = RATE_IN_3XXX }, { .div = 0 }, }; @@ -3069,9 +3069,9 @@ static struct clk traceclk_src_fck = { }; static const struct clksel_rate traceclk_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_3XXX }, { .div = 0 }, }; @@ -3488,14 +3488,8 @@ int __init omap3xxx_clk_init(void) struct omap_clk *c; u32 cpu_clkflg = CK_3XXX; - if (cpu_is_omap3517()) { - cpu_mask = RATE_IN_343X | RATE_IN_3430ES2; - cpu_clkflg |= CK_3517; - } else if (cpu_is_omap3505()) { - cpu_mask = RATE_IN_343X | RATE_IN_3430ES2; - cpu_clkflg |= CK_3505; - } else if (cpu_is_omap34xx()) { - cpu_mask = RATE_IN_343X; + if (cpu_is_omap34xx()) { + cpu_mask = RATE_IN_3XXX; cpu_clkflg |= CK_343X; /* @@ -3506,10 +3500,17 @@ int __init omap3xxx_clk_init(void) /* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */ cpu_clkflg |= CK_3430ES1; } else { - cpu_mask |= RATE_IN_3430ES2; + cpu_mask |= RATE_IN_3430ES2PLUS; cpu_clkflg |= CK_3430ES2; } + } else if (cpu_is_omap3517()) { + cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS; + cpu_clkflg |= CK_3517; + } else if (cpu_is_omap3505()) { + cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS; + cpu_clkflg |= CK_3505; } + if (omap3_has_192mhz_clk()) omap_96m_alwon_fck = omap_96m_alwon_fck_3630; diff --git a/arch/arm/mach-omap2/clock_common_data.c b/arch/arm/mach-omap2/clock_common_data.c index 6f96dc4ef254..1cf8131205fa 100644 --- a/arch/arm/mach-omap2/clock_common_data.c +++ b/arch/arm/mach-omap2/clock_common_data.c @@ -20,20 +20,20 @@ /* clksel_rate data common to 24xx/343x */ const struct clksel_rate gpt_32k_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | RATE_IN_343X }, + { .div = 1, .val = 0, .flags = RATE_IN_24XX | RATE_IN_3XXX }, { .div = 0 } }; const struct clksel_rate gpt_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_3XXX }, { .div = 0 } }; const struct clksel_rate gfx_l3_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX | RATE_IN_343X }, - { .div = 3, .val = 3, .flags = RATE_IN_243X | RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_243X | RATE_IN_343X }, + { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX | RATE_IN_3XXX }, + { .div = 3, .val = 3, .flags = RATE_IN_243X | RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_243X | RATE_IN_3XXX }, { .div = 0 } }; diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index 9c551d676c63..dfc472ca0cc4 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -198,12 +198,13 @@ extern struct clk dummy_ck; /* Clksel_rate flags */ #define RATE_IN_242X (1 << 0) #define RATE_IN_243X (1 << 1) -#define RATE_IN_343X (1 << 2) /* rates common to all 343X */ +#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */ #define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */ #define RATE_IN_36XX (1 << 4) #define RATE_IN_4430 (1 << 5) #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) +#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX) #endif -- cgit v1.2.3-59-g8ed1b From 2a9f5a4d455aa88a03dac1dca8f686e3c21fc1b2 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 18 May 2010 18:40:26 -0600 Subject: OMAP3 clock: remove unnecessary duplicate of dpll4_m2_ck, added for 36xx Commit 678bc9a2eabb7f444ef8ad1cfc5ef394e2bd8bf2 split dpll4_m2_ck, creating a 34xx and a 36xx variant, to handle the additional 16 divider steps provided on the 36xx. This in turn required dynamic rewriting of the clock tree during initialization, which is undesirable. All this seems to be unnecessary, though, since the additional 16 divider steps can simply be marked with RATE_IN_36XX. This patch does so and re-merges the affected structures. Signed-off-by: Paul Walmsley Cc: Vishwanath Sripathy --- arch/arm/mach-omap2/clock3xxx_data.c | 163 ++++++++--------------------------- 1 file changed, 36 insertions(+), 127 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 1c564c982270..5ab44b055282 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -232,23 +232,23 @@ static const struct clksel_rate div16_dpll_rates[] = { { .div = 0 } }; -static const struct clksel_rate div32_dpll4_rates_3630[] = { - { .div = 1, .val = 1, .flags = RATE_IN_36XX }, - { .div = 2, .val = 2, .flags = RATE_IN_36XX }, - { .div = 3, .val = 3, .flags = RATE_IN_36XX }, - { .div = 4, .val = 4, .flags = RATE_IN_36XX }, - { .div = 5, .val = 5, .flags = RATE_IN_36XX }, - { .div = 6, .val = 6, .flags = RATE_IN_36XX }, - { .div = 7, .val = 7, .flags = RATE_IN_36XX }, - { .div = 8, .val = 8, .flags = RATE_IN_36XX }, - { .div = 9, .val = 9, .flags = RATE_IN_36XX }, - { .div = 10, .val = 10, .flags = RATE_IN_36XX }, - { .div = 11, .val = 11, .flags = RATE_IN_36XX }, - { .div = 12, .val = 12, .flags = RATE_IN_36XX }, - { .div = 13, .val = 13, .flags = RATE_IN_36XX }, - { .div = 14, .val = 14, .flags = RATE_IN_36XX }, - { .div = 15, .val = 15, .flags = RATE_IN_36XX }, - { .div = 16, .val = 16, .flags = RATE_IN_36XX }, +static const struct clksel_rate dpll4_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 3, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_3XXX }, + { .div = 5, .val = 5, .flags = RATE_IN_3XXX }, + { .div = 6, .val = 6, .flags = RATE_IN_3XXX }, + { .div = 7, .val = 7, .flags = RATE_IN_3XXX }, + { .div = 8, .val = 8, .flags = RATE_IN_3XXX }, + { .div = 9, .val = 9, .flags = RATE_IN_3XXX }, + { .div = 10, .val = 10, .flags = RATE_IN_3XXX }, + { .div = 11, .val = 11, .flags = RATE_IN_3XXX }, + { .div = 12, .val = 12, .flags = RATE_IN_3XXX }, + { .div = 13, .val = 13, .flags = RATE_IN_3XXX }, + { .div = 14, .val = 14, .flags = RATE_IN_3XXX }, + { .div = 15, .val = 15, .flags = RATE_IN_3XXX }, + { .div = 16, .val = 16, .flags = RATE_IN_3XXX }, { .div = 17, .val = 17, .flags = RATE_IN_36XX }, { .div = 18, .val = 18, .flags = RATE_IN_36XX }, { .div = 19, .val = 19, .flags = RATE_IN_36XX }, @@ -562,6 +562,7 @@ static struct clk emu_core_alwon_ck = { /* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */ /* Type: DPLL */ static struct dpll_data dpll4_dd; + static struct dpll_data dpll4_dd_34xx __initdata = { .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK, @@ -632,39 +633,20 @@ static struct clk dpll4_x2_ck = { .recalc = &omap3_clkoutx2_recalc, }; -static const struct clksel div16_dpll4_clksel[] = { - { .parent = &dpll4_ck, .rates = div16_dpll_rates }, - { .parent = NULL } -}; - -static const struct clksel div32_dpll4_clksel[] = { - { .parent = &dpll4_ck, .rates = div32_dpll4_rates_3630 }, +static const struct clksel dpll4_clksel[] = { + { .parent = &dpll4_ck, .rates = dpll4_rates }, { .parent = NULL } }; /* This virtual clock is the source for dpll4_m2x2_ck */ -static struct clk dpll4_m2_ck; - -static struct clk dpll4_m2_ck_34xx __initdata = { - .name = "dpll4_m2_ck", - .ops = &clkops_null, - .parent = &dpll4_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3), - .clksel_mask = OMAP3430_DIV_96M_MASK, - .clksel = div16_dpll4_clksel, - .clkdm_name = "dpll4_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk dpll4_m2_ck_3630 __initdata = { +static struct clk dpll4_m2_ck = { .name = "dpll4_m2_ck", .ops = &clkops_null, .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3), .clksel_mask = OMAP3630_DIV_96M_MASK, - .clksel = div32_dpll4_clksel, + .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -760,28 +742,14 @@ static struct clk omap_96m_fck = { }; /* This virtual clock is the source for dpll4_m3x2_ck */ -static struct clk dpll4_m3_ck; - -static struct clk dpll4_m3_ck_34xx __initdata = { +static struct clk dpll4_m3_ck = { .name = "dpll4_m3_ck", .ops = &clkops_null, .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), .clksel_mask = OMAP3430_CLKSEL_TV_MASK, - .clksel = div16_dpll4_clksel, - .clkdm_name = "dpll4_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk dpll4_m3_ck_3630 __initdata = { - .name = "dpll4_m3_ck", - .ops = &clkops_null, - .parent = &dpll4_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), - .clksel_mask = OMAP3630_CLKSEL_TV_MASK, - .clksel = div32_dpll4_clksel, + .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -858,31 +826,15 @@ static struct clk omap_12m_fck = { .recalc = &omap_fixed_divisor_recalc, }; -/* This virstual clock is the source for dpll4_m4x2_ck */ -static struct clk dpll4_m4_ck; - -static struct clk dpll4_m4_ck_34xx __initdata = { +/* This virtual clock is the source for dpll4_m4x2_ck */ +static struct clk dpll4_m4_ck = { .name = "dpll4_m4_ck", .ops = &clkops_null, .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), .clksel_mask = OMAP3430_CLKSEL_DSS1_MASK, - .clksel = div16_dpll4_clksel, - .clkdm_name = "dpll4_clkdm", - .recalc = &omap2_clksel_recalc, - .set_rate = &omap2_clksel_set_rate, - .round_rate = &omap2_clksel_round_rate, -}; - -static struct clk dpll4_m4_ck_3630 __initdata = { - .name = "dpll4_m4_ck", - .ops = &clkops_null, - .parent = &dpll4_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), - .clksel_mask = OMAP3630_CLKSEL_DSS1_MASK, - .clksel = div32_dpll4_clksel, + .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .recalc = &omap2_clksel_recalc, .set_rate = &omap2_clksel_set_rate, @@ -902,30 +854,14 @@ static struct clk dpll4_m4x2_ck = { }; /* This virtual clock is the source for dpll4_m5x2_ck */ -static struct clk dpll4_m5_ck; - -static struct clk dpll4_m5_ck_34xx __initdata = { +static struct clk dpll4_m5_ck = { .name = "dpll4_m5_ck", .ops = &clkops_null, .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL), .clksel_mask = OMAP3430_CLKSEL_CAM_MASK, - .clksel = div16_dpll4_clksel, - .clkdm_name = "dpll4_clkdm", - .set_rate = &omap2_clksel_set_rate, - .round_rate = &omap2_clksel_round_rate, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk dpll4_m5_ck_3630 __initdata = { - .name = "dpll4_m5_ck", - .ops = &clkops_null, - .parent = &dpll4_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL), - .clksel_mask = OMAP3630_CLKSEL_CAM_MASK, - .clksel = div32_dpll4_clksel, + .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .set_rate = &omap2_clksel_set_rate, .round_rate = &omap2_clksel_round_rate, @@ -945,28 +881,14 @@ static struct clk dpll4_m5x2_ck = { }; /* This virtual clock is the source for dpll4_m6x2_ck */ -static struct clk dpll4_m6_ck; - -static struct clk dpll4_m6_ck_34xx __initdata = { +static struct clk dpll4_m6_ck = { .name = "dpll4_m6_ck", .ops = &clkops_null, .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), .clksel_mask = OMAP3430_DIV_DPLL4_MASK, - .clksel = div16_dpll4_clksel, - .clkdm_name = "dpll4_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk dpll4_m6_ck_3630 __initdata = { - .name = "dpll4_m6_ck", - .ops = &clkops_null, - .parent = &dpll4_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3630_DIV_DPLL4_MASK, - .clksel = div32_dpll4_clksel, + .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -3521,14 +3443,7 @@ int __init omap3xxx_clk_init(void) /* * XXX This type of dynamic rewriting of the clock tree is * deprecated and should be revised soon. - */ - dpll4_m2_ck = dpll4_m2_ck_3630; - dpll4_m3_ck = dpll4_m3_ck_3630; - dpll4_m4_ck = dpll4_m4_ck_3630; - dpll4_m5_ck = dpll4_m5_ck_3630; - dpll4_m6_ck = dpll4_m6_ck_3630; - - /* + * * For 3630: override clkops_omap2_dflt_wait for the * clocks affected from PWRDN reset Limitation */ @@ -3544,18 +3459,12 @@ int __init omap3xxx_clk_init(void) &clkops_omap36xx_pwrdn_with_hsdiv_wait_restore; dpll4_m6x2_ck.ops = &clkops_omap36xx_pwrdn_with_hsdiv_wait_restore; - } else { - /* - * XXX This type of dynamic rewriting of the clock tree is - * deprecated and should be revised soon. - */ - dpll4_m2_ck = dpll4_m2_ck_34xx; - dpll4_m3_ck = dpll4_m3_ck_34xx; - dpll4_m4_ck = dpll4_m4_ck_34xx; - dpll4_m5_ck = dpll4_m5_ck_34xx; - dpll4_m6_ck = dpll4_m6_ck_34xx; } + /* + * XXX This type of dynamic rewriting of the clock tree is + * deprecated and should be revised soon. + */ if (cpu_is_omap3630()) dpll4_dd = dpll4_dd_3630; else -- cgit v1.2.3-59-g8ed1b From 3587aeb067a71b26aa0349daf061572a17e6dcba Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 18 May 2010 18:40:26 -0600 Subject: OMAP clock: resolve old checkpatch and CodingStyle issues with plat-omap/clock.c Clean up comment style, remove unnecessary includes, and resolve some checkpatch warnings in plat-omap/clock.c. Signed-off-by: Paul Walmsley --- arch/arm/plat-omap/clock.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 5261a0923691..c9cd98a97abb 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -12,14 +12,12 @@ */ #include #include -#include #include #include #include #include #include #include -#include #include #include #include @@ -32,9 +30,9 @@ static DEFINE_SPINLOCK(clockfw_lock); static struct clk_functions *arch_clock; -/*------------------------------------------------------------------------- +/* * Standard clock functions defined in include/linux/clk.h - *-------------------------------------------------------------------------*/ + */ int clk_enable(struct clk *clk) { @@ -92,9 +90,9 @@ unsigned long clk_get_rate(struct clk *clk) } EXPORT_SYMBOL(clk_get_rate); -/*------------------------------------------------------------------------- +/* * Optional clock functions defined in include/linux/clk.h - *-------------------------------------------------------------------------*/ + */ long clk_round_rate(struct clk *clk, unsigned long rate) { @@ -140,9 +138,11 @@ int clk_set_parent(struct clk *clk, struct clk *parent) unsigned long flags; int ret = -EINVAL; - if (cpu_is_omap44xx()) - /* OMAP4 clk framework not supported yet */ + if (cpu_is_omap44xx()) { + WARN(1, "clock: %s: not supported yet on OMAP4\n", __func__); return 0; + } + if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent)) return ret; @@ -169,9 +169,9 @@ struct clk *clk_get_parent(struct clk *clk) } EXPORT_SYMBOL(clk_get_parent); -/*------------------------------------------------------------------------- +/* * OMAP specific clock functions shared between omap1 and omap2 - *-------------------------------------------------------------------------*/ + */ int __initdata mpurate; @@ -222,7 +222,7 @@ void clk_reparent(struct clk *child, struct clk *parent) } /* Propagate rate to children */ -void propagate_rate(struct clk * tclk) +void propagate_rate(struct clk *tclk) { struct clk *clkp; @@ -389,7 +389,9 @@ void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) } #endif -/*-------------------------------------------------------------------------*/ +/* + * + */ #ifdef CONFIG_OMAP_RESET_CLOCKS /* @@ -404,7 +406,7 @@ static int __init clk_disable_unused(void) if (ck->ops == &clkops_null) continue; - if (ck->usecount > 0 || ck->enable_reg == 0) + if (ck->usecount > 0 || !ck->enable_reg) continue; spin_lock_irqsave(&clockfw_lock, flags); -- cgit v1.2.3-59-g8ed1b From 53934aa74d49daa7c31c38028fd05c99475489d6 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:08 -0600 Subject: OMAP4: hwmod: Replace module & device offsets by absolute clkctrl address Accessing the clkctrl register using offset of module & device is hard to do in OMAP4 due to the way the CM1, CM2, PRM and PRCM_MPU are located in the address space. There is no common base address anymore for all the CM registers. The easiest way to handle that on OMAP4 is to provide the absolute address of the XXX_CLKCTRL register per hwmod. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley Cc: Rajendra Nayak --- arch/arm/plat-omap/include/plat/omap_hwmod.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 36d6ea56ab51..4965bbe8efb7 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -327,14 +327,12 @@ struct omap_hwmod_omap2_prcm { /** * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data - * @module_offs: PRCM submodule offset from the start of the PRM/CM1/CM2 - * @device_offs: device register offset from @module_offs + * @clkctrl_reg: PRCM address of the clock control register * @submodule_wkdep_bit: bit shift of the WKDEP range */ struct omap_hwmod_omap4_prcm { - u32 module_offs; - u16 device_offs; - u8 submodule_wkdep_bit; + void __iomem *clkctrl_reg; + u8 submodule_wkdep_bit; }; -- cgit v1.2.3-59-g8ed1b From d9e6625c70ff007ae246c9d62f8cdec8d08b2457 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:08 -0600 Subject: OMAP: CM: Move MAX_MODULE_READY_TIME to cm.h The maximum timeout to wait for the PRCM to request that a module exit idle or reach functionnal state is common to OMAP2/3/4 SoCs, so, move it to the chip family-common cm.h include file. Reduce the timeout from 20 ms to 2 ms. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/cm.c | 3 --- arch/arm/mach-omap2/cm.h | 9 +++++++++ arch/arm/mach-omap2/cm4xxx.c | 18 +----------------- 3 files changed, 10 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/cm.c b/arch/arm/mach-omap2/cm.c index 58e4a1c557d8..2d83565d2be2 100644 --- a/arch/arm/mach-omap2/cm.c +++ b/arch/arm/mach-omap2/cm.c @@ -27,9 +27,6 @@ #include "cm-regbits-24xx.h" #include "cm-regbits-34xx.h" -/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */ -#define MAX_MODULE_READY_TIME 20000 - static const u8 cm_idlest_offs[] = { CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3 }; diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index b6ab183212df..bbc69df3bf3d 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -144,4 +144,13 @@ static inline u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) #define OMAP24XX_CM_IDLEST_VAL 0 #define OMAP34XX_CM_IDLEST_VAL 1 +/* + * MAX_MODULE_READY_TIME: max duration in microseconds to wait for the + * PRCM to request that a module exit the inactive state in the case of + * OMAP2 & 3. + * In the case of OMAP4 this is the max duration in microseconds for the + * module to reach the functionnal state from an inactive state. + */ +#define MAX_MODULE_READY_TIME 2000 + #endif diff --git a/arch/arm/mach-omap2/cm4xxx.c b/arch/arm/mach-omap2/cm4xxx.c index 4af76bb1003a..af32a457a46b 100644 --- a/arch/arm/mach-omap2/cm4xxx.c +++ b/arch/arm/mach-omap2/cm4xxx.c @@ -22,23 +22,7 @@ #include #include "cm.h" - -/* XXX move this to cm.h */ -/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */ -#define MAX_MODULE_READY_TIME 20000 - -/* - * OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK: isolates the IDLEST field in the - * CM_CLKCTRL register. - */ -#define OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK (0x2 << 16) - -/* - * OMAP4 prcm_mod u32 fields contain packed data: the CM ID in bit 16 and - * the PRCM module offset address (from the CM module base) in bits 15-0. - */ -#define OMAP4_PRCM_MOD_CM_ID_SHIFT 16 -#define OMAP4_PRCM_MOD_OFFS_MASK 0xffff +#include "cm-regbits-44xx.h" /** * omap4_cm_wait_idlest_ready - wait for a module to leave idle or standby -- cgit v1.2.3-59-g8ed1b From 9a23dfe12806920a8dfadec5ea5b83e5ca5378c9 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:08 -0600 Subject: OMAP4: hwmod & CM: Implement the omap4_cm_wait_module_ready function The return of the omap4_cm_wait_module_ready function is checked in order to avoid accessing the sysconfig register if the module is not in the correct state. In that case the _setup will exit without trying to reset using sysconfig. For the moment a warning is printed. A proper management of fclk and module reset will have to be done in order to init correctly the problematic IPs listed below. <4>omap_hwmod: ivahd: cannot be enabled (3) <4>omap_hwmod: iss: cannot be enabled (3) <4>omap_hwmod: tesla: cannot be enabled (3) <4>omap_hwmod: sdma: cannot be enabled (3) <4>omap_hwmod: sl2: cannot be enabled (3) <4>omap_hwmod: sad2d: cannot be enabled (3) <4>omap_hwmod: ducati: cannot be enabled (3) Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/cm.h | 2 +- arch/arm/mach-omap2/cm4xxx.c | 36 +++++++++++++++++++++++++++++------- arch/arm/mach-omap2/omap_hwmod.c | 33 ++++++++++++++++++++------------- 3 files changed, 50 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index bbc69df3bf3d..a02ca30423dc 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -112,7 +112,7 @@ extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); -extern int omap4_cm_wait_module_ready(u32 prcm_mod, u8 prcm_dev_offs); +extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg); static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) { diff --git a/arch/arm/mach-omap2/cm4xxx.c b/arch/arm/mach-omap2/cm4xxx.c index af32a457a46b..b101091e95d6 100644 --- a/arch/arm/mach-omap2/cm4xxx.c +++ b/arch/arm/mach-omap2/cm4xxx.c @@ -21,19 +21,41 @@ #include +#include + #include "cm.h" #include "cm-regbits-44xx.h" /** - * omap4_cm_wait_idlest_ready - wait for a module to leave idle or standby - * @prcm_mod: PRCM module offset (XXX example) - * @prcm_dev_offs: PRCM device offset (e.g. MCASP XXX example) + * omap4_cm_wait_module_ready - wait for a module to be in 'func' state + * @clkctrl_reg: CLKCTRL module address + * + * Wait for the module IDLEST to be functional. If the idle state is in any + * the non functional state (trans, idle or disabled), module and thus the + * sysconfig cannot be accessed and will probably lead to an "imprecise + * external abort" + * + * Module idle state: + * 0x0 func: Module is fully functional, including OCP + * 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep + * abortion + * 0x2 idle: Module is in Idle mode (only OCP part). It is functional if + * using separate functional clock + * 0x3 disabled: Module is disabled and cannot be accessed * - * XXX document + * TODO: Need to handle module accessible in idle state */ -int omap4_cm_wait_idlest_ready(u32 prcm_mod, u8 prcm_dev_offs) +int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg) { - /* FIXME: Add clock manager related code */ - return 0; + int i = 0; + + if (!clkctrl_reg) + return 0; + + omap_test_timeout(((__raw_readl(clkctrl_reg) & + OMAP4430_IDLEST_MASK) == 0), + MAX_MODULE_READY_TIME, i); + + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; } diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index e436dcb19795..4a134c4d2271 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -819,11 +819,8 @@ static int _wait_target_ready(struct omap_hwmod *oh) ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs, oh->prcm.omap2.idlest_reg_id, oh->prcm.omap2.idlest_idle_bit); -#if 0 } else if (cpu_is_omap44xx()) { - ret = omap4_cm_wait_module_ready(oh->prcm.omap4.module_offs, - oh->prcm.omap4.device_offs); -#endif + ret = omap4_cm_wait_module_ready(oh->prcm.omap4.clkctrl_reg); } else { BUG(); }; @@ -912,16 +909,21 @@ static int _enable(struct omap_hwmod *oh) _add_initiator_dep(oh, mpu_oh); _enable_clocks(oh); - if (oh->class->sysc) { - if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) - _update_sysc_cache(oh); - _sysc_enable(oh); - } - r = _wait_target_ready(oh); - if (!r) + if (!r) { oh->_state = _HWMOD_STATE_ENABLED; + /* Access the sysconfig only if the target is ready */ + if (oh->class->sysc) { + if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) + _update_sysc_cache(oh); + _sysc_enable(oh); + } + } else { + pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", + oh->name, r); + } + return r; } @@ -999,7 +1001,7 @@ static int _shutdown(struct omap_hwmod *oh) static int _setup(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - int i; + int i, r; if (!oh) return -EINVAL; @@ -1023,7 +1025,12 @@ static int _setup(struct omap_hwmod *oh) oh->_state = _HWMOD_STATE_INITIALIZED; - _enable(oh); + r = _enable(oh); + if (r) { + pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n", + oh->name, oh->_state); + return 0; + } if (!(oh->flags & HWMOD_INIT_NO_RESET)) { /* -- cgit v1.2.3-59-g8ed1b From 33f7ec81fb3e525eec0575f33dbab02240eda6d4 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:09 -0600 Subject: OMAP4: hwmod: Replace OCPIF_HAS_IDLEST by HWMOD_NO_IDLEST Some initiator modules in OMAP2 & 3 does not have IDLEST bit, in that case we cannot detect the module readiness by polling that bit and must exist the function immediately assuming that the module is ready. The previous flag was affected to the OCP interface. While it is technically true that the idlest is related to the L4 slave interface of the module, the PRCM status belong to the module. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 2 +- arch/arm/plat-omap/include/plat/omap_hwmod.h | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 4a134c4d2271..6459d07785b7 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -808,7 +808,7 @@ static int _wait_target_ready(struct omap_hwmod *oh) os = *oh->slaves + oh->_mpu_port_index; - if (!(os->flags & OCPIF_HAS_IDLEST)) + if (oh->flags & HWMOD_NO_IDLEST) return 0; /* XXX check module SIDLEMODE */ diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 4965bbe8efb7..0eccc09ac4a9 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -176,9 +176,8 @@ struct omap_hwmod_addr_space { #define OCP_USER_SDMA (1 << 1) /* omap_hwmod_ocp_if.flags bits */ -#define OCPIF_HAS_IDLEST (1 << 0) -#define OCPIF_SWSUP_IDLE (1 << 1) -#define OCPIF_CAN_BURST (1 << 2) +#define OCPIF_SWSUP_IDLE (1 << 0) +#define OCPIF_CAN_BURST (1 << 1) /** * struct omap_hwmod_ocp_if - OCP interface data @@ -351,6 +350,8 @@ struct omap_hwmod_omap4_prcm { * when module is enabled, rather than the default, which is to * enable autoidle * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup + * HWMOD_NO_IDLEST : this module does not have idle status - this is the case + * only for few initiator modules on OMAP2 & 3. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -358,6 +359,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_INIT_NO_IDLE (1 << 3) #define HWMOD_NO_OCP_AUTOIDLE (1 << 4) #define HWMOD_SET_DEFAULT_CLOCKACT (1 << 5) +#define HWMOD_NO_IDLEST (1 << 6) /* * omap_hwmod._int_flags definitions -- cgit v1.2.3-59-g8ed1b From 682fdc96f3afb5ec34e4893fae41d09346d656ed Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:09 -0600 Subject: OMAP: hwmod: Fix wrong pointer iteration in oh->slaves The iteration is currently done on the omap_hwmod_ocp_if pointer and not on the table pointer that reference them. It worked most of the time because the structure are contiguous in memory. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 6459d07785b7..a280ccc31a7f 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -432,7 +432,6 @@ static int _init_main_clk(struct omap_hwmod *oh) */ static int _init_interface_clks(struct omap_hwmod *oh) { - struct omap_hwmod_ocp_if *os; struct clk *c; int i; int ret = 0; @@ -440,7 +439,9 @@ static int _init_interface_clks(struct omap_hwmod *oh) if (oh->slaves_cnt == 0) return 0; - for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { + for (i = 0; i < oh->slaves_cnt; i++) { + struct omap_hwmod_ocp_if *os = oh->slaves[i]; + if (!os->clk) continue; @@ -490,7 +491,6 @@ static int _init_opt_clks(struct omap_hwmod *oh) */ static int _enable_clocks(struct omap_hwmod *oh) { - struct omap_hwmod_ocp_if *os; int i; pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name); @@ -499,7 +499,8 @@ static int _enable_clocks(struct omap_hwmod *oh) clk_enable(oh->_clk); if (oh->slaves_cnt > 0) { - for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { + for (i = 0; i < oh->slaves_cnt; i++) { + struct omap_hwmod_ocp_if *os = oh->slaves[i]; struct clk *c = os->_clk; if (c && !IS_ERR(c) && (os->flags & OCPIF_SWSUP_IDLE)) @@ -520,7 +521,6 @@ static int _enable_clocks(struct omap_hwmod *oh) */ static int _disable_clocks(struct omap_hwmod *oh) { - struct omap_hwmod_ocp_if *os; int i; pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); @@ -529,7 +529,8 @@ static int _disable_clocks(struct omap_hwmod *oh) clk_disable(oh->_clk); if (oh->slaves_cnt > 0) { - for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { + for (i = 0; i < oh->slaves_cnt; i++) { + struct omap_hwmod_ocp_if *os = oh->slaves[i]; struct clk *c = os->_clk; if (c && !IS_ERR(c) && (os->flags & OCPIF_SWSUP_IDLE)) @@ -551,14 +552,15 @@ static int _disable_clocks(struct omap_hwmod *oh) */ static int _find_mpu_port_index(struct omap_hwmod *oh) { - struct omap_hwmod_ocp_if *os; int i; int found = 0; if (!oh || oh->slaves_cnt == 0) return -EINVAL; - for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { + for (i = 0; i < oh->slaves_cnt; i++) { + struct omap_hwmod_ocp_if *os = oh->slaves[i]; + if (os->user & OCP_USER_MPU) { found = 1; break; @@ -593,7 +595,7 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index) if (!oh || oh->slaves_cnt == 0) return NULL; - os = *oh->slaves + index; + os = oh->slaves[index]; for (i = 0, mem = os->addr; i < os->addr_cnt; i++, mem++) { if (mem->flags & ADDR_TYPE_RT) { @@ -806,7 +808,7 @@ static int _wait_target_ready(struct omap_hwmod *oh) if (oh->_int_flags & _HWMOD_NO_MPU_PORT) return 0; - os = *oh->slaves + oh->_mpu_port_index; + os = oh->slaves[oh->_mpu_port_index]; if (oh->flags & HWMOD_NO_IDLEST) return 0; @@ -1000,7 +1002,6 @@ static int _shutdown(struct omap_hwmod *oh) */ static int _setup(struct omap_hwmod *oh) { - struct omap_hwmod_ocp_if *os; int i, r; if (!oh) @@ -1008,7 +1009,8 @@ static int _setup(struct omap_hwmod *oh) /* Set iclk autoidle mode */ if (oh->slaves_cnt > 0) { - for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { + for (i = 0; i < oh->slaves_cnt; i++) { + struct omap_hwmod_ocp_if *os = oh->slaves[i]; struct clk *c = os->_clk; if (!c || IS_ERR(c)) @@ -1438,7 +1440,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh) ret = oh->mpu_irqs_cnt + oh->sdma_chs_cnt; for (i = 0; i < oh->slaves_cnt; i++) - ret += (*oh->slaves + i)->addr_cnt; + ret += oh->slaves[i]->addr_cnt; return ret; } @@ -1479,7 +1481,7 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) for (i = 0; i < oh->slaves_cnt; i++) { struct omap_hwmod_ocp_if *os; - os = *oh->slaves + i; + os = oh->slaves[i]; for (j = 0; j < os->addr_cnt; j++) { (res + r)->start = (os->addr + j)->pa_start; -- cgit v1.2.3-59-g8ed1b From 4d3ae5a9a7b3685c6d260a82f4098145862b2cd3 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:09 -0600 Subject: OMAP: hwmod: Remove IS_ERR check with omap_clk_get_by_name return value The previous clock API was returning a standard linux error code in case of failure. This is not the case anymore with the new omap_clk_get_by_name API. A NULL value means that the clock node does not exist. Replace all the IS_ERR check by a !clk check. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index a280ccc31a7f..a62920beebc6 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -411,9 +411,9 @@ static int _init_main_clk(struct omap_hwmod *oh) return 0; c = omap_clk_get_by_name(oh->main_clk); - WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get main_clk %s\n", + WARN(!c, "omap_hwmod: %s: cannot clk_get main_clk %s\n", oh->name, oh->main_clk); - if (IS_ERR(c)) + if (!c) ret = -EINVAL; oh->_clk = c; @@ -446,9 +446,9 @@ static int _init_interface_clks(struct omap_hwmod *oh) continue; c = omap_clk_get_by_name(os->clk); - WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get " - "interface_clk %s\n", oh->name, os->clk); - if (IS_ERR(c)) + WARN(!c, "omap_hwmod: %s: cannot clk_get interface_clk %s\n", + oh->name, os->clk); + if (!c) ret = -EINVAL; os->_clk = c; } @@ -472,9 +472,9 @@ static int _init_opt_clks(struct omap_hwmod *oh) for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) { c = omap_clk_get_by_name(oc->clk); - WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get opt_clk " - "%s\n", oh->name, oc->clk); - if (IS_ERR(c)) + WARN(!c, "omap_hwmod: %s: cannot clk_get opt_clk %s\n", + oh->name, oc->clk); + if (!c) ret = -EINVAL; oc->_clk = c; } @@ -495,7 +495,7 @@ static int _enable_clocks(struct omap_hwmod *oh) pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name); - if (oh->_clk && !IS_ERR(oh->_clk)) + if (oh->_clk) clk_enable(oh->_clk); if (oh->slaves_cnt > 0) { @@ -503,7 +503,7 @@ static int _enable_clocks(struct omap_hwmod *oh) struct omap_hwmod_ocp_if *os = oh->slaves[i]; struct clk *c = os->_clk; - if (c && !IS_ERR(c) && (os->flags & OCPIF_SWSUP_IDLE)) + if (c && (os->flags & OCPIF_SWSUP_IDLE)) clk_enable(c); } } @@ -525,7 +525,7 @@ static int _disable_clocks(struct omap_hwmod *oh) pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); - if (oh->_clk && !IS_ERR(oh->_clk)) + if (oh->_clk) clk_disable(oh->_clk); if (oh->slaves_cnt > 0) { @@ -533,7 +533,7 @@ static int _disable_clocks(struct omap_hwmod *oh) struct omap_hwmod_ocp_if *os = oh->slaves[i]; struct clk *c = os->_clk; - if (c && !IS_ERR(c) && (os->flags & OCPIF_SWSUP_IDLE)) + if (c && (os->flags & OCPIF_SWSUP_IDLE)) clk_disable(c); } } @@ -1013,7 +1013,7 @@ static int _setup(struct omap_hwmod *oh) struct omap_hwmod_ocp_if *os = oh->slaves[i]; struct clk *c = os->_clk; - if (!c || IS_ERR(c)) + if (!c) continue; if (os->flags & OCPIF_SWSUP_IDLE) { -- cgit v1.2.3-59-g8ed1b From 20383d82160d918047bb10a4f6e170f4bac195a7 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:09 -0600 Subject: OMAP: hwmod: Replace WARN by pr_warning if clock lookup failed The WARN is a little bit too verbose and is not providing usefull information in that case. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index a62920beebc6..5d3a3ea37422 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -411,9 +411,9 @@ static int _init_main_clk(struct omap_hwmod *oh) return 0; c = omap_clk_get_by_name(oh->main_clk); - WARN(!c, "omap_hwmod: %s: cannot clk_get main_clk %s\n", - oh->name, oh->main_clk); if (!c) + pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n", + oh->name, oh->main_clk); ret = -EINVAL; oh->_clk = c; @@ -446,9 +446,9 @@ static int _init_interface_clks(struct omap_hwmod *oh) continue; c = omap_clk_get_by_name(os->clk); - WARN(!c, "omap_hwmod: %s: cannot clk_get interface_clk %s\n", - oh->name, os->clk); if (!c) + pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n", + oh->name, os->clk); ret = -EINVAL; os->_clk = c; } @@ -472,9 +472,9 @@ static int _init_opt_clks(struct omap_hwmod *oh) for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) { c = omap_clk_get_by_name(oc->clk); - WARN(!c, "omap_hwmod: %s: cannot clk_get opt_clk %s\n", - oh->name, oc->clk); if (!c) + pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n", + oh->name, oc->clk); ret = -EINVAL; oc->_clk = c; } -- cgit v1.2.3-59-g8ed1b From f5c1f84bcc9c5b7a664886d0a5e7143d0bc3251f Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:10 -0600 Subject: OMAP: hwmod: Do not exit the iteration if one clock init failed During the _init_clocks phase, the iteration is stopped but the status is still change from _HWMOD_STATE_REGISTERED to _HWMOD_STATE_CLKS_INITED. Since the _setup phase will be done nevertheless, it might be better to keep initializing the others clocks nodes and just keep the warning. It is much easier to debug when a important number of clocks name are wrong during the early debug phase of a new platform. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 5d3a3ea37422..b624ad648212 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -783,9 +783,10 @@ static int _init_clocks(struct omap_hwmod *oh) ret |= _init_interface_clks(oh); ret |= _init_opt_clks(oh); - oh->_state = _HWMOD_STATE_CLKS_INITED; + if (!ret) + oh->_state = _HWMOD_STATE_CLKS_INITED; - return ret; + return 0; } /** -- cgit v1.2.3-59-g8ed1b From 5c2c02961ea39d7bbe4d87f362ab3173a424794b Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:10 -0600 Subject: OMAP: hwmod: Rename hwmod name for the MPU In the lastest OMAP4 hwmod data file, the _hwmod was removed in order to save some memory space and because it does not bring a lot. The same cleanup will be have to done for other hwmods in OMAP2 & 3 data files. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley Cc: Rajendra Nayak --- arch/arm/mach-omap2/omap_hwmod.c | 2 +- arch/arm/mach-omap2/omap_hwmod_2420_data.c | 2 +- arch/arm/mach-omap2/omap_hwmod_2430_data.c | 2 +- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index b624ad648212..b6031e468def 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -58,7 +58,7 @@ #define MAX_MODULE_RESET_WAIT 10000 /* Name of the OMAP hwmod for the MPU */ -#define MPU_INITIATOR_NAME "mpu_hwmod" +#define MPU_INITIATOR_NAME "mpu" /* omap_hwmod_list contains all registered struct omap_hwmods */ static LIST_HEAD(omap_hwmod_list); diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index eb7ee2453b24..e5530c51f77d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -125,7 +125,7 @@ static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = { /* MPU */ static struct omap_hwmod omap2420_mpu_hwmod = { - .name = "mpu_hwmod", + .name = "mpu", .class = &mpu_hwmod_class, .main_clk = "mpu_ck", .masters = omap2420_mpu_masters, diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 241bd8230729..0852d954da40 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -127,7 +127,7 @@ static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = { /* MPU */ static struct omap_hwmod omap2430_mpu_hwmod = { - .name = "mpu_hwmod", + .name = "mpu", .class = &mpu_hwmod_class, .main_clk = "mpu_ck", .masters = omap2430_mpu_masters, diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index ed6084004260..39b0c0eaa37d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -156,7 +156,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = { /* MPU */ static struct omap_hwmod omap3xxx_mpu_hwmod = { - .name = "mpu_hwmod", + .name = "mpu", .class = &mpu_hwmod_class, .main_clk = "arm_fck", .masters = omap3xxx_mpu_masters, -- cgit v1.2.3-59-g8ed1b From 63403384233e3f58514eea891003458dedd43c12 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:10 -0600 Subject: OMAP: hwmod: Replace WARN by pr_warning for clockdomain check Most of the clock nodes belong to a clock domain, but it is perfectly valid to have clock without clock domain. Root clocks for example does not belong to any clock domain. Keep the warning but reduce the verbosity. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index b6031e468def..2fff39ff4080 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -404,21 +404,20 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) */ static int _init_main_clk(struct omap_hwmod *oh) { - struct clk *c; int ret = 0; if (!oh->main_clk) return 0; - c = omap_clk_get_by_name(oh->main_clk); - if (!c) + oh->_clk = omap_clk_get_by_name(oh->main_clk); + if (!oh->_clk) pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n", oh->name, oh->main_clk); - ret = -EINVAL; - oh->_clk = c; + return -EINVAL; - WARN(!c->clkdm, "omap_hwmod: %s: missing clockdomain for %s.\n", - oh->main_clk, c->name); + if (!oh->_clk->clkdm) + pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n", + oh->main_clk, oh->_clk->name); return ret; } -- cgit v1.2.3-59-g8ed1b From a610855ca3694f9134b0198517c39121058e9e10 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:11 -0600 Subject: OMAP4: CM: Remove non-functional registers in ES1.0 The automatic HW restore from OFF mode is not functional at all in OMAP4430 ES1.0. Because of that, it will be extensively changed in the next Si revision, and the compatibilty will not be maintained with ES1.0. Remove the current XXX_RESTORE registers definition to avoid future conflicts with the next Si revision. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley Cc: Rajendra Nayak --- arch/arm/mach-omap2/cm44xx.h | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h index c575b9b0c041..b889ac633731 100644 --- a/arch/arm/mach-omap2/cm44xx.h +++ b/arch/arm/mach-omap2/cm44xx.h @@ -1,8 +1,8 @@ /* * OMAP44xx CM1 & CM2 instance offset macros * - * Copyright (C) 2009 Texas Instruments, Inc. - * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation * * Paul Walmsley (paul@pwsan.com) * Rajendra Nayak (rnayak@ti.com) @@ -25,7 +25,6 @@ /* CM1 */ - /* CM1.OCP_SOCKET_CM1 register offsets */ #define OMAP4430_REVISION_CM1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_MOD, 0x0000) #define OMAP4430_CM_CM1_PROFILING_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_MOD, 0x0040) @@ -116,25 +115,8 @@ #define OMAP4430_CM1_ABE_TIMER8_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0080) #define OMAP4430_CM1_ABE_WDT3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0088) -/* CM1.RESTORE_CM1 register offsets */ -#define OMAP4430_CM_CLKSEL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0000) -#define OMAP4430_CM_DIV_M2_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0004) -#define OMAP4430_CM_DIV_M3_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0008) -#define OMAP4430_CM_DIV_M4_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x000c) -#define OMAP4430_CM_DIV_M5_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0010) -#define OMAP4430_CM_DIV_M6_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0014) -#define OMAP4430_CM_DIV_M7_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0018) -#define OMAP4430_CM_CLKSEL_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x001c) -#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0020) -#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0024) -#define OMAP4430_CM_CLKMODE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0028) -#define OMAP4430_CM_SHADOW_FREQ_CONFIG1_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x002c) -#define OMAP4430_CM_AUTOIDLE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0030) -#define OMAP4430_CM_MPU_CLKSTCTRL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0034) - /* CM2 */ - /* CM2.OCP_SOCKET_CM2 register offsets */ #define OMAP4430_REVISION_CM2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_MOD, 0x0000) #define OMAP4430_CM_CM2_PROFILING_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_MOD, 0x0040) @@ -336,23 +318,4 @@ /* CM2.CEFUSE_CM2 register offsets */ #define OMAP4430_CM_CEFUSE_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_MOD, 0x0000) #define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_MOD, 0x0020) - -/* CM2.RESTORE_CM2 register offsets */ -#define OMAP4430_CM_L3_1_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0000) -#define OMAP4430_CM_L3_2_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0004) -#define OMAP4430_CM_L4CFG_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0008) -#define OMAP4430_CM_MEMIF_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x000c) -#define OMAP4430_CM_L4PER_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0010) -#define OMAP4430_CM_L3INIT_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0014) -#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0018) -#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x001c) -#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0020) -#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0024) -#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0028) -#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x002c) -#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0030) -#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0034) -#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0038) -#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x003c) -#define OMAP4430_CM_SDMA_STATICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0040) #endif -- cgit v1.2.3-59-g8ed1b From 793287062304da2f2718c1ad156830b4e99816c7 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:11 -0600 Subject: OMAP4: PRM: Remove MPU internal code name and apply PRCM naming convention The MPU subsystem was named based on internal code name (CHIRON). This patch will remove all the occurences of the chiron name are replace it with PRCM_MPU in order to differentiate the MPU local PRCM to the global one. Remove PDA_ from PRCM_MPU registers names to stick to the global PRM naming convention. Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley Cc: Rajendra Nayak --- arch/arm/mach-omap2/clockdomains44xx.h | 4 +-- arch/arm/mach-omap2/powerdomains44xx.h | 10 +++--- arch/arm/mach-omap2/prcm-common.h | 10 +++--- arch/arm/mach-omap2/prm.h | 4 +-- arch/arm/mach-omap2/prm44xx.h | 55 ++++++++++++++++-------------- arch/arm/plat-omap/include/plat/omap44xx.h | 1 + 6 files changed, 45 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clockdomains44xx.h b/arch/arm/mach-omap2/clockdomains44xx.h index 438aaee2e392..7e5ba0f67925 100644 --- a/arch/arm/mach-omap2/clockdomains44xx.h +++ b/arch/arm/mach-omap2/clockdomains44xx.h @@ -131,7 +131,7 @@ static struct clockdomain mpuss_44xx_clkdm = { static struct clockdomain mpu0_44xx_clkdm = { .name = "mpu0_clkdm", .pwrdm = { .name = "cpu0_pwrdm" }, - .clkstctrl_reg = OMAP4430_CM_PDA_CPU0_CLKSTCTRL, + .clkstctrl_reg = OMAP4430_CM_CPU0_CLKSTCTRL, .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK, .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -140,7 +140,7 @@ static struct clockdomain mpu0_44xx_clkdm = { static struct clockdomain mpu1_44xx_clkdm = { .name = "mpu1_clkdm", .pwrdm = { .name = "cpu1_pwrdm" }, - .clkstctrl_reg = OMAP4430_CM_PDA_CPU1_CLKSTCTRL, + .clkstctrl_reg = OMAP4430_CM_CPU1_CLKSTCTRL, .clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK, .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), diff --git a/arch/arm/mach-omap2/powerdomains44xx.h b/arch/arm/mach-omap2/powerdomains44xx.h index c1015147d579..e002d4289f4e 100644 --- a/arch/arm/mach-omap2/powerdomains44xx.h +++ b/arch/arm/mach-omap2/powerdomains44xx.h @@ -1,12 +1,12 @@ /* * OMAP4 Power domains framework * - * Copyright (C) 2009 Texas Instruments, Inc. - * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation * * Abhijit Pagare (abhijitpagare@ti.com) * Benoit Cousson (b-cousson@ti.com) - * Paul Walmsley + * Paul Walmsley (paul@pwsan.com) * * This file is automatically generated from the OMAP hardware databases. * We respectfully ask that any modifications to this file be coordinated @@ -143,7 +143,7 @@ static struct powerdomain wkup_44xx_pwrdm = { /* cpu0_44xx_pwrdm: MPU0 processor and Neon coprocessor power domain */ static struct powerdomain cpu0_44xx_pwrdm = { .name = "cpu0_pwrdm", - .prcm_offs = OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, + .prcm_offs = OMAP4430_PRCM_MPU_CPU0_MOD, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), .pwrsts = PWRSTS_OFF_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, @@ -159,7 +159,7 @@ static struct powerdomain cpu0_44xx_pwrdm = { /* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */ static struct powerdomain cpu1_44xx_pwrdm = { .name = "cpu1_pwrdm", - .prcm_offs = OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, + .prcm_offs = OMAP4430_PRCM_MPU_CPU1_MOD, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), .pwrsts = PWRSTS_OFF_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index ed2379f38db8..ad1df56585e8 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -112,12 +112,12 @@ #define OMAP4430_SCRM_SCRM_MOD 0x0000 -/* CHIRONSS instances */ +/* PRCM_MPU instances */ -#define OMAP4430_CHIRONSS_CHIRONSS_OCP_SOCKET_PRCM_MOD 0x0000 -#define OMAP4430_CHIRONSS_CHIRONSS_DEVICE_PRM_MOD 0x0200 -#define OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD 0x0400 -#define OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD 0x0800 +#define OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_MOD 0x0000 +#define OMAP4430_PRCM_MPU_DEVICE_PRM_MOD 0x0200 +#define OMAP4430_PRCM_MPU_CPU0_MOD 0x0400 +#define OMAP4430_PRCM_MPU_CPU1_MOD 0x0800 /* Base Addresses for the OMAP4 */ diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 7bffb6e39d79..588873b9303a 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -24,8 +24,8 @@ OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg)) #define OMAP44XX_PRM_REGADDR(module, reg) \ OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE + (module) + (reg)) -#define OMAP44XX_CHIRONSS_REGADDR(module, reg) \ - OMAP2_L4_IO_ADDRESS(OMAP4430_CHIRONSS_BASE + (module) + (reg)) +#define OMAP44XX_PRCM_MPU_REGADDR(module, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE + (module) + (reg)) #include "prm44xx.h" diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h index adb2558bb121..54edaba617b3 100644 --- a/arch/arm/mach-omap2/prm44xx.h +++ b/arch/arm/mach-omap2/prm44xx.h @@ -1,8 +1,8 @@ /* * OMAP44xx PRM instance offset macros * - * Copyright (C) 2009 Texas Instruments, Inc. - * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation * * Paul Walmsley (paul@pwsan.com) * Rajendra Nayak (rnayak@ti.com) @@ -25,7 +25,6 @@ /* PRM */ - /* PRM.OCP_SOCKET_PRM register offsets */ #define OMAP4430_REVISION_PRM OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0000) #define OMAP4430_PRM_IRQSTATUS_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0010) @@ -382,30 +381,36 @@ #define OMAP4430_PRM_PHASE2B_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f0) #define OMAP4430_PRM_MODEM_IF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f4) -/* CHIRON_PRCM */ - +/* + * PRCM_MPU + * + * The PRCM_MPU is a local PRCM inside the MPU subsystem. For the PRCM (global) + * point of view the PRCM_MPU is a single entity. It shares the same + * programming model as the global PRCM and thus can be assimilate as two new + * MOD inside the PRCM + */ -/* CHIRON_PRCM.CHIRONSS_OCP_SOCKET_PRCM register offsets */ -#define OMAP4430_REVISION_PRCM OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_OCP_SOCKET_PRCM_MOD, 0x0000) +/* PRCM_MPU.OCP_SOCKET_PRCM register offsets */ +#define OMAP4430_REVISION_PRCM OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_MOD, 0x0000) -/* CHIRON_PRCM.CHIRONSS_DEVICE_PRM register offsets */ -#define OMAP4430_CHIRON_PRCM_PRM_RSTST OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_DEVICE_PRM_MOD, 0x0000) +/* PRCM_MPU.DEVICE_PRM register offsets */ +#define OMAP4430_PRCM_MPU_PRM_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_MOD, 0x0000) -/* CHIRON_PRCM.CHIRONSS_CPU0 register offsets */ -#define OMAP4430_PM_PDA_CPU0_PWRSTCTRL OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0000) -#define OMAP4430_PM_PDA_CPU0_PWRSTST OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0004) -#define OMAP4430_RM_PDA_CPU0_CPU0_CONTEXT OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0008) -#define OMAP4430_RM_PDA_CPU0_CPU0_RSTCTRL OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x000c) -#define OMAP4430_RM_PDA_CPU0_CPU0_RSTST OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0010) -#define OMAP4430_CM_PDA_CPU0_CPU0_CLKCTRL OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0014) -#define OMAP4430_CM_PDA_CPU0_CLKSTCTRL OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0018) +/* PRCM_MPU.CPU0 register offsets */ +#define OMAP4430_PM_CPU0_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0000) +#define OMAP4430_PM_CPU0_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0004) +#define OMAP4430_RM_CPU0_CPU0_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0008) +#define OMAP4430_RM_CPU0_CPU0_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x000c) +#define OMAP4430_RM_CPU0_CPU0_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0010) +#define OMAP4430_CM_CPU0_CPU0_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0014) +#define OMAP4430_CM_CPU0_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0018) -/* CHIRON_PRCM.CHIRONSS_CPU1 register offsets */ -#define OMAP4430_PM_PDA_CPU1_PWRSTCTRL OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0000) -#define OMAP4430_PM_PDA_CPU1_PWRSTST OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0004) -#define OMAP4430_RM_PDA_CPU1_CPU1_CONTEXT OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0008) -#define OMAP4430_RM_PDA_CPU1_CPU1_RSTCTRL OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x000c) -#define OMAP4430_RM_PDA_CPU1_CPU1_RSTST OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0010) -#define OMAP4430_CM_PDA_CPU1_CPU1_CLKCTRL OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0014) -#define OMAP4430_CM_PDA_CPU1_CLKSTCTRL OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0018) +/* PRCM_MPU.CPU1 register offsets */ +#define OMAP4430_PM_CPU1_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0000) +#define OMAP4430_PM_CPU1_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0004) +#define OMAP4430_RM_CPU1_CPU1_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0008) +#define OMAP4430_RM_CPU1_CPU1_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x000c) +#define OMAP4430_RM_CPU1_CPU1_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0010) +#define OMAP4430_CM_CPU1_CPU1_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0014) +#define OMAP4430_CM_CPU1_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0018) #endif diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h index bb94a0baee8a..8b3f12ff5cbc 100644 --- a/arch/arm/plat-omap/include/plat/omap44xx.h +++ b/arch/arm/plat-omap/include/plat/omap44xx.h @@ -30,6 +30,7 @@ #define OMAP4430_CM_BASE OMAP4430_CM1_BASE #define OMAP4430_CM2_BASE 0x4a008000 #define OMAP4430_PRM_BASE 0x4a306000 +#define OMAP4430_PRCM_MPU_BASE 0x48243000 #define OMAP44XX_GPMC_BASE 0x50000000 #define OMAP443X_SCM_BASE 0x4a002000 #define OMAP443X_CTRL_BASE 0x4a100000 -- cgit v1.2.3-59-g8ed1b From 78026dda2ac8ffb54cc7d3c618448083376b17eb Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 20 May 2010 12:31:12 -0600 Subject: OMAP4: PRCM: Remove duplicate definition of base addresses CM1, CM2, PRM, SCRM and MPU_PRCM are already defined in omap44xx.h Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley Cc: Rajendra Nayak --- arch/arm/mach-omap2/prcm-common.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index ad1df56585e8..995b7edbf18d 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -119,14 +119,6 @@ #define OMAP4430_PRCM_MPU_CPU0_MOD 0x0400 #define OMAP4430_PRCM_MPU_CPU1_MOD 0x0800 -/* Base Addresses for the OMAP4 */ - -#define OMAP4430_CM1_BASE 0x4a004000 -#define OMAP4430_CM2_BASE 0x4a008000 -#define OMAP4430_PRM_BASE 0x4a306000 -#define OMAP4430_SCRM_BASE 0x4a30a000 -#define OMAP4430_CHIRONSS_BASE 0x48243000 - /* 24XX register bits shared between CM & PRM registers */ -- cgit v1.2.3-59-g8ed1b From 2339ea99cc6bb6a6d36d02c641e21dc950f50360 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 20 May 2010 12:31:12 -0600 Subject: OMAP4: PRCM: Add offset defines for all PRM registers The prm44xx.h files only had absolute register address defines for all PRM registers. This patch adds additional register offset defines for all the registers, so they can be used with apis like prm_read_mod_* Signed-off-by: Rajendra Nayak Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/prm44xx.h | 334 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h index 54edaba617b3..fe8ef26431e5 100644 --- a/arch/arm/mach-omap2/prm44xx.h +++ b/arch/arm/mach-omap2/prm44xx.h @@ -26,359 +26,677 @@ /* PRM */ /* PRM.OCP_SOCKET_PRM register offsets */ +#define OMAP4_REVISION_PRM_OFFSET 0x0000 #define OMAP4430_REVISION_PRM OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0000) +#define OMAP4_PRM_IRQSTATUS_MPU_OFFSET 0x0010 #define OMAP4430_PRM_IRQSTATUS_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0010) +#define OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET 0x0014 #define OMAP4430_PRM_IRQSTATUS_MPU_2 OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0014) +#define OMAP4_PRM_IRQENABLE_MPU_OFFSET 0x0018 #define OMAP4430_PRM_IRQENABLE_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0018) +#define OMAP4_PRM_IRQENABLE_MPU_2_OFFSET 0x001c #define OMAP4430_PRM_IRQENABLE_MPU_2 OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x001c) +#define OMAP4_PRM_IRQSTATUS_DUCATI_OFFSET 0x0020 #define OMAP4430_PRM_IRQSTATUS_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0020) +#define OMAP4_PRM_IRQENABLE_DUCATI_OFFSET 0x0028 #define OMAP4430_PRM_IRQENABLE_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0028) +#define OMAP4_PRM_IRQSTATUS_TESLA_OFFSET 0x0030 #define OMAP4430_PRM_IRQSTATUS_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0030) +#define OMAP4_PRM_IRQENABLE_TESLA_OFFSET 0x0038 #define OMAP4430_PRM_IRQENABLE_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0038) +#define OMAP4_PRM_PRM_PROFILING_CLKCTRL_OFFSET 0x0040 #define OMAP4430_PRM_PRM_PROFILING_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0040) /* PRM.CKGEN_PRM register offsets */ +#define OMAP4_CM_ABE_DSS_SYS_CLKSEL_OFFSET 0x0000 #define OMAP4430_CM_ABE_DSS_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0000) +#define OMAP4_CM_DPLL_SYS_REF_CLKSEL_OFFSET 0x0004 #define OMAP4430_CM_DPLL_SYS_REF_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0004) +#define OMAP4_CM_L4_WKUP_CLKSEL_OFFSET 0x0008 #define OMAP4430_CM_L4_WKUP_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0008) +#define OMAP4_CM_ABE_PLL_REF_CLKSEL_OFFSET 0x000c #define OMAP4430_CM_ABE_PLL_REF_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x000c) +#define OMAP4_CM_SYS_CLKSEL_OFFSET 0x0010 #define OMAP4430_CM_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0010) /* PRM.MPU_PRM register offsets */ +#define OMAP4_PM_MPU_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_MPU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0000) +#define OMAP4_PM_MPU_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_MPU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0004) +#define OMAP4_RM_MPU_RSTST_OFFSET 0x0014 #define OMAP4430_RM_MPU_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0014) +#define OMAP4_RM_MPU_MPU_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_MPU_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0024) /* PRM.TESLA_PRM register offsets */ +#define OMAP4_PM_TESLA_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_TESLA_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0000) +#define OMAP4_PM_TESLA_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_TESLA_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0004) +#define OMAP4_RM_TESLA_RSTCTRL_OFFSET 0x0010 #define OMAP4430_RM_TESLA_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0010) +#define OMAP4_RM_TESLA_RSTST_OFFSET 0x0014 #define OMAP4430_RM_TESLA_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0014) +#define OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_TESLA_TESLA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0024) /* PRM.ABE_PRM register offsets */ +#define OMAP4_PM_ABE_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_ABE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0000) +#define OMAP4_PM_ABE_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_ABE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0004) +#define OMAP4_RM_ABE_AESS_CONTEXT_OFFSET 0x002c #define OMAP4430_RM_ABE_AESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x002c) +#define OMAP4_PM_ABE_PDM_WKDEP_OFFSET 0x0030 #define OMAP4430_PM_ABE_PDM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0030) +#define OMAP4_RM_ABE_PDM_CONTEXT_OFFSET 0x0034 #define OMAP4430_RM_ABE_PDM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0034) +#define OMAP4_PM_ABE_DMIC_WKDEP_OFFSET 0x0038 #define OMAP4430_PM_ABE_DMIC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0038) +#define OMAP4_RM_ABE_DMIC_CONTEXT_OFFSET 0x003c #define OMAP4430_RM_ABE_DMIC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x003c) +#define OMAP4_PM_ABE_MCASP_WKDEP_OFFSET 0x0040 #define OMAP4430_PM_ABE_MCASP_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0040) +#define OMAP4_RM_ABE_MCASP_CONTEXT_OFFSET 0x0044 #define OMAP4430_RM_ABE_MCASP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0044) +#define OMAP4_PM_ABE_MCBSP1_WKDEP_OFFSET 0x0048 #define OMAP4430_PM_ABE_MCBSP1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0048) +#define OMAP4_RM_ABE_MCBSP1_CONTEXT_OFFSET 0x004c #define OMAP4430_RM_ABE_MCBSP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x004c) +#define OMAP4_PM_ABE_MCBSP2_WKDEP_OFFSET 0x0050 #define OMAP4430_PM_ABE_MCBSP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0050) +#define OMAP4_RM_ABE_MCBSP2_CONTEXT_OFFSET 0x0054 #define OMAP4430_RM_ABE_MCBSP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0054) +#define OMAP4_PM_ABE_MCBSP3_WKDEP_OFFSET 0x0058 #define OMAP4430_PM_ABE_MCBSP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0058) +#define OMAP4_RM_ABE_MCBSP3_CONTEXT_OFFSET 0x005c #define OMAP4430_RM_ABE_MCBSP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x005c) +#define OMAP4_PM_ABE_SLIMBUS_WKDEP_OFFSET 0x0060 #define OMAP4430_PM_ABE_SLIMBUS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0060) +#define OMAP4_RM_ABE_SLIMBUS_CONTEXT_OFFSET 0x0064 #define OMAP4430_RM_ABE_SLIMBUS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0064) +#define OMAP4_PM_ABE_TIMER5_WKDEP_OFFSET 0x0068 #define OMAP4430_PM_ABE_TIMER5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0068) +#define OMAP4_RM_ABE_TIMER5_CONTEXT_OFFSET 0x006c #define OMAP4430_RM_ABE_TIMER5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x006c) +#define OMAP4_PM_ABE_TIMER6_WKDEP_OFFSET 0x0070 #define OMAP4430_PM_ABE_TIMER6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0070) +#define OMAP4_RM_ABE_TIMER6_CONTEXT_OFFSET 0x0074 #define OMAP4430_RM_ABE_TIMER6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0074) +#define OMAP4_PM_ABE_TIMER7_WKDEP_OFFSET 0x0078 #define OMAP4430_PM_ABE_TIMER7_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0078) +#define OMAP4_RM_ABE_TIMER7_CONTEXT_OFFSET 0x007c #define OMAP4430_RM_ABE_TIMER7_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x007c) +#define OMAP4_PM_ABE_TIMER8_WKDEP_OFFSET 0x0080 #define OMAP4430_PM_ABE_TIMER8_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0080) +#define OMAP4_RM_ABE_TIMER8_CONTEXT_OFFSET 0x0084 #define OMAP4430_RM_ABE_TIMER8_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0084) +#define OMAP4_PM_ABE_WDT3_WKDEP_OFFSET 0x0088 #define OMAP4430_PM_ABE_WDT3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0088) +#define OMAP4_RM_ABE_WDT3_CONTEXT_OFFSET 0x008c #define OMAP4430_RM_ABE_WDT3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x008c) /* PRM.ALWAYS_ON_PRM register offsets */ +#define OMAP4_RM_ALWON_MDMINTC_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_ALWON_MDMINTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0024) +#define OMAP4_PM_ALWON_SR_MPU_WKDEP_OFFSET 0x0028 #define OMAP4430_PM_ALWON_SR_MPU_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0028) +#define OMAP4_RM_ALWON_SR_MPU_CONTEXT_OFFSET 0x002c #define OMAP4430_RM_ALWON_SR_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x002c) +#define OMAP4_PM_ALWON_SR_IVA_WKDEP_OFFSET 0x0030 #define OMAP4430_PM_ALWON_SR_IVA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0030) +#define OMAP4_RM_ALWON_SR_IVA_CONTEXT_OFFSET 0x0034 #define OMAP4430_RM_ALWON_SR_IVA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0034) +#define OMAP4_PM_ALWON_SR_CORE_WKDEP_OFFSET 0x0038 #define OMAP4430_PM_ALWON_SR_CORE_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0038) +#define OMAP4_RM_ALWON_SR_CORE_CONTEXT_OFFSET 0x003c #define OMAP4430_RM_ALWON_SR_CORE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x003c) /* PRM.CORE_PRM register offsets */ +#define OMAP4_PM_CORE_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_CORE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0000) +#define OMAP4_PM_CORE_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_CORE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0004) +#define OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_L3_1_L3_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0024) +#define OMAP4_RM_L3_2_L3_2_CONTEXT_OFFSET 0x0124 #define OMAP4430_RM_L3_2_L3_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0124) +#define OMAP4_RM_L3_2_GPMC_CONTEXT_OFFSET 0x012c #define OMAP4430_RM_L3_2_GPMC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x012c) +#define OMAP4_RM_L3_2_OCMC_RAM_CONTEXT_OFFSET 0x0134 #define OMAP4430_RM_L3_2_OCMC_RAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0134) +#define OMAP4_RM_DUCATI_RSTCTRL_OFFSET 0x0210 #define OMAP4430_RM_DUCATI_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0210) +#define OMAP4_RM_DUCATI_RSTST_OFFSET 0x0214 #define OMAP4430_RM_DUCATI_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0214) +#define OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET 0x0224 #define OMAP4430_RM_DUCATI_DUCATI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0224) +#define OMAP4_RM_SDMA_SDMA_CONTEXT_OFFSET 0x0324 #define OMAP4430_RM_SDMA_SDMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0324) +#define OMAP4_RM_MEMIF_DMM_CONTEXT_OFFSET 0x0424 #define OMAP4430_RM_MEMIF_DMM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0424) +#define OMAP4_RM_MEMIF_EMIF_FW_CONTEXT_OFFSET 0x042c #define OMAP4430_RM_MEMIF_EMIF_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x042c) +#define OMAP4_RM_MEMIF_EMIF_1_CONTEXT_OFFSET 0x0434 #define OMAP4430_RM_MEMIF_EMIF_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0434) +#define OMAP4_RM_MEMIF_EMIF_2_CONTEXT_OFFSET 0x043c #define OMAP4430_RM_MEMIF_EMIF_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x043c) +#define OMAP4_RM_MEMIF_DLL_CONTEXT_OFFSET 0x0444 #define OMAP4430_RM_MEMIF_DLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0444) +#define OMAP4_RM_MEMIF_EMIF_H1_CONTEXT_OFFSET 0x0454 #define OMAP4430_RM_MEMIF_EMIF_H1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0454) +#define OMAP4_RM_MEMIF_EMIF_H2_CONTEXT_OFFSET 0x045c #define OMAP4430_RM_MEMIF_EMIF_H2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x045c) +#define OMAP4_RM_MEMIF_DLL_H_CONTEXT_OFFSET 0x0464 #define OMAP4430_RM_MEMIF_DLL_H_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0464) +#define OMAP4_RM_D2D_SAD2D_CONTEXT_OFFSET 0x0524 #define OMAP4430_RM_D2D_SAD2D_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0524) +#define OMAP4_RM_D2D_MODEM_ICR_CONTEXT_OFFSET 0x052c #define OMAP4430_RM_D2D_MODEM_ICR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x052c) +#define OMAP4_RM_D2D_SAD2D_FW_CONTEXT_OFFSET 0x0534 #define OMAP4430_RM_D2D_SAD2D_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0534) +#define OMAP4_RM_L4CFG_L4_CFG_CONTEXT_OFFSET 0x0624 #define OMAP4430_RM_L4CFG_L4_CFG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0624) +#define OMAP4_RM_L4CFG_HW_SEM_CONTEXT_OFFSET 0x062c #define OMAP4430_RM_L4CFG_HW_SEM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x062c) +#define OMAP4_RM_L4CFG_MAILBOX_CONTEXT_OFFSET 0x0634 #define OMAP4430_RM_L4CFG_MAILBOX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0634) +#define OMAP4_RM_L4CFG_SAR_ROM_CONTEXT_OFFSET 0x063c #define OMAP4430_RM_L4CFG_SAR_ROM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x063c) +#define OMAP4_RM_L3INSTR_L3_3_CONTEXT_OFFSET 0x0724 #define OMAP4430_RM_L3INSTR_L3_3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0724) +#define OMAP4_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET 0x072c #define OMAP4430_RM_L3INSTR_L3_INSTR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x072c) +#define OMAP4_RM_L3INSTR_OCP_WP1_CONTEXT_OFFSET 0x0744 #define OMAP4430_RM_L3INSTR_OCP_WP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0744) /* PRM.IVAHD_PRM register offsets */ +#define OMAP4_PM_IVAHD_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_IVAHD_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0000) +#define OMAP4_PM_IVAHD_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_IVAHD_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0004) +#define OMAP4_RM_IVAHD_RSTCTRL_OFFSET 0x0010 #define OMAP4430_RM_IVAHD_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0010) +#define OMAP4_RM_IVAHD_RSTST_OFFSET 0x0014 #define OMAP4430_RM_IVAHD_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0014) +#define OMAP4_RM_IVAHD_IVAHD_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_IVAHD_IVAHD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0024) +#define OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET 0x002c #define OMAP4430_RM_IVAHD_SL2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x002c) /* PRM.CAM_PRM register offsets */ +#define OMAP4_PM_CAM_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_CAM_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x0000) +#define OMAP4_PM_CAM_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_CAM_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x0004) +#define OMAP4_RM_CAM_ISS_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_CAM_ISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x0024) +#define OMAP4_RM_CAM_FDIF_CONTEXT_OFFSET 0x002c #define OMAP4430_RM_CAM_FDIF_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x002c) /* PRM.DSS_PRM register offsets */ +#define OMAP4_PM_DSS_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_DSS_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0000) +#define OMAP4_PM_DSS_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_DSS_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0004) +#define OMAP4_PM_DSS_DSS_WKDEP_OFFSET 0x0020 #define OMAP4430_PM_DSS_DSS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0020) +#define OMAP4_RM_DSS_DSS_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_DSS_DSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0024) +#define OMAP4_RM_DSS_DEISS_CONTEXT_OFFSET 0x002c #define OMAP4430_RM_DSS_DEISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x002c) /* PRM.GFX_PRM register offsets */ +#define OMAP4_PM_GFX_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_GFX_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_MOD, 0x0000) +#define OMAP4_PM_GFX_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_GFX_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_MOD, 0x0004) +#define OMAP4_RM_GFX_GFX_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_GFX_GFX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_MOD, 0x0024) /* PRM.L3INIT_PRM register offsets */ +#define OMAP4_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_L3INIT_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0000) +#define OMAP4_PM_L3INIT_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_L3INIT_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0004) +#define OMAP4_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028 #define OMAP4430_PM_L3INIT_MMC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0028) +#define OMAP4_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c #define OMAP4430_RM_L3INIT_MMC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x002c) +#define OMAP4_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030 #define OMAP4430_PM_L3INIT_MMC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0030) +#define OMAP4_RM_L3INIT_MMC2_CONTEXT_OFFSET 0x0034 #define OMAP4430_RM_L3INIT_MMC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0034) +#define OMAP4_PM_L3INIT_HSI_WKDEP_OFFSET 0x0038 #define OMAP4430_PM_L3INIT_HSI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0038) +#define OMAP4_RM_L3INIT_HSI_CONTEXT_OFFSET 0x003c #define OMAP4430_RM_L3INIT_HSI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x003c) +#define OMAP4_PM_L3INIT_UNIPRO1_WKDEP_OFFSET 0x0040 #define OMAP4430_PM_L3INIT_UNIPRO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0040) +#define OMAP4_RM_L3INIT_UNIPRO1_CONTEXT_OFFSET 0x0044 #define OMAP4430_RM_L3INIT_UNIPRO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0044) +#define OMAP4_PM_L3INIT_USB_HOST_WKDEP_OFFSET 0x0058 #define OMAP4430_PM_L3INIT_USB_HOST_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0058) +#define OMAP4_RM_L3INIT_USB_HOST_CONTEXT_OFFSET 0x005c #define OMAP4430_RM_L3INIT_USB_HOST_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x005c) +#define OMAP4_PM_L3INIT_USB_OTG_WKDEP_OFFSET 0x0060 #define OMAP4430_PM_L3INIT_USB_OTG_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0060) +#define OMAP4_RM_L3INIT_USB_OTG_CONTEXT_OFFSET 0x0064 #define OMAP4430_RM_L3INIT_USB_OTG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0064) +#define OMAP4_PM_L3INIT_USB_TLL_WKDEP_OFFSET 0x0068 #define OMAP4430_PM_L3INIT_USB_TLL_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0068) +#define OMAP4_RM_L3INIT_USB_TLL_CONTEXT_OFFSET 0x006c #define OMAP4430_RM_L3INIT_USB_TLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x006c) +#define OMAP4_RM_L3INIT_P1500_CONTEXT_OFFSET 0x007c #define OMAP4430_RM_L3INIT_P1500_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x007c) +#define OMAP4_RM_L3INIT_EMAC_CONTEXT_OFFSET 0x0084 #define OMAP4430_RM_L3INIT_EMAC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0084) +#define OMAP4_PM_L3INIT_SATA_WKDEP_OFFSET 0x0088 #define OMAP4430_PM_L3INIT_SATA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0088) +#define OMAP4_RM_L3INIT_SATA_CONTEXT_OFFSET 0x008c #define OMAP4430_RM_L3INIT_SATA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x008c) +#define OMAP4_RM_L3INIT_TPPSS_CONTEXT_OFFSET 0x0094 #define OMAP4430_RM_L3INIT_TPPSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0094) +#define OMAP4_PM_L3INIT_PCIESS_WKDEP_OFFSET 0x0098 #define OMAP4430_PM_L3INIT_PCIESS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0098) +#define OMAP4_RM_L3INIT_PCIESS_CONTEXT_OFFSET 0x009c #define OMAP4430_RM_L3INIT_PCIESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x009c) +#define OMAP4_RM_L3INIT_CCPTX_CONTEXT_OFFSET 0x00ac #define OMAP4430_RM_L3INIT_CCPTX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00ac) +#define OMAP4_PM_L3INIT_XHPI_WKDEP_OFFSET 0x00c0 #define OMAP4430_PM_L3INIT_XHPI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00c0) +#define OMAP4_RM_L3INIT_XHPI_CONTEXT_OFFSET 0x00c4 #define OMAP4430_RM_L3INIT_XHPI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00c4) +#define OMAP4_PM_L3INIT_MMC6_WKDEP_OFFSET 0x00c8 #define OMAP4430_PM_L3INIT_MMC6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00c8) +#define OMAP4_RM_L3INIT_MMC6_CONTEXT_OFFSET 0x00cc #define OMAP4430_RM_L3INIT_MMC6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00cc) +#define OMAP4_PM_L3INIT_USB_HOST_FS_WKDEP_OFFSET 0x00d0 #define OMAP4430_PM_L3INIT_USB_HOST_FS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00d0) +#define OMAP4_RM_L3INIT_USB_HOST_FS_CONTEXT_OFFSET 0x00d4 #define OMAP4430_RM_L3INIT_USB_HOST_FS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00d4) +#define OMAP4_RM_L3INIT_USBPHYOCP2SCP_CONTEXT_OFFSET 0x00e4 #define OMAP4430_RM_L3INIT_USBPHYOCP2SCP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00e4) /* PRM.L4PER_PRM register offsets */ +#define OMAP4_PM_L4PER_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_L4PER_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0000) +#define OMAP4_PM_L4PER_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_L4PER_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0004) +#define OMAP4_RM_L4PER_ADC_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_L4PER_ADC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0024) +#define OMAP4_PM_L4PER_DMTIMER10_WKDEP_OFFSET 0x0028 #define OMAP4430_PM_L4PER_DMTIMER10_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0028) +#define OMAP4_RM_L4PER_DMTIMER10_CONTEXT_OFFSET 0x002c #define OMAP4430_RM_L4PER_DMTIMER10_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x002c) +#define OMAP4_PM_L4PER_DMTIMER11_WKDEP_OFFSET 0x0030 #define OMAP4430_PM_L4PER_DMTIMER11_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0030) +#define OMAP4_RM_L4PER_DMTIMER11_CONTEXT_OFFSET 0x0034 #define OMAP4430_RM_L4PER_DMTIMER11_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0034) +#define OMAP4_PM_L4PER_DMTIMER2_WKDEP_OFFSET 0x0038 #define OMAP4430_PM_L4PER_DMTIMER2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0038) +#define OMAP4_RM_L4PER_DMTIMER2_CONTEXT_OFFSET 0x003c #define OMAP4430_RM_L4PER_DMTIMER2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x003c) +#define OMAP4_PM_L4PER_DMTIMER3_WKDEP_OFFSET 0x0040 #define OMAP4430_PM_L4PER_DMTIMER3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0040) +#define OMAP4_RM_L4PER_DMTIMER3_CONTEXT_OFFSET 0x0044 #define OMAP4430_RM_L4PER_DMTIMER3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0044) +#define OMAP4_PM_L4PER_DMTIMER4_WKDEP_OFFSET 0x0048 #define OMAP4430_PM_L4PER_DMTIMER4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0048) +#define OMAP4_RM_L4PER_DMTIMER4_CONTEXT_OFFSET 0x004c #define OMAP4430_RM_L4PER_DMTIMER4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x004c) +#define OMAP4_PM_L4PER_DMTIMER9_WKDEP_OFFSET 0x0050 #define OMAP4430_PM_L4PER_DMTIMER9_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0050) +#define OMAP4_RM_L4PER_DMTIMER9_CONTEXT_OFFSET 0x0054 #define OMAP4430_RM_L4PER_DMTIMER9_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0054) +#define OMAP4_RM_L4PER_ELM_CONTEXT_OFFSET 0x005c #define OMAP4430_RM_L4PER_ELM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x005c) +#define OMAP4_PM_L4PER_GPIO2_WKDEP_OFFSET 0x0060 #define OMAP4430_PM_L4PER_GPIO2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0060) +#define OMAP4_RM_L4PER_GPIO2_CONTEXT_OFFSET 0x0064 #define OMAP4430_RM_L4PER_GPIO2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0064) +#define OMAP4_PM_L4PER_GPIO3_WKDEP_OFFSET 0x0068 #define OMAP4430_PM_L4PER_GPIO3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0068) +#define OMAP4_RM_L4PER_GPIO3_CONTEXT_OFFSET 0x006c #define OMAP4430_RM_L4PER_GPIO3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x006c) +#define OMAP4_PM_L4PER_GPIO4_WKDEP_OFFSET 0x0070 #define OMAP4430_PM_L4PER_GPIO4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0070) +#define OMAP4_RM_L4PER_GPIO4_CONTEXT_OFFSET 0x0074 #define OMAP4430_RM_L4PER_GPIO4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0074) +#define OMAP4_PM_L4PER_GPIO5_WKDEP_OFFSET 0x0078 #define OMAP4430_PM_L4PER_GPIO5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0078) +#define OMAP4_RM_L4PER_GPIO5_CONTEXT_OFFSET 0x007c #define OMAP4430_RM_L4PER_GPIO5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x007c) +#define OMAP4_PM_L4PER_GPIO6_WKDEP_OFFSET 0x0080 #define OMAP4430_PM_L4PER_GPIO6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0080) +#define OMAP4_RM_L4PER_GPIO6_CONTEXT_OFFSET 0x0084 #define OMAP4430_RM_L4PER_GPIO6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0084) +#define OMAP4_RM_L4PER_HDQ1W_CONTEXT_OFFSET 0x008c #define OMAP4430_RM_L4PER_HDQ1W_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x008c) +#define OMAP4_PM_L4PER_HECC1_WKDEP_OFFSET 0x0090 #define OMAP4430_PM_L4PER_HECC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0090) +#define OMAP4_RM_L4PER_HECC1_CONTEXT_OFFSET 0x0094 #define OMAP4430_RM_L4PER_HECC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0094) +#define OMAP4_PM_L4PER_HECC2_WKDEP_OFFSET 0x0098 #define OMAP4430_PM_L4PER_HECC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0098) +#define OMAP4_RM_L4PER_HECC2_CONTEXT_OFFSET 0x009c #define OMAP4430_RM_L4PER_HECC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x009c) +#define OMAP4_PM_L4PER_I2C1_WKDEP_OFFSET 0x00a0 #define OMAP4430_PM_L4PER_I2C1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00a0) +#define OMAP4_RM_L4PER_I2C1_CONTEXT_OFFSET 0x00a4 #define OMAP4430_RM_L4PER_I2C1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00a4) +#define OMAP4_PM_L4PER_I2C2_WKDEP_OFFSET 0x00a8 #define OMAP4430_PM_L4PER_I2C2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00a8) +#define OMAP4_RM_L4PER_I2C2_CONTEXT_OFFSET 0x00ac #define OMAP4430_RM_L4PER_I2C2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00ac) +#define OMAP4_PM_L4PER_I2C3_WKDEP_OFFSET 0x00b0 #define OMAP4430_PM_L4PER_I2C3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00b0) +#define OMAP4_RM_L4PER_I2C3_CONTEXT_OFFSET 0x00b4 #define OMAP4430_RM_L4PER_I2C3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00b4) +#define OMAP4_PM_L4PER_I2C4_WKDEP_OFFSET 0x00b8 #define OMAP4430_PM_L4PER_I2C4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00b8) +#define OMAP4_RM_L4PER_I2C4_CONTEXT_OFFSET 0x00bc #define OMAP4430_RM_L4PER_I2C4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00bc) +#define OMAP4_RM_L4PER_L4_PER_CONTEXT_OFFSET 0x00c0 #define OMAP4430_RM_L4PER_L4_PER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00c0) +#define OMAP4_PM_L4PER_MCASP2_WKDEP_OFFSET 0x00d0 #define OMAP4430_PM_L4PER_MCASP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00d0) +#define OMAP4_RM_L4PER_MCASP2_CONTEXT_OFFSET 0x00d4 #define OMAP4430_RM_L4PER_MCASP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00d4) +#define OMAP4_PM_L4PER_MCASP3_WKDEP_OFFSET 0x00d8 #define OMAP4430_PM_L4PER_MCASP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00d8) +#define OMAP4_RM_L4PER_MCASP3_CONTEXT_OFFSET 0x00dc #define OMAP4430_RM_L4PER_MCASP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00dc) +#define OMAP4_PM_L4PER_MCBSP4_WKDEP_OFFSET 0x00e0 #define OMAP4430_PM_L4PER_MCBSP4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00e0) +#define OMAP4_RM_L4PER_MCBSP4_CONTEXT_OFFSET 0x00e4 #define OMAP4430_RM_L4PER_MCBSP4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00e4) +#define OMAP4_RM_L4PER_MGATE_CONTEXT_OFFSET 0x00ec #define OMAP4430_RM_L4PER_MGATE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00ec) +#define OMAP4_PM_L4PER_MCSPI1_WKDEP_OFFSET 0x00f0 #define OMAP4430_PM_L4PER_MCSPI1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00f0) +#define OMAP4_RM_L4PER_MCSPI1_CONTEXT_OFFSET 0x00f4 #define OMAP4430_RM_L4PER_MCSPI1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00f4) +#define OMAP4_PM_L4PER_MCSPI2_WKDEP_OFFSET 0x00f8 #define OMAP4430_PM_L4PER_MCSPI2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00f8) +#define OMAP4_RM_L4PER_MCSPI2_CONTEXT_OFFSET 0x00fc #define OMAP4430_RM_L4PER_MCSPI2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00fc) +#define OMAP4_PM_L4PER_MCSPI3_WKDEP_OFFSET 0x0100 #define OMAP4430_PM_L4PER_MCSPI3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0100) +#define OMAP4_RM_L4PER_MCSPI3_CONTEXT_OFFSET 0x0104 #define OMAP4430_RM_L4PER_MCSPI3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0104) +#define OMAP4_PM_L4PER_MCSPI4_WKDEP_OFFSET 0x0108 #define OMAP4430_PM_L4PER_MCSPI4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0108) +#define OMAP4_RM_L4PER_MCSPI4_CONTEXT_OFFSET 0x010c #define OMAP4430_RM_L4PER_MCSPI4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x010c) +#define OMAP4_PM_L4PER_MMCSD3_WKDEP_OFFSET 0x0120 #define OMAP4430_PM_L4PER_MMCSD3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0120) +#define OMAP4_RM_L4PER_MMCSD3_CONTEXT_OFFSET 0x0124 #define OMAP4430_RM_L4PER_MMCSD3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0124) +#define OMAP4_PM_L4PER_MMCSD4_WKDEP_OFFSET 0x0128 #define OMAP4430_PM_L4PER_MMCSD4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0128) +#define OMAP4_RM_L4PER_MMCSD4_CONTEXT_OFFSET 0x012c #define OMAP4430_RM_L4PER_MMCSD4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x012c) +#define OMAP4_RM_L4PER_MSPROHG_CONTEXT_OFFSET 0x0134 #define OMAP4430_RM_L4PER_MSPROHG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0134) +#define OMAP4_PM_L4PER_SLIMBUS2_WKDEP_OFFSET 0x0138 #define OMAP4430_PM_L4PER_SLIMBUS2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0138) +#define OMAP4_RM_L4PER_SLIMBUS2_CONTEXT_OFFSET 0x013c #define OMAP4430_RM_L4PER_SLIMBUS2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x013c) +#define OMAP4_PM_L4PER_UART1_WKDEP_OFFSET 0x0140 #define OMAP4430_PM_L4PER_UART1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0140) +#define OMAP4_RM_L4PER_UART1_CONTEXT_OFFSET 0x0144 #define OMAP4430_RM_L4PER_UART1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0144) +#define OMAP4_PM_L4PER_UART2_WKDEP_OFFSET 0x0148 #define OMAP4430_PM_L4PER_UART2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0148) +#define OMAP4_RM_L4PER_UART2_CONTEXT_OFFSET 0x014c #define OMAP4430_RM_L4PER_UART2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x014c) +#define OMAP4_PM_L4PER_UART3_WKDEP_OFFSET 0x0150 #define OMAP4430_PM_L4PER_UART3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0150) +#define OMAP4_RM_L4PER_UART3_CONTEXT_OFFSET 0x0154 #define OMAP4430_RM_L4PER_UART3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0154) +#define OMAP4_PM_L4PER_UART4_WKDEP_OFFSET 0x0158 #define OMAP4430_PM_L4PER_UART4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0158) +#define OMAP4_RM_L4PER_UART4_CONTEXT_OFFSET 0x015c #define OMAP4430_RM_L4PER_UART4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x015c) +#define OMAP4_PM_L4PER_MMCSD5_WKDEP_OFFSET 0x0160 #define OMAP4430_PM_L4PER_MMCSD5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0160) +#define OMAP4_RM_L4PER_MMCSD5_CONTEXT_OFFSET 0x0164 #define OMAP4430_RM_L4PER_MMCSD5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0164) +#define OMAP4_PM_L4PER_I2C5_WKDEP_OFFSET 0x0168 #define OMAP4430_PM_L4PER_I2C5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0168) +#define OMAP4_RM_L4PER_I2C5_CONTEXT_OFFSET 0x016c #define OMAP4430_RM_L4PER_I2C5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x016c) +#define OMAP4_RM_L4SEC_AES1_CONTEXT_OFFSET 0x01a4 #define OMAP4430_RM_L4SEC_AES1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01a4) +#define OMAP4_RM_L4SEC_AES2_CONTEXT_OFFSET 0x01ac #define OMAP4430_RM_L4SEC_AES2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01ac) +#define OMAP4_RM_L4SEC_DES3DES_CONTEXT_OFFSET 0x01b4 #define OMAP4430_RM_L4SEC_DES3DES_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01b4) +#define OMAP4_RM_L4SEC_PKAEIP29_CONTEXT_OFFSET 0x01bc #define OMAP4430_RM_L4SEC_PKAEIP29_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01bc) +#define OMAP4_RM_L4SEC_RNG_CONTEXT_OFFSET 0x01c4 #define OMAP4430_RM_L4SEC_RNG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01c4) +#define OMAP4_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET 0x01cc #define OMAP4430_RM_L4SEC_SHA2MD51_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01cc) +#define OMAP4_RM_L4SEC_CRYPTODMA_CONTEXT_OFFSET 0x01dc #define OMAP4430_RM_L4SEC_CRYPTODMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01dc) /* PRM.CEFUSE_PRM register offsets */ +#define OMAP4_PM_CEFUSE_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_CEFUSE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_MOD, 0x0000) +#define OMAP4_PM_CEFUSE_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_CEFUSE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_MOD, 0x0004) +#define OMAP4_RM_CEFUSE_CEFUSE_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_CEFUSE_CEFUSE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_MOD, 0x0024) /* PRM.WKUP_PRM register offsets */ +#define OMAP4_RM_WKUP_L4WKUP_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_WKUP_L4WKUP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0024) +#define OMAP4_RM_WKUP_WDT1_CONTEXT_OFFSET 0x002c #define OMAP4430_RM_WKUP_WDT1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x002c) +#define OMAP4_PM_WKUP_WDT2_WKDEP_OFFSET 0x0030 #define OMAP4430_PM_WKUP_WDT2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0030) +#define OMAP4_RM_WKUP_WDT2_CONTEXT_OFFSET 0x0034 #define OMAP4430_RM_WKUP_WDT2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0034) +#define OMAP4_PM_WKUP_GPIO1_WKDEP_OFFSET 0x0038 #define OMAP4430_PM_WKUP_GPIO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0038) +#define OMAP4_RM_WKUP_GPIO1_CONTEXT_OFFSET 0x003c #define OMAP4430_RM_WKUP_GPIO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x003c) +#define OMAP4_PM_WKUP_TIMER1_WKDEP_OFFSET 0x0040 #define OMAP4430_PM_WKUP_TIMER1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0040) +#define OMAP4_RM_WKUP_TIMER1_CONTEXT_OFFSET 0x0044 #define OMAP4430_RM_WKUP_TIMER1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0044) +#define OMAP4_PM_WKUP_TIMER12_WKDEP_OFFSET 0x0048 #define OMAP4430_PM_WKUP_TIMER12_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0048) +#define OMAP4_RM_WKUP_TIMER12_CONTEXT_OFFSET 0x004c #define OMAP4430_RM_WKUP_TIMER12_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x004c) +#define OMAP4_RM_WKUP_SYNCTIMER_CONTEXT_OFFSET 0x0054 #define OMAP4430_RM_WKUP_SYNCTIMER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0054) +#define OMAP4_PM_WKUP_USIM_WKDEP_OFFSET 0x0058 #define OMAP4430_PM_WKUP_USIM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0058) +#define OMAP4_RM_WKUP_USIM_CONTEXT_OFFSET 0x005c #define OMAP4430_RM_WKUP_USIM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x005c) +#define OMAP4_RM_WKUP_SARRAM_CONTEXT_OFFSET 0x0064 #define OMAP4430_RM_WKUP_SARRAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0064) +#define OMAP4_PM_WKUP_KEYBOARD_WKDEP_OFFSET 0x0078 #define OMAP4430_PM_WKUP_KEYBOARD_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0078) +#define OMAP4_RM_WKUP_KEYBOARD_CONTEXT_OFFSET 0x007c #define OMAP4430_RM_WKUP_KEYBOARD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x007c) +#define OMAP4_PM_WKUP_RTC_WKDEP_OFFSET 0x0080 #define OMAP4430_PM_WKUP_RTC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0080) +#define OMAP4_RM_WKUP_RTC_CONTEXT_OFFSET 0x0084 #define OMAP4430_RM_WKUP_RTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0084) /* PRM.WKUP_CM register offsets */ +#define OMAP4_CM_WKUP_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_WKUP_CLKSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0000) +#define OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_WKUP_L4WKUP_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0020) +#define OMAP4_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x0028 #define OMAP4430_CM_WKUP_WDT1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0028) +#define OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET 0x0030 #define OMAP4430_CM_WKUP_WDT2_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0030) +#define OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET 0x0038 #define OMAP4430_CM_WKUP_GPIO1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0038) +#define OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x0040 #define OMAP4430_CM_WKUP_TIMER1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0040) +#define OMAP4_CM_WKUP_TIMER12_CLKCTRL_OFFSET 0x0048 #define OMAP4430_CM_WKUP_TIMER12_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0048) +#define OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET 0x0050 #define OMAP4430_CM_WKUP_SYNCTIMER_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0050) +#define OMAP4_CM_WKUP_USIM_CLKCTRL_OFFSET 0x0058 #define OMAP4430_CM_WKUP_USIM_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0058) +#define OMAP4_CM_WKUP_SARRAM_CLKCTRL_OFFSET 0x0060 #define OMAP4430_CM_WKUP_SARRAM_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0060) +#define OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET 0x0078 #define OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0078) +#define OMAP4_CM_WKUP_RTC_CLKCTRL_OFFSET 0x0080 #define OMAP4430_CM_WKUP_RTC_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0080) +#define OMAP4_CM_WKUP_BANDGAP_CLKCTRL_OFFSET 0x0088 #define OMAP4430_CM_WKUP_BANDGAP_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0088) /* PRM.EMU_PRM register offsets */ +#define OMAP4_PM_EMU_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_EMU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_MOD, 0x0000) +#define OMAP4_PM_EMU_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_EMU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_MOD, 0x0004) +#define OMAP4_RM_EMU_DEBUGSS_CONTEXT_OFFSET 0x0024 #define OMAP4430_RM_EMU_DEBUGSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_MOD, 0x0024) /* PRM.EMU_CM register offsets */ +#define OMAP4_CM_EMU_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_EMU_CLKSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_MOD, 0x0000) +#define OMAP4_CM_EMU_DYNAMICDEP_OFFSET 0x0008 #define OMAP4430_CM_EMU_DYNAMICDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_MOD, 0x0008) +#define OMAP4_CM_EMU_DEBUGSS_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_EMU_DEBUGSS_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_MOD, 0x0020) /* PRM.DEVICE_PRM register offsets */ +#define OMAP4_PRM_RSTCTRL_OFFSET 0x0000 #define OMAP4430_PRM_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0000) +#define OMAP4_PRM_RSTST_OFFSET 0x0004 #define OMAP4430_PRM_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0004) +#define OMAP4_PRM_RSTTIME_OFFSET 0x0008 #define OMAP4430_PRM_RSTTIME OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0008) +#define OMAP4_PRM_CLKREQCTRL_OFFSET 0x000c #define OMAP4430_PRM_CLKREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x000c) +#define OMAP4_PRM_VOLTCTRL_OFFSET 0x0010 #define OMAP4430_PRM_VOLTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0010) +#define OMAP4_PRM_PWRREQCTRL_OFFSET 0x0014 #define OMAP4430_PRM_PWRREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0014) +#define OMAP4_PRM_PSCON_COUNT_OFFSET 0x0018 #define OMAP4430_PRM_PSCON_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0018) +#define OMAP4_PRM_IO_COUNT_OFFSET 0x001c #define OMAP4430_PRM_IO_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x001c) +#define OMAP4_PRM_IO_PMCTRL_OFFSET 0x0020 #define OMAP4430_PRM_IO_PMCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0020) +#define OMAP4_PRM_VOLTSETUP_WARMRESET_OFFSET 0x0024 #define OMAP4430_PRM_VOLTSETUP_WARMRESET OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0024) +#define OMAP4_PRM_VOLTSETUP_CORE_OFF_OFFSET 0x0028 #define OMAP4430_PRM_VOLTSETUP_CORE_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0028) +#define OMAP4_PRM_VOLTSETUP_MPU_OFF_OFFSET 0x002c #define OMAP4430_PRM_VOLTSETUP_MPU_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x002c) +#define OMAP4_PRM_VOLTSETUP_IVA_OFF_OFFSET 0x0030 #define OMAP4430_PRM_VOLTSETUP_IVA_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0030) +#define OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET 0x0034 #define OMAP4430_PRM_VOLTSETUP_CORE_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0034) +#define OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET 0x0038 #define OMAP4430_PRM_VOLTSETUP_MPU_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0038) +#define OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET 0x003c #define OMAP4430_PRM_VOLTSETUP_IVA_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x003c) +#define OMAP4_PRM_VP_CORE_CONFIG_OFFSET 0x0040 #define OMAP4430_PRM_VP_CORE_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0040) +#define OMAP4_PRM_VP_CORE_STATUS_OFFSET 0x0044 #define OMAP4430_PRM_VP_CORE_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0044) +#define OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET 0x0048 #define OMAP4430_PRM_VP_CORE_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0048) +#define OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET 0x004c #define OMAP4430_PRM_VP_CORE_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x004c) +#define OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET 0x0050 #define OMAP4430_PRM_VP_CORE_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0050) +#define OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET 0x0054 #define OMAP4430_PRM_VP_CORE_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0054) +#define OMAP4_PRM_VP_MPU_CONFIG_OFFSET 0x0058 #define OMAP4430_PRM_VP_MPU_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0058) +#define OMAP4_PRM_VP_MPU_STATUS_OFFSET 0x005c #define OMAP4430_PRM_VP_MPU_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x005c) +#define OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET 0x0060 #define OMAP4430_PRM_VP_MPU_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0060) +#define OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET 0x0064 #define OMAP4430_PRM_VP_MPU_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0064) +#define OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET 0x0068 #define OMAP4430_PRM_VP_MPU_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0068) +#define OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET 0x006c #define OMAP4430_PRM_VP_MPU_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x006c) +#define OMAP4_PRM_VP_IVA_CONFIG_OFFSET 0x0070 #define OMAP4430_PRM_VP_IVA_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0070) +#define OMAP4_PRM_VP_IVA_STATUS_OFFSET 0x0074 #define OMAP4430_PRM_VP_IVA_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0074) +#define OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET 0x0078 #define OMAP4430_PRM_VP_IVA_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0078) +#define OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET 0x007c #define OMAP4430_PRM_VP_IVA_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x007c) +#define OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET 0x0080 #define OMAP4430_PRM_VP_IVA_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0080) +#define OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET 0x0084 #define OMAP4430_PRM_VP_IVA_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0084) +#define OMAP4_PRM_VC_SMPS_SA_OFFSET 0x0088 #define OMAP4430_PRM_VC_SMPS_SA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0088) +#define OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET 0x008c #define OMAP4430_PRM_VC_VAL_SMPS_RA_VOL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x008c) +#define OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET 0x0090 #define OMAP4430_PRM_VC_VAL_SMPS_RA_CMD OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0090) +#define OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET 0x0094 #define OMAP4430_PRM_VC_VAL_CMD_VDD_CORE_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0094) +#define OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET 0x0098 #define OMAP4430_PRM_VC_VAL_CMD_VDD_MPU_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0098) +#define OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET 0x009c #define OMAP4430_PRM_VC_VAL_CMD_VDD_IVA_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x009c) +#define OMAP4_PRM_VC_VAL_BYPASS_OFFSET 0x00a0 #define OMAP4430_PRM_VC_VAL_BYPASS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00a0) +#define OMAP4_PRM_VC_CFG_CHANNEL_OFFSET 0x00a4 #define OMAP4430_PRM_VC_CFG_CHANNEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00a4) +#define OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET 0x00a8 #define OMAP4430_PRM_VC_CFG_I2C_MODE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00a8) +#define OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET 0x00ac #define OMAP4430_PRM_VC_CFG_I2C_CLK OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00ac) +#define OMAP4_PRM_SRAM_COUNT_OFFSET 0x00b0 #define OMAP4430_PRM_SRAM_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00b0) +#define OMAP4_PRM_SRAM_WKUP_SETUP_OFFSET 0x00b4 #define OMAP4430_PRM_SRAM_WKUP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00b4) +#define OMAP4_PRM_LDO_SRAM_CORE_SETUP_OFFSET 0x00b8 #define OMAP4430_PRM_LDO_SRAM_CORE_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00b8) +#define OMAP4_PRM_LDO_SRAM_CORE_CTRL_OFFSET 0x00bc #define OMAP4430_PRM_LDO_SRAM_CORE_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00bc) +#define OMAP4_PRM_LDO_SRAM_MPU_SETUP_OFFSET 0x00c0 #define OMAP4430_PRM_LDO_SRAM_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00c0) +#define OMAP4_PRM_LDO_SRAM_MPU_CTRL_OFFSET 0x00c4 #define OMAP4430_PRM_LDO_SRAM_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00c4) +#define OMAP4_PRM_LDO_SRAM_IVA_SETUP_OFFSET 0x00c8 #define OMAP4430_PRM_LDO_SRAM_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00c8) +#define OMAP4_PRM_LDO_SRAM_IVA_CTRL_OFFSET 0x00cc #define OMAP4430_PRM_LDO_SRAM_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00cc) +#define OMAP4_PRM_LDO_ABB_MPU_SETUP_OFFSET 0x00d0 #define OMAP4430_PRM_LDO_ABB_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00d0) +#define OMAP4_PRM_LDO_ABB_MPU_CTRL_OFFSET 0x00d4 #define OMAP4430_PRM_LDO_ABB_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00d4) +#define OMAP4_PRM_LDO_ABB_IVA_SETUP_OFFSET 0x00d8 #define OMAP4430_PRM_LDO_ABB_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00d8) +#define OMAP4_PRM_LDO_ABB_IVA_CTRL_OFFSET 0x00dc #define OMAP4430_PRM_LDO_ABB_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00dc) +#define OMAP4_PRM_LDO_BANDGAP_CTRL_OFFSET 0x00e0 #define OMAP4430_PRM_LDO_BANDGAP_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e0) +#define OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET 0x00e4 #define OMAP4430_PRM_DEVICE_OFF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e4) +#define OMAP4_PRM_PHASE1_CNDP_OFFSET 0x00e8 #define OMAP4430_PRM_PHASE1_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e8) +#define OMAP4_PRM_PHASE2A_CNDP_OFFSET 0x00ec #define OMAP4430_PRM_PHASE2A_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00ec) +#define OMAP4_PRM_PHASE2B_CNDP_OFFSET 0x00f0 #define OMAP4430_PRM_PHASE2B_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f0) +#define OMAP4_PRM_MODEM_IF_CTRL_OFFSET 0x00f4 #define OMAP4430_PRM_MODEM_IF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f4) /* @@ -391,26 +709,42 @@ */ /* PRCM_MPU.OCP_SOCKET_PRCM register offsets */ +#define OMAP4_REVISION_PRCM_OFFSET 0x0000 #define OMAP4430_REVISION_PRCM OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_MOD, 0x0000) /* PRCM_MPU.DEVICE_PRM register offsets */ +#define OMAP4_PRCM_MPU_PRM_RSTST_OFFSET 0x0000 #define OMAP4430_PRCM_MPU_PRM_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_MOD, 0x0000) /* PRCM_MPU.CPU0 register offsets */ +#define OMAP4_PM_CPU0_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_CPU0_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0000) +#define OMAP4_PM_CPU0_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_CPU0_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0004) +#define OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET 0x0008 #define OMAP4430_RM_CPU0_CPU0_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0008) +#define OMAP4_RM_CPU0_CPU0_RSTCTRL_OFFSET 0x000c #define OMAP4430_RM_CPU0_CPU0_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x000c) +#define OMAP4_RM_CPU0_CPU0_RSTST_OFFSET 0x0010 #define OMAP4430_RM_CPU0_CPU0_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0010) +#define OMAP4_CM_CPU0_CPU0_CLKCTRL_OFFSET 0x0014 #define OMAP4430_CM_CPU0_CPU0_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0014) +#define OMAP4_CM_CPU0_CLKSTCTRL_OFFSET 0x0018 #define OMAP4430_CM_CPU0_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_MOD, 0x0018) /* PRCM_MPU.CPU1 register offsets */ +#define OMAP4_PM_CPU1_PWRSTCTRL_OFFSET 0x0000 #define OMAP4430_PM_CPU1_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0000) +#define OMAP4_PM_CPU1_PWRSTST_OFFSET 0x0004 #define OMAP4430_PM_CPU1_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0004) +#define OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET 0x0008 #define OMAP4430_RM_CPU1_CPU1_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0008) +#define OMAP4_RM_CPU1_CPU1_RSTCTRL_OFFSET 0x000c #define OMAP4430_RM_CPU1_CPU1_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x000c) +#define OMAP4_RM_CPU1_CPU1_RSTST_OFFSET 0x0010 #define OMAP4430_RM_CPU1_CPU1_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0010) +#define OMAP4_CM_CPU1_CPU1_CLKCTRL_OFFSET 0x0014 #define OMAP4430_CM_CPU1_CPU1_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0014) +#define OMAP4_CM_CPU1_CLKSTCTRL_OFFSET 0x0018 #define OMAP4430_CM_CPU1_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_MOD, 0x0018) #endif -- cgit v1.2.3-59-g8ed1b From fe894d56322b10910631800b86f25f13bc64c639 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 20 May 2010 12:31:12 -0600 Subject: OMAP4: PRCM: Add offset defines for all CM registers The cm44xx.h files only had absolute register address defines for all CM registers. This patch adds additional register offset defines for all the registers, so they can be used with apis like cm_read_mod_* Signed-off-by: Rajendra Nayak Signed-off-by: Benoit Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/cm44xx.h | 260 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h index b889ac633731..336d94889e5b 100644 --- a/arch/arm/mach-omap2/cm44xx.h +++ b/arch/arm/mach-omap2/cm44xx.h @@ -26,296 +26,556 @@ /* CM1 */ /* CM1.OCP_SOCKET_CM1 register offsets */ +#define OMAP4_REVISION_CM1_OFFSET 0x0000 #define OMAP4430_REVISION_CM1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_MOD, 0x0000) +#define OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET 0x0040 #define OMAP4430_CM_CM1_PROFILING_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_MOD, 0x0040) /* CM1.CKGEN_CM1 register offsets */ +#define OMAP4_CM_CLKSEL_CORE_OFFSET 0x0000 #define OMAP4430_CM_CLKSEL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0000) +#define OMAP4_CM_CLKSEL_ABE_OFFSET 0x0008 #define OMAP4430_CM_CLKSEL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0008) +#define OMAP4_CM_DLL_CTRL_OFFSET 0x0010 #define OMAP4430_CM_DLL_CTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0010) +#define OMAP4_CM_CLKMODE_DPLL_CORE_OFFSET 0x0020 #define OMAP4430_CM_CLKMODE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0020) +#define OMAP4_CM_IDLEST_DPLL_CORE_OFFSET 0x0024 #define OMAP4430_CM_IDLEST_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0024) +#define OMAP4_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0028 #define OMAP4430_CM_AUTOIDLE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0028) +#define OMAP4_CM_CLKSEL_DPLL_CORE_OFFSET 0x002c #define OMAP4430_CM_CLKSEL_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x002c) +#define OMAP4_CM_DIV_M2_DPLL_CORE_OFFSET 0x0030 #define OMAP4430_CM_DIV_M2_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0030) +#define OMAP4_CM_DIV_M3_DPLL_CORE_OFFSET 0x0034 #define OMAP4430_CM_DIV_M3_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0034) +#define OMAP4_CM_DIV_M4_DPLL_CORE_OFFSET 0x0038 #define OMAP4430_CM_DIV_M4_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0038) +#define OMAP4_CM_DIV_M5_DPLL_CORE_OFFSET 0x003c #define OMAP4430_CM_DIV_M5_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x003c) +#define OMAP4_CM_DIV_M6_DPLL_CORE_OFFSET 0x0040 #define OMAP4430_CM_DIV_M6_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0040) +#define OMAP4_CM_DIV_M7_DPLL_CORE_OFFSET 0x0044 #define OMAP4430_CM_DIV_M7_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0044) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0048 #define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0048) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x004c #define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x004c) +#define OMAP4_CM_EMU_OVERRIDE_DPLL_CORE_OFFSET 0x0050 #define OMAP4430_CM_EMU_OVERRIDE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0050) +#define OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET 0x0060 #define OMAP4430_CM_CLKMODE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0060) +#define OMAP4_CM_IDLEST_DPLL_MPU_OFFSET 0x0064 #define OMAP4430_CM_IDLEST_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0064) +#define OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x0068 #define OMAP4430_CM_AUTOIDLE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0068) +#define OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET 0x006c #define OMAP4430_CM_CLKSEL_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x006c) +#define OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET 0x0070 #define OMAP4430_CM_DIV_M2_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0070) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0088 #define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0088) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x008c #define OMAP4430_CM_SSC_MODFREQDIV_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x008c) +#define OMAP4_CM_BYPCLK_DPLL_MPU_OFFSET 0x009c #define OMAP4430_CM_BYPCLK_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x009c) +#define OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET 0x00a0 #define OMAP4430_CM_CLKMODE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00a0) +#define OMAP4_CM_IDLEST_DPLL_IVA_OFFSET 0x00a4 #define OMAP4430_CM_IDLEST_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00a4) +#define OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET 0x00a8 #define OMAP4430_CM_AUTOIDLE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00a8) +#define OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET 0x00ac #define OMAP4430_CM_CLKSEL_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00ac) +#define OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET 0x00b8 #define OMAP4430_CM_DIV_M4_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00b8) +#define OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET 0x00bc #define OMAP4430_CM_DIV_M5_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00bc) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET 0x00c8 #define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00c8) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_IVA_OFFSET 0x00cc #define OMAP4430_CM_SSC_MODFREQDIV_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00cc) +#define OMAP4_CM_BYPCLK_DPLL_IVA_OFFSET 0x00dc #define OMAP4430_CM_BYPCLK_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00dc) +#define OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET 0x00e0 #define OMAP4430_CM_CLKMODE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00e0) +#define OMAP4_CM_IDLEST_DPLL_ABE_OFFSET 0x00e4 #define OMAP4430_CM_IDLEST_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00e4) +#define OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET 0x00e8 #define OMAP4430_CM_AUTOIDLE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00e8) +#define OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET 0x00ec #define OMAP4430_CM_CLKSEL_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00ec) +#define OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET 0x00f0 #define OMAP4430_CM_DIV_M2_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00f0) +#define OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET 0x00f4 #define OMAP4430_CM_DIV_M3_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00f4) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET 0x0108 #define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0108) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_ABE_OFFSET 0x010c #define OMAP4430_CM_SSC_MODFREQDIV_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x010c) +#define OMAP4_CM_CLKMODE_DPLL_DDRPHY_OFFSET 0x0120 #define OMAP4430_CM_CLKMODE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0120) +#define OMAP4_CM_IDLEST_DPLL_DDRPHY_OFFSET 0x0124 #define OMAP4430_CM_IDLEST_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0124) +#define OMAP4_CM_AUTOIDLE_DPLL_DDRPHY_OFFSET 0x0128 #define OMAP4430_CM_AUTOIDLE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0128) +#define OMAP4_CM_CLKSEL_DPLL_DDRPHY_OFFSET 0x012c #define OMAP4430_CM_CLKSEL_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x012c) +#define OMAP4_CM_DIV_M2_DPLL_DDRPHY_OFFSET 0x0130 #define OMAP4430_CM_DIV_M2_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0130) +#define OMAP4_CM_DIV_M4_DPLL_DDRPHY_OFFSET 0x0138 #define OMAP4430_CM_DIV_M4_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0138) +#define OMAP4_CM_DIV_M5_DPLL_DDRPHY_OFFSET 0x013c #define OMAP4430_CM_DIV_M5_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x013c) +#define OMAP4_CM_DIV_M6_DPLL_DDRPHY_OFFSET 0x0140 #define OMAP4430_CM_DIV_M6_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0140) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_DDRPHY_OFFSET 0x0148 #define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0148) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_DDRPHY_OFFSET 0x014c #define OMAP4430_CM_SSC_MODFREQDIV_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x014c) +#define OMAP4_CM_SHADOW_FREQ_CONFIG1_OFFSET 0x0160 #define OMAP4430_CM_SHADOW_FREQ_CONFIG1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0160) +#define OMAP4_CM_SHADOW_FREQ_CONFIG2_OFFSET 0x0164 #define OMAP4430_CM_SHADOW_FREQ_CONFIG2 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0164) +#define OMAP4_CM_DYN_DEP_PRESCAL_OFFSET 0x0170 #define OMAP4430_CM_DYN_DEP_PRESCAL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0170) +#define OMAP4_CM_RESTORE_ST_OFFSET 0x0180 #define OMAP4430_CM_RESTORE_ST OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0180) /* CM1.MPU_CM1 register offsets */ +#define OMAP4_CM_MPU_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_MPU_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0000) +#define OMAP4_CM_MPU_STATICDEP_OFFSET 0x0004 #define OMAP4430_CM_MPU_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0004) +#define OMAP4_CM_MPU_DYNAMICDEP_OFFSET 0x0008 #define OMAP4430_CM_MPU_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0008) +#define OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_MPU_MPU_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0020) /* CM1.TESLA_CM1 register offsets */ +#define OMAP4_CM_TESLA_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_TESLA_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0000) +#define OMAP4_CM_TESLA_STATICDEP_OFFSET 0x0004 #define OMAP4430_CM_TESLA_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0004) +#define OMAP4_CM_TESLA_DYNAMICDEP_OFFSET 0x0008 #define OMAP4430_CM_TESLA_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0008) +#define OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_TESLA_TESLA_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0020) /* CM1.ABE_CM1 register offsets */ +#define OMAP4_CM1_ABE_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM1_ABE_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0000) +#define OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM1_ABE_L4ABE_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0020) +#define OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET 0x0028 #define OMAP4430_CM1_ABE_AESS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0028) +#define OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET 0x0030 #define OMAP4430_CM1_ABE_PDM_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0030) +#define OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET 0x0038 #define OMAP4430_CM1_ABE_DMIC_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0038) +#define OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET 0x0040 #define OMAP4430_CM1_ABE_MCASP_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0040) +#define OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET 0x0048 #define OMAP4430_CM1_ABE_MCBSP1_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0048) +#define OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET 0x0050 #define OMAP4430_CM1_ABE_MCBSP2_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0050) +#define OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET 0x0058 #define OMAP4430_CM1_ABE_MCBSP3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0058) +#define OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET 0x0060 #define OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0060) +#define OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET 0x0068 #define OMAP4430_CM1_ABE_TIMER5_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0068) +#define OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET 0x0070 #define OMAP4430_CM1_ABE_TIMER6_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0070) +#define OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET 0x0078 #define OMAP4430_CM1_ABE_TIMER7_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0078) +#define OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET 0x0080 #define OMAP4430_CM1_ABE_TIMER8_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0080) +#define OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET 0x0088 #define OMAP4430_CM1_ABE_WDT3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0088) /* CM2 */ /* CM2.OCP_SOCKET_CM2 register offsets */ +#define OMAP4_REVISION_CM2_OFFSET 0x0000 #define OMAP4430_REVISION_CM2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_MOD, 0x0000) +#define OMAP4_CM_CM2_PROFILING_CLKCTRL_OFFSET 0x0040 #define OMAP4430_CM_CM2_PROFILING_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_MOD, 0x0040) /* CM2.CKGEN_CM2 register offsets */ +#define OMAP4_CM_CLKSEL_DUCATI_ISS_ROOT_OFFSET 0x0000 #define OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0000) +#define OMAP4_CM_CLKSEL_USB_60MHZ_OFFSET 0x0004 #define OMAP4430_CM_CLKSEL_USB_60MHZ OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0004) +#define OMAP4_CM_SCALE_FCLK_OFFSET 0x0008 #define OMAP4430_CM_SCALE_FCLK OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0008) +#define OMAP4_CM_CORE_DVFS_PERF1_OFFSET 0x0010 #define OMAP4430_CM_CORE_DVFS_PERF1 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0010) +#define OMAP4_CM_CORE_DVFS_PERF2_OFFSET 0x0014 #define OMAP4430_CM_CORE_DVFS_PERF2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0014) +#define OMAP4_CM_CORE_DVFS_PERF3_OFFSET 0x0018 #define OMAP4430_CM_CORE_DVFS_PERF3 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0018) +#define OMAP4_CM_CORE_DVFS_PERF4_OFFSET 0x001c #define OMAP4430_CM_CORE_DVFS_PERF4 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x001c) +#define OMAP4_CM_CORE_DVFS_CURRENT_OFFSET 0x0024 #define OMAP4430_CM_CORE_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0024) +#define OMAP4_CM_IVA_DVFS_PERF_TESLA_OFFSET 0x0028 #define OMAP4430_CM_IVA_DVFS_PERF_TESLA OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0028) +#define OMAP4_CM_IVA_DVFS_PERF_IVAHD_OFFSET 0x002c #define OMAP4430_CM_IVA_DVFS_PERF_IVAHD OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x002c) +#define OMAP4_CM_IVA_DVFS_PERF_ABE_OFFSET 0x0030 #define OMAP4430_CM_IVA_DVFS_PERF_ABE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0030) +#define OMAP4_CM_IVA_DVFS_CURRENT_OFFSET 0x0038 #define OMAP4430_CM_IVA_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0038) +#define OMAP4_CM_CLKMODE_DPLL_PER_OFFSET 0x0040 #define OMAP4430_CM_CLKMODE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0040) +#define OMAP4_CM_IDLEST_DPLL_PER_OFFSET 0x0044 #define OMAP4430_CM_IDLEST_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0044) +#define OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET 0x0048 #define OMAP4430_CM_AUTOIDLE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0048) +#define OMAP4_CM_CLKSEL_DPLL_PER_OFFSET 0x004c #define OMAP4430_CM_CLKSEL_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x004c) +#define OMAP4_CM_DIV_M2_DPLL_PER_OFFSET 0x0050 #define OMAP4430_CM_DIV_M2_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0050) +#define OMAP4_CM_DIV_M3_DPLL_PER_OFFSET 0x0054 #define OMAP4430_CM_DIV_M3_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0054) +#define OMAP4_CM_DIV_M4_DPLL_PER_OFFSET 0x0058 #define OMAP4430_CM_DIV_M4_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0058) +#define OMAP4_CM_DIV_M5_DPLL_PER_OFFSET 0x005c #define OMAP4430_CM_DIV_M5_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x005c) +#define OMAP4_CM_DIV_M6_DPLL_PER_OFFSET 0x0060 #define OMAP4430_CM_DIV_M6_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0060) +#define OMAP4_CM_DIV_M7_DPLL_PER_OFFSET 0x0064 #define OMAP4430_CM_DIV_M7_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0064) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0068 #define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0068) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x006c #define OMAP4430_CM_SSC_MODFREQDIV_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x006c) +#define OMAP4_CM_EMU_OVERRIDE_DPLL_PER_OFFSET 0x0070 #define OMAP4430_CM_EMU_OVERRIDE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0070) +#define OMAP4_CM_CLKMODE_DPLL_USB_OFFSET 0x0080 #define OMAP4430_CM_CLKMODE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0080) +#define OMAP4_CM_IDLEST_DPLL_USB_OFFSET 0x0084 #define OMAP4430_CM_IDLEST_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0084) +#define OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET 0x0088 #define OMAP4430_CM_AUTOIDLE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0088) +#define OMAP4_CM_CLKSEL_DPLL_USB_OFFSET 0x008c #define OMAP4430_CM_CLKSEL_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x008c) +#define OMAP4_CM_DIV_M2_DPLL_USB_OFFSET 0x0090 #define OMAP4430_CM_DIV_M2_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0090) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET 0x00a8 #define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00a8) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_USB_OFFSET 0x00ac #define OMAP4430_CM_SSC_MODFREQDIV_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00ac) +#define OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET 0x00b4 #define OMAP4430_CM_CLKDCOLDO_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00b4) +#define OMAP4_CM_CLKMODE_DPLL_UNIPRO_OFFSET 0x00c0 #define OMAP4430_CM_CLKMODE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00c0) +#define OMAP4_CM_IDLEST_DPLL_UNIPRO_OFFSET 0x00c4 #define OMAP4430_CM_IDLEST_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00c4) +#define OMAP4_CM_AUTOIDLE_DPLL_UNIPRO_OFFSET 0x00c8 #define OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00c8) +#define OMAP4_CM_CLKSEL_DPLL_UNIPRO_OFFSET 0x00cc #define OMAP4430_CM_CLKSEL_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00cc) +#define OMAP4_CM_DIV_M2_DPLL_UNIPRO_OFFSET 0x00d0 #define OMAP4430_CM_DIV_M2_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00d0) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_UNIPRO_OFFSET 0x00e8 #define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00e8) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_UNIPRO_OFFSET 0x00ec #define OMAP4430_CM_SSC_MODFREQDIV_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00ec) /* CM2.ALWAYS_ON_CM2 register offsets */ +#define OMAP4_CM_ALWON_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_ALWON_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0000) +#define OMAP4_CM_ALWON_MDMINTC_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_ALWON_MDMINTC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0020) +#define OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET 0x0028 #define OMAP4430_CM_ALWON_SR_MPU_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0028) +#define OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET 0x0030 #define OMAP4430_CM_ALWON_SR_IVA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0030) +#define OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET 0x0038 #define OMAP4430_CM_ALWON_SR_CORE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0038) /* CM2.CORE_CM2 register offsets */ +#define OMAP4_CM_L3_1_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_L3_1_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0000) +#define OMAP4_CM_L3_1_DYNAMICDEP_OFFSET 0x0008 #define OMAP4430_CM_L3_1_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0008) +#define OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_L3_1_L3_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0020) +#define OMAP4_CM_L3_2_CLKSTCTRL_OFFSET 0x0100 #define OMAP4430_CM_L3_2_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0100) +#define OMAP4_CM_L3_2_DYNAMICDEP_OFFSET 0x0108 #define OMAP4430_CM_L3_2_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0108) +#define OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET 0x0120 #define OMAP4430_CM_L3_2_L3_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0120) +#define OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET 0x0128 #define OMAP4430_CM_L3_2_GPMC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0128) +#define OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET 0x0130 #define OMAP4430_CM_L3_2_OCMC_RAM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0130) +#define OMAP4_CM_DUCATI_CLKSTCTRL_OFFSET 0x0200 #define OMAP4430_CM_DUCATI_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0200) +#define OMAP4_CM_DUCATI_STATICDEP_OFFSET 0x0204 #define OMAP4430_CM_DUCATI_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0204) +#define OMAP4_CM_DUCATI_DYNAMICDEP_OFFSET 0x0208 #define OMAP4430_CM_DUCATI_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0208) +#define OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET 0x0220 #define OMAP4430_CM_DUCATI_DUCATI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0220) +#define OMAP4_CM_SDMA_CLKSTCTRL_OFFSET 0x0300 #define OMAP4430_CM_SDMA_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0300) +#define OMAP4_CM_SDMA_STATICDEP_OFFSET 0x0304 #define OMAP4430_CM_SDMA_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0304) +#define OMAP4_CM_SDMA_DYNAMICDEP_OFFSET 0x0308 #define OMAP4430_CM_SDMA_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0308) +#define OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET 0x0320 #define OMAP4430_CM_SDMA_SDMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0320) +#define OMAP4_CM_MEMIF_CLKSTCTRL_OFFSET 0x0400 #define OMAP4430_CM_MEMIF_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0400) +#define OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET 0x0420 #define OMAP4430_CM_MEMIF_DMM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0420) +#define OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET 0x0428 #define OMAP4430_CM_MEMIF_EMIF_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0428) +#define OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET 0x0430 #define OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0430) +#define OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET 0x0438 #define OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0438) +#define OMAP4_CM_MEMIF_DLL_CLKCTRL_OFFSET 0x0440 #define OMAP4430_CM_MEMIF_DLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0440) +#define OMAP4_CM_MEMIF_EMIF_H1_CLKCTRL_OFFSET 0x0450 #define OMAP4430_CM_MEMIF_EMIF_H1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0450) +#define OMAP4_CM_MEMIF_EMIF_H2_CLKCTRL_OFFSET 0x0458 #define OMAP4430_CM_MEMIF_EMIF_H2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0458) +#define OMAP4_CM_MEMIF_DLL_H_CLKCTRL_OFFSET 0x0460 #define OMAP4430_CM_MEMIF_DLL_H_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0460) +#define OMAP4_CM_D2D_CLKSTCTRL_OFFSET 0x0500 #define OMAP4430_CM_D2D_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0500) +#define OMAP4_CM_D2D_STATICDEP_OFFSET 0x0504 #define OMAP4430_CM_D2D_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0504) +#define OMAP4_CM_D2D_DYNAMICDEP_OFFSET 0x0508 #define OMAP4430_CM_D2D_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0508) +#define OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET 0x0520 #define OMAP4430_CM_D2D_SAD2D_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0520) +#define OMAP4_CM_D2D_MODEM_ICR_CLKCTRL_OFFSET 0x0528 #define OMAP4430_CM_D2D_MODEM_ICR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0528) +#define OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET 0x0530 #define OMAP4430_CM_D2D_SAD2D_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0530) +#define OMAP4_CM_L4CFG_CLKSTCTRL_OFFSET 0x0600 #define OMAP4430_CM_L4CFG_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0600) +#define OMAP4_CM_L4CFG_DYNAMICDEP_OFFSET 0x0608 #define OMAP4430_CM_L4CFG_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0608) +#define OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET 0x0620 #define OMAP4430_CM_L4CFG_L4_CFG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0620) +#define OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET 0x0628 #define OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0628) +#define OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET 0x0630 #define OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0630) +#define OMAP4_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET 0x0638 #define OMAP4430_CM_L4CFG_SAR_ROM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0638) +#define OMAP4_CM_L3INSTR_CLKSTCTRL_OFFSET 0x0700 #define OMAP4430_CM_L3INSTR_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0700) +#define OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET 0x0720 #define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0720) +#define OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET 0x0728 #define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0728) +#define OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET 0x0740 #define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0740) /* CM2.IVAHD_CM2 register offsets */ +#define OMAP4_CM_IVAHD_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_IVAHD_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0000) +#define OMAP4_CM_IVAHD_STATICDEP_OFFSET 0x0004 #define OMAP4430_CM_IVAHD_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0004) +#define OMAP4_CM_IVAHD_DYNAMICDEP_OFFSET 0x0008 #define OMAP4430_CM_IVAHD_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0008) +#define OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_IVAHD_IVAHD_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0020) +#define OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET 0x0028 #define OMAP4430_CM_IVAHD_SL2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0028) /* CM2.CAM_CM2 register offsets */ +#define OMAP4_CM_CAM_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_CAM_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0000) +#define OMAP4_CM_CAM_STATICDEP_OFFSET 0x0004 #define OMAP4430_CM_CAM_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0004) +#define OMAP4_CM_CAM_DYNAMICDEP_OFFSET 0x0008 #define OMAP4430_CM_CAM_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0008) +#define OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_CAM_ISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0020) +#define OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET 0x0028 #define OMAP4430_CM_CAM_FDIF_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0028) /* CM2.DSS_CM2 register offsets */ +#define OMAP4_CM_DSS_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_DSS_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0000) +#define OMAP4_CM_DSS_STATICDEP_OFFSET 0x0004 #define OMAP4430_CM_DSS_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0004) +#define OMAP4_CM_DSS_DYNAMICDEP_OFFSET 0x0008 #define OMAP4430_CM_DSS_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0008) +#define OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_DSS_DSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0020) +#define OMAP4_CM_DSS_DEISS_CLKCTRL_OFFSET 0x0028 #define OMAP4430_CM_DSS_DEISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0028) /* CM2.GFX_CM2 register offsets */ +#define OMAP4_CM_GFX_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_GFX_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0000) +#define OMAP4_CM_GFX_STATICDEP_OFFSET 0x0004 #define OMAP4430_CM_GFX_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0004) +#define OMAP4_CM_GFX_DYNAMICDEP_OFFSET 0x0008 #define OMAP4430_CM_GFX_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0008) +#define OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_GFX_GFX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0020) /* CM2.L3INIT_CM2 register offsets */ +#define OMAP4_CM_L3INIT_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_L3INIT_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0000) +#define OMAP4_CM_L3INIT_STATICDEP_OFFSET 0x0004 #define OMAP4430_CM_L3INIT_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0004) +#define OMAP4_CM_L3INIT_DYNAMICDEP_OFFSET 0x0008 #define OMAP4430_CM_L3INIT_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0008) +#define OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET 0x0028 #define OMAP4430_CM_L3INIT_MMC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0028) +#define OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET 0x0030 #define OMAP4430_CM_L3INIT_MMC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0030) +#define OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET 0x0038 #define OMAP4430_CM_L3INIT_HSI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0038) +#define OMAP4_CM_L3INIT_UNIPRO1_CLKCTRL_OFFSET 0x0040 #define OMAP4430_CM_L3INIT_UNIPRO1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0040) +#define OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET 0x0058 #define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0058) +#define OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET 0x0060 #define OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0060) +#define OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET 0x0068 #define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0068) +#define OMAP4_CM_L3INIT_P1500_CLKCTRL_OFFSET 0x0078 #define OMAP4430_CM_L3INIT_P1500_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0078) +#define OMAP4_CM_L3INIT_EMAC_CLKCTRL_OFFSET 0x0080 #define OMAP4430_CM_L3INIT_EMAC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0080) +#define OMAP4_CM_L3INIT_SATA_CLKCTRL_OFFSET 0x0088 #define OMAP4430_CM_L3INIT_SATA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0088) +#define OMAP4_CM_L3INIT_TPPSS_CLKCTRL_OFFSET 0x0090 #define OMAP4430_CM_L3INIT_TPPSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0090) +#define OMAP4_CM_L3INIT_PCIESS_CLKCTRL_OFFSET 0x0098 #define OMAP4430_CM_L3INIT_PCIESS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0098) +#define OMAP4_CM_L3INIT_CCPTX_CLKCTRL_OFFSET 0x00a8 #define OMAP4430_CM_L3INIT_CCPTX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00a8) +#define OMAP4_CM_L3INIT_XHPI_CLKCTRL_OFFSET 0x00c0 #define OMAP4430_CM_L3INIT_XHPI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00c0) +#define OMAP4_CM_L3INIT_MMC6_CLKCTRL_OFFSET 0x00c8 #define OMAP4430_CM_L3INIT_MMC6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00c8) +#define OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET 0x00d0 #define OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00d0) +#define OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET 0x00e0 #define OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00e0) /* CM2.L4PER_CM2 register offsets */ +#define OMAP4_CM_L4PER_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_L4PER_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0000) +#define OMAP4_CM_L4PER_DYNAMICDEP_OFFSET 0x0008 #define OMAP4430_CM_L4PER_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0008) +#define OMAP4_CM_L4PER_ADC_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_L4PER_ADC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0020) +#define OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET 0x0028 #define OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0028) +#define OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET 0x0030 #define OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0030) +#define OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET 0x0038 #define OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0038) +#define OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET 0x0040 #define OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0040) +#define OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET 0x0048 #define OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0048) +#define OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET 0x0050 #define OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0050) +#define OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET 0x0058 #define OMAP4430_CM_L4PER_ELM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0058) +#define OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET 0x0060 #define OMAP4430_CM_L4PER_GPIO2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0060) +#define OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET 0x0068 #define OMAP4430_CM_L4PER_GPIO3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0068) +#define OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET 0x0070 #define OMAP4430_CM_L4PER_GPIO4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0070) +#define OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET 0x0078 #define OMAP4430_CM_L4PER_GPIO5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0078) +#define OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET 0x0080 #define OMAP4430_CM_L4PER_GPIO6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0080) +#define OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET 0x0088 #define OMAP4430_CM_L4PER_HDQ1W_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0088) +#define OMAP4_CM_L4PER_HECC1_CLKCTRL_OFFSET 0x0090 #define OMAP4430_CM_L4PER_HECC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0090) +#define OMAP4_CM_L4PER_HECC2_CLKCTRL_OFFSET 0x0098 #define OMAP4430_CM_L4PER_HECC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0098) +#define OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET 0x00a0 #define OMAP4430_CM_L4PER_I2C1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00a0) +#define OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET 0x00a8 #define OMAP4430_CM_L4PER_I2C2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00a8) +#define OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET 0x00b0 #define OMAP4430_CM_L4PER_I2C3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00b0) +#define OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET 0x00b8 #define OMAP4430_CM_L4PER_I2C4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00b8) +#define OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET 0x00c0 #define OMAP4430_CM_L4PER_L4PER_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00c0) +#define OMAP4_CM_L4PER_MCASP2_CLKCTRL_OFFSET 0x00d0 #define OMAP4430_CM_L4PER_MCASP2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00d0) +#define OMAP4_CM_L4PER_MCASP3_CLKCTRL_OFFSET 0x00d8 #define OMAP4430_CM_L4PER_MCASP3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00d8) +#define OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET 0x00e0 #define OMAP4430_CM_L4PER_MCBSP4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00e0) +#define OMAP4_CM_L4PER_MGATE_CLKCTRL_OFFSET 0x00e8 #define OMAP4430_CM_L4PER_MGATE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00e8) +#define OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET 0x00f0 #define OMAP4430_CM_L4PER_MCSPI1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00f0) +#define OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET 0x00f8 #define OMAP4430_CM_L4PER_MCSPI2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00f8) +#define OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET 0x0100 #define OMAP4430_CM_L4PER_MCSPI3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0100) +#define OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET 0x0108 #define OMAP4430_CM_L4PER_MCSPI4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0108) +#define OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET 0x0120 #define OMAP4430_CM_L4PER_MMCSD3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0120) +#define OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET 0x0128 #define OMAP4430_CM_L4PER_MMCSD4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0128) +#define OMAP4_CM_L4PER_MSPROHG_CLKCTRL_OFFSET 0x0130 #define OMAP4430_CM_L4PER_MSPROHG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0130) +#define OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET 0x0138 #define OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0138) +#define OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET 0x0140 #define OMAP4430_CM_L4PER_UART1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0140) +#define OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET 0x0148 #define OMAP4430_CM_L4PER_UART2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0148) +#define OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET 0x0150 #define OMAP4430_CM_L4PER_UART3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0150) +#define OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET 0x0158 #define OMAP4430_CM_L4PER_UART4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0158) +#define OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET 0x0160 #define OMAP4430_CM_L4PER_MMCSD5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0160) +#define OMAP4_CM_L4PER_I2C5_CLKCTRL_OFFSET 0x0168 #define OMAP4430_CM_L4PER_I2C5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0168) +#define OMAP4_CM_L4SEC_CLKSTCTRL_OFFSET 0x0180 #define OMAP4430_CM_L4SEC_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0180) +#define OMAP4_CM_L4SEC_STATICDEP_OFFSET 0x0184 #define OMAP4430_CM_L4SEC_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0184) +#define OMAP4_CM_L4SEC_DYNAMICDEP_OFFSET 0x0188 #define OMAP4430_CM_L4SEC_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0188) +#define OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET 0x01a0 #define OMAP4430_CM_L4SEC_AES1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01a0) +#define OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET 0x01a8 #define OMAP4430_CM_L4SEC_AES2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01a8) +#define OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET 0x01b0 #define OMAP4430_CM_L4SEC_DES3DES_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01b0) +#define OMAP4_CM_L4SEC_PKAEIP29_CLKCTRL_OFFSET 0x01b8 #define OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01b8) +#define OMAP4_CM_L4SEC_RNG_CLKCTRL_OFFSET 0x01c0 #define OMAP4430_CM_L4SEC_RNG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01c0) +#define OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET 0x01c8 #define OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01c8) +#define OMAP4_CM_L4SEC_CRYPTODMA_CLKCTRL_OFFSET 0x01d8 #define OMAP4430_CM_L4SEC_CRYPTODMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01d8) /* CM2.CEFUSE_CM2 register offsets */ +#define OMAP4_CM_CEFUSE_CLKSTCTRL_OFFSET 0x0000 #define OMAP4430_CM_CEFUSE_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_MOD, 0x0000) +#define OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET 0x0020 #define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_MOD, 0x0020) #endif -- cgit v1.2.3-59-g8ed1b From 89e5ab26d89fda15924658866b57c967ba7507cc Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 18 May 2010 20:23:59 -0600 Subject: OMAP4 clock: Support clk_set_parent Remove the hack put in place while clock framework was still not in place for OMAP4. Signed-off-by: Rajendra Nayak Signed-off-by: Paul Walmsley --- arch/arm/plat-omap/clock.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index c9cd98a97abb..7190cbd92620 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -138,11 +138,6 @@ int clk_set_parent(struct clk *clk, struct clk *parent) unsigned long flags; int ret = -EINVAL; - if (cpu_is_omap44xx()) { - WARN(1, "clock: %s: not supported yet on OMAP4\n", __func__); - return 0; - } - if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent)) return ret; -- cgit v1.2.3-59-g8ed1b From 1dc993b218c089230f463234380795c237de5038 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 18 May 2010 20:24:00 -0600 Subject: OMAP: timers: Fix clock source names for OMAP4 The clock sources for timers on OMAP4 (system clock and 32k clock) have their names wronly populated. This patch fixes them so the omap_dm_timer_set_source does not fail anymore. Signed-off-by: Rajendra Nayak Signed-off-by: Paul Walmsley --- arch/arm/plat-omap/dmtimer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 4d99dfbc8bef..c64875f11fac 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -264,8 +264,8 @@ static struct omap_dm_timer omap4_dm_timers[] = { { .phys_base = 0x4a320000, .irq = OMAP44XX_IRQ_GPT12 }, }; static const char *omap4_dm_source_names[] __initdata = { - "sys_ck", - "omap_32k_fck", + "sys_clkin_ck", + "sys_32k_ck", NULL }; static struct clk *omap4_dm_source_clocks[2]; -- cgit v1.2.3-59-g8ed1b From d3353e1654f60fc56b7a9a965af67e14b54d7f61 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 18 May 2010 20:24:01 -0600 Subject: OMAP4 powerdomain: Fix pwrsts flags for ALWAYS ON domains The pwrsts flag for ALWAYS ON domains like always_on_core_pwrdm and wkup_pwrdm is wrongly populated with the define for a powerdomain power state, instead of the allowable state bitfields. This causes a few api's to fail sensing invalid pwrst requested. Signed-off-by: Rajendra Nayak Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/powerdomains44xx.h | 4 ++-- arch/arm/plat-omap/include/plat/powerdomain.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/powerdomains44xx.h b/arch/arm/mach-omap2/powerdomains44xx.h index e002d4289f4e..ad5a2655ad44 100644 --- a/arch/arm/mach-omap2/powerdomains44xx.h +++ b/arch/arm/mach-omap2/powerdomains44xx.h @@ -130,7 +130,7 @@ static struct powerdomain wkup_44xx_pwrdm = { .name = "wkup_pwrdm", .prcm_offs = OMAP4430_PRM_WKUP_MOD, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - .pwrsts = PWRDM_POWER_ON, + .pwrsts = PWRSTS_ON, .banks = 1, .pwrsts_mem_ret = { [0] = PWRDM_POWER_OFF, /* wkup_bank */ @@ -286,7 +286,7 @@ static struct powerdomain always_on_core_44xx_pwrdm = { .name = "always_on_core_pwrdm", .prcm_offs = OMAP4430_PRM_ALWAYS_ON_MOD, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - .pwrsts = PWRDM_POWER_ON, + .pwrsts = PWRSTS_ON, }; /* cefuse_44xx_pwrdm: Customer efuse controller power domain */ diff --git a/arch/arm/plat-omap/include/plat/powerdomain.h b/arch/arm/plat-omap/include/plat/powerdomain.h index d82b2c00d4f1..e7cc7e66e977 100644 --- a/arch/arm/plat-omap/include/plat/powerdomain.h +++ b/arch/arm/plat-omap/include/plat/powerdomain.h @@ -31,6 +31,7 @@ #define PWRDM_MAX_PWRSTS 4 /* Powerdomain allowable state bitfields */ +#define PWRSTS_ON (1 << PWRDM_POWER_ON) #define PWRSTS_OFF_ON ((1 << PWRDM_POWER_OFF) | \ (1 << PWRDM_POWER_ON)) -- cgit v1.2.3-59-g8ed1b From 71ee297a9bc69748510179f5333a3f4541c27723 Mon Sep 17 00:00:00 2001 From: Laine Walker-Avina Date: Tue, 18 May 2010 20:24:02 -0600 Subject: OMAP3 clock: add support for setting the divider for sys_clkout2 using clk_set_rate Add clock framework support for changing the rate of sys_clkout2. Signed-off-by: Laine Walker-Avina [paul@pwsan.com: added commit message, added .round_rate pointer] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clock3xxx_data.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 5ab44b055282..833be485c89e 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -1033,6 +1033,8 @@ static struct clk sys_clkout2 = { .clksel_mask = OMAP3430_CLKOUT2_DIV_MASK, .clksel = sys_clkout2_clksel, .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate }; /* CM OUTPUT CLOCKS */ -- cgit v1.2.3-59-g8ed1b From 90dbc7b0b80725afd7ed52f18e541dbc671dfd70 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 18 May 2010 20:24:03 -0600 Subject: OMAP4 powerdomain: Support LOWPOWERSTATECHANGE for powerdomains Some powerdomains in OMAP4 support a direct transition from one sleep state to another deeper sleep state without having to wakeup the powerdomain. This patch adds an api in the powerdomain framework to set the LOWPOWERSTATECHANGE bit in PWRSTCTRL register. Signed-off-by: Rajendra Nayak Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/powerdomain.c | 28 +++++++++++++++++++++++++++ arch/arm/mach-omap2/powerdomains44xx.h | 9 +++++++++ arch/arm/plat-omap/include/plat/powerdomain.h | 6 ++++++ 3 files changed, 43 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 4a91d38d7b1a..f9f0bca1926a 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -979,6 +979,34 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0; } +/** + * pwrdm_set_lowpwrstchange - Request a low power state change + * @pwrdm: struct powerdomain * + * + * Allows a powerdomain to transtion to a lower power sleep state + * from an existing sleep state without waking up the powerdomain. + * Returns -EINVAL if the powerdomain pointer is null or if the + * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0 + * upon success. + */ +int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) +{ + if (!pwrdm) + return -EINVAL; + + if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) + return -EINVAL; + + pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n", + pwrdm->name); + + prm_rmw_mod_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK, + (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT), + pwrdm->prcm_offs, pwrstctrl_reg_offs); + + return 0; +} + /** * pwrdm_wait_transition - wait for powerdomain power transition to finish * @pwrdm: struct powerdomain * to wait for diff --git a/arch/arm/mach-omap2/powerdomains44xx.h b/arch/arm/mach-omap2/powerdomains44xx.h index ad5a2655ad44..c7219513472a 100644 --- a/arch/arm/mach-omap2/powerdomains44xx.h +++ b/arch/arm/mach-omap2/powerdomains44xx.h @@ -54,6 +54,7 @@ static struct powerdomain core_44xx_pwrdm = { [3] = PWRDM_POWER_ON, /* ducati_l2ram */ [4] = PWRDM_POWER_ON, /* ducati_unicache */ }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; /* gfx_44xx_pwrdm: 3D accelerator power domain */ @@ -69,6 +70,7 @@ static struct powerdomain gfx_44xx_pwrdm = { .pwrsts_mem_on = { [0] = PWRDM_POWER_ON, /* gfx_mem */ }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; /* abe_44xx_pwrdm: Audio back end power domain */ @@ -87,6 +89,7 @@ static struct powerdomain abe_44xx_pwrdm = { [0] = PWRDM_POWER_ON, /* aessmem */ [1] = PWRDM_POWER_ON, /* periphmem */ }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; /* dss_44xx_pwrdm: Display subsystem power domain */ @@ -103,6 +106,7 @@ static struct powerdomain dss_44xx_pwrdm = { .pwrsts_mem_on = { [0] = PWRDM_POWER_ON, /* dss_mem */ }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; /* tesla_44xx_pwrdm: Tesla processor power domain */ @@ -123,6 +127,7 @@ static struct powerdomain tesla_44xx_pwrdm = { [1] = PWRDM_POWER_ON, /* tesla_l1 */ [2] = PWRDM_POWER_ON, /* tesla_l2 */ }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; /* wkup_44xx_pwrdm: Wake-up power domain */ @@ -227,6 +232,7 @@ static struct powerdomain ivahd_44xx_pwrdm = { [2] = PWRDM_POWER_ON, /* tcm1_mem */ [3] = PWRDM_POWER_ON, /* tcm2_mem */ }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; /* cam_44xx_pwrdm: Camera subsystem power domain */ @@ -242,6 +248,7 @@ static struct powerdomain cam_44xx_pwrdm = { .pwrsts_mem_on = { [0] = PWRDM_POWER_ON, /* cam_mem */ }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; /* l3init_44xx_pwrdm: L3 initators pheripherals power domain */ @@ -258,6 +265,7 @@ static struct powerdomain l3init_44xx_pwrdm = { .pwrsts_mem_on = { [0] = PWRDM_POWER_ON, /* l3init_bank1 */ }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; /* l4per_44xx_pwrdm: Target peripherals power domain */ @@ -276,6 +284,7 @@ static struct powerdomain l4per_44xx_pwrdm = { [0] = PWRDM_POWER_ON, /* nonretained_bank */ [1] = PWRDM_POWER_ON, /* retained_bank */ }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; /* diff --git a/arch/arm/plat-omap/include/plat/powerdomain.h b/arch/arm/plat-omap/include/plat/powerdomain.h index e7cc7e66e977..fb6ec74fe39e 100644 --- a/arch/arm/plat-omap/include/plat/powerdomain.h +++ b/arch/arm/plat-omap/include/plat/powerdomain.h @@ -50,6 +50,12 @@ * in MEM bank 1 position. This is * true for OMAP3430 */ +#define PWRDM_HAS_LOWPOWERSTATECHANGE (1 << 2) /* + * support to transition from a + * sleep state to a lower sleep + * state without waking up the + * powerdomain + */ /* * Number of memory banks that are power-controllable. On OMAP4430, the -- cgit v1.2.3-59-g8ed1b From 4788da268f83dedc58b79dc7b2f6072687f63a19 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 18 May 2010 20:24:05 -0600 Subject: OMAP powerdomain, hwmod, omap_device: add some credits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add some missing credits for people who have contributed significant features or fixes. Signed-off-by: Paul Walmsley Cc: BenoĂ®t Cousson Cc: Tero Kristo Cc: Kevin Hilman Cc: Thara Gopinath --- arch/arm/mach-omap2/omap_hwmod.c | 10 +++++----- arch/arm/mach-omap2/powerdomain.c | 2 +- arch/arm/plat-omap/omap_device.c | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 2fff39ff4080..0a563a671dde 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2,12 +2,12 @@ * omap_hwmod implementation for OMAP2/3/4 * * Copyright (C) 2009 Nokia Corporation - * Paul Walmsley - * With fixes and testing from Kevin Hilman * - * Created in collaboration with (alphabetical order): Benoit Cousson, - * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari - * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff + * Paul Walmsley, BenoĂ®t Cousson, Kevin Hilman + * + * Created in collaboration with (alphabetical order): Thara Gopinath, + * Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari Poussa, Anand + * Sawant, Santosh Shilimkar, Richard Woodruff * * 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 diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index f9f0bca1926a..a2904aa7065e 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -5,8 +5,8 @@ * Copyright (C) 2007-2009 Nokia Corporation * * Written by Paul Walmsley - * * Added OMAP4 specific support by Abhijit Pagare + * State counting code by Tero Kristo * * 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 diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 0f5197479513..f899603051ac 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -2,10 +2,10 @@ * omap_device implementation * * Copyright (C) 2009 Nokia Corporation - * Paul Walmsley + * Paul Walmsley, Kevin Hilman * * Developed in collaboration with (alphabetical order): Benoit - * Cousson, Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram + * Cousson, Thara Gopinath, Tony Lindgren, Rajendra Nayak, Vikram * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard * Woodruff * -- cgit v1.2.3-59-g8ed1b From 59dd7224892142fe1d8505cf2c90bd732d730005 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 18 May 2010 20:24:06 -0600 Subject: OMAP2 clock: fix recursive spinlock attempt when CONFIG_CPU_FREQ=y The OMAP2 MPU virtual clock node code attempted to call clk_get_rate() while the clockfw_lock spinlock was held. Fix by reading the sys_ck rate directly. Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index e60ca4e47bbd..aef62918aaf0 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -68,16 +68,13 @@ long omap2_round_to_table_rate(struct clk *clk, unsigned long rate) { const struct prcm_config *ptr; long highest_rate; - long sys_ck_rate; - - sys_ck_rate = clk_get_rate(sclk); highest_rate = -EINVAL; for (ptr = rate_table; ptr->mpu_speed; ptr++) { if (!(ptr->flags & cpu_mask)) continue; - if (ptr->xtal_speed != sys_ck_rate) + if (ptr->xtal_speed != sclk->rate) continue; highest_rate = ptr->mpu_speed; @@ -96,15 +93,12 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate) const struct prcm_config *prcm; unsigned long found_speed = 0; unsigned long flags; - long sys_ck_rate; - - sys_ck_rate = clk_get_rate(sclk); for (prcm = rate_table; prcm->mpu_speed; prcm++) { if (!(prcm->flags & cpu_mask)) continue; - if (prcm->xtal_speed != sys_ck_rate) + if (prcm->xtal_speed != sclk->rate) continue; if (prcm->mpu_speed <= rate) { @@ -181,19 +175,16 @@ static struct cpufreq_frequency_table *freq_table; void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) { const struct prcm_config *prcm; - long sys_ck_rate; int i = 0; int tbl_sz = 0; if (!cpu_is_omap24xx()) return; - sys_ck_rate = clk_get_rate(sclk); - for (prcm = rate_table; prcm->mpu_speed; prcm++) { if (!(prcm->flags & cpu_mask)) continue; - if (prcm->xtal_speed != sys_ck_rate) + if (prcm->xtal_speed != sclk->rate) continue; /* don't put bypass rates in table */ @@ -226,7 +217,7 @@ void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) for (prcm = rate_table; prcm->mpu_speed; prcm++) { if (!(prcm->flags & cpu_mask)) continue; - if (prcm->xtal_speed != sys_ck_rate) + if (prcm->xtal_speed != sclk->rate) continue; /* don't put bypass rates in table */ -- cgit v1.2.3-59-g8ed1b From b32dd41ed645c22ac3ce4e25bcbd7eee30297292 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 20 May 2010 11:36:43 -0700 Subject: omap: Fix i2c platform init code for omap4 Add separate omap_i2c_add_bus functions for mach-omap1 and mach-omap2. Make the mach-omap2 init set the interrupt dynamically to support. This is needed to add support for omap4 in a way that works with multi-omap builds. This will eventually get fixed in a generic way with the omap hwmods. Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/i2c.c | 67 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index f044b5927508..78d1cea9118d 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -100,33 +100,44 @@ static int __init omap_i2c_nr_ports(void) return ports; } -static int __init omap_i2c_add_bus(int bus_id) +/* Shared between omap2 and 3 */ +static resource_size_t omap2_i2c_irq[3] __initdata = { + INT_24XX_I2C1_IRQ, + INT_24XX_I2C2_IRQ, + INT_34XX_I2C3_IRQ, +}; + +static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id) { - struct platform_device *pdev; struct omap_i2c_bus_platform_data *pd; struct resource *res; - resource_size_t base, irq; - pdev = &omap_i2c_devices[bus_id - 1]; pd = pdev->dev.platform_data; + res = pdev->resource; + res[0].start = OMAP1_I2C_BASE; + res[0].end = res[0].start + OMAP_I2C_SIZE; + res[1].start = INT_I2C; + omap1_i2c_mux_pins(bus_id); + + return platform_device_register(pdev); +} + +static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id) +{ + struct resource *res; + resource_size_t *irq; + + res = pdev->resource; + + irq = omap2_i2c_irq; + if (bus_id == 1) { - res = pdev->resource; - if (cpu_class_is_omap1()) { - base = OMAP1_I2C_BASE; - irq = INT_I2C; - } else { - base = OMAP2_I2C_BASE1; - irq = INT_24XX_I2C1_IRQ; - } - res[0].start = base; - res[0].end = base + OMAP_I2C_SIZE; - res[1].start = irq; + res[0].start = OMAP2_I2C_BASE1; + res[0].end = res[0].start + OMAP_I2C_SIZE; } - if (cpu_class_is_omap1()) - omap1_i2c_mux_pins(bus_id); - if (cpu_class_is_omap2()) - omap2_i2c_mux_pins(bus_id); + res[1].start = irq[bus_id - 1]; + omap2_i2c_mux_pins(bus_id); /* * When waiting for completion of a i2c transfer, we need to @@ -134,12 +145,28 @@ static int __init omap_i2c_add_bus(int bus_id) * ensure quick enough wakeup from idle, when transfer * completes. */ - if (cpu_is_omap34xx()) + if (cpu_is_omap34xx()) { + struct omap_i2c_bus_platform_data *pd; + + pd = pdev->dev.platform_data; pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat; + } return platform_device_register(pdev); } +static int __init omap_i2c_add_bus(int bus_id) +{ + struct platform_device *pdev; + + pdev = &omap_i2c_devices[bus_id - 1]; + + if (cpu_class_is_omap1()) + return omap1_i2c_add_bus(pdev, bus_id); + else + return omap2_i2c_add_bus(pdev, bus_id); +} + /** * omap_i2c_bus_setup - Process command line options for the I2C bus speed * @str: String of options -- cgit v1.2.3-59-g8ed1b From 6daa642d9b8ec762b3c5641cd5e5fa855a5405bf Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 20 May 2010 11:36:43 -0700 Subject: omap4: Add support for i2c init Add support for i2c init for omap4. This patch is based on and earlier patch by Santosh Shilimkar . Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/i2c.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 78d1cea9118d..eec2b4993c69 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -38,6 +38,7 @@ #define OMAP2_I2C_BASE1 0x48070000 #define OMAP2_I2C_BASE2 0x48072000 #define OMAP2_I2C_BASE3 0x48060000 +#define OMAP4_I2C_BASE4 0x48350000 static const char name[] = "i2c_omap"; @@ -54,11 +55,14 @@ static const char name[] = "i2c_omap"; static struct resource i2c_resources[][2] = { { I2C_RESOURCE_BUILDER(0, 0) }, -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) - { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_24XX_I2C2_IRQ) }, +#if defined(CONFIG_ARCH_OMAP2PLUS) + { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, 0) }, #endif -#if defined(CONFIG_ARCH_OMAP3) - { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ) }, +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) + { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, 0) }, +#endif +#if defined(CONFIG_ARCH_OMAP4) + { I2C_RESOURCE_BUILDER(OMAP4_I2C_BASE4, 0) }, #endif }; @@ -76,12 +80,15 @@ static struct resource i2c_resources[][2] = { static struct omap_i2c_bus_platform_data i2c_pdata[ARRAY_SIZE(i2c_resources)]; static struct platform_device omap_i2c_devices[] = { I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]), -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) +#if defined(CONFIG_ARCH_OMAP2PLUS) I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_pdata[1]), #endif -#if defined(CONFIG_ARCH_OMAP3) +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_pdata[2]), #endif +#if defined(CONFIG_ARCH_OMAP4) + I2C_DEV_BUILDER(4, i2c_resources[3], &i2c_pdata[3]), +#endif }; #define OMAP_I2C_CMDLINE_SETUP (BIT(31)) @@ -96,6 +103,8 @@ static int __init omap_i2c_nr_ports(void) ports = 2; else if (cpu_is_omap34xx()) ports = 3; + else if (cpu_is_omap44xx()) + ports = 4; return ports; } @@ -107,6 +116,13 @@ static resource_size_t omap2_i2c_irq[3] __initdata = { INT_34XX_I2C3_IRQ, }; +static resource_size_t omap4_i2c_irq[4] __initdata = { + OMAP44XX_IRQ_I2C1, + OMAP44XX_IRQ_I2C2, + OMAP44XX_IRQ_I2C3, + OMAP44XX_IRQ_I2C4, +}; + static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id) { struct omap_i2c_bus_platform_data *pd; @@ -129,7 +145,10 @@ static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id) res = pdev->resource; - irq = omap2_i2c_irq; + if (!cpu_is_omap44xx()) + irq = omap2_i2c_irq; + else + irq = omap4_i2c_irq; if (bus_id == 1) { res[0].start = OMAP2_I2C_BASE1; -- cgit v1.2.3-59-g8ed1b From 58815fa3bffdee8dbac5af6931eea991d7a71a19 Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Thu, 25 Mar 2010 13:25:27 +0200 Subject: usb: musb: Add extvbus in musb_board_data EXTVBUS programming is required by OMAP3EVM REV >=E to supply 500mA power so adding a flag which can be used by musb driver to program EXTVBUS. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/board-omap3evm.c | 3 +++ arch/arm/mach-omap2/usb-musb.c | 1 + arch/arm/plat-omap/include/plat/usb.h | 1 + 3 files changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 017bb2f4f7d2..7d7b5bc8dc31 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -702,6 +702,9 @@ static void __init omap3_evm_init(void) omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP); ehci_pdata.reset_gpio_port[1] = 21; + /* EVM REV >= E can supply 500mA with EXTVBUS programming */ + musb_board_data.power = 500; + musb_board_data.extvbus = 1; } else { /* setup EHCI phy reset on MDC */ omap_mux_init_gpio(135, OMAP_PIN_OUTPUT); diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 6d41fa7b2ce8..96f6787e00b2 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -107,6 +107,7 @@ void __init usb_musb_init(struct omap_musb_board_data *board_data) musb_plat.board_data = board_data; musb_plat.power = board_data->power >> 1; musb_plat.mode = board_data->mode; + musb_plat.extvbus = board_data->extvbus; if (platform_device_register(&musb_device) < 0) printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n"); diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 876ca8d5e927..60c734f40ed1 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -47,6 +47,7 @@ struct omap_musb_board_data { u8 interface_type; u8 mode; u16 power; + unsigned extvbus:1; }; enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI}; -- cgit v1.2.3-59-g8ed1b From 95344fcc07964202737f85c16dbabbc40cae5e4d Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Mon, 10 May 2010 21:56:10 +0530 Subject: USB: omap3: add platform init code for OHCI driver Add platform init code for the OMAP3 OHCI driver. Also, configure padconf settings for OMAP3 depending on which port mode is used. Signed-off-by: Anand Gadiyar Cc: David Brownell Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/usb-ehci.c | 155 ++++++++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/usb.h | 23 +++++ 2 files changed, 178 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c index ee9f548d5d81..c68f799e83c5 100644 --- a/arch/arm/mach-omap2/usb-ehci.c +++ b/arch/arm/mach-omap2/usb-ehci.c @@ -236,3 +236,158 @@ void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata) #endif /* CONFIG_USB_EHCI_HCD */ +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) + +static struct resource ohci_resources[] = { + { + .start = OMAP34XX_OHCI_BASE, + .end = OMAP34XX_OHCI_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP34XX_UHH_CONFIG_BASE, + .end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP34XX_USBTLL_BASE, + .end = OMAP34XX_USBTLL_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* general IRQ */ + .start = INT_34XX_OHCI_IRQ, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 ohci_dmamask = DMA_BIT_MASK(32); + +static struct platform_device ohci_device = { + .name = "ohci-omap3", + .id = 0, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(ohci_resources), + .resource = ohci_resources, +}; + +static void setup_ohci_io_mux(const enum ohci_omap3_port_mode *port_mode) +{ + switch (port_mode[0]) { + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: + omap_mux_init_signal("mm1_rxdp", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm1_rxdm", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: + omap_mux_init_signal("mm1_rxrcv", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: + omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: + omap_mux_init_signal("mm1_txse0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm1_txdat", + OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_OHCI_PORT_MODE_UNUSED: + /* FALLTHROUGH */ + default: + break; + } + switch (port_mode[1]) { + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: + omap_mux_init_signal("mm2_rxdp", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm2_rxdm", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: + omap_mux_init_signal("mm2_rxrcv", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: + omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: + omap_mux_init_signal("mm2_txse0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm2_txdat", + OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_OHCI_PORT_MODE_UNUSED: + /* FALLTHROUGH */ + default: + break; + } + switch (port_mode[2]) { + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: + omap_mux_init_signal("mm3_rxdp", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm3_rxdm", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: + omap_mux_init_signal("mm3_rxrcv", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: + omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: + omap_mux_init_signal("mm3_txse0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm3_txdat", + OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_OHCI_PORT_MODE_UNUSED: + /* FALLTHROUGH */ + default: + break; + } +} + +void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata) +{ + platform_device_add_data(&ohci_device, pdata, sizeof(*pdata)); + + /* Setup Pin IO MUX for OHCI */ + if (cpu_is_omap34xx()) + setup_ohci_io_mux(pdata->port_mode); + + if (platform_device_register(&ohci_device) < 0) { + pr_err("Unable to register FS-USB (OHCI) device\n"); + return; + } +} + +#else + +void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata) +{ +} + +#endif /* CONFIG_USB_OHCI_HCD */ diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 60c734f40ed1..98eef5360e6d 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -13,6 +13,20 @@ enum ehci_hcd_omap_mode { EHCI_HCD_OMAP_MODE_TLL, }; +enum ohci_omap3_port_mode { + OMAP_OHCI_PORT_MODE_UNUSED, + OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0, + OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM, + OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0, + OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM, + OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0, + OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM, + OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0, + OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM, + OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0, + OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM, +}; + struct ehci_hcd_omap_platform_data { enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; unsigned phy_reset:1; @@ -21,6 +35,13 @@ struct ehci_hcd_omap_platform_data { int reset_gpio_port[OMAP3_HS_USB_PORTS]; }; +struct ohci_hcd_omap_platform_data { + enum ohci_omap3_port_mode port_mode[OMAP3_HS_USB_PORTS]; + + /* Set this to true for ES2.x silicon */ + unsigned es2_compatibility:1; +}; + /*-------------------------------------------------------------------------*/ #define OMAP1_OTG_BASE 0xfffb0400 @@ -56,6 +77,8 @@ extern void usb_musb_init(struct omap_musb_board_data *board_data); extern void usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata); +extern void usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata); + #endif void omap_usb_init(struct omap_usb_config *pdata); -- cgit v1.2.3-59-g8ed1b From c75fbb05b523571c0fdc48d4b968b73f0e20acbb Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:19 -0500 Subject: kgdb,sparc: Add in kgdb_arch_set_pc for sparc The new debug core api requires all architectures that use to debug core to implement a function to set the program counter. Signed-off-by: Jason Wessel Acked-by: David S. Miller --- arch/sparc/kernel/kgdb_32.c | 6 ++++++ arch/sparc/kernel/kgdb_64.c | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/sparc/kernel/kgdb_32.c b/arch/sparc/kernel/kgdb_32.c index 04df4edc0073..539243b236fa 100644 --- a/arch/sparc/kernel/kgdb_32.c +++ b/arch/sparc/kernel/kgdb_32.c @@ -158,6 +158,12 @@ void kgdb_arch_exit(void) { } +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) +{ + regs->pc = ip; + regs->npc = regs->pc + 4; +} + struct kgdb_arch arch_kgdb_ops = { /* Breakpoint instruction: ta 0x7d */ .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x7d }, diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index 0a2bd0f99fc1..768290a6c028 100644 --- a/arch/sparc/kernel/kgdb_64.c +++ b/arch/sparc/kernel/kgdb_64.c @@ -181,6 +181,12 @@ void kgdb_arch_exit(void) { } +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) +{ + regs->tpc = ip; + regs->tnpc = regs->tpc + 4; +} + struct kgdb_arch arch_kgdb_ops = { /* Breakpoint instruction: ta 0x72 */ .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x72 }, -- cgit v1.2.3-59-g8ed1b From 489022cc86ec8817a30226d00d35c67d74dd24a0 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:20 -0500 Subject: kgdb,sh: update superh kgdb exception handling Implement kgdb_arch_pc() which adjusts the pc if it needs to be adjusted after a software breakpoint trap. Implement kgdb_arch_set_pc() which is a new required function in the kgdb debug core. When processing a single step return zero in the error exception field so that the debug core can distinguish between a single step trap and a breakpoint trap generically. Signed-off-by: Jason Wessel Acked-by: Paul Mundt --- arch/sh/kernel/kgdb.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c index 70c69659b846..efb6d398dec3 100644 --- a/arch/sh/kernel/kgdb.c +++ b/arch/sh/kernel/kgdb.c @@ -237,6 +237,18 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, return -1; } +unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs) +{ + if (exception == 60) + return instruction_pointer(regs) - 2; + return instruction_pointer(regs); +} + +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) +{ + regs->pc = ip; +} + /* * The primary entry points for the kgdb debug trap table entries. */ @@ -247,7 +259,7 @@ BUILD_TRAP_HANDLER(singlestep) local_irq_save(flags); regs->pc -= instruction_size(__raw_readw(regs->pc - 4)); - kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs); + kgdb_handle_exception(0, SIGTRAP, 0, regs); local_irq_restore(flags); } -- cgit v1.2.3-59-g8ed1b From e8861129d3c1a64e3c62f459aeb1cd54a55ab045 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:20 -0500 Subject: kgdb,blackfin: Add in kgdb_arch_set_pc for blackfin The new debug core api requires all architectures that use to debug core to implement a function to set the program counter. Signed-off-by: Jason Wessel Acked-by: Sonic Zhang Acked-by: Mike Frysinger --- arch/blackfin/kernel/kgdb.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index 2c501ceb1e55..7367aea4ae59 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c @@ -439,6 +439,11 @@ int kgdb_validate_break_address(unsigned long addr) return -EFAULT; } +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) +{ + regs->retx = ip; +} + int kgdb_arch_init(void) { kgdb_single_step = 0; -- cgit v1.2.3-59-g8ed1b From 67fc4e0cb931d6b4ccf21248e4199b154478ecea Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:21 -0500 Subject: kdb: core for kgdb back end (2 of 2) This patch contains the hooks and instrumentation into kernel which live outside the kernel/debug directory, which the kdb core will call to run commands like lsmod, dmesg, bt etc... CC: linux-arch@vger.kernel.org Signed-off-by: Jason Wessel Signed-off-by: Martin Hicks --- arch/arm/include/asm/kmap_types.h | 1 + arch/powerpc/include/asm/kmap_types.h | 1 + include/asm-generic/kmap_types.h | 3 ++- init/main.c | 2 ++ kernel/kallsyms.c | 21 ++++++++++++++++++ kernel/module.c | 4 ++++ kernel/printk.c | 16 ++++++++++++++ kernel/sched.c | 7 ++++-- kernel/signal.c | 40 +++++++++++++++++++++++++++++++++++ 9 files changed, 92 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h index c4b2ea3fbe42..e51b1e81df05 100644 --- a/arch/arm/include/asm/kmap_types.h +++ b/arch/arm/include/asm/kmap_types.h @@ -20,6 +20,7 @@ enum km_type { KM_SOFTIRQ1, KM_L1_CACHE, KM_L2_CACHE, + KM_KDB, KM_TYPE_NR }; diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h index 916369575c97..bca8fdcd2542 100644 --- a/arch/powerpc/include/asm/kmap_types.h +++ b/arch/powerpc/include/asm/kmap_types.h @@ -26,6 +26,7 @@ enum km_type { KM_SOFTIRQ1, KM_PPC_SYNC_PAGE, KM_PPC_SYNC_ICACHE, + KM_KDB, KM_TYPE_NR }; diff --git a/include/asm-generic/kmap_types.h b/include/asm-generic/kmap_types.h index e5f234a08540..97e807c8c812 100644 --- a/include/asm-generic/kmap_types.h +++ b/include/asm-generic/kmap_types.h @@ -28,7 +28,8 @@ KMAP_D(15) KM_UML_USERCOPY, KMAP_D(16) KM_IRQ_PTE, KMAP_D(17) KM_NMI, KMAP_D(18) KM_NMI_PTE, -KMAP_D(19) KM_TYPE_NR +KMAP_D(19) KM_KDB, +KMAP_D(20) KM_TYPE_NR }; #undef KMAP_D diff --git a/init/main.c b/init/main.c index 5c8540271529..372771333d98 100644 --- a/init/main.c +++ b/init/main.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -675,6 +676,7 @@ asmlinkage void __init start_kernel(void) buffer_init(); key_init(); security_init(); + kdb_init(KDB_INIT_FULL); vfs_caches_init(totalram_pages); signals_init(); /* rootfs populating might need page-writeback */ diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 13aff293f4de..6f6d091b5757 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include /* for cond_resched */ @@ -516,6 +517,26 @@ static int kallsyms_open(struct inode *inode, struct file *file) return ret; } +#ifdef CONFIG_KGDB_KDB +const char *kdb_walk_kallsyms(loff_t *pos) +{ + static struct kallsym_iter kdb_walk_kallsyms_iter; + if (*pos == 0) { + memset(&kdb_walk_kallsyms_iter, 0, + sizeof(kdb_walk_kallsyms_iter)); + reset_iter(&kdb_walk_kallsyms_iter, 0); + } + while (1) { + if (!update_iter(&kdb_walk_kallsyms_iter, *pos)) + return NULL; + ++*pos; + /* Some debugging symbols have no name. Ignore them. */ + if (kdb_walk_kallsyms_iter.name[0]) + return kdb_walk_kallsyms_iter.name; + } +} +#endif /* CONFIG_KGDB_KDB */ + static const struct file_operations kallsyms_operations = { .open = kallsyms_open, .read = seq_read, diff --git a/kernel/module.c b/kernel/module.c index e2564580f3f1..b751f1902476 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -77,6 +77,10 @@ DEFINE_MUTEX(module_mutex); EXPORT_SYMBOL_GPL(module_mutex); static LIST_HEAD(modules); +#ifdef CONFIG_KGDB_KDB +struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ +#endif /* CONFIG_KGDB_KDB */ + /* Block module loading/unloading? */ int modules_disabled = 0; diff --git a/kernel/printk.c b/kernel/printk.c index 75077ad0b537..9213b8b5bb4f 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -413,6 +413,22 @@ SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) return do_syslog(type, buf, len, SYSLOG_FROM_CALL); } +#ifdef CONFIG_KGDB_KDB +/* kdb dmesg command needs access to the syslog buffer. do_syslog() + * uses locks so it cannot be used during debugging. Just tell kdb + * where the start and end of the physical and logical logs are. This + * is equivalent to do_syslog(3). + */ +void kdb_syslog_data(char *syslog_data[4]) +{ + syslog_data[0] = log_buf; + syslog_data[1] = log_buf + log_buf_len; + syslog_data[2] = log_buf + log_end - + (logged_chars < log_buf_len ? logged_chars : log_buf_len); + syslog_data[3] = log_buf + log_end; +} +#endif /* CONFIG_KGDB_KDB */ + /* * Call the console drivers on a range of log_buf */ diff --git a/kernel/sched.c b/kernel/sched.c index 1d93cd0ae4d3..a25c1324af54 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -7758,9 +7758,9 @@ void normalize_rt_tasks(void) #endif /* CONFIG_MAGIC_SYSRQ */ -#ifdef CONFIG_IA64 +#if defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB) /* - * These functions are only useful for the IA64 MCA handling. + * These functions are only useful for the IA64 MCA handling, or kdb. * * They can only be called when the whole system has been * stopped - every CPU needs to be quiescent, and no scheduling @@ -7780,6 +7780,9 @@ struct task_struct *curr_task(int cpu) return cpu_curr(cpu); } +#endif /* defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB) */ + +#ifdef CONFIG_IA64 /** * set_curr_task - set the current task for a given cpu. * @cpu: the processor in question. diff --git a/kernel/signal.c b/kernel/signal.c index dbd7fe073c55..825a3f24ad76 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2735,3 +2735,43 @@ void __init signals_init(void) { sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC); } + +#ifdef CONFIG_KGDB_KDB +#include +/* + * kdb_send_sig_info - Allows kdb to send signals without exposing + * signal internals. This function checks if the required locks are + * available before calling the main signal code, to avoid kdb + * deadlocks. + */ +void +kdb_send_sig_info(struct task_struct *t, struct siginfo *info) +{ + static struct task_struct *kdb_prev_t; + int sig, new_t; + if (!spin_trylock(&t->sighand->siglock)) { + kdb_printf("Can't do kill command now.\n" + "The sigmask lock is held somewhere else in " + "kernel, try again later\n"); + return; + } + spin_unlock(&t->sighand->siglock); + new_t = kdb_prev_t != t; + kdb_prev_t = t; + if (t->state != TASK_RUNNING && new_t) { + kdb_printf("Process is not RUNNING, sending a signal from " + "kdb risks deadlock\n" + "on the run queue locks. " + "The signal has _not_ been sent.\n" + "Reissue the kill command if you want to risk " + "the deadlock.\n"); + return; + } + sig = info->si_signo; + if (send_sig_info(sig, info, t)) + kdb_printf("Fail to deliver Signal %d to process %d.\n", + sig, t->pid); + else + kdb_printf("Signal %d is sent to process %d.\n", sig, t->pid); +} +#endif /* CONFIG_KGDB_KDB */ -- cgit v1.2.3-59-g8ed1b From dcc7871128e99458ca86186b7bc8bf27ff0c47b5 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:21 -0500 Subject: kgdb: core changes to support kdb These are the minimum changes to the kgdb core in order to enable an API to connect a new front end (kdb) to the debug core. This patch introduces the dbg_kdb_mode variable controls where the user level I/O is routed. It will be routed to the gdbstub (kgdb) or to the kdb front end which is a simple shell available over the kgdboc connection. You can switch back and forth between kdb or the gdb stub mode of operation dynamically. From gdb stub mode you can blindly type "$3#33", or from the kdb mode you can enter "kgdb" to switch to the gdb stub. The logic in the debug core depends on kdb to look for the typical gdb connection sequences and return immediately with KGDB_PASS_EVENT if a gdb serial command sequence is detected. That should allow a reasonably seamless transition between kdb -> gdb without leaving the kernel exception state. The two gdb serial queries that kdb is responsible for detecting are the "?" and "qSupported" packets. CC: Ingo Molnar Signed-off-by: Jason Wessel Acked-by: Martin Hicks --- arch/arm/kernel/kgdb.c | 5 +++ arch/mips/kernel/kgdb.c | 5 +++ arch/powerpc/kernel/kgdb.c | 5 +++ arch/x86/kernel/kgdb.c | 5 +++ include/linux/kgdb.h | 11 ++++- kernel/debug/debug_core.c | 107 ++++++++++++++++++++++++++++++++++++++------- kernel/debug/debug_core.h | 24 ++++++++++ kernel/debug/gdbstub.c | 36 +++++++++++++++ lib/Kconfig.kgdb | 8 +++- 9 files changed, 186 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index a5b846b9895d..c868a8864117 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c @@ -98,6 +98,11 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) gdb_regs[_CPSR] = thread_regs->ARM_cpsr; } +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) +{ + regs->ARM_pc = pc; +} + static int compiled_break; int kgdb_arch_handle_exception(int exception_vector, int signo, diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 50c9bb880667..6ed4c83c869b 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -180,6 +180,11 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) *(ptr++) = regs->cp0_epc; } +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) +{ + regs->cp0_epc = pc; +} + /* * Calls linux_debug_hook before the kernel dies. If KGDB is enabled, * then try to fall into the debugger diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 41bada0298c8..c81e3de1306e 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -309,6 +309,11 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) (unsigned long)(((void *)gdb_regs) + NUMREGBYTES)); } +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) +{ + regs->nip = pc; +} + /* * This function does PowerPC specific procesing for interfacing to gdb. */ diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index b2258ca91003..f95a2c0b915c 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -690,6 +690,11 @@ unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs) return instruction_pointer(regs); } +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) +{ + regs->ip = ip; +} + struct kgdb_arch arch_kgdb_ops = { /* Breakpoint instruction: */ .gdb_bpt_instr = { 0xcc }, diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 4830142ec339..5b37df00000d 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -16,10 +16,12 @@ #include #include #include - #include +#ifdef CONFIG_HAVE_ARCH_KGDB #include +#endif +#ifdef CONFIG_KGDB struct pt_regs; /** @@ -262,6 +264,7 @@ extern struct kgdb_arch arch_kgdb_ops; extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs); +extern void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc); extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops); extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops); extern struct kgdb_io *dbg_io_ops; @@ -279,5 +282,9 @@ extern int kgdb_nmicallback(int cpu, void *regs); extern int kgdb_single_step; extern atomic_t kgdb_active; - +#define in_dbg_master() \ + (raw_smp_processor_id() == atomic_read(&kgdb_active)) +#else /* ! CONFIG_KGDB */ +#define in_dbg_master() (0) +#endif /* ! CONFIG_KGDB */ #endif /* _KGDB_H_ */ diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 7e03969330bc..6e1fa829fdeb 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,11 @@ static DEFINE_SPINLOCK(kgdb_registration_lock); static int kgdb_con_registered; /* determine if kgdb console output should be used */ static int kgdb_use_con; +/* Next cpu to become the master debug core */ +int dbg_switch_cpu; + +/* Use kdb or gdbserver mode */ +static int dbg_kdb_mode = 1; static int __init opt_kgdb_con(char *str) { @@ -100,6 +106,7 @@ static struct kgdb_bkpt kgdb_break[KGDB_MAX_BREAKPOINTS] = { * The CPU# of the active CPU, or -1 if none: */ atomic_t kgdb_active = ATOMIC_INIT(-1); +EXPORT_SYMBOL_GPL(kgdb_active); /* * We use NR_CPUs not PERCPU, in case kgdb is used to debug early @@ -301,7 +308,7 @@ int dbg_set_sw_break(unsigned long addr) return 0; } -static int kgdb_deactivate_sw_breakpoints(void) +int dbg_deactivate_sw_breakpoints(void) { unsigned long addr; int error; @@ -395,8 +402,14 @@ static int kgdb_io_ready(int print_wait) return 1; if (atomic_read(&kgdb_setting_breakpoint)) return 1; - if (print_wait) + if (print_wait) { +#ifdef CONFIG_KGDB_KDB + if (!dbg_kdb_mode) + printk(KERN_CRIT "KGDB: waiting... or $3#33 for KDB\n"); +#else printk(KERN_CRIT "KGDB: Waiting for remote debugger\n"); +#endif + } return 1; } @@ -410,7 +423,7 @@ static int kgdb_reenter_check(struct kgdb_state *ks) /* Panic on recursive debugger calls: */ exception_level++; addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs); - kgdb_deactivate_sw_breakpoints(); + dbg_deactivate_sw_breakpoints(); /* * If the break point removed ok at the place exception @@ -443,11 +456,24 @@ static int kgdb_reenter_check(struct kgdb_state *ks) return 1; } +static void dbg_cpu_switch(int cpu, int next_cpu) +{ + /* Mark the cpu we are switching away from as a slave when it + * holds the kgdb_active token. This must be done so that the + * that all the cpus wait in for the debug core will not enter + * again as the master. */ + if (cpu == atomic_read(&kgdb_active)) { + kgdb_info[cpu].exception_state |= DCPU_IS_SLAVE; + kgdb_info[cpu].exception_state &= ~DCPU_WANT_MASTER; + } + kgdb_info[next_cpu].exception_state |= DCPU_NEXT_MASTER; +} + static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs) { unsigned long flags; int sstep_tries = 100; - int error = 0; + int error; int i, cpu; int trace_on = 0; acquirelock: @@ -460,6 +486,8 @@ acquirelock: cpu = ks->cpu; kgdb_info[cpu].debuggerinfo = regs; kgdb_info[cpu].task = current; + kgdb_info[cpu].ret_state = 0; + kgdb_info[cpu].irq_depth = hardirq_count() >> HARDIRQ_SHIFT; /* * Make sure the above info reaches the primary CPU before * our cpu_in_kgdb[] flag setting does: @@ -471,7 +499,11 @@ acquirelock: * master cpu and acquire the kgdb_active lock: */ while (1) { - if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) { +cpu_loop: + if (kgdb_info[cpu].exception_state & DCPU_NEXT_MASTER) { + kgdb_info[cpu].exception_state &= ~DCPU_NEXT_MASTER; + goto cpu_master_loop; + } else if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) { if (atomic_cmpxchg(&kgdb_active, -1, cpu) == cpu) break; } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) { @@ -513,7 +545,7 @@ return_normal: } if (!kgdb_io_ready(1)) { - error = 1; + kgdb_info[cpu].ret_state = 1; goto kgdb_restore; /* No I/O connection, resume the system */ } @@ -548,7 +580,7 @@ return_normal: * Wait for the other CPUs to be notified and be waiting for us: */ for_each_online_cpu(i) { - while (!atomic_read(&cpu_in_kgdb[i])) + while (kgdb_do_roundup && !atomic_read(&cpu_in_kgdb[i])) cpu_relax(); } @@ -557,7 +589,7 @@ return_normal: * in the debugger and all secondary CPUs are quiescent */ kgdb_post_primary_code(ks->linux_regs, ks->ex_vector, ks->err_code); - kgdb_deactivate_sw_breakpoints(); + dbg_deactivate_sw_breakpoints(); kgdb_single_step = 0; kgdb_contthread = current; exception_level = 0; @@ -565,8 +597,26 @@ return_normal: if (trace_on) tracing_off(); - /* Talk to debugger with gdbserial protocol */ - error = gdb_serial_stub(ks); + while (1) { +cpu_master_loop: + if (dbg_kdb_mode) { + kgdb_connected = 1; + error = kdb_stub(ks); + } else { + error = gdb_serial_stub(ks); + } + + if (error == DBG_PASS_EVENT) { + dbg_kdb_mode = !dbg_kdb_mode; + kgdb_connected = 0; + } else if (error == DBG_SWITCH_CPU_EVENT) { + dbg_cpu_switch(cpu, dbg_switch_cpu); + goto cpu_loop; + } else { + kgdb_info[cpu].ret_state = error; + break; + } + } /* Call the I/O driver's post_exception routine */ if (dbg_io_ops->post_exception) @@ -578,11 +628,16 @@ return_normal: for (i = NR_CPUS-1; i >= 0; i--) atomic_dec(&passive_cpu_wait[i]); /* - * Wait till all the CPUs have quit - * from the debugger. + * Wait till all the CPUs have quit from the debugger, + * but allow a CPU that hit an exception and is + * waiting to become the master to remain in the debug + * core. */ for_each_online_cpu(i) { - while (atomic_read(&cpu_in_kgdb[i])) + while (kgdb_do_roundup && + atomic_read(&cpu_in_kgdb[i]) && + !(kgdb_info[i].exception_state & + DCPU_WANT_MASTER)) cpu_relax(); } } @@ -603,7 +658,7 @@ kgdb_restore: clocksource_touch_watchdog(); local_irq_restore(flags); - return error; + return kgdb_info[cpu].ret_state; } /* @@ -632,7 +687,8 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) return 0; /* Ouch, double exception ! */ kgdb_info[ks->cpu].exception_state |= DCPU_WANT_MASTER; ret = kgdb_cpu_enter(ks, regs); - kgdb_info[ks->cpu].exception_state &= ~DCPU_WANT_MASTER; + kgdb_info[ks->cpu].exception_state &= ~(DCPU_WANT_MASTER | + DCPU_IS_SLAVE); return ret; } @@ -665,7 +721,7 @@ static void kgdb_console_write(struct console *co, const char *s, /* If we're debugging, or KGDB has not connected, don't try * and print. */ - if (!kgdb_connected || atomic_read(&kgdb_active) != -1) + if (!kgdb_connected || atomic_read(&kgdb_active) != -1 || dbg_kdb_mode) return; local_irq_save(flags); @@ -687,8 +743,14 @@ static void sysrq_handle_dbg(int key, struct tty_struct *tty) printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); return; } - if (!kgdb_connected) + if (!kgdb_connected) { +#ifdef CONFIG_KGDB_KDB + if (!dbg_kdb_mode) + printk(KERN_CRIT "KGDB or $3#33 for KDB\n"); +#else printk(KERN_CRIT "Entering KGDB\n"); +#endif + } kgdb_breakpoint(); } @@ -817,6 +879,16 @@ void kgdb_unregister_io_module(struct kgdb_io *old_dbg_io_ops) } EXPORT_SYMBOL_GPL(kgdb_unregister_io_module); +int dbg_io_get_char(void) +{ + int ret = dbg_io_ops->read_char(); + if (!dbg_kdb_mode) + return ret; + if (ret == 127) + return 8; + return ret; +} + /** * kgdb_breakpoint - generate breakpoint exception * @@ -839,6 +911,7 @@ static int __init opt_kgdb_wait(char *str) { kgdb_break_asap = 1; + kdb_init(KDB_INIT_EARLY); if (kgdb_io_module_registered) kgdb_initial_breakpoint(); diff --git a/kernel/debug/debug_core.h b/kernel/debug/debug_core.h index db554f9be51d..44cf3de8cf9e 100644 --- a/kernel/debug/debug_core.h +++ b/kernel/debug/debug_core.h @@ -38,6 +38,8 @@ struct debuggerinfo_struct { void *debuggerinfo; struct task_struct *task; int exception_state; + int ret_state; + int irq_depth; }; extern struct debuggerinfo_struct kgdb_info[]; @@ -47,9 +49,31 @@ extern int dbg_remove_all_break(void); extern int dbg_set_sw_break(unsigned long addr); extern int dbg_remove_sw_break(unsigned long addr); extern int dbg_activate_sw_breakpoints(void); +extern int dbg_deactivate_sw_breakpoints(void); + +/* polled character access to i/o module */ +extern int dbg_io_get_char(void); + +/* stub return value for switching between the gdbstub and kdb */ +#define DBG_PASS_EVENT -12345 +/* Switch from one cpu to another */ +#define DBG_SWITCH_CPU_EVENT -123456 +extern int dbg_switch_cpu; /* gdbstub interface functions */ extern int gdb_serial_stub(struct kgdb_state *ks); extern void gdbstub_msg_write(const char *s, int len); +/* gdbstub functions used for kdb <-> gdbstub transition */ +extern int gdbstub_state(struct kgdb_state *ks, char *cmd); + +#ifdef CONFIG_KGDB_KDB +extern int kdb_stub(struct kgdb_state *ks); +#else /* ! CONFIG_KGDB_KDB */ +static inline int kdb_stub(struct kgdb_state *ks) +{ + return DBG_PASS_EVENT; +} +#endif /* CONFIG_KGDB_KDB */ + #endif /* _DEBUG_CORE_H_ */ diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c index ccdf0929f12d..188203a19657 100644 --- a/kernel/debug/gdbstub.c +++ b/kernel/debug/gdbstub.c @@ -887,6 +887,13 @@ int gdb_serial_stub(struct kgdb_state *ks) case 'Z': /* Break point set */ gdb_cmd_break(ks); break; +#ifdef CONFIG_KGDB_KDB + case '3': /* Escape into back into kdb */ + if (remcom_in_buffer[1] == '\0') { + gdb_cmd_detachkill(ks); + return DBG_PASS_EVENT; + } +#endif case 'C': /* Exception passing */ tmp = gdb_cmd_exception_pass(ks); if (tmp > 0) @@ -932,3 +939,32 @@ kgdb_exit: error = 1; return error; } + +int gdbstub_state(struct kgdb_state *ks, char *cmd) +{ + int error; + + switch (cmd[0]) { + case 'e': + error = kgdb_arch_handle_exception(ks->ex_vector, + ks->signo, + ks->err_code, + remcom_in_buffer, + remcom_out_buffer, + ks->linux_regs); + return error; + case 's': + case 'c': + strcpy(remcom_in_buffer, cmd); + return 0; + case '?': + gdb_cmd_status(ks); + break; + case '\0': + strcpy(remcom_out_buffer, ""); + break; + } + dbg_io_ops->write_char('+'); + put_packet(remcom_out_buffer); + return 0; +} diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb index 9b5d1d7f2ef7..78de43a5e902 100644 --- a/lib/Kconfig.kgdb +++ b/lib/Kconfig.kgdb @@ -3,7 +3,7 @@ config HAVE_ARCH_KGDB bool menuconfig KGDB - bool "KGDB: kernel debugging with remote gdb" + bool "KGDB: kernel debugger" depends on HAVE_ARCH_KGDB depends on DEBUG_KERNEL && EXPERIMENTAL help @@ -57,4 +57,10 @@ config KGDB_TESTS_BOOT_STRING information about other strings you could use beyond the default of V1F100. +config KGDB_KDB + bool "KGDB_KDB: include kdb frontend for kgdb" + default n + help + KDB frontend for kernel + endif # KGDB -- cgit v1.2.3-59-g8ed1b From 98ec1878cacb393975cba64f7392eece81716cb4 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Mon, 27 Apr 2009 10:58:06 -0500 Subject: kgdb: remove post_primary_code references Remove all the references to the kgdb_post_primary_code. This function serves no useful purpose because you can obtain the same information from the "struct kgdb_state *ks" from with in the debugger, if for some reason you want the data. Also remove the unintentional duplicate assignment for ks->ex_vector. Signed-off-by: Jason Wessel --- arch/x86/kernel/kgdb.c | 29 ----------------------------- include/linux/kgdb.h | 14 -------------- kernel/debug/debug_core.c | 8 -------- 3 files changed, 51 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index f95a2c0b915c..acba57169938 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -47,20 +47,8 @@ #include #include #include - #include -/* - * Put the error code here just in case the user cares: - */ -static int gdb_x86errcode; - -/* - * Likewise, the vector number here (since GDB only gets the signal - * number through the usual means, and that's not very specific): - */ -static int gdb_x86vector = -1; - /** * pt_regs_to_gdb_regs - Convert ptrace regs to GDB regs * @gdb_regs: A pointer to hold the registers in the order GDB wants. @@ -399,23 +387,6 @@ void kgdb_disable_hw_debug(struct pt_regs *regs) } } -/** - * kgdb_post_primary_code - Save error vector/code numbers. - * @regs: Original pt_regs. - * @e_vector: Original error vector. - * @err_code: Original error code. - * - * This is needed on architectures which support SMP and KGDB. - * This function is called after all the slave cpus have been put - * to a know spin state and the primary CPU has control over KGDB. - */ -void kgdb_post_primary_code(struct pt_regs *regs, int e_vector, int err_code) -{ - /* primary processor is completely in the debugger */ - gdb_x86vector = e_vector; - gdb_x86errcode = err_code; -} - #ifdef CONFIG_SMP /** * kgdb_roundup_cpus - Get other CPUs into a holding pattern diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 407edb1e0c4d..406f6f9286f3 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -35,20 +35,6 @@ struct pt_regs; */ extern int kgdb_skipexception(int exception, struct pt_regs *regs); -/** - * kgdb_post_primary_code - (optional) Save error vector/code numbers. - * @regs: Original pt_regs. - * @e_vector: Original error vector. - * @err_code: Original error code. - * - * This is usually needed on architectures which support SMP and - * KGDB. This function is called after all the secondary cpus have - * been put to a know spin state and the primary CPU has control over - * KGDB. - */ -extern void kgdb_post_primary_code(struct pt_regs *regs, int e_vector, - int err_code); - /** * kgdb_disable_hw_debug - (optional) Disable hardware debugging hook * @regs: Current &struct pt_regs. diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 1aed37b4c564..88a83a225374 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -203,12 +203,6 @@ int __weak kgdb_skipexception(int exception, struct pt_regs *regs) return 0; } -void __weak -kgdb_post_primary_code(struct pt_regs *regs, int e_vector, int err_code) -{ - return; -} - /** * kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb. * @regs: Current &struct pt_regs. @@ -588,7 +582,6 @@ return_normal: * At this point the primary processor is completely * in the debugger and all secondary CPUs are quiescent */ - kgdb_post_primary_code(ks->linux_regs, ks->ex_vector, ks->err_code); dbg_deactivate_sw_breakpoints(); kgdb_single_step = 0; kgdb_contthread = current; @@ -678,7 +671,6 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) ks->cpu = raw_smp_processor_id(); ks->ex_vector = evector; ks->signo = signo; - ks->ex_vector = evector; ks->err_code = ecode; ks->kgdb_usethreadid = 0; ks->linux_regs = regs; -- cgit v1.2.3-59-g8ed1b From f503b5ae53cb557ac351a668fcac1baab1cef0db Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:25 -0500 Subject: x86,kgdb: Add low level debug hook The only way the debugger can handle a trap in inside rcu_lock, notify_die, or atomic_notifier_call_chain without a triple fault is to have a low level "first opportunity handler" in the int3 exception handler. Generally this will be something the vast majority of folks will not need, but for those who need it, it is added as a kernel .config option called KGDB_LOW_LEVEL_TRAP. CC: Ingo Molnar CC: Thomas Gleixner CC: H. Peter Anvin CC: x86@kernel.org Signed-off-by: Jason Wessel --- arch/x86/include/asm/kgdb.h | 3 +++ arch/x86/kernel/kgdb.c | 22 +++++++++++++++++++++- arch/x86/kernel/traps.c | 6 ++++++ include/linux/kgdb.h | 1 + kernel/debug/debug_core.c | 2 +- lib/Kconfig.kgdb | 9 +++++++++ 6 files changed, 41 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/kgdb.h b/arch/x86/include/asm/kgdb.h index e6c6c808489f..006da3687cdc 100644 --- a/arch/x86/include/asm/kgdb.h +++ b/arch/x86/include/asm/kgdb.h @@ -76,4 +76,7 @@ static inline void arch_kgdb_breakpoint(void) #define BREAK_INSTR_SIZE 1 #define CACHE_FLUSH_IS_SAFE 1 +extern int kgdb_ll_trap(int cmd, const char *str, + struct pt_regs *regs, long err, int trap, int sig); + #endif /* _ASM_X86_KGDB_H */ diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index acba57169938..95b89d4cb8f1 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -538,7 +538,7 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd) return NOTIFY_DONE; } - if (kgdb_handle_exception(args->trapnr, args->signr, args->err, regs)) + if (kgdb_handle_exception(args->trapnr, args->signr, cmd, regs)) return NOTIFY_DONE; /* Must touch watchdog before return to normal operation */ @@ -546,6 +546,26 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd) return NOTIFY_STOP; } +#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP +int kgdb_ll_trap(int cmd, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig, + + }; + + if (!kgdb_io_module_registered) + return NOTIFY_DONE; + + return __kgdb_notify(&args, cmd); +} +#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ + static int kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) { diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 02cfb9b8f5b1..7eaad4c5110a 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -451,6 +452,11 @@ void restart_nmi(void) /* May run on IST stack. */ dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) { +#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP + if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) + == NOTIFY_STOP) + return; +#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ #ifdef CONFIG_KPROBES if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 406f6f9286f3..19d1b29a2694 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -60,6 +60,7 @@ struct uart_port; void kgdb_breakpoint(void); extern int kgdb_connected; +extern int kgdb_io_module_registered; extern atomic_t kgdb_setting_breakpoint; extern atomic_t kgdb_cpu_doing_single_step; diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 88a83a225374..375e42f0baf0 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -66,7 +66,7 @@ int kgdb_connected; EXPORT_SYMBOL_GPL(kgdb_connected); /* All the KGDB handlers are installed */ -static int kgdb_io_module_registered; +int kgdb_io_module_registered; /* Guard for recursive entry */ static int exception_level; diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb index ee8ae7132f20..c56ccb4ad292 100644 --- a/lib/Kconfig.kgdb +++ b/lib/Kconfig.kgdb @@ -57,6 +57,15 @@ config KGDB_TESTS_BOOT_STRING information about other strings you could use beyond the default of V1F100. +config KGDB_LOW_LEVEL_TRAP + bool "KGDB: Allow debugging with traps in notifiers" + depends on X86 + default n + help + This will add an extra call back to kgdb for the breakpoint + exception handler on which will will allow kgdb to step + through a notify handler. + config KGDB_KDB bool "KGDB_KDB: include kdb frontend for kgdb" default n -- cgit v1.2.3-59-g8ed1b From ba797b28131b1f1367b662936ea370239d603cff Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:25 -0500 Subject: powerpc,kgdb: Introduce low level trap catching The only way the debugger can handle a trap in inside rcu_lock, notify_die, or atomic_notifier_call_chain without a recursive fault is to allow the kernel debugger to handle the exception first in program_check_exception(). The other change here is to make sure that kgdb_handle_exception() is called with correct parameters when catching an oops, because kdb needs to know if the entry was an oops, single step, or breakpoint exception. [benh@kernel.crashing.org: move debugger_bpt instead of #ifdef] CC: Paul Mackerras Signed-off-by: Jason Wessel Acked-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/kgdb.c | 6 ++++-- arch/powerpc/kernel/traps.c | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index c81e3de1306e..82a7b228c81a 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -115,7 +116,8 @@ void kgdb_roundup_cpus(unsigned long flags) /* KGDB functions to use existing PowerPC64 hooks. */ static int kgdb_debugger(struct pt_regs *regs) { - return kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs); + return !kgdb_handle_exception(1, computeSignal(TRAP(regs)), + DIE_OOPS, regs); } static int kgdb_handle_breakpoint(struct pt_regs *regs) @@ -123,7 +125,7 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs) if (user_mode(regs)) return 0; - if (kgdb_handle_exception(0, SIGTRAP, 0, regs) != 0) + if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0) return 0; if (*(u32 *) (regs->nip) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr)) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 29d128eb6c43..b6859aade9c2 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -815,12 +815,15 @@ void __kprobes program_check_exception(struct pt_regs *regs) return; } if (reason & REASON_TRAP) { + /* Debugger is first in line to stop recursive faults in + * rcu_lock, notify_die, or atomic_notifier_call_chain */ + if (debugger_bpt(regs)) + return; + /* trap exception */ if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) return; - if (debugger_bpt(regs)) - return; if (!(regs->msr & MSR_PR) && /* not user-mode */ report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { -- cgit v1.2.3-59-g8ed1b From 5dd11d5d47d248850c58292513f0e164ba98b01e Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:26 -0500 Subject: mips,kgdb: kdb low level trap catch and stack trace The only way the debugger can handle a trap in inside rcu_lock, notify_die, or atomic_notifier_call_chain without a recursive fault is to have a low level "first opportunity handler" do_trap_or_bp() handler. Generally this will be something the vast majority of folks will not need, but for those who need it, it is added as a kernel .config option called KGDB_LOW_LEVEL_TRAP. Also added was a die notification for oops such that kdb can catch an oops for analysis. There appeared to be no obvious way to pass the struct pt_regs from the original exception back to the stack back tracer, so a special case was added to show_stack() for when kdb is active because you generally desire to generally look at the back trace of the original exception. Signed-off-by: Jason Wessel Acked-by: Ralf Baechle --- arch/mips/include/asm/kgdb.h | 2 ++ arch/mips/kernel/kgdb.c | 22 +++++++++++++++++++++- arch/mips/kernel/traps.c | 13 +++++++++++++ lib/Kconfig.kgdb | 2 +- 4 files changed, 37 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/kgdb.h b/arch/mips/include/asm/kgdb.h index 48223b09396c..19002d605ac4 100644 --- a/arch/mips/include/asm/kgdb.h +++ b/arch/mips/include/asm/kgdb.h @@ -38,6 +38,8 @@ extern int kgdb_early_setup; extern void *saved_vectors[32]; extern void handle_exception(struct pt_regs *regs); extern void breakinst(void); +extern int kgdb_ll_trap(int cmd, const char *str, + struct pt_regs *regs, long err, int trap, int sig); #endif /* __KERNEL__ */ diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 6ed4c83c869b..9b78ff6e9b84 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -203,7 +203,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, if (atomic_read(&kgdb_active) != -1) kgdb_nmicallback(smp_processor_id(), regs); - if (kgdb_handle_exception(trap, compute_signal(trap), 0, regs)) + if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs)) return NOTIFY_DONE; if (atomic_read(&kgdb_setting_breakpoint)) @@ -217,6 +217,26 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, return NOTIFY_STOP; } +#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP +int kgdb_ll_trap(int cmd, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig, + + }; + + if (!kgdb_io_module_registered) + return NOTIFY_DONE; + + return kgdb_mips_notify(NULL, cmd, &args); +} +#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ + static struct notifier_block kgdb_notifier = { .notifier_call = kgdb_mips_notify, }; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index d612c6dcb746..950bde8813fc 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -185,6 +186,11 @@ void show_stack(struct task_struct *task, unsigned long *sp) regs.regs[29] = task->thread.reg29; regs.regs[31] = 0; regs.cp0_epc = task->thread.reg31; +#ifdef CONFIG_KGDB_KDB + } else if (atomic_read(&kgdb_active) != -1 && + kdb_current_regs) { + memcpy(®s, kdb_current_regs, sizeof(regs)); +#endif /* CONFIG_KGDB_KDB */ } else { prepare_frametrace(®s); } @@ -360,6 +366,8 @@ void __noreturn die(const char * str, struct pt_regs * regs) unsigned long dvpret = dvpe(); #endif /* CONFIG_MIPS_MT_SMTC */ + notify_die(DIE_OOPS, str, (struct pt_regs *)regs, SIGSEGV, 0, 0); + console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); @@ -704,6 +712,11 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, siginfo_t info; char b[40]; +#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP + if (kgdb_ll_trap(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP) + return; +#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ + if (notify_die(DIE_TRAP, str, regs, code, 0, 0) == NOTIFY_STOP) return; diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb index c56ccb4ad292..43cb93fa2651 100644 --- a/lib/Kconfig.kgdb +++ b/lib/Kconfig.kgdb @@ -59,7 +59,7 @@ config KGDB_TESTS_BOOT_STRING config KGDB_LOW_LEVEL_TRAP bool "KGDB: Allow debugging with traps in notifiers" - depends on X86 + depends on X86 || MIPS default n help This will add an extra call back to kgdb for the breakpoint -- cgit v1.2.3-59-g8ed1b From 29c843912a0baa7fa63033fe28e1ca7e796686a5 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Thu, 20 May 2010 21:04:29 -0500 Subject: x86, kgdb: early trap init for early debug Allow the x86 arch to have early exception processing for the purpose of debugging via the kgdb. Signed-off-by: Jan Kiszka Signed-off-by: Jason Wessel --- arch/x86/include/asm/processor.h | 2 ++ arch/x86/kernel/setup.c | 1 + arch/x86/kernel/traps.c | 14 ++++++++++---- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 5a51379dcbe4..7e5c6a60b8ee 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -789,6 +789,8 @@ static inline void wbinvd_halt(void) extern void enable_sep_cpu(void); extern int sysenter_setup(void); +extern void early_trap_init(void); + /* Defined in head.S */ extern struct desc_ptr early_gdt_descr; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index c4851eff57b3..e8029896309a 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -725,6 +725,7 @@ void __init setup_arch(char **cmdline_p) /* VMI may relocate the fixmap; do this before touching ioremap area */ vmi_init(); + early_trap_init(); early_cpu_init(); early_ioremap_init(); diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 7eaad4c5110a..142d70c74b02 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -808,6 +808,16 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) } #endif +/* Set of traps needed for early debugging. */ +void __init early_trap_init(void) +{ + set_intr_gate_ist(1, &debug, DEBUG_STACK); + /* int3 can be called from all */ + set_system_intr_gate_ist(3, &int3, DEBUG_STACK); + set_intr_gate(14, &page_fault); + load_idt(&idt_descr); +} + void __init trap_init(void) { int i; @@ -821,10 +831,7 @@ void __init trap_init(void) #endif set_intr_gate(0, ÷_error); - set_intr_gate_ist(1, &debug, DEBUG_STACK); set_intr_gate_ist(2, &nmi, NMI_STACK); - /* int3 can be called from all */ - set_system_intr_gate_ist(3, &int3, DEBUG_STACK); /* int4 can be called from all */ set_system_intr_gate(4, &overflow); set_intr_gate(5, &bounds); @@ -840,7 +847,6 @@ void __init trap_init(void) set_intr_gate(11, &segment_not_present); set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK); set_intr_gate(13, &general_protection); - set_intr_gate(14, &page_fault); set_intr_gate(15, &spurious_interrupt_bug); set_intr_gate(16, &coprocessor_error); set_intr_gate(17, &alignment_check); -- cgit v1.2.3-59-g8ed1b From 0b4b3827db386ec6034a5aba1261025b039440c2 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:29 -0500 Subject: x86, kgdb, init: Add early and late debug states The kernel debugger can operate well before mm_init(), but the x86 hardware breakpoint code which uses the perf api requires that the kernel allocators are initialized. This means the kernel debug core needs to provide an optional arch specific call back to allow the initialization functions to run after the kernel has been further initialized. The kdb shell already had a similar restriction with an early initialization and late initialization. The kdb_init() was moved into the debug core's version of the late init which is called dbg_late_init(); CC: kgdb-bugreport@lists.sourceforge.net Signed-off-by: Jason Wessel --- arch/x86/kernel/kgdb.c | 17 ++++++++++------- include/linux/kgdb.h | 14 ++++++++++++++ init/main.c | 4 ++-- kernel/debug/debug_core.c | 16 ++++++++++++++++ 4 files changed, 42 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 95b89d4cb8f1..2b71ec41869f 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -595,15 +595,16 @@ static struct notifier_block kgdb_notifier = { * specific callbacks. */ int kgdb_arch_init(void) +{ + return register_die_notifier(&kgdb_notifier); +} + +void kgdb_arch_late(void) { int i, cpu; - int ret; struct perf_event_attr attr; struct perf_event **pevent; - ret = register_die_notifier(&kgdb_notifier); - if (ret != 0) - return ret; /* * Pre-allocate the hw breakpoint structions in the non-atomic * portion of kgdb because this operation requires mutexs to @@ -615,12 +616,15 @@ int kgdb_arch_init(void) attr.bp_type = HW_BREAKPOINT_W; attr.disabled = 1; for (i = 0; i < 4; i++) { + if (breakinfo[i].pev) + continue; breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); if (IS_ERR(breakinfo[i].pev)) { - printk(KERN_ERR "kgdb: Could not allocate hw breakpoints\n"); + printk(KERN_ERR "kgdb: Could not allocate hw" + "breakpoints\nDisabling the kernel debugger\n"); breakinfo[i].pev = NULL; kgdb_arch_exit(); - return -1; + return; } for_each_online_cpu(cpu) { pevent = per_cpu_ptr(breakinfo[i].pev, cpu); @@ -631,7 +635,6 @@ int kgdb_arch_init(void) } } } - return ret; } /** diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 6c784ab6856a..9340f34d1bb5 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -207,6 +207,17 @@ extern int kgdb_validate_break_address(unsigned long addr); extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr); extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle); +/** + * kgdb_arch_late - Perform any architecture specific initalization. + * + * This function will handle the late initalization of any + * architecture specific callbacks. This is an optional function for + * handling things like late initialization of hw breakpoints. The + * default implementation does nothing. + */ +extern void kgdb_arch_late(void); + + /** * struct kgdb_arch - Describe architecture specific values. * @gdb_bpt_instr: The instruction to trigger a breakpoint. @@ -285,7 +296,10 @@ extern int kgdb_single_step; extern atomic_t kgdb_active; #define in_dbg_master() \ (raw_smp_processor_id() == atomic_read(&kgdb_active)) +extern bool dbg_is_early; +extern void __init dbg_late_init(void); #else /* ! CONFIG_KGDB */ #define in_dbg_master() (0) +#define dbg_late_init() #endif /* ! CONFIG_KGDB */ #endif /* _KGDB_H_ */ diff --git a/init/main.c b/init/main.c index 372771333d98..22881b5e95e3 100644 --- a/init/main.c +++ b/init/main.c @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include #include #include @@ -676,7 +676,7 @@ asmlinkage void __init start_kernel(void) buffer_init(); key_init(); security_init(); - kdb_init(KDB_INIT_FULL); + dbg_late_init(); vfs_caches_init(totalram_pages); signals_init(); /* rootfs populating might need page-writeback */ diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 64b5588c9638..5cb7cd1de10c 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -78,6 +78,8 @@ static DEFINE_SPINLOCK(kgdb_registration_lock); static int kgdb_con_registered; /* determine if kgdb console output should be used */ static int kgdb_use_con; +/* Flag for alternate operations for early debugging */ +bool dbg_is_early = true; /* Next cpu to become the master debug core */ int dbg_switch_cpu; @@ -777,11 +779,25 @@ static struct notifier_block kgdb_panic_event_nb = { .priority = INT_MAX, }; +void __weak kgdb_arch_late(void) +{ +} + +void __init dbg_late_init(void) +{ + dbg_is_early = false; + if (kgdb_io_module_registered) + kgdb_arch_late(); + kdb_init(KDB_INIT_FULL); +} + static void kgdb_register_callbacks(void) { if (!kgdb_io_module_registered) { kgdb_io_module_registered = 1; kgdb_arch_init(); + if (!dbg_is_early) + kgdb_arch_late(); atomic_notifier_chain_register(&panic_notifier_list, &kgdb_panic_event_nb); #ifdef CONFIG_MAGIC_SYSRQ -- cgit v1.2.3-59-g8ed1b From 031acd8c42edd61070f81c51edc89e83147a3d0e Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:30 -0500 Subject: x86,kgdb: Implement early hardware breakpoint debugging It is not possible to use the hw_breakpoint.c API prior to mm_init(), but it is possible to use hardware breakpoints with the kernel debugger. Prior to smp_init() it is possible to simply write to the dr registers of the boot cpu directly. This can be used up until the kgdb_arch_late() is invoked, at which point the standard hw_breakpoint.c API will get used. CC: Frederic Weisbecker CC: Ingo Molnar Signed-off-by: Jason Wessel --- arch/x86/kernel/kgdb.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 2b71ec41869f..4f4af75b9482 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -199,6 +199,8 @@ static struct hw_breakpoint { struct perf_event **pev; } breakinfo[4]; +static unsigned long early_dr7; + static void kgdb_correct_hw_break(void) { int breakno; @@ -210,6 +212,14 @@ static void kgdb_correct_hw_break(void) int cpu = raw_smp_processor_id(); if (!breakinfo[breakno].enabled) continue; + if (dbg_is_early) { + set_debugreg(breakinfo[breakno].addr, breakno); + early_dr7 |= encode_dr7(breakno, + breakinfo[breakno].len, + breakinfo[breakno].type); + set_debugreg(early_dr7, 7); + continue; + } bp = *per_cpu_ptr(breakinfo[breakno].pev, cpu); info = counter_arch_bp(bp); if (bp->attr.disabled != 1) @@ -224,7 +234,8 @@ static void kgdb_correct_hw_break(void) if (!val) bp->attr.disabled = 0; } - hw_breakpoint_restore(); + if (!dbg_is_early) + hw_breakpoint_restore(); } static int hw_break_reserve_slot(int breakno) @@ -233,6 +244,9 @@ static int hw_break_reserve_slot(int breakno) int cnt = 0; struct perf_event **pevent; + if (dbg_is_early) + return 0; + for_each_online_cpu(cpu) { cnt++; pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); @@ -258,6 +272,9 @@ static int hw_break_release_slot(int breakno) struct perf_event **pevent; int cpu; + if (dbg_is_early) + return 0; + for_each_online_cpu(cpu) { pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); if (dbg_release_bp_slot(*pevent)) @@ -302,7 +319,11 @@ static void kgdb_remove_all_hw_break(void) bp = *per_cpu_ptr(breakinfo[i].pev, cpu); if (bp->attr.disabled == 1) continue; - arch_uninstall_hw_breakpoint(bp); + if (dbg_is_early) + early_dr7 &= ~encode_dr7(i, breakinfo[i].len, + breakinfo[i].type); + else + arch_uninstall_hw_breakpoint(bp); bp->attr.disabled = 1; } } @@ -379,6 +400,11 @@ void kgdb_disable_hw_debug(struct pt_regs *regs) for (i = 0; i < 4; i++) { if (!breakinfo[i].enabled) continue; + if (dbg_is_early) { + early_dr7 &= ~encode_dr7(i, breakinfo[i].len, + breakinfo[i].type); + continue; + } bp = *per_cpu_ptr(breakinfo[i].pev, cpu); if (bp->attr.disabled == 1) continue; -- cgit v1.2.3-59-g8ed1b From 0bb9fef9134cf4fdcfce02f9adc22d3d0725cc29 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:30 -0500 Subject: x86,early dr regs,kgdb: Allow kernel debugger early dr register access If the kernel debugger was configured, attached and started with kgdbwait, the hardware breakpoint registers should get restored by the kgdb code which is managing the dr registers. CC: x86@kernel.org CC: Thomas Gleixner CC: Ingo Molnar CC: H. Peter Anvin Signed-off-by: Jason Wessel --- arch/x86/kernel/cpu/common.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c1c00d0b1692..cc83a002786e 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1084,6 +1084,20 @@ static void clear_all_debug_regs(void) } } +#ifdef CONFIG_KGDB +/* + * Restore debug regs if using kgdbwait and you have a kernel debugger + * connection established. + */ +static void dbg_restore_debug_regs(void) +{ + if (unlikely(kgdb_connected && arch_kgdb_ops.correct_hw_break)) + arch_kgdb_ops.correct_hw_break(); +} +#else /* ! CONFIG_KGDB */ +#define dbg_restore_debug_regs() +#endif /* ! CONFIG_KGDB */ + /* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT @@ -1174,18 +1188,8 @@ void __cpuinit cpu_init(void) load_TR_desc(); load_LDT(&init_mm.context); -#ifdef CONFIG_KGDB - /* - * If the kgdb is connected no debug regs should be altered. This - * is only applicable when KGDB and a KGDB I/O module are built - * into the kernel and you are using early debugging with - * kgdbwait. KGDB will control the kernel HW breakpoint registers. - */ - if (kgdb_connected && arch_kgdb_ops.correct_hw_break) - arch_kgdb_ops.correct_hw_break(); - else -#endif - clear_all_debug_regs(); + clear_all_debug_regs(); + dbg_restore_debug_regs(); fpu_init(); @@ -1239,6 +1243,7 @@ void __cpuinit cpu_init(void) #endif clear_all_debug_regs(); + dbg_restore_debug_regs(); /* * Force FPU initialization: -- cgit v1.2.3-59-g8ed1b From 61eaf539b9fb4926ed57e38f6545100c3432cf1b Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:31 -0500 Subject: earlyprintk,vga,kdb: Fix \b and \r for earlyprintk=vga with kdb Allow kdb to work properly with with earlyprintk=vga by interpreting the backspace and carriage return output characters. These interpretation of these characters is used for simple line editing provided in the kdb shell. CC: Thomas Gleixner CC: Ingo Molnar CC: H. Peter Anvin CC: x86@kernel.org Signed-off-by: Jason Wessel --- arch/x86/kernel/early_printk.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index b9c830c12b4a..fa99bae75ace 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -41,6 +41,14 @@ static void early_vga_write(struct console *con, const char *str, unsigned n) writew(0x720, VGABASE + 2*(max_xpos*j + i)); current_ypos = max_ypos-1; } +#ifdef CONFIG_KGDB_KDB + if (c == '\b') { + if (current_xpos > 0) + current_xpos--; + } else if (c == '\r') { + current_xpos = 0; + } else +#endif if (c == '\n') { current_xpos = 0; current_ypos++; -- cgit v1.2.3-59-g8ed1b From 7358650e9e9a81c854dc4582b4193eb5ea500bf6 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 19 May 2010 02:12:32 +0000 Subject: powerpc/rtasd: Don't start event scan if scan rate is zero There appear to be Pegasos systems which have the rtas-event-scan RTAS tokens, but on which the event scan always fails. They also have an event-scan-rate property containing 0, which means call event scan 0 times per minute. So interpret a scan rate of 0 to mean don't scan at all. This fixes the problem on the Pegasos machines and makes sense as well. Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/rtasd.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index e907ca66f75a..638883e23e3a 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -490,6 +490,12 @@ static int __init rtas_init(void) return -ENODEV; } + if (!rtas_event_scan_rate) { + /* Broken firmware: take a rate of zero to mean don't scan */ + printk(KERN_DEBUG "rtasd: scan rate is 0, not scanning\n"); + return 0; + } + /* Make room for the sequence number */ rtas_error_log_max = rtas_get_error_log_max(); rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int); -- cgit v1.2.3-59-g8ed1b From ca5d0674c37840366f04a7bbfbf78e7b5f3ce0a4 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Tue, 18 May 2010 08:15:21 +0000 Subject: powerpc: Fix string library functions The powerpc strncmp implementation does not correctly handle a zero length, despite the claim in 0119536cd314ef95553604208c25bc35581f7f0a (Add hand-coded assembly strcmp). Additionally, all the length arguments are size_t, not int, so use PPC_LCMPI and eq instead of cmpwi and le throughout. Signed-off-by: Andreas Schwab Acked-by: Paul Mackerras Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/lib/string.S | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S index 3ac0cd3a5373..455881a5563f 100644 --- a/arch/powerpc/lib/string.S +++ b/arch/powerpc/lib/string.S @@ -28,7 +28,7 @@ _GLOBAL(strcpy) /* This clears out any unused part of the destination buffer, just as the libc version does. -- paulus */ _GLOBAL(strncpy) - cmpwi 0,r5,0 + PPC_LCMPI 0,r5,0 beqlr mtctr r5 addi r6,r3,-1 @@ -39,7 +39,7 @@ _GLOBAL(strncpy) bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ bnelr /* if we didn't hit a null char, we're done */ mfctr r5 - cmpwi 0,r5,0 /* any space left in destination buffer? */ + PPC_LCMPI 0,r5,0 /* any space left in destination buffer? */ beqlr /* we know r0 == 0 here */ 2: stbu r0,1(r6) /* clear it out if so */ bdnz 2b @@ -70,8 +70,8 @@ _GLOBAL(strcmp) blr _GLOBAL(strncmp) - PPC_LCMPI r5,0 - ble- 2f + PPC_LCMPI 0,r5,0 + beq- 2f mtctr r5 addi r5,r3,-1 addi r4,r4,-1 @@ -94,8 +94,8 @@ _GLOBAL(strlen) blr _GLOBAL(memcmp) - cmpwi 0,r5,0 - ble- 2f + PPC_LCMPI 0,r5,0 + beq- 2f mtctr r5 addi r6,r3,-1 addi r4,r4,-1 @@ -108,8 +108,8 @@ _GLOBAL(memcmp) blr _GLOBAL(memchr) - cmpwi 0,r5,0 - ble- 2f + PPC_LCMPI 0,r5,0 + beq- 2f mtctr r5 addi r3,r3,-1 1: lbzu r0,1(r3) -- cgit v1.2.3-59-g8ed1b From abb17f9c3a92c5acf30e749efdf0419b7f50a5b8 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Wed, 19 May 2010 02:56:29 +0000 Subject: powerpc: Use common cpu_die (fixes SMP+SUSPEND build) Configuring a powerpc 32 bit kernel for both SMP and SUSPEND turns on CPU_HOTPLUG to enable disable_nonboot_cpus to be called by the common suspend code. Previously the definition of cpu_die for ppc32 was in the powermac platform code, causing it to be undefined if that platform as not selected. arch/powerpc/kernel/built-in.o: In function 'cpu_idle': arch/powerpc/kernel/idle.c:98: undefined reference to 'cpu_die' Move the code from setup_64 to smp.c and rename the power mac versions to their specific names. Note that this does not setup the cpu_die pointers in either smp_ops (request a given cpu die) or ppc_md (make this cpu die), for other platforms but there are generic versions in smp.c. Reported-by: Matt Sealey Reported-by: Kumar Gala Signed-off-by: Milton Miller Signed-off-by: Anton Vorontsov Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/setup_64.c | 6 ------ arch/powerpc/kernel/smp.c | 6 ++++++ arch/powerpc/platforms/powermac/pmac.h | 2 ++ arch/powerpc/platforms/powermac/setup.c | 11 ++++++++--- arch/powerpc/platforms/powermac/smp.c | 5 +++-- 5 files changed, 19 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 914389158a9b..cea66987a6ea 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -573,12 +573,6 @@ void ppc64_boot_msg(unsigned int src, const char *msg) printk("[boot]%04x %s\n", src, msg); } -void cpu_die(void) -{ - if (ppc_md.cpu_die) - ppc_md.cpu_die(); -} - #ifdef CONFIG_SMP #define PCPU_DYN_SIZE () diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index bf366167d369..5c196d1086d9 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -648,4 +648,10 @@ void cpu_hotplug_driver_unlock() { mutex_unlock(&powerpc_cpu_hotplug_driver_mutex); } + +void cpu_die(void) +{ + if (ppc_md.cpu_die) + ppc_md.cpu_die(); +} #endif diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 3362e781b6a7..f0bc08f6c1f0 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -33,6 +33,8 @@ extern void pmac_setup_pci_dma(void); extern void pmac_check_ht_link(void); extern void pmac_setup_smp(void); +extern void pmac32_cpu_die(void); +extern void low_cpu_die(void) __attribute__((noreturn)); extern int pmac_nvram_init(void); extern void pmac_pic_init(void); diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 47a2b4488557..f1d0132ebcc7 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -646,7 +646,7 @@ static int pmac_pci_probe_mode(struct pci_bus *bus) /* access per cpu vars from generic smp.c */ DECLARE_PER_CPU(int, cpu_state); -static void pmac_cpu_die(void) +static void pmac64_cpu_die(void) { /* * turn off as much as possible, we'll be @@ -717,8 +717,13 @@ define_machine(powermac) { .pcibios_after_init = pmac_pcibios_after_init, .phys_mem_access_prot = pci_phys_mem_access_prot, #endif -#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) - .cpu_die = pmac_cpu_die, +#ifdef CONFIG_HOTPLUG_CPU +#ifdef CONFIG_PPC64 + .cpu_die = pmac64_cpu_die, +#endif +#ifdef CONFIG_PPC32 + .cpu_die = pmac32_cpu_die, +#endif #endif #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) .cpu_die = generic_mach_cpu_die, diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 02d0b8e5b13c..c95215f4f8b6 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -53,6 +53,8 @@ #include #include +#include "pmac.h" + #undef DEBUG #ifdef DEBUG @@ -878,10 +880,9 @@ int smp_core99_cpu_disable(void) return 0; } -extern void low_cpu_die(void) __attribute__((noreturn)); /* in sleep.S */ static int cpu_dead[NR_CPUS]; -void cpu_die(void) +void pmac32_cpu_die(void) { local_irq_disable(); cpu_dead[smp_processor_id()] = 1; -- cgit v1.2.3-59-g8ed1b From e62cee42e66dcca83aae02748535f62e0f564a0c Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 May 2010 19:46:50 +0000 Subject: powerpc: Avoid bad relocations in iSeries code Subrata Modak reported that building a CONFIG_RELOCATABLE kernel with CONFIG_ISERIES enabled gives the following warnings: WARNING: 4 bad relocations c00000000007216e R_PPC64_ADDR16_HIGHEST __ksymtab+0x00000000009dcec8 c000000000072172 R_PPC64_ADDR16_HIGHER __ksymtab+0x00000000009dcec8 c00000000007217a R_PPC64_ADDR16_HI __ksymtab+0x00000000009dcec8 c00000000007217e R_PPC64_ADDR16_LO __ksymtab+0x00000000009dcec8 The reason is that decrementer_iSeries_masked is using LOAD_REG_IMMEDIATE to get the address of a kernel symbol, which creates relocations that aren't handled by the kernel relocator code. Instead of reading the tb_ticks_per_jiffy variable, we can just set the decrementer to its maximum value (0x7fffffff) and that will work just as well. In fact timer_interrupt sets the decrementer to that value initially anyway, and we are sure to get into timer_interrupt once interrupts are reenabled because we store 1 to the decrementer interrupt flag in the lppaca (LPPACADECRINT(r12) here). Reported-by: Subrata Modak Signed-off-by: Paul Mackerras Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/iseries/exception.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/iseries/exception.S b/arch/powerpc/platforms/iseries/exception.S index fba5bf915073..32a56c6dfa72 100644 --- a/arch/powerpc/platforms/iseries/exception.S +++ b/arch/powerpc/platforms/iseries/exception.S @@ -252,8 +252,8 @@ decrementer_iSeries_masked: li r11,1 ld r12,PACALPPACAPTR(r13) stb r11,LPPACADECRINT(r12) - LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy) - lwz r12,0(r12) + li r12,-1 + clrldi r12,r12,33 /* set DEC to 0x7fffffff */ mtspr SPRN_DEC,r12 /* fall through */ -- cgit v1.2.3-59-g8ed1b From a1263c71448aa70afb6097fdedf93c3dff5a7a15 Mon Sep 17 00:00:00 2001 From: Brian King Date: Fri, 14 May 2010 12:04:41 +0000 Subject: powerpc/vio: Switch VIO Bus PM to use generic helpers Switch to use the generic power management helpers. Signed-off-by: Brian King Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vio.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index b8e311d64ad5..9ce7b62dc3a4 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -1381,29 +1381,6 @@ static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env) return 0; } -static int vio_pm_suspend(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm && pm->suspend) - return pm->suspend(dev); - return 0; -} - -static int vio_pm_resume(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - - if (pm && pm->resume) - return pm->resume(dev); - return 0; -} - -const struct dev_pm_ops vio_dev_pm_ops = { - .suspend = vio_pm_suspend, - .resume = vio_pm_resume, -}; - static struct bus_type vio_bus_type = { .name = "vio", .dev_attrs = vio_dev_attrs, @@ -1411,7 +1388,7 @@ static struct bus_type vio_bus_type = { .match = vio_bus_match, .probe = vio_bus_probe, .remove = vio_bus_remove, - .pm = &vio_dev_pm_ops, + .pm = GENERIC_SUBSYS_PM_OPS, }; /** -- cgit v1.2.3-59-g8ed1b From 5b339bdf164d8aee394609768f7e2e4415b0252a Mon Sep 17 00:00:00 2001 From: Sonny Rao Date: Mon, 10 May 2010 15:13:41 +0000 Subject: powerpc/pci: Check devices status property when scanning OF tree We ran into an issue where it looks like we're not properly ignoring a pci device with a non-good status property when we walk the device tree and instanciate the Linux side PCI devices. However, the EEH init code does look for the property and disables EEH on these devices. This leaves us in an inconsistent where we are poking at a supposedly bad piece of hardware and RTAS will block our config cycles because EEH isn't enabled anyway. Signed-of-by: Sonny Rao Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/pci_of_scan.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index cd11d5ca80df..6ddb795f83e8 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -310,6 +310,8 @@ static void __devinit __of_scan_bus(struct device_node *node, /* Scan direct children */ for_each_child_of_node(node, child) { pr_debug(" * %s\n", child->full_name); + if (!of_device_is_available(child)) + continue; reg = of_get_property(child, "reg", ®len); if (reg == NULL || reglen < 20) continue; -- cgit v1.2.3-59-g8ed1b From ce47c1c45b2b17ad07af82c775f27cc5196080f8 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 10 May 2010 15:38:56 +0000 Subject: powerpc/eeh: Fix oops when probing in early boot If we take an EEH error early enough, we oops: Call Trace: [c000000010483770] [c000000000013ee4] .show_stack+0xd8/0x218 (unreliable) [c000000010483850] [c000000000658940] .dump_stack+0x28/0x3c [c0000000104838d0] [c000000000057a68] .eeh_dn_check_failure+0x2b8/0x304 [c000000010483990] [c0000000000259c8] .rtas_read_config+0x120/0x168 [c000000010483a40] [c000000000025af4] .rtas_pci_read_config+0xe4/0x124 [c000000010483af0] [c00000000037af18] .pci_bus_read_config_word+0xac/0x104 [c000000010483bc0] [c0000000008fec98] .pcibios_allocate_resources+0x7c/0x220 [c000000010483c90] [c0000000008feed8] .pcibios_resource_survey+0x9c/0x418 [c000000010483d80] [c0000000008fea10] .pcibios_init+0xbc/0xf4 [c000000010483e20] [c000000000009844] .do_one_initcall+0x98/0x1d8 [c000000010483ed0] [c0000000008f0560] .kernel_init+0x228/0x2e8 [c000000010483f90] [c000000000031a08] .kernel_thread+0x54/0x70 EEH: Detected PCI bus error on device EEH: This PCI device has failed 1 times in the last hour: EEH: location=U78A5.001.WIH8464-P1 driver= pci addr=0001:00:01.0 EEH: of node=/pci@800000020000209/usb@1 EEH: PCI device/vendor: 00351033 EEH: PCI cmd/status register: 12100146 Unable to handle kernel paging request for data at address 0x00000468 Oops: Kernel access of bad area, sig: 11 [#1] .... NIP [c000000000057610] .rtas_set_slot_reset+0x38/0x10c LR [c000000000058724] .eeh_reset_device+0x5c/0x124 Call Trace: [c00000000bc6bd00] [c00000000005a0e0] .pcibios_remove_pci_devices+0x7c/0xb0 (unreliable) [c00000000bc6bd90] [c000000000058724] .eeh_reset_device+0x5c/0x124 [c00000000bc6be40] [c0000000000589c0] .handle_eeh_events+0x1d4/0x39c [c00000000bc6bf00] [c000000000059124] .eeh_event_handler+0xf0/0x188 [c00000000bc6bf90] [c000000000031a08] .kernel_thread+0x54/0x70 We called rtas_set_slot_reset while scanning the bus and before the pci_dn to pcidev mapping has been created. Since we only need the pcidev to work out the type of reset and that only gets set after the module for the device loads, lets just do a hot reset if the pcidev is NULL. Signed-off-by: Anton Blanchard Acked-by: Linas Vepstas Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/eeh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 7df7fbb7cacb..34b7dc12e731 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -749,7 +749,7 @@ static void __rtas_set_slot_reset(struct pci_dn *pdn) /* Determine type of EEH reset required by device, * default hot reset or fundamental reset */ - if (dev->needs_freset) + if (dev && dev->needs_freset) rtas_pci_slot_reset(pdn, 3); else rtas_pci_slot_reset(pdn, 1); -- cgit v1.2.3-59-g8ed1b From 426b6cb478e60352a463a0d1ec75c1c9fab30b13 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Tue, 11 May 2010 05:41:08 +0000 Subject: powerpc/crashdump: Do not fail on NULL pointer dereferencing Signed-off-by: Maxim Uvarov Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/crash.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 6f4613dd05ef..341d8af6f33e 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -375,6 +375,9 @@ void default_machine_crash_shutdown(struct pt_regs *regs) for_each_irq(i) { struct irq_desc *desc = irq_to_desc(i); + if (!desc || !desc->chip || !desc->chip->eoi) + continue; + if (desc->status & IRQ_INPROGRESS) desc->chip->eoi(i); -- cgit v1.2.3-59-g8ed1b From 0644079410065567e3bb31fcb8e6441f2b7685a9 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 10 May 2010 16:25:51 +0000 Subject: powerpc/kdump: CPUs assume the context of the oopsing CPU We wrap the crash_shutdown_handles[] calls with longjmp/setjmp, so if any of them fault we can recover. The problem is we add a hook to the debugger fault handler hook which calls longjmp unconditionally. This first part of kdump is run before we marshall the other CPUs, so there is a very good chance some CPU on the box is going to page fault. And when it does it hits the longjmp code and assumes the context of the oopsing CPU. The machine gets very confused when it has 10 CPUs all with the same stack, all thinking they have the same CPU id. I get even more confused trying to debug it. The patch below adds crash_shutdown_cpu and uses it to specify which cpu is in the protected region. Since it can only be -1 or the oopsing CPU, we don't need to use memory barriers since it is only valid on the local CPU - no other CPU will ever see a value that matches it's local CPU id. Eventually we should switch the order and marshall all CPUs before doing the crash_shutdown_handles[] calls, but that is a bigger fix. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/crash.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 341d8af6f33e..7ced58dacb12 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -347,10 +347,12 @@ int crash_shutdown_unregister(crash_shutdown_t handler) EXPORT_SYMBOL(crash_shutdown_unregister); static unsigned long crash_shutdown_buf[JMP_BUF_LEN]; +static int crash_shutdown_cpu = -1; static int handle_fault(struct pt_regs *regs) { - longjmp(crash_shutdown_buf, 1); + if (crash_shutdown_cpu == smp_processor_id()) + longjmp(crash_shutdown_buf, 1); return 0; } @@ -391,6 +393,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) */ old_handler = __debugger_fault_handler; __debugger_fault_handler = handle_fault; + crash_shutdown_cpu = smp_processor_id(); for (i = 0; crash_shutdown_handles[i]; i++) { if (setjmp(crash_shutdown_buf) == 0) { /* @@ -404,6 +407,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) asm volatile("sync; isync"); } } + crash_shutdown_cpu = -1; __debugger_fault_handler = old_handler; /* -- cgit v1.2.3-59-g8ed1b From 5d7a87217de48b234b3c8ff8a73059947d822e07 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 10 May 2010 16:27:38 +0000 Subject: powerpc/kdump: Use chip->shutdown to disable IRQs I saw this in a kdump kernel: IOMMU table initialized, virtual merging enabled Interrupt 155954 (real) is invalid, disabling it. Interrupt 155953 (real) is invalid, disabling it. ie we took some spurious interrupts. default_machine_crash_shutdown tries to disable all interrupt sources but uses chip->disable which maps to the default action of: static void default_disable(unsigned int irq) { } If we use chip->shutdown, then we actually mask the IRQ: static void default_shutdown(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); desc->chip->mask(irq); desc->status |= IRQ_MASKED; } Not sure why we don't implement a ->disable action for xics.c, or why default_disable doesn't mask the interrupt. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/crash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 7ced58dacb12..cca7c8fafc1c 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -384,7 +384,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) desc->chip->eoi(i); if (!(desc->status & IRQ_DISABLED)) - desc->chip->disable(i); + desc->chip->shutdown(i); } /* -- cgit v1.2.3-59-g8ed1b From 095c7965f4dc870ed2b65143b1e2610de653416c Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 10 May 2010 18:59:18 +0000 Subject: powerpc: Use more accurate limit for first segment memory allocations Author: Milton Miller On large machines we are running out of room below 256MB. In some cases we only need to ensure the allocation is in the first segment, which may be 256MB or 1TB. Add slb0_limit and use it to specify the upper limit for the irqstack and emergency stacks. On a large ppc64 box, this fixes a panic at boot when the crashkernel= option is specified (previously we would run out of memory below 256MB). Signed-off-by: Milton Miller Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/setup_64.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index cea66987a6ea..f3fb5a79de52 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -424,9 +424,18 @@ void __init setup_system(void) DBG(" <- setup_system()\n"); } +static u64 slb0_limit(void) +{ + if (cpu_has_feature(CPU_FTR_1T_SEGMENT)) { + return 1UL << SID_SHIFT_1T; + } + return 1UL << SID_SHIFT; +} + #ifdef CONFIG_IRQSTACKS static void __init irqstack_early_init(void) { + u64 limit = slb0_limit(); unsigned int i; /* @@ -436,10 +445,10 @@ static void __init irqstack_early_init(void) for_each_possible_cpu(i) { softirq_ctx[i] = (struct thread_info *) __va(lmb_alloc_base(THREAD_SIZE, - THREAD_SIZE, 0x10000000)); + THREAD_SIZE, limit)); hardirq_ctx[i] = (struct thread_info *) __va(lmb_alloc_base(THREAD_SIZE, - THREAD_SIZE, 0x10000000)); + THREAD_SIZE, limit)); } } #else @@ -470,7 +479,7 @@ static void __init exc_lvl_early_init(void) */ static void __init emergency_stack_init(void) { - unsigned long limit; + u64 limit; unsigned int i; /* @@ -482,7 +491,7 @@ static void __init emergency_stack_init(void) * bringup, we need to get at them in real mode. This means they * must also be within the RMO region. */ - limit = min(0x10000000ULL, lmb.rmo_size); + limit = min(slb0_limit(), lmb.rmo_size); for_each_possible_cpu(i) { unsigned long sp; -- cgit v1.2.3-59-g8ed1b From f90ece28c1f5b3ec13fe481406857fe92f4bc7d1 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Mon, 10 May 2010 20:28:26 +0000 Subject: powerpc/pseries: Add hcall to read 4 ptes at a time in real mode This adds plpar_pte_read_4_raw() which can be used read 4 PTEs from PHYP at a time, while in real mode. It also creates a new hcall9 which can be used in real mode. It's the same as plpar_hcall9 but minus the tracing hcall statistics which may require variables outside the RMO. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/hvcall.h | 1 + arch/powerpc/platforms/pseries/hvCall.S | 38 +++++++++++++++++++++++++ arch/powerpc/platforms/pseries/plpar_wrappers.h | 18 ++++++++++++ 3 files changed, 57 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index ebe7493e93e3..5119b7db3142 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -282,6 +282,7 @@ long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...); */ #define PLPAR_HCALL9_BUFSIZE 9 long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...); +long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...); /* For hcall instrumentation. One structure per-hcall, per-CPU */ struct hcall_stats { diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 383a5d0e9818..48d20573e4de 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S @@ -228,3 +228,41 @@ _GLOBAL(plpar_hcall9) mtcrf 0xff,r0 blr /* return r3 = status */ + +/* See plpar_hcall_raw to see why this is needed */ +_GLOBAL(plpar_hcall9_raw) + HMT_MEDIUM + + mfcr r0 + stw r0,8(r1) + + std r4,STK_PARM(r4)(r1) /* Save ret buffer */ + + mr r4,r5 + mr r5,r6 + mr r6,r7 + mr r7,r8 + mr r8,r9 + mr r9,r10 + ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */ + ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */ + ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */ + + HVSC /* invoke the hypervisor */ + + mr r0,r12 + ld r12,STK_PARM(r4)(r1) + std r4, 0(r12) + std r5, 8(r12) + std r6, 16(r12) + std r7, 24(r12) + std r8, 32(r12) + std r9, 40(r12) + std r10,48(r12) + std r11,56(r12) + std r0, 64(r12) + + lwz r0,8(r1) + mtcrf 0xff,r0 + + blr /* return r3 = status */ diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index 6c4fd2c3f385..d9801117124b 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -191,6 +191,24 @@ static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex, return rc; } +/* + * plpar_pte_read_4_raw can be called in real mode. + * ptes must be 8*sizeof(unsigned long) + */ +static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex, + unsigned long *ptes) + +{ + long rc; + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; + + rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex); + + memcpy(ptes, retbuf, 8*sizeof(unsigned long)); + + return rc; +} + static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, unsigned long avpn) { -- cgit v1.2.3-59-g8ed1b From d504bed676caad29a3dba3d3727298c560628f5c Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Mon, 10 May 2010 20:28:26 +0000 Subject: powerpc/kexec: Speedup kexec hash PTE tear down Currently for kexec the PTE tear down on 1TB segment systems normally requires 3 hcalls for each PTE removal. On a machine with 32GB of memory it can take around a minute to remove all the PTEs. This optimises the path so that we only remove PTEs that are valid. It also uses the read 4 PTEs at once HCALL. For the common case where a PTEs is invalid in a 1TB segment, this turns the 3 HCALLs per PTE down to 1 HCALL per 4 PTEs. This gives an > 10x speedup in kexec times on PHYP, taking a 32GB machine from around 1 minute down to a few seconds. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/lpar.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 0707653612ba..cf79b46d8f88 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -367,21 +367,28 @@ static void pSeries_lpar_hptab_clear(void) { unsigned long size_bytes = 1UL << ppc64_pft_size; unsigned long hpte_count = size_bytes >> 4; - unsigned long dummy1, dummy2, dword0; + struct { + unsigned long pteh; + unsigned long ptel; + } ptes[4]; long lpar_rc; - int i; + int i, j; - /* TODO: Use bulk call */ - for (i = 0; i < hpte_count; i++) { - /* dont remove HPTEs with VRMA mappings */ - lpar_rc = plpar_pte_remove_raw(H_ANDCOND, i, HPTE_V_1TB_SEG, - &dummy1, &dummy2); - if (lpar_rc == H_NOT_FOUND) { - lpar_rc = plpar_pte_read_raw(0, i, &dword0, &dummy1); - if (!lpar_rc && ((dword0 & HPTE_V_VRMA_MASK) - != HPTE_V_VRMA_MASK)) - /* Can be hpte for 1TB Seg. So remove it */ - plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2); + /* Read in batches of 4, + * invalidate only valid entries not in the VRMA + * hpte_count will be a multiple of 4 + */ + for (i = 0; i < hpte_count; i += 4) { + lpar_rc = plpar_pte_read_4_raw(0, i, (void *)ptes); + if (lpar_rc != H_SUCCESS) + continue; + for (j = 0; j < 4; j++){ + if ((ptes[j].pteh & HPTE_V_VRMA_MASK) == + HPTE_V_VRMA_MASK) + continue; + if (ptes[j].pteh & HPTE_V_VALID) + plpar_pte_remove_raw(0, i + j, 0, + &(ptes[j].pteh), &(ptes[j].ptel)); } } } -- cgit v1.2.3-59-g8ed1b From 1fc711f7ffb01089efc58042cfdbac8573d1b59a Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Thu, 13 May 2010 19:40:11 +0000 Subject: powerpc/kexec: Fix race in kexec shutdown In kexec_prepare_cpus, the primary CPU IPIs the secondary CPUs to kexec_smp_down(). kexec_smp_down() calls kexec_smp_wait() which sets the hw_cpu_id() to -1. The primary does this while leaving IRQs on which means the primary can take a timer interrupt which can lead to the IPIing one of the secondary CPUs (say, for a scheduler re-balance) but since the secondary CPU now has a hw_cpu_id = -1, we IPI CPU -1... Kaboom! We are hitting this case regularly on POWER7 machines. There is also a second race, where the primary will tear down the MMU mappings before knowing the secondaries have entered real mode. Also, the secondaries are clearing out any pending IPIs before guaranteeing that no more will be received. This changes kexec_prepare_cpus() so that we turn off IRQs in the primary CPU much earlier. It adds a paca flag to say that the secondaries have entered the kexec_smp_down() IPI and turned off IRQs, rather than overloading hw_cpu_id with -1. This new paca flag is again used to in indicate when the secondaries has entered real mode. It also ensures that all CPUs have their IRQs off before we clear out any pending IPI requests (in kexec_cpu_down()) to ensure there are no trailing IPIs left unacknowledged. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/kexec.h | 4 +++ arch/powerpc/include/asm/paca.h | 1 + arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kernel/machine_kexec_64.c | 48 ++++++++++++++++++++++++---------- arch/powerpc/kernel/misc_64.S | 8 +++--- arch/powerpc/kernel/paca.c | 2 ++ 6 files changed, 47 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index 7e06b43720d3..a6ca6da1430b 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h @@ -31,6 +31,10 @@ #define KEXEC_ARCH KEXEC_ARCH_PPC #endif +#define KEXEC_STATE_NONE 0 +#define KEXEC_STATE_IRQS_OFF 1 +#define KEXEC_STATE_REAL_MODE 2 + #ifndef __ASSEMBLY__ #include #include diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index a011603d4079..971dfa4815f0 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -82,6 +82,7 @@ struct paca_struct { s16 hw_cpu_id; /* Physical processor number */ u8 cpu_start; /* At startup, processor spins until */ /* this becomes non-zero. */ + u8 kexec_state; /* set when kexec down has irqs off */ #ifdef CONFIG_PPC_STD_MMU_64 struct slb_shadow *slb_shadow_ptr; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 0271b58ec31e..1b784ff92d9d 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -184,6 +184,7 @@ int main(void) #endif /* CONFIG_PPC_STD_MMU_64 */ DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); + DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state)); DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr)); DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr)); DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 040bd1de8d99..26f9900f773c 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c @@ -155,33 +155,38 @@ void kexec_copy_flush(struct kimage *image) #ifdef CONFIG_SMP -/* FIXME: we should schedule this function to be called on all cpus based - * on calling the interrupts, but we would like to call it off irq level - * so that the interrupt controller is clean. - */ +static int kexec_all_irq_disabled = 0; + static void kexec_smp_down(void *arg) { + local_irq_disable(); + mb(); /* make sure our irqs are disabled before we say they are */ + get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF; + while(kexec_all_irq_disabled == 0) + cpu_relax(); + mb(); /* make sure all irqs are disabled before this */ + /* + * Now every CPU has IRQs off, we can clear out any pending + * IPIs and be sure that no more will come in after this. + */ if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(0, 1); - local_irq_disable(); kexec_smp_wait(); /* NOTREACHED */ } -static void kexec_prepare_cpus(void) +static void kexec_prepare_cpus_wait(int wait_state) { int my_cpu, i, notified=-1; - smp_call_function(kexec_smp_down, NULL, /* wait */0); my_cpu = get_cpu(); - - /* check the others cpus are now down (via paca hw cpu id == -1) */ + /* Make sure each CPU has atleast made it to the state we need */ for (i=0; i < NR_CPUS; i++) { if (i == my_cpu) continue; - while (paca[i].hw_cpu_id != -1) { + while (paca[i].kexec_state < wait_state) { barrier(); if (!cpu_possible(i)) { printk("kexec: cpu %d hw_cpu_id %d is not" @@ -201,20 +206,35 @@ static void kexec_prepare_cpus(void) } if (i != notified) { printk( "kexec: waiting for cpu %d (physical" - " %d) to go down\n", - i, paca[i].hw_cpu_id); + " %d) to enter %i state\n", + i, paca[i].hw_cpu_id, wait_state); notified = i; } } } + mb(); +} + +static void kexec_prepare_cpus(void) +{ + + smp_call_function(kexec_smp_down, NULL, /* wait */0); + local_irq_disable(); + mb(); /* make sure IRQs are disabled before we say they are */ + get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF; + + kexec_prepare_cpus_wait(KEXEC_STATE_IRQS_OFF); + /* we are sure every CPU has IRQs off at this point */ + kexec_all_irq_disabled = 1; /* after we tell the others to go down */ if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(0, 0); - put_cpu(); + /* Before removing MMU mapings make sure all CPUs have entered real mode */ + kexec_prepare_cpus_wait(KEXEC_STATE_REAL_MODE); - local_irq_disable(); + put_cpu(); } #else /* ! SMP */ diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index a5cf9c1356a6..a2b18dffa03e 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -24,6 +24,7 @@ #include #include #include +#include .text @@ -471,6 +472,10 @@ _GLOBAL(kexec_wait) 1: mflr r5 addi r5,r5,kexec_flag-1b + li r4,KEXEC_STATE_REAL_MODE + stb r4,PACAKEXECSTATE(r13) + SYNC + 99: HMT_LOW #ifdef CONFIG_KEXEC /* use no memory without kexec */ lwz r4,0(r5) @@ -494,14 +499,11 @@ kexec_flag: * note: this is a terminal routine, it does not save lr * * get phys id from paca - * set paca id to -1 to say we got here * switch to real mode * join other cpus in kexec_wait(phys_id) */ _GLOBAL(kexec_smp_wait) lhz r3,PACAHWCPUID(r13) - li r4,-1 - sth r4,PACAHWCPUID(r13) /* let others know we left */ bl real_mode b .kexec_wait diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 0c40c6f476fe..f88acf0218db 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -18,6 +18,7 @@ #include #include #include +#include /* This symbol is provided by the linker - let it fill in the paca * field correctly */ @@ -97,6 +98,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) new_paca->kernelbase = (unsigned long) _stext; new_paca->kernel_msr = MSR_KERNEL; new_paca->hw_cpu_id = 0xffff; + new_paca->kexec_state = KEXEC_STATE_NONE; new_paca->__current = &init_task; #ifdef CONFIG_PPC_STD_MMU_64 new_paca->slb_shadow_ptr = &slb_shadow[cpu]; -- cgit v1.2.3-59-g8ed1b From 60adec6226bbcf061d4c2d10944fced209d1847d Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Thu, 13 May 2010 19:40:11 +0000 Subject: powerpc/kdump: Fix race in kdump shutdown When we are crashing, the crashing/primary CPU IPIs the secondaries to turn off IRQs, go into real mode and wait in kexec_wait. While this is happening, the primary tears down all the MMU maps. Unfortunately the primary doesn't check to make sure the secondaries have entered real mode before doing this. On PHYP machines, the secondaries can take a long time shutting down the IRQ controller as RTAS calls are need. These RTAS calls need to be serialised which resilts in the secondaries contending in lock_rtas() and hence taking a long time to shut down. We've hit this on large POWER7 machines, where some secondaries are still waiting in lock_rtas(), when the primary tears down the HPTEs. This patch makes sure all secondaries are in real mode before the primary tears down the MMU. It uses the new kexec_state entry in the paca. It times out if the secondaries don't reach real mode after 10sec. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/crash.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index cca7c8fafc1c..8c066d6a8e4b 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -162,6 +162,32 @@ static void crash_kexec_prepare_cpus(int cpu) /* Leave the IPI callback set */ } +/* wait for all the CPUs to hit real mode but timeout if they don't come in */ +static void crash_kexec_wait_realmode(int cpu) +{ + unsigned int msecs; + int i; + + msecs = 10000; + for (i=0; i < NR_CPUS && msecs > 0; i++) { + if (i == cpu) + continue; + + while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) { + barrier(); + if (!cpu_possible(i)) { + break; + } + if (!cpu_online(i)) { + break; + } + msecs--; + mdelay(1); + } + } + mb(); +} + /* * This function will be called by secondary cpus or by kexec cpu * if soft-reset is activated to stop some CPUs. @@ -419,6 +445,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) crash_kexec_prepare_cpus(crashing_cpu); cpu_set(crashing_cpu, cpus_in_crash); crash_kexec_stop_spus(); + crash_kexec_wait_realmode(crashing_cpu); if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 0); } -- cgit v1.2.3-59-g8ed1b From dd04c63c96425af9b6741f3abf0ad25d6b1c0e8d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 16 May 2010 20:01:28 +0000 Subject: powerpc: Remove check of ibm,smt-snooze-delay OF property I'm not sure why we have code for parsing an ibm,smt-snooze-delay OF property. Since we have a smt-snooze-delay= boot option and we can also set it at runtime via sysfs, it should be safe to get rid of this code. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/sysfs.c | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index e235e52dc4fe..158fb731e199 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -67,33 +67,6 @@ static ssize_t show_smt_snooze_delay(struct sys_device *dev, static SYSDEV_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay, store_smt_snooze_delay); -/* Only parse OF options if the matching cmdline option was not specified */ -static int smt_snooze_cmdline; - -static int __init smt_setup(void) -{ - struct device_node *options; - const unsigned int *val; - unsigned int cpu; - - if (!cpu_has_feature(CPU_FTR_SMT)) - return -ENODEV; - - options = of_find_node_by_path("/options"); - if (!options) - return -ENODEV; - - val = of_get_property(options, "ibm,smt-snooze-delay", NULL); - if (!smt_snooze_cmdline && val) { - for_each_possible_cpu(cpu) - per_cpu(smt_snooze_delay, cpu) = *val; - } - - of_node_put(options); - return 0; -} -__initcall(smt_setup); - static int __init setup_smt_snooze_delay(char *str) { unsigned int cpu; @@ -102,8 +75,6 @@ static int __init setup_smt_snooze_delay(char *str) if (!cpu_has_feature(CPU_FTR_SMT)) return 1; - smt_snooze_cmdline = 1; - if (get_option(&str, &snooze)) { for_each_possible_cpu(cpu) per_cpu(smt_snooze_delay, cpu) = snooze; -- cgit v1.2.3-59-g8ed1b From b878dc00595440586874952dd85ce9b803360b87 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 16 May 2010 20:02:39 +0000 Subject: powerpc: Use smt_snooze_delay=-1 to always busy loop Right now if we want to busy loop and not give up any time to the hypervisor we put a very large value into smt_snooze_delay. This is sometimes useful when running a single partition and you want to avoid any latencies due to the hypervisor or CPU power state transitions. While this works, it's a bit ugly - how big a number is enough now we have NO_HZ and can be idle for a very long time. The patch below makes smt_snooze_delay signed, and a negative value means loop forever: echo -1 > /sys/devices/system/cpu/cpu0/smt_snooze_delay This change shouldn't affect the existing userspace tools (eg ppc64_cpu), but I'm cc-ing Nathan just to be sure. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/sysfs.c | 17 ++++++++--------- arch/powerpc/platforms/pseries/setup.c | 10 +++++----- 2 files changed, 13 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 158fb731e199..c0d8c2006bf4 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -35,7 +35,7 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); #ifdef CONFIG_PPC64 /* Time in microseconds we delay before sleeping in the idle loop */ -DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 }; +DEFINE_PER_CPU(long, smt_snooze_delay) = { 100 }; static ssize_t store_smt_snooze_delay(struct sys_device *dev, struct sysdev_attribute *attr, @@ -44,9 +44,9 @@ static ssize_t store_smt_snooze_delay(struct sys_device *dev, { struct cpu *cpu = container_of(dev, struct cpu, sysdev); ssize_t ret; - unsigned long snooze; + long snooze; - ret = sscanf(buf, "%lu", &snooze); + ret = sscanf(buf, "%ld", &snooze); if (ret != 1) return -EINVAL; @@ -61,7 +61,7 @@ static ssize_t show_smt_snooze_delay(struct sys_device *dev, { struct cpu *cpu = container_of(dev, struct cpu, sysdev); - return sprintf(buf, "%lu\n", per_cpu(smt_snooze_delay, cpu->sysdev.id)); + return sprintf(buf, "%ld\n", per_cpu(smt_snooze_delay, cpu->sysdev.id)); } static SYSDEV_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay, @@ -70,15 +70,14 @@ static SYSDEV_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay, static int __init setup_smt_snooze_delay(char *str) { unsigned int cpu; - int snooze; + long snooze; if (!cpu_has_feature(CPU_FTR_SMT)) return 1; - if (get_option(&str, &snooze)) { - for_each_possible_cpu(cpu) - per_cpu(smt_snooze_delay, cpu) = snooze; - } + snooze = simple_strtol(str, NULL, 10); + for_each_possible_cpu(cpu) + per_cpu(smt_snooze_delay, cpu) = snooze; return 1; } diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 6710761bf60f..a6d19e3a505e 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -496,13 +496,14 @@ static int __init pSeries_probe(void) } -DECLARE_PER_CPU(unsigned long, smt_snooze_delay); +DECLARE_PER_CPU(long, smt_snooze_delay); static void pseries_dedicated_idle_sleep(void) { unsigned int cpu = smp_processor_id(); unsigned long start_snooze; unsigned long in_purr, out_purr; + long snooze = __get_cpu_var(smt_snooze_delay); /* * Indicate to the HV that we are idle. Now would be @@ -517,13 +518,12 @@ static void pseries_dedicated_idle_sleep(void) * has been checked recently. If we should poll for a little * while, do so. */ - if (__get_cpu_var(smt_snooze_delay)) { - start_snooze = get_tb() + - __get_cpu_var(smt_snooze_delay) * tb_ticks_per_usec; + if (snooze) { + start_snooze = get_tb() + snooze * tb_ticks_per_usec; local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); - while (get_tb() < start_snooze) { + while ((snooze < 0) || (get_tb() < start_snooze)) { if (need_resched() || cpu_is_offline(cpu)) goto out; ppc64_runlatch_off(); -- cgit v1.2.3-59-g8ed1b From 56608209d34b8add40af54031d4e420afbcde9f6 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 16 May 2010 20:19:56 +0000 Subject: powerpc/numa: Set a smaller value for RECLAIM_DISTANCE to enable zone reclaim I noticed /proc/sys/vm/zone_reclaim_mode was 0 on a ppc64 NUMA box. It gets enabled via this: /* * If another node is sufficiently far away then it is better * to reclaim pages in a zone before going off node. */ if (distance > RECLAIM_DISTANCE) zone_reclaim_mode = 1; Since we use the default value of 20 for REMOTE_DISTANCE and 20 for RECLAIM_DISTANCE it never kicks in. The local to remote bandwidth ratios can be quite large on System p machines so it makes sense for us to reclaim clean pagecache locally before going off node. The patch below sets a smaller value for RECLAIM_DISTANCE and thus enables zone reclaim. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/topology.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 84ad11f65dc2..32adf7280720 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -18,6 +18,16 @@ struct device_node; */ #define RECLAIM_DISTANCE 10 +/* + * Before going off node we want the VM to try and reclaim from the local + * node. It does this if the remote distance is larger than RECLAIM_DISTANCE. + * With the default REMOTE_DISTANCE of 20 and the default RECLAIM_DISTANCE of + * 20, we never reclaim and go off node straight away. + * + * To fix this we choose a smaller value of RECLAIM_DISTANCE. + */ +#define RECLAIM_DISTANCE 10 + #include static inline int cpu_to_node(int cpu) -- cgit v1.2.3-59-g8ed1b From bc8449cc57898bc9cf1ffc4619d026f77bf327c1 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 16 May 2010 20:28:35 +0000 Subject: powerpc/numa: Use ibm,architecture-vec-5 to detect form 1 affinity I've been told that the architected way to determine we are in form 1 affinity mode is by reading the ibm,architecture-vec-5 property which mirrors the layout of the fifth vector of the ibm,client-architecture structure. Eventually we may want to parse the ibm,architecture-vec-5 and create FW_FEATURE_* bits. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index aace5e5dfa0a..80d110635d24 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -271,7 +271,8 @@ static int __init find_min_common_depth(void) const unsigned int *ref_points; struct device_node *rtas_root; unsigned int len; - struct device_node *options; + struct device_node *chosen; + const char *vec5; rtas_root = of_find_node_by_path("/rtas"); @@ -289,14 +290,17 @@ static int __init find_min_common_depth(void) "ibm,associativity-reference-points", &len); /* - * For type 1 affinity information we want the first field + * For form 1 affinity information we want the first field */ - options = of_find_node_by_path("/options"); - if (options) { - const char *str; - str = of_get_property(options, "ibm,associativity-form", NULL); - if (str && !strcmp(str, "1")) - index = 0; +#define VEC5_AFFINITY_BYTE 5 +#define VEC5_AFFINITY 0x80 + chosen = of_find_node_by_path("/chosen"); + if (chosen) { + vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL); + if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) { + dbg("Using form 1 affinity\n"); + index = 0; + } } if ((len >= 2 * sizeof(unsigned int)) && ref_points) { -- cgit v1.2.3-59-g8ed1b From 32c96f7765b881ab1f6ab8ff04b733e4cf157239 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Tue, 18 May 2010 22:51:00 +0000 Subject: powerpc/pseries: Make request_ras_irqs() available to other pseries code At the moment only the RAS code uses event-sources interrupts (for EPOW events and internal errors) so request_ras_irqs() (which actually requests the event-sources interrupts) is found in ras.c and is static. We want to be able to use event-sources interrupts in other pseries code, so let's rename request_ras_irqs() to request_event_sources_irqs() and move it to event_sources.c. This will be used in an upcoming patch that adds support for IO Event interrupts that come through as event sources. Signed-off-by: Mark Nelson Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/Makefile | 2 +- arch/powerpc/platforms/pseries/event_sources.c | 79 ++++++++++++++++++++++++++ arch/powerpc/platforms/pseries/pseries.h | 7 +++ arch/powerpc/platforms/pseries/ras.c | 62 +------------------- 4 files changed, 90 insertions(+), 60 deletions(-) create mode 100644 arch/powerpc/platforms/pseries/event_sources.c (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 0ff5174ae4f5..3dbef309bc8d 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -7,7 +7,7 @@ EXTRA_CFLAGS += -DDEBUG endif obj-y := lpar.o hvCall.o nvram.o reconfig.o \ - setup.o iommu.o ras.o \ + setup.o iommu.o event_sources.o ras.o \ firmware.o power.o dlpar.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_XICS) += xics.o diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c new file mode 100644 index 000000000000..e889c9d9586a --- /dev/null +++ b/arch/powerpc/platforms/pseries/event_sources.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2001 Dave Engebretsen IBM Corporation + * + * 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 + +#include "pseries.h" + +void request_event_sources_irqs(struct device_node *np, + irq_handler_t handler, + const char *name) +{ + int i, index, count = 0; + struct of_irq oirq; + const u32 *opicprop; + unsigned int opicplen; + unsigned int virqs[16]; + + /* Check for obsolete "open-pic-interrupt" property. If present, then + * map those interrupts using the default interrupt host and default + * trigger + */ + opicprop = of_get_property(np, "open-pic-interrupt", &opicplen); + if (opicprop) { + opicplen /= sizeof(u32); + for (i = 0; i < opicplen; i++) { + if (count > 15) + break; + virqs[count] = irq_create_mapping(NULL, *(opicprop++)); + if (virqs[count] == NO_IRQ) + printk(KERN_ERR "Unable to allocate interrupt " + "number for %s\n", np->full_name); + else + count++; + + } + } + /* Else use normal interrupt tree parsing */ + else { + /* First try to do a proper OF tree parsing */ + for (index = 0; of_irq_map_one(np, index, &oirq) == 0; + index++) { + if (count > 15) + break; + virqs[count] = irq_create_of_mapping(oirq.controller, + oirq.specifier, + oirq.size); + if (virqs[count] == NO_IRQ) + printk(KERN_ERR "Unable to allocate interrupt " + "number for %s\n", np->full_name); + else + count++; + } + } + + /* Now request them */ + for (i = 0; i < count; i++) { + if (request_irq(virqs[i], handler, 0, name, NULL)) { + printk(KERN_ERR "Unable to request interrupt %d for " + "%s\n", virqs[i], np->full_name); + return; + } + } +} + diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 9e17c0d2a0c8..40c93cad91d2 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -10,6 +10,13 @@ #ifndef _PSERIES_PSERIES_H #define _PSERIES_PSERIES_H +#include + +struct device_node; + +extern void request_event_sources_irqs(struct device_node *np, + irq_handler_t handler, const char *name); + extern void __init fw_feature_init(const char *hypertas, unsigned long len); struct pt_regs; diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index db940d2c39a0..41a3e9a039ed 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -67,63 +67,6 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id); static irqreturn_t ras_error_interrupt(int irq, void *dev_id); -static void request_ras_irqs(struct device_node *np, - irq_handler_t handler, - const char *name) -{ - int i, index, count = 0; - struct of_irq oirq; - const u32 *opicprop; - unsigned int opicplen; - unsigned int virqs[16]; - - /* Check for obsolete "open-pic-interrupt" property. If present, then - * map those interrupts using the default interrupt host and default - * trigger - */ - opicprop = of_get_property(np, "open-pic-interrupt", &opicplen); - if (opicprop) { - opicplen /= sizeof(u32); - for (i = 0; i < opicplen; i++) { - if (count > 15) - break; - virqs[count] = irq_create_mapping(NULL, *(opicprop++)); - if (virqs[count] == NO_IRQ) - printk(KERN_ERR "Unable to allocate interrupt " - "number for %s\n", np->full_name); - else - count++; - - } - } - /* Else use normal interrupt tree parsing */ - else { - /* First try to do a proper OF tree parsing */ - for (index = 0; of_irq_map_one(np, index, &oirq) == 0; - index++) { - if (count > 15) - break; - virqs[count] = irq_create_of_mapping(oirq.controller, - oirq.specifier, - oirq.size); - if (virqs[count] == NO_IRQ) - printk(KERN_ERR "Unable to allocate interrupt " - "number for %s\n", np->full_name); - else - count++; - } - } - - /* Now request them */ - for (i = 0; i < count; i++) { - if (request_irq(virqs[i], handler, 0, name, NULL)) { - printk(KERN_ERR "Unable to request interrupt %d for " - "%s\n", virqs[i], np->full_name); - return; - } - } -} - /* * Initialize handlers for the set of interrupts caused by hardware errors * and power system events. @@ -138,14 +81,15 @@ static int __init init_ras_IRQ(void) /* Internal Errors */ np = of_find_node_by_path("/event-sources/internal-errors"); if (np != NULL) { - request_ras_irqs(np, ras_error_interrupt, "RAS_ERROR"); + request_event_sources_irqs(np, ras_error_interrupt, + "RAS_ERROR"); of_node_put(np); } /* EPOW Events */ np = of_find_node_by_path("/event-sources/epow-events"); if (np != NULL) { - request_ras_irqs(np, ras_epow_interrupt, "RAS_EPOW"); + request_event_sources_irqs(np, ras_epow_interrupt, "RAS_EPOW"); of_node_put(np); } -- cgit v1.2.3-59-g8ed1b From 40a5a4435f37b172dec09852ad2036865f9ca3c8 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Sun, 18 Apr 2010 20:05:41 +0000 Subject: powerpc: Build-in e1000e for pseries & ppc64_defconfig The e1000e device is becoming more common these days, so let's just build it in for pseries & ppc64_defconfig. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/configs/ppc64_defconfig | 2 +- arch/powerpc/configs/pseries_defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 12980d544654..dad617e2a88c 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -988,7 +988,7 @@ CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y # CONFIG_DL2K is not set CONFIG_E1000=y -CONFIG_E1000E=m +CONFIG_E1000E=y # CONFIG_IP1000 is not set # CONFIG_IGB is not set # CONFIG_NS83820 is not set diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 41de3ddc9f24..16a14589bd40 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -804,7 +804,7 @@ CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y # CONFIG_DL2K is not set CONFIG_E1000=y -CONFIG_E1000E=m +CONFIG_E1000E=y # CONFIG_IP1000 is not set # CONFIG_IGB is not set # CONFIG_NS83820 is not set -- cgit v1.2.3-59-g8ed1b From 99ec28f183daa450faa7bdad6f932364ae325648 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sun, 9 May 2010 17:39:05 +0000 Subject: powerpc: Remove unused 'protect4gb' boot parameter 'protect4gb' boot parameter was introduced to avoid allocating dma space acrossing 4GB boundary in 2007 (the commit 569975591c5530fdc9c7a3c45122e5e46f075a74). In 2008, the IOMMU was fixed to use the boundary_mask parameter per device properly. So 'protect4gb' workaround was removed (the 383af9525bb27f927511874f6306247ec13f1c28). But somehow I messed the 'protect4gb' boot parameter that was used to enable the workaround. Signed-off-by: FUJITA Tomonori Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/iommu.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index ec94f906ea43..d5839179ec77 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -43,20 +43,9 @@ #define DBG(...) static int novmerge; -static int protect4gb = 1; static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int); -static int __init setup_protect4gb(char *str) -{ - if (strcmp(str, "on") == 0) - protect4gb = 1; - else if (strcmp(str, "off") == 0) - protect4gb = 0; - - return 1; -} - static int __init setup_iommu(char *str) { if (!strcmp(str, "novmerge")) @@ -66,7 +55,6 @@ static int __init setup_iommu(char *str) return 1; } -__setup("protect4gb=", setup_protect4gb); __setup("iommu=", setup_iommu); static unsigned long iommu_range_alloc(struct device *dev, -- cgit v1.2.3-59-g8ed1b From f074e48e0a54d8c1370f319ef95e71f796cd8048 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 23 Apr 2009 21:28:32 +0000 Subject: Blackfin: drop unused bad_page pages and move zero_page to the bss The empty_bad_page/empty_bad_page_table pages are unused, so punt them. The zero_page is always allocated, so push it out to the bss to speed up the booting process a bit and pack data nicer. Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/pgtable.h | 3 ++- arch/blackfin/mm/init.c | 29 ++++------------------------- 2 files changed, 6 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/include/asm/pgtable.h b/arch/blackfin/include/asm/pgtable.h index 821c699c2238..dcca3e6d6e80 100644 --- a/arch/blackfin/include/asm/pgtable.h +++ b/arch/blackfin/include/asm/pgtable.h @@ -80,7 +80,8 @@ PTE_BIT_FUNC(mkyoung, |= _PAGE_ACCESSED); * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. */ -#define ZERO_PAGE(vaddr) (virt_to_page(0)) +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) +extern char empty_zero_page[]; extern unsigned int kobjsize(const void *objp); diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index 355b87aa6b93..10c8a59a96c5 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c @@ -15,23 +15,11 @@ #include "blackfin_sram.h" /* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a - * do_exit(), but using this instead means there is less risk - * for a process dying in kernel mode, possibly leaving a inode - * unused etc.. - * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. - * - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. + * ZERO_PAGE is a special page that is used for zero-initialized data and COW. + * Let the bss do its zero-init magic so we don't have to do it ourselves. */ -static unsigned long empty_bad_page_table; - -static unsigned long empty_bad_page; - -static unsigned long empty_zero_page; +char empty_zero_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); +EXPORT_SYMBOL(empty_zero_page); #ifndef CONFIG_EXCEPTION_L1_SCRATCH #if defined CONFIG_SYSCALL_TAB_L1 @@ -59,15 +47,6 @@ void __init paging_init(void) pr_debug("start_mem is %#lx virtual_end is %#lx\n", PAGE_ALIGN(memory_start), end_mem); - /* - * initialize the bad page table and bad page to point - * to a couple of allocated pages - */ - empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); - empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); - empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); - memset((void *)empty_zero_page, 0, PAGE_SIZE); - /* * Set up SFC/DFC registers (user data space) */ -- cgit v1.2.3-59-g8ed1b From d012ce22a492a38977ba727b02bcd216ed571710 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 23 Apr 2009 22:17:37 +0000 Subject: Blackfin: cleanup style/comments/etc... in paging_init() Signed-off-by: Mike Frysinger --- arch/blackfin/mm/init.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index 10c8a59a96c5..bb4e8fff4b55 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c @@ -40,31 +40,26 @@ EXPORT_SYMBOL(cpu_pda); void __init paging_init(void) { /* - * make sure start_mem is page aligned, otherwise bootmem and - * page_alloc get different views og the world + * make sure start_mem is page aligned, otherwise bootmem and + * page_alloc get different views of the world */ unsigned long end_mem = memory_end & PAGE_MASK; - pr_debug("start_mem is %#lx virtual_end is %#lx\n", PAGE_ALIGN(memory_start), end_mem); + unsigned long zones_size[MAX_NR_ZONES] = { + [0] = 0, + [ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT, + [ZONE_NORMAL] = 0, +#ifdef CONFIG_HIGHMEM + [ZONE_HIGHMEM] = 0, +#endif + }; - /* - * Set up SFC/DFC registers (user data space) - */ + /* Set up SFC/DFC registers (user data space) */ set_fs(KERNEL_DS); - pr_debug("free_area_init -> start_mem is %#lx virtual_end is %#lx\n", + pr_debug("free_area_init -> start_mem is %#lx virtual_end is %#lx\n", PAGE_ALIGN(memory_start), end_mem); - - { - unsigned long zones_size[MAX_NR_ZONES] = { 0, }; - - zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; - zones_size[ZONE_NORMAL] = 0; -#ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = 0; -#endif - free_area_init(zones_size); - } + free_area_init(zones_size); } asmlinkage void __init init_pda(void) -- cgit v1.2.3-59-g8ed1b From def282d61578e157ed6362eaffafef8a13af10be Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 15 Dec 2009 13:33:19 +0000 Subject: Blackfin: punt duplicated CAN MMRs Now that there's a common header with everything unified, drop the defines from the global namespace. Pollution sucks. Signed-off-by: Mike Frysinger --- arch/blackfin/mach-bf537/include/mach/defBF534.h | 622 ------------------- arch/blackfin/mach-bf538/include/mach/defBF539.h | 621 ------------------- .../mach-bf548/include/mach/defBF54x_base.h | 671 --------------------- 3 files changed, 1914 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h index 066d5c261f47..cf396ea40092 100644 --- a/arch/blackfin/mach-bf537/include/mach/defBF534.h +++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h @@ -1702,628 +1702,6 @@ #define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ #define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ -/* ************ CONTROLLER AREA NETWORK (CAN) MASKS ***************/ -/* CAN_CONTROL Masks */ -#define SRS 0x0001 /* Software Reset */ -#define DNM 0x0002 /* Device Net Mode */ -#define ABO 0x0004 /* Auto-Bus On Enable */ -#define TXPRIO 0x0008 /* TX Priority (Priority/Mailbox*) */ -#define WBA 0x0010 /* Wake-Up On CAN Bus Activity Enable */ -#define SMR 0x0020 /* Sleep Mode Request */ -#define CSR 0x0040 /* CAN Suspend Mode Request */ -#define CCR 0x0080 /* CAN Configuration Mode Request */ - -/* CAN_STATUS Masks */ -#define WT 0x0001 /* TX Warning Flag */ -#define WR 0x0002 /* RX Warning Flag */ -#define EP 0x0004 /* Error Passive Mode */ -#define EBO 0x0008 /* Error Bus Off Mode */ -#define SMA 0x0020 /* Sleep Mode Acknowledge */ -#define CSA 0x0040 /* Suspend Mode Acknowledge */ -#define CCA 0x0080 /* Configuration Mode Acknowledge */ -#define MBPTR 0x1F00 /* Mailbox Pointer */ -#define TRM 0x4000 /* Transmit Mode */ -#define REC 0x8000 /* Receive Mode */ - -/* CAN_CLOCK Masks */ -#define BRP 0x03FF /* Bit-Rate Pre-Scaler */ - -/* CAN_TIMING Masks */ -#define TSEG1 0x000F /* Time Segment 1 */ -#define TSEG2 0x0070 /* Time Segment 2 */ -#define SAM 0x0080 /* Sampling */ -#define SJW 0x0300 /* Synchronization Jump Width */ - -/* CAN_DEBUG Masks */ -#define DEC 0x0001 /* Disable CAN Error Counters */ -#define DRI 0x0002 /* Disable CAN RX Input */ -#define DTO 0x0004 /* Disable CAN TX Output */ -#define DIL 0x0008 /* Disable CAN Internal Loop */ -#define MAA 0x0010 /* Mode Auto-Acknowledge Enable */ -#define MRB 0x0020 /* Mode Read Back Enable */ -#define CDE 0x8000 /* CAN Debug Enable */ - -/* CAN_CEC Masks */ -#define RXECNT 0x00FF /* Receive Error Counter */ -#define TXECNT 0xFF00 /* Transmit Error Counter */ - -/* CAN_INTR Masks */ -#define MBRIRQ 0x0001 /* Mailbox Receive Interrupt */ -#define MBRIF MBRIRQ /* legacy */ -#define MBTIRQ 0x0002 /* Mailbox Transmit Interrupt */ -#define MBTIF MBTIRQ /* legacy */ -#define GIRQ 0x0004 /* Global Interrupt */ -#define SMACK 0x0008 /* Sleep Mode Acknowledge */ -#define CANTX 0x0040 /* CAN TX Bus Value */ -#define CANRX 0x0080 /* CAN RX Bus Value */ - -/* CAN_MBxx_ID1 and CAN_MBxx_ID0 Masks */ -#define DFC 0xFFFF /* Data Filtering Code (If Enabled) (ID0) */ -#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (ID0) */ -#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (ID1) */ -#define BASEID 0x1FFC /* Base Identifier */ -#define IDE 0x2000 /* Identifier Extension */ -#define RTR 0x4000 /* Remote Frame Transmission Request */ -#define AME 0x8000 /* Acceptance Mask Enable */ - -/* CAN_MBxx_TIMESTAMP Masks */ -#define TSV 0xFFFF /* Timestamp */ - -/* CAN_MBxx_LENGTH Masks */ -#define DLC 0x000F /* Data Length Code */ - -/* CAN_AMxxH and CAN_AMxxL Masks */ -#define DFM 0xFFFF /* Data Field Mask (If Enabled) (CAN_AMxxL) */ -#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (CAN_AMxxL) */ -#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (CAN_AMxxH) */ -#define BASEID 0x1FFC /* Base Identifier */ -#define AMIDE 0x2000 /* Acceptance Mask ID Extension Enable */ -#define FMD 0x4000 /* Full Mask Data Field Enable */ -#define FDF 0x8000 /* Filter On Data Field Enable */ - -/* CAN_MC1 Masks */ -#define MC0 0x0001 /* Enable Mailbox 0 */ -#define MC1 0x0002 /* Enable Mailbox 1 */ -#define MC2 0x0004 /* Enable Mailbox 2 */ -#define MC3 0x0008 /* Enable Mailbox 3 */ -#define MC4 0x0010 /* Enable Mailbox 4 */ -#define MC5 0x0020 /* Enable Mailbox 5 */ -#define MC6 0x0040 /* Enable Mailbox 6 */ -#define MC7 0x0080 /* Enable Mailbox 7 */ -#define MC8 0x0100 /* Enable Mailbox 8 */ -#define MC9 0x0200 /* Enable Mailbox 9 */ -#define MC10 0x0400 /* Enable Mailbox 10 */ -#define MC11 0x0800 /* Enable Mailbox 11 */ -#define MC12 0x1000 /* Enable Mailbox 12 */ -#define MC13 0x2000 /* Enable Mailbox 13 */ -#define MC14 0x4000 /* Enable Mailbox 14 */ -#define MC15 0x8000 /* Enable Mailbox 15 */ - -/* CAN_MC2 Masks */ -#define MC16 0x0001 /* Enable Mailbox 16 */ -#define MC17 0x0002 /* Enable Mailbox 17 */ -#define MC18 0x0004 /* Enable Mailbox 18 */ -#define MC19 0x0008 /* Enable Mailbox 19 */ -#define MC20 0x0010 /* Enable Mailbox 20 */ -#define MC21 0x0020 /* Enable Mailbox 21 */ -#define MC22 0x0040 /* Enable Mailbox 22 */ -#define MC23 0x0080 /* Enable Mailbox 23 */ -#define MC24 0x0100 /* Enable Mailbox 24 */ -#define MC25 0x0200 /* Enable Mailbox 25 */ -#define MC26 0x0400 /* Enable Mailbox 26 */ -#define MC27 0x0800 /* Enable Mailbox 27 */ -#define MC28 0x1000 /* Enable Mailbox 28 */ -#define MC29 0x2000 /* Enable Mailbox 29 */ -#define MC30 0x4000 /* Enable Mailbox 30 */ -#define MC31 0x8000 /* Enable Mailbox 31 */ - -/* CAN_MD1 Masks */ -#define MD0 0x0001 /* Enable Mailbox 0 For Receive */ -#define MD1 0x0002 /* Enable Mailbox 1 For Receive */ -#define MD2 0x0004 /* Enable Mailbox 2 For Receive */ -#define MD3 0x0008 /* Enable Mailbox 3 For Receive */ -#define MD4 0x0010 /* Enable Mailbox 4 For Receive */ -#define MD5 0x0020 /* Enable Mailbox 5 For Receive */ -#define MD6 0x0040 /* Enable Mailbox 6 For Receive */ -#define MD7 0x0080 /* Enable Mailbox 7 For Receive */ -#define MD8 0x0100 /* Enable Mailbox 8 For Receive */ -#define MD9 0x0200 /* Enable Mailbox 9 For Receive */ -#define MD10 0x0400 /* Enable Mailbox 10 For Receive */ -#define MD11 0x0800 /* Enable Mailbox 11 For Receive */ -#define MD12 0x1000 /* Enable Mailbox 12 For Receive */ -#define MD13 0x2000 /* Enable Mailbox 13 For Receive */ -#define MD14 0x4000 /* Enable Mailbox 14 For Receive */ -#define MD15 0x8000 /* Enable Mailbox 15 For Receive */ - -/* CAN_MD2 Masks */ -#define MD16 0x0001 /* Enable Mailbox 16 For Receive */ -#define MD17 0x0002 /* Enable Mailbox 17 For Receive */ -#define MD18 0x0004 /* Enable Mailbox 18 For Receive */ -#define MD19 0x0008 /* Enable Mailbox 19 For Receive */ -#define MD20 0x0010 /* Enable Mailbox 20 For Receive */ -#define MD21 0x0020 /* Enable Mailbox 21 For Receive */ -#define MD22 0x0040 /* Enable Mailbox 22 For Receive */ -#define MD23 0x0080 /* Enable Mailbox 23 For Receive */ -#define MD24 0x0100 /* Enable Mailbox 24 For Receive */ -#define MD25 0x0200 /* Enable Mailbox 25 For Receive */ -#define MD26 0x0400 /* Enable Mailbox 26 For Receive */ -#define MD27 0x0800 /* Enable Mailbox 27 For Receive */ -#define MD28 0x1000 /* Enable Mailbox 28 For Receive */ -#define MD29 0x2000 /* Enable Mailbox 29 For Receive */ -#define MD30 0x4000 /* Enable Mailbox 30 For Receive */ -#define MD31 0x8000 /* Enable Mailbox 31 For Receive */ - -/* CAN_RMP1 Masks */ -#define RMP0 0x0001 /* RX Message Pending In Mailbox 0 */ -#define RMP1 0x0002 /* RX Message Pending In Mailbox 1 */ -#define RMP2 0x0004 /* RX Message Pending In Mailbox 2 */ -#define RMP3 0x0008 /* RX Message Pending In Mailbox 3 */ -#define RMP4 0x0010 /* RX Message Pending In Mailbox 4 */ -#define RMP5 0x0020 /* RX Message Pending In Mailbox 5 */ -#define RMP6 0x0040 /* RX Message Pending In Mailbox 6 */ -#define RMP7 0x0080 /* RX Message Pending In Mailbox 7 */ -#define RMP8 0x0100 /* RX Message Pending In Mailbox 8 */ -#define RMP9 0x0200 /* RX Message Pending In Mailbox 9 */ -#define RMP10 0x0400 /* RX Message Pending In Mailbox 10 */ -#define RMP11 0x0800 /* RX Message Pending In Mailbox 11 */ -#define RMP12 0x1000 /* RX Message Pending In Mailbox 12 */ -#define RMP13 0x2000 /* RX Message Pending In Mailbox 13 */ -#define RMP14 0x4000 /* RX Message Pending In Mailbox 14 */ -#define RMP15 0x8000 /* RX Message Pending In Mailbox 15 */ - -/* CAN_RMP2 Masks */ -#define RMP16 0x0001 /* RX Message Pending In Mailbox 16 */ -#define RMP17 0x0002 /* RX Message Pending In Mailbox 17 */ -#define RMP18 0x0004 /* RX Message Pending In Mailbox 18 */ -#define RMP19 0x0008 /* RX Message Pending In Mailbox 19 */ -#define RMP20 0x0010 /* RX Message Pending In Mailbox 20 */ -#define RMP21 0x0020 /* RX Message Pending In Mailbox 21 */ -#define RMP22 0x0040 /* RX Message Pending In Mailbox 22 */ -#define RMP23 0x0080 /* RX Message Pending In Mailbox 23 */ -#define RMP24 0x0100 /* RX Message Pending In Mailbox 24 */ -#define RMP25 0x0200 /* RX Message Pending In Mailbox 25 */ -#define RMP26 0x0400 /* RX Message Pending In Mailbox 26 */ -#define RMP27 0x0800 /* RX Message Pending In Mailbox 27 */ -#define RMP28 0x1000 /* RX Message Pending In Mailbox 28 */ -#define RMP29 0x2000 /* RX Message Pending In Mailbox 29 */ -#define RMP30 0x4000 /* RX Message Pending In Mailbox 30 */ -#define RMP31 0x8000 /* RX Message Pending In Mailbox 31 */ - -/* CAN_RML1 Masks */ -#define RML0 0x0001 /* RX Message Lost In Mailbox 0 */ -#define RML1 0x0002 /* RX Message Lost In Mailbox 1 */ -#define RML2 0x0004 /* RX Message Lost In Mailbox 2 */ -#define RML3 0x0008 /* RX Message Lost In Mailbox 3 */ -#define RML4 0x0010 /* RX Message Lost In Mailbox 4 */ -#define RML5 0x0020 /* RX Message Lost In Mailbox 5 */ -#define RML6 0x0040 /* RX Message Lost In Mailbox 6 */ -#define RML7 0x0080 /* RX Message Lost In Mailbox 7 */ -#define RML8 0x0100 /* RX Message Lost In Mailbox 8 */ -#define RML9 0x0200 /* RX Message Lost In Mailbox 9 */ -#define RML10 0x0400 /* RX Message Lost In Mailbox 10 */ -#define RML11 0x0800 /* RX Message Lost In Mailbox 11 */ -#define RML12 0x1000 /* RX Message Lost In Mailbox 12 */ -#define RML13 0x2000 /* RX Message Lost In Mailbox 13 */ -#define RML14 0x4000 /* RX Message Lost In Mailbox 14 */ -#define RML15 0x8000 /* RX Message Lost In Mailbox 15 */ - -/* CAN_RML2 Masks */ -#define RML16 0x0001 /* RX Message Lost In Mailbox 16 */ -#define RML17 0x0002 /* RX Message Lost In Mailbox 17 */ -#define RML18 0x0004 /* RX Message Lost In Mailbox 18 */ -#define RML19 0x0008 /* RX Message Lost In Mailbox 19 */ -#define RML20 0x0010 /* RX Message Lost In Mailbox 20 */ -#define RML21 0x0020 /* RX Message Lost In Mailbox 21 */ -#define RML22 0x0040 /* RX Message Lost In Mailbox 22 */ -#define RML23 0x0080 /* RX Message Lost In Mailbox 23 */ -#define RML24 0x0100 /* RX Message Lost In Mailbox 24 */ -#define RML25 0x0200 /* RX Message Lost In Mailbox 25 */ -#define RML26 0x0400 /* RX Message Lost In Mailbox 26 */ -#define RML27 0x0800 /* RX Message Lost In Mailbox 27 */ -#define RML28 0x1000 /* RX Message Lost In Mailbox 28 */ -#define RML29 0x2000 /* RX Message Lost In Mailbox 29 */ -#define RML30 0x4000 /* RX Message Lost In Mailbox 30 */ -#define RML31 0x8000 /* RX Message Lost In Mailbox 31 */ - -/* CAN_OPSS1 Masks */ -#define OPSS0 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 0 */ -#define OPSS1 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 1 */ -#define OPSS2 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 2 */ -#define OPSS3 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 3 */ -#define OPSS4 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 4 */ -#define OPSS5 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 5 */ -#define OPSS6 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 6 */ -#define OPSS7 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 7 */ -#define OPSS8 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 8 */ -#define OPSS9 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 9 */ -#define OPSS10 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 10 */ -#define OPSS11 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 11 */ -#define OPSS12 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 12 */ -#define OPSS13 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 13 */ -#define OPSS14 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 14 */ -#define OPSS15 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 15 */ - -/* CAN_OPSS2 Masks */ -#define OPSS16 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 16 */ -#define OPSS17 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 17 */ -#define OPSS18 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 18 */ -#define OPSS19 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 19 */ -#define OPSS20 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 20 */ -#define OPSS21 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 21 */ -#define OPSS22 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 22 */ -#define OPSS23 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 23 */ -#define OPSS24 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 24 */ -#define OPSS25 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 25 */ -#define OPSS26 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 26 */ -#define OPSS27 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 27 */ -#define OPSS28 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 28 */ -#define OPSS29 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 29 */ -#define OPSS30 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 30 */ -#define OPSS31 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 31 */ - -/* CAN_TRR1 Masks */ -#define TRR0 0x0001 /* Deny But Don't Lock Access To Mailbox 0 */ -#define TRR1 0x0002 /* Deny But Don't Lock Access To Mailbox 1 */ -#define TRR2 0x0004 /* Deny But Don't Lock Access To Mailbox 2 */ -#define TRR3 0x0008 /* Deny But Don't Lock Access To Mailbox 3 */ -#define TRR4 0x0010 /* Deny But Don't Lock Access To Mailbox 4 */ -#define TRR5 0x0020 /* Deny But Don't Lock Access To Mailbox 5 */ -#define TRR6 0x0040 /* Deny But Don't Lock Access To Mailbox 6 */ -#define TRR7 0x0080 /* Deny But Don't Lock Access To Mailbox 7 */ -#define TRR8 0x0100 /* Deny But Don't Lock Access To Mailbox 8 */ -#define TRR9 0x0200 /* Deny But Don't Lock Access To Mailbox 9 */ -#define TRR10 0x0400 /* Deny But Don't Lock Access To Mailbox 10 */ -#define TRR11 0x0800 /* Deny But Don't Lock Access To Mailbox 11 */ -#define TRR12 0x1000 /* Deny But Don't Lock Access To Mailbox 12 */ -#define TRR13 0x2000 /* Deny But Don't Lock Access To Mailbox 13 */ -#define TRR14 0x4000 /* Deny But Don't Lock Access To Mailbox 14 */ -#define TRR15 0x8000 /* Deny But Don't Lock Access To Mailbox 15 */ - -/* CAN_TRR2 Masks */ -#define TRR16 0x0001 /* Deny But Don't Lock Access To Mailbox 16 */ -#define TRR17 0x0002 /* Deny But Don't Lock Access To Mailbox 17 */ -#define TRR18 0x0004 /* Deny But Don't Lock Access To Mailbox 18 */ -#define TRR19 0x0008 /* Deny But Don't Lock Access To Mailbox 19 */ -#define TRR20 0x0010 /* Deny But Don't Lock Access To Mailbox 20 */ -#define TRR21 0x0020 /* Deny But Don't Lock Access To Mailbox 21 */ -#define TRR22 0x0040 /* Deny But Don't Lock Access To Mailbox 22 */ -#define TRR23 0x0080 /* Deny But Don't Lock Access To Mailbox 23 */ -#define TRR24 0x0100 /* Deny But Don't Lock Access To Mailbox 24 */ -#define TRR25 0x0200 /* Deny But Don't Lock Access To Mailbox 25 */ -#define TRR26 0x0400 /* Deny But Don't Lock Access To Mailbox 26 */ -#define TRR27 0x0800 /* Deny But Don't Lock Access To Mailbox 27 */ -#define TRR28 0x1000 /* Deny But Don't Lock Access To Mailbox 28 */ -#define TRR29 0x2000 /* Deny But Don't Lock Access To Mailbox 29 */ -#define TRR30 0x4000 /* Deny But Don't Lock Access To Mailbox 30 */ -#define TRR31 0x8000 /* Deny But Don't Lock Access To Mailbox 31 */ - -/* CAN_TRS1 Masks */ -#define TRS0 0x0001 /* Remote Frame Request For Mailbox 0 */ -#define TRS1 0x0002 /* Remote Frame Request For Mailbox 1 */ -#define TRS2 0x0004 /* Remote Frame Request For Mailbox 2 */ -#define TRS3 0x0008 /* Remote Frame Request For Mailbox 3 */ -#define TRS4 0x0010 /* Remote Frame Request For Mailbox 4 */ -#define TRS5 0x0020 /* Remote Frame Request For Mailbox 5 */ -#define TRS6 0x0040 /* Remote Frame Request For Mailbox 6 */ -#define TRS7 0x0080 /* Remote Frame Request For Mailbox 7 */ -#define TRS8 0x0100 /* Remote Frame Request For Mailbox 8 */ -#define TRS9 0x0200 /* Remote Frame Request For Mailbox 9 */ -#define TRS10 0x0400 /* Remote Frame Request For Mailbox 10 */ -#define TRS11 0x0800 /* Remote Frame Request For Mailbox 11 */ -#define TRS12 0x1000 /* Remote Frame Request For Mailbox 12 */ -#define TRS13 0x2000 /* Remote Frame Request For Mailbox 13 */ -#define TRS14 0x4000 /* Remote Frame Request For Mailbox 14 */ -#define TRS15 0x8000 /* Remote Frame Request For Mailbox 15 */ - -/* CAN_TRS2 Masks */ -#define TRS16 0x0001 /* Remote Frame Request For Mailbox 16 */ -#define TRS17 0x0002 /* Remote Frame Request For Mailbox 17 */ -#define TRS18 0x0004 /* Remote Frame Request For Mailbox 18 */ -#define TRS19 0x0008 /* Remote Frame Request For Mailbox 19 */ -#define TRS20 0x0010 /* Remote Frame Request For Mailbox 20 */ -#define TRS21 0x0020 /* Remote Frame Request For Mailbox 21 */ -#define TRS22 0x0040 /* Remote Frame Request For Mailbox 22 */ -#define TRS23 0x0080 /* Remote Frame Request For Mailbox 23 */ -#define TRS24 0x0100 /* Remote Frame Request For Mailbox 24 */ -#define TRS25 0x0200 /* Remote Frame Request For Mailbox 25 */ -#define TRS26 0x0400 /* Remote Frame Request For Mailbox 26 */ -#define TRS27 0x0800 /* Remote Frame Request For Mailbox 27 */ -#define TRS28 0x1000 /* Remote Frame Request For Mailbox 28 */ -#define TRS29 0x2000 /* Remote Frame Request For Mailbox 29 */ -#define TRS30 0x4000 /* Remote Frame Request For Mailbox 30 */ -#define TRS31 0x8000 /* Remote Frame Request For Mailbox 31 */ - -/* CAN_AA1 Masks */ -#define AA0 0x0001 /* Aborted Message In Mailbox 0 */ -#define AA1 0x0002 /* Aborted Message In Mailbox 1 */ -#define AA2 0x0004 /* Aborted Message In Mailbox 2 */ -#define AA3 0x0008 /* Aborted Message In Mailbox 3 */ -#define AA4 0x0010 /* Aborted Message In Mailbox 4 */ -#define AA5 0x0020 /* Aborted Message In Mailbox 5 */ -#define AA6 0x0040 /* Aborted Message In Mailbox 6 */ -#define AA7 0x0080 /* Aborted Message In Mailbox 7 */ -#define AA8 0x0100 /* Aborted Message In Mailbox 8 */ -#define AA9 0x0200 /* Aborted Message In Mailbox 9 */ -#define AA10 0x0400 /* Aborted Message In Mailbox 10 */ -#define AA11 0x0800 /* Aborted Message In Mailbox 11 */ -#define AA12 0x1000 /* Aborted Message In Mailbox 12 */ -#define AA13 0x2000 /* Aborted Message In Mailbox 13 */ -#define AA14 0x4000 /* Aborted Message In Mailbox 14 */ -#define AA15 0x8000 /* Aborted Message In Mailbox 15 */ - -/* CAN_AA2 Masks */ -#define AA16 0x0001 /* Aborted Message In Mailbox 16 */ -#define AA17 0x0002 /* Aborted Message In Mailbox 17 */ -#define AA18 0x0004 /* Aborted Message In Mailbox 18 */ -#define AA19 0x0008 /* Aborted Message In Mailbox 19 */ -#define AA20 0x0010 /* Aborted Message In Mailbox 20 */ -#define AA21 0x0020 /* Aborted Message In Mailbox 21 */ -#define AA22 0x0040 /* Aborted Message In Mailbox 22 */ -#define AA23 0x0080 /* Aborted Message In Mailbox 23 */ -#define AA24 0x0100 /* Aborted Message In Mailbox 24 */ -#define AA25 0x0200 /* Aborted Message In Mailbox 25 */ -#define AA26 0x0400 /* Aborted Message In Mailbox 26 */ -#define AA27 0x0800 /* Aborted Message In Mailbox 27 */ -#define AA28 0x1000 /* Aborted Message In Mailbox 28 */ -#define AA29 0x2000 /* Aborted Message In Mailbox 29 */ -#define AA30 0x4000 /* Aborted Message In Mailbox 30 */ -#define AA31 0x8000 /* Aborted Message In Mailbox 31 */ - -/* CAN_TA1 Masks */ -#define TA0 0x0001 /* Transmit Successful From Mailbox 0 */ -#define TA1 0x0002 /* Transmit Successful From Mailbox 1 */ -#define TA2 0x0004 /* Transmit Successful From Mailbox 2 */ -#define TA3 0x0008 /* Transmit Successful From Mailbox 3 */ -#define TA4 0x0010 /* Transmit Successful From Mailbox 4 */ -#define TA5 0x0020 /* Transmit Successful From Mailbox 5 */ -#define TA6 0x0040 /* Transmit Successful From Mailbox 6 */ -#define TA7 0x0080 /* Transmit Successful From Mailbox 7 */ -#define TA8 0x0100 /* Transmit Successful From Mailbox 8 */ -#define TA9 0x0200 /* Transmit Successful From Mailbox 9 */ -#define TA10 0x0400 /* Transmit Successful From Mailbox 10 */ -#define TA11 0x0800 /* Transmit Successful From Mailbox 11 */ -#define TA12 0x1000 /* Transmit Successful From Mailbox 12 */ -#define TA13 0x2000 /* Transmit Successful From Mailbox 13 */ -#define TA14 0x4000 /* Transmit Successful From Mailbox 14 */ -#define TA15 0x8000 /* Transmit Successful From Mailbox 15 */ - -/* CAN_TA2 Masks */ -#define TA16 0x0001 /* Transmit Successful From Mailbox 16 */ -#define TA17 0x0002 /* Transmit Successful From Mailbox 17 */ -#define TA18 0x0004 /* Transmit Successful From Mailbox 18 */ -#define TA19 0x0008 /* Transmit Successful From Mailbox 19 */ -#define TA20 0x0010 /* Transmit Successful From Mailbox 20 */ -#define TA21 0x0020 /* Transmit Successful From Mailbox 21 */ -#define TA22 0x0040 /* Transmit Successful From Mailbox 22 */ -#define TA23 0x0080 /* Transmit Successful From Mailbox 23 */ -#define TA24 0x0100 /* Transmit Successful From Mailbox 24 */ -#define TA25 0x0200 /* Transmit Successful From Mailbox 25 */ -#define TA26 0x0400 /* Transmit Successful From Mailbox 26 */ -#define TA27 0x0800 /* Transmit Successful From Mailbox 27 */ -#define TA28 0x1000 /* Transmit Successful From Mailbox 28 */ -#define TA29 0x2000 /* Transmit Successful From Mailbox 29 */ -#define TA30 0x4000 /* Transmit Successful From Mailbox 30 */ -#define TA31 0x8000 /* Transmit Successful From Mailbox 31 */ - -/* CAN_MBTD Masks */ -#define TDPTR 0x001F /* Mailbox To Temporarily Disable */ -#define TDA 0x0040 /* Temporary Disable Acknowledge */ -#define TDR 0x0080 /* Temporary Disable Request */ - -/* CAN_RFH1 Masks */ -#define RFH0 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 0 */ -#define RFH1 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 1 */ -#define RFH2 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 2 */ -#define RFH3 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 3 */ -#define RFH4 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 4 */ -#define RFH5 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 5 */ -#define RFH6 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 6 */ -#define RFH7 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 7 */ -#define RFH8 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 8 */ -#define RFH9 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 9 */ -#define RFH10 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 10 */ -#define RFH11 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 11 */ -#define RFH12 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 12 */ -#define RFH13 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 13 */ -#define RFH14 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 14 */ -#define RFH15 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 15 */ - -/* CAN_RFH2 Masks */ -#define RFH16 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 16 */ -#define RFH17 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 17 */ -#define RFH18 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 18 */ -#define RFH19 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 19 */ -#define RFH20 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 20 */ -#define RFH21 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 21 */ -#define RFH22 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 22 */ -#define RFH23 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 23 */ -#define RFH24 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 24 */ -#define RFH25 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 25 */ -#define RFH26 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 26 */ -#define RFH27 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 27 */ -#define RFH28 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 28 */ -#define RFH29 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 29 */ -#define RFH30 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 30 */ -#define RFH31 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 31 */ - -/* CAN_MBTIF1 Masks */ -#define MBTIF0 0x0001 /* TX Interrupt Active In Mailbox 0 */ -#define MBTIF1 0x0002 /* TX Interrupt Active In Mailbox 1 */ -#define MBTIF2 0x0004 /* TX Interrupt Active In Mailbox 2 */ -#define MBTIF3 0x0008 /* TX Interrupt Active In Mailbox 3 */ -#define MBTIF4 0x0010 /* TX Interrupt Active In Mailbox 4 */ -#define MBTIF5 0x0020 /* TX Interrupt Active In Mailbox 5 */ -#define MBTIF6 0x0040 /* TX Interrupt Active In Mailbox 6 */ -#define MBTIF7 0x0080 /* TX Interrupt Active In Mailbox 7 */ -#define MBTIF8 0x0100 /* TX Interrupt Active In Mailbox 8 */ -#define MBTIF9 0x0200 /* TX Interrupt Active In Mailbox 9 */ -#define MBTIF10 0x0400 /* TX Interrupt Active In Mailbox 10 */ -#define MBTIF11 0x0800 /* TX Interrupt Active In Mailbox 11 */ -#define MBTIF12 0x1000 /* TX Interrupt Active In Mailbox 12 */ -#define MBTIF13 0x2000 /* TX Interrupt Active In Mailbox 13 */ -#define MBTIF14 0x4000 /* TX Interrupt Active In Mailbox 14 */ -#define MBTIF15 0x8000 /* TX Interrupt Active In Mailbox 15 */ - -/* CAN_MBTIF2 Masks */ -#define MBTIF16 0x0001 /* TX Interrupt Active In Mailbox 16 */ -#define MBTIF17 0x0002 /* TX Interrupt Active In Mailbox 17 */ -#define MBTIF18 0x0004 /* TX Interrupt Active In Mailbox 18 */ -#define MBTIF19 0x0008 /* TX Interrupt Active In Mailbox 19 */ -#define MBTIF20 0x0010 /* TX Interrupt Active In Mailbox 20 */ -#define MBTIF21 0x0020 /* TX Interrupt Active In Mailbox 21 */ -#define MBTIF22 0x0040 /* TX Interrupt Active In Mailbox 22 */ -#define MBTIF23 0x0080 /* TX Interrupt Active In Mailbox 23 */ -#define MBTIF24 0x0100 /* TX Interrupt Active In Mailbox 24 */ -#define MBTIF25 0x0200 /* TX Interrupt Active In Mailbox 25 */ -#define MBTIF26 0x0400 /* TX Interrupt Active In Mailbox 26 */ -#define MBTIF27 0x0800 /* TX Interrupt Active In Mailbox 27 */ -#define MBTIF28 0x1000 /* TX Interrupt Active In Mailbox 28 */ -#define MBTIF29 0x2000 /* TX Interrupt Active In Mailbox 29 */ -#define MBTIF30 0x4000 /* TX Interrupt Active In Mailbox 30 */ -#define MBTIF31 0x8000 /* TX Interrupt Active In Mailbox 31 */ - -/* CAN_MBRIF1 Masks */ -#define MBRIF0 0x0001 /* RX Interrupt Active In Mailbox 0 */ -#define MBRIF1 0x0002 /* RX Interrupt Active In Mailbox 1 */ -#define MBRIF2 0x0004 /* RX Interrupt Active In Mailbox 2 */ -#define MBRIF3 0x0008 /* RX Interrupt Active In Mailbox 3 */ -#define MBRIF4 0x0010 /* RX Interrupt Active In Mailbox 4 */ -#define MBRIF5 0x0020 /* RX Interrupt Active In Mailbox 5 */ -#define MBRIF6 0x0040 /* RX Interrupt Active In Mailbox 6 */ -#define MBRIF7 0x0080 /* RX Interrupt Active In Mailbox 7 */ -#define MBRIF8 0x0100 /* RX Interrupt Active In Mailbox 8 */ -#define MBRIF9 0x0200 /* RX Interrupt Active In Mailbox 9 */ -#define MBRIF10 0x0400 /* RX Interrupt Active In Mailbox 10 */ -#define MBRIF11 0x0800 /* RX Interrupt Active In Mailbox 11 */ -#define MBRIF12 0x1000 /* RX Interrupt Active In Mailbox 12 */ -#define MBRIF13 0x2000 /* RX Interrupt Active In Mailbox 13 */ -#define MBRIF14 0x4000 /* RX Interrupt Active In Mailbox 14 */ -#define MBRIF15 0x8000 /* RX Interrupt Active In Mailbox 15 */ - -/* CAN_MBRIF2 Masks */ -#define MBRIF16 0x0001 /* RX Interrupt Active In Mailbox 16 */ -#define MBRIF17 0x0002 /* RX Interrupt Active In Mailbox 17 */ -#define MBRIF18 0x0004 /* RX Interrupt Active In Mailbox 18 */ -#define MBRIF19 0x0008 /* RX Interrupt Active In Mailbox 19 */ -#define MBRIF20 0x0010 /* RX Interrupt Active In Mailbox 20 */ -#define MBRIF21 0x0020 /* RX Interrupt Active In Mailbox 21 */ -#define MBRIF22 0x0040 /* RX Interrupt Active In Mailbox 22 */ -#define MBRIF23 0x0080 /* RX Interrupt Active In Mailbox 23 */ -#define MBRIF24 0x0100 /* RX Interrupt Active In Mailbox 24 */ -#define MBRIF25 0x0200 /* RX Interrupt Active In Mailbox 25 */ -#define MBRIF26 0x0400 /* RX Interrupt Active In Mailbox 26 */ -#define MBRIF27 0x0800 /* RX Interrupt Active In Mailbox 27 */ -#define MBRIF28 0x1000 /* RX Interrupt Active In Mailbox 28 */ -#define MBRIF29 0x2000 /* RX Interrupt Active In Mailbox 29 */ -#define MBRIF30 0x4000 /* RX Interrupt Active In Mailbox 30 */ -#define MBRIF31 0x8000 /* RX Interrupt Active In Mailbox 31 */ - -/* CAN_MBIM1 Masks */ -#define MBIM0 0x0001 /* Enable Interrupt For Mailbox 0 */ -#define MBIM1 0x0002 /* Enable Interrupt For Mailbox 1 */ -#define MBIM2 0x0004 /* Enable Interrupt For Mailbox 2 */ -#define MBIM3 0x0008 /* Enable Interrupt For Mailbox 3 */ -#define MBIM4 0x0010 /* Enable Interrupt For Mailbox 4 */ -#define MBIM5 0x0020 /* Enable Interrupt For Mailbox 5 */ -#define MBIM6 0x0040 /* Enable Interrupt For Mailbox 6 */ -#define MBIM7 0x0080 /* Enable Interrupt For Mailbox 7 */ -#define MBIM8 0x0100 /* Enable Interrupt For Mailbox 8 */ -#define MBIM9 0x0200 /* Enable Interrupt For Mailbox 9 */ -#define MBIM10 0x0400 /* Enable Interrupt For Mailbox 10 */ -#define MBIM11 0x0800 /* Enable Interrupt For Mailbox 11 */ -#define MBIM12 0x1000 /* Enable Interrupt For Mailbox 12 */ -#define MBIM13 0x2000 /* Enable Interrupt For Mailbox 13 */ -#define MBIM14 0x4000 /* Enable Interrupt For Mailbox 14 */ -#define MBIM15 0x8000 /* Enable Interrupt For Mailbox 15 */ - -/* CAN_MBIM2 Masks */ -#define MBIM16 0x0001 /* Enable Interrupt For Mailbox 16 */ -#define MBIM17 0x0002 /* Enable Interrupt For Mailbox 17 */ -#define MBIM18 0x0004 /* Enable Interrupt For Mailbox 18 */ -#define MBIM19 0x0008 /* Enable Interrupt For Mailbox 19 */ -#define MBIM20 0x0010 /* Enable Interrupt For Mailbox 20 */ -#define MBIM21 0x0020 /* Enable Interrupt For Mailbox 21 */ -#define MBIM22 0x0040 /* Enable Interrupt For Mailbox 22 */ -#define MBIM23 0x0080 /* Enable Interrupt For Mailbox 23 */ -#define MBIM24 0x0100 /* Enable Interrupt For Mailbox 24 */ -#define MBIM25 0x0200 /* Enable Interrupt For Mailbox 25 */ -#define MBIM26 0x0400 /* Enable Interrupt For Mailbox 26 */ -#define MBIM27 0x0800 /* Enable Interrupt For Mailbox 27 */ -#define MBIM28 0x1000 /* Enable Interrupt For Mailbox 28 */ -#define MBIM29 0x2000 /* Enable Interrupt For Mailbox 29 */ -#define MBIM30 0x4000 /* Enable Interrupt For Mailbox 30 */ -#define MBIM31 0x8000 /* Enable Interrupt For Mailbox 31 */ - -/* CAN_GIM Masks */ -#define EWTIM 0x0001 /* Enable TX Error Count Interrupt */ -#define EWRIM 0x0002 /* Enable RX Error Count Interrupt */ -#define EPIM 0x0004 /* Enable Error-Passive Mode Interrupt */ -#define BOIM 0x0008 /* Enable Bus Off Interrupt */ -#define WUIM 0x0010 /* Enable Wake-Up Interrupt */ -#define UIAIM 0x0020 /* Enable Access To Unimplemented Address Interrupt */ -#define AAIM 0x0040 /* Enable Abort Acknowledge Interrupt */ -#define RMLIM 0x0080 /* Enable RX Message Lost Interrupt */ -#define UCEIM 0x0100 /* Enable Universal Counter Overflow Interrupt */ -#define EXTIM 0x0200 /* Enable External Trigger Output Interrupt */ -#define ADIM 0x0400 /* Enable Access Denied Interrupt */ - -/* CAN_GIS Masks */ -#define EWTIS 0x0001 /* TX Error Count IRQ Status */ -#define EWRIS 0x0002 /* RX Error Count IRQ Status */ -#define EPIS 0x0004 /* Error-Passive Mode IRQ Status */ -#define BOIS 0x0008 /* Bus Off IRQ Status */ -#define WUIS 0x0010 /* Wake-Up IRQ Status */ -#define UIAIS 0x0020 /* Access To Unimplemented Address IRQ Status */ -#define AAIS 0x0040 /* Abort Acknowledge IRQ Status */ -#define RMLIS 0x0080 /* RX Message Lost IRQ Status */ -#define UCEIS 0x0100 /* Universal Counter Overflow IRQ Status */ -#define EXTIS 0x0200 /* External Trigger Output IRQ Status */ -#define ADIS 0x0400 /* Access Denied IRQ Status */ - -/* CAN_GIF Masks */ -#define EWTIF 0x0001 /* TX Error Count IRQ Flag */ -#define EWRIF 0x0002 /* RX Error Count IRQ Flag */ -#define EPIF 0x0004 /* Error-Passive Mode IRQ Flag */ -#define BOIF 0x0008 /* Bus Off IRQ Flag */ -#define WUIF 0x0010 /* Wake-Up IRQ Flag */ -#define UIAIF 0x0020 /* Access To Unimplemented Address IRQ Flag */ -#define AAIF 0x0040 /* Abort Acknowledge IRQ Flag */ -#define RMLIF 0x0080 /* RX Message Lost IRQ Flag */ -#define UCEIF 0x0100 /* Universal Counter Overflow IRQ Flag */ -#define EXTIF 0x0200 /* External Trigger Output IRQ Flag */ -#define ADIF 0x0400 /* Access Denied IRQ Flag */ - -/* CAN_UCCNF Masks */ -#define UCCNF 0x000F /* Universal Counter Mode */ -#define UC_STAMP 0x0001 /* Timestamp Mode */ -#define UC_WDOG 0x0002 /* Watchdog Mode */ -#define UC_AUTOTX 0x0003 /* Auto-Transmit Mode */ -#define UC_ERROR 0x0006 /* CAN Error Frame Count */ -#define UC_OVER 0x0007 /* CAN Overload Frame Count */ -#define UC_LOST 0x0008 /* Arbitration Lost During TX Count */ -#define UC_AA 0x0009 /* TX Abort Count */ -#define UC_TA 0x000A /* TX Successful Count */ -#define UC_REJECT 0x000B /* RX Message Rejected Count */ -#define UC_RML 0x000C /* RX Message Lost Count */ -#define UC_RX 0x000D /* Total Successful RX Messages Count */ -#define UC_RMP 0x000E /* Successful RX W/Matching ID Count */ -#define UC_ALL 0x000F /* Correct Message On CAN Bus Line Count */ -#define UCRC 0x0020 /* Universal Counter Reload/Clear */ -#define UCCT 0x0040 /* Universal Counter CAN Trigger */ -#define UCE 0x0080 /* Universal Counter Enable */ - -/* CAN_ESR Masks */ -#define ACKE 0x0004 /* Acknowledge Error */ -#define SER 0x0008 /* Stuff Error */ -#define CRCE 0x0010 /* CRC Error */ -#define SA0 0x0020 /* Stuck At Dominant Error */ -#define BEF 0x0040 /* Bit Error Flag */ -#define FER 0x0080 /* Form Error Flag */ - -/* CAN_EWR Masks */ -#define EWLREC 0x00FF /* RX Error Count Limit (For EWRIS) */ -#define EWLTEC 0xFF00 /* TX Error Count Limit (For EWTIS) */ - /* ******************* PIN CONTROL REGISTER MASKS ************************/ /* PORT_MUX Masks */ #define PJSE 0x0001 /* Port J SPI/SPORT Enable */ diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index fac563e6f62f..d7061d9f2a83 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h @@ -2418,625 +2418,4 @@ #define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ #define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ - -/* ************ CONTROLLER AREA NETWORK (CAN) MASKS ***************/ -/* CAN_CONTROL Masks */ -#define SRS 0x0001 /* Software Reset */ -#define DNM 0x0002 /* Device Net Mode */ -#define ABO 0x0004 /* Auto-Bus On Enable */ -#define WBA 0x0010 /* Wake-Up On CAN Bus Activity Enable */ -#define SMR 0x0020 /* Sleep Mode Request */ -#define CSR 0x0040 /* CAN Suspend Mode Request */ -#define CCR 0x0080 /* CAN Configuration Mode Request */ - -/* CAN_STATUS Masks */ -#define WT 0x0001 /* TX Warning Flag */ -#define WR 0x0002 /* RX Warning Flag */ -#define EP 0x0004 /* Error Passive Mode */ -#define EBO 0x0008 /* Error Bus Off Mode */ -#define CSA 0x0040 /* Suspend Mode Acknowledge */ -#define CCA 0x0080 /* Configuration Mode Acknowledge */ -#define MBPTR 0x1F00 /* Mailbox Pointer */ -#define TRM 0x4000 /* Transmit Mode */ -#define REC 0x8000 /* Receive Mode */ - -/* CAN_CLOCK Masks */ -#define BRP 0x03FF /* Bit-Rate Pre-Scaler */ - -/* CAN_TIMING Masks */ -#define TSEG1 0x000F /* Time Segment 1 */ -#define TSEG2 0x0070 /* Time Segment 2 */ -#define SAM 0x0080 /* Sampling */ -#define SJW 0x0300 /* Synchronization Jump Width */ - -/* CAN_DEBUG Masks */ -#define DEC 0x0001 /* Disable CAN Error Counters */ -#define DRI 0x0002 /* Disable CAN RX Input */ -#define DTO 0x0004 /* Disable CAN TX Output */ -#define DIL 0x0008 /* Disable CAN Internal Loop */ -#define MAA 0x0010 /* Mode Auto-Acknowledge Enable */ -#define MRB 0x0020 /* Mode Read Back Enable */ -#define CDE 0x8000 /* CAN Debug Enable */ - -/* CAN_CEC Masks */ -#define RXECNT 0x00FF /* Receive Error Counter */ -#define TXECNT 0xFF00 /* Transmit Error Counter */ - -/* CAN_INTR Masks */ -#define MBRIRQ 0x0001 /* Mailbox Receive Interrupt */ -#define MBRIF MBRIRQ /* legacy */ -#define MBTIRQ 0x0002 /* Mailbox Transmit Interrupt */ -#define MBTIF MBTIRQ /* legacy */ -#define GIRQ 0x0004 /* Global Interrupt */ -#define SMACK 0x0008 /* Sleep Mode Acknowledge */ -#define CANTX 0x0040 /* CAN TX Bus Value */ -#define CANRX 0x0080 /* CAN RX Bus Value */ - -/* CAN_MBxx_ID1 and CAN_MBxx_ID0 Masks */ -#define DFC 0xFFFF /* Data Filtering Code (If Enabled) (ID0) */ -#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (ID0) */ -#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (ID1) */ -#define BASEID 0x1FFC /* Base Identifier */ -#define IDE 0x2000 /* Identifier Extension */ -#define RTR 0x4000 /* Remote Frame Transmission Request */ -#define AME 0x8000 /* Acceptance Mask Enable */ - -/* CAN_MBxx_TIMESTAMP Masks */ -#define TSV 0xFFFF /* Timestamp */ - -/* CAN_MBxx_LENGTH Masks */ -#define DLC 0x000F /* Data Length Code */ - -/* CAN_AMxxH and CAN_AMxxL Masks */ -#define DFM 0xFFFF /* Data Field Mask (If Enabled) (CAN_AMxxL) */ -#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (CAN_AMxxL) */ -#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (CAN_AMxxH) */ -#define BASEID 0x1FFC /* Base Identifier */ -#define AMIDE 0x2000 /* Acceptance Mask ID Extension Enable */ -#define FMD 0x4000 /* Full Mask Data Field Enable */ -#define FDF 0x8000 /* Filter On Data Field Enable */ - -/* CAN_MC1 Masks */ -#define MC0 0x0001 /* Enable Mailbox 0 */ -#define MC1 0x0002 /* Enable Mailbox 1 */ -#define MC2 0x0004 /* Enable Mailbox 2 */ -#define MC3 0x0008 /* Enable Mailbox 3 */ -#define MC4 0x0010 /* Enable Mailbox 4 */ -#define MC5 0x0020 /* Enable Mailbox 5 */ -#define MC6 0x0040 /* Enable Mailbox 6 */ -#define MC7 0x0080 /* Enable Mailbox 7 */ -#define MC8 0x0100 /* Enable Mailbox 8 */ -#define MC9 0x0200 /* Enable Mailbox 9 */ -#define MC10 0x0400 /* Enable Mailbox 10 */ -#define MC11 0x0800 /* Enable Mailbox 11 */ -#define MC12 0x1000 /* Enable Mailbox 12 */ -#define MC13 0x2000 /* Enable Mailbox 13 */ -#define MC14 0x4000 /* Enable Mailbox 14 */ -#define MC15 0x8000 /* Enable Mailbox 15 */ - -/* CAN_MC2 Masks */ -#define MC16 0x0001 /* Enable Mailbox 16 */ -#define MC17 0x0002 /* Enable Mailbox 17 */ -#define MC18 0x0004 /* Enable Mailbox 18 */ -#define MC19 0x0008 /* Enable Mailbox 19 */ -#define MC20 0x0010 /* Enable Mailbox 20 */ -#define MC21 0x0020 /* Enable Mailbox 21 */ -#define MC22 0x0040 /* Enable Mailbox 22 */ -#define MC23 0x0080 /* Enable Mailbox 23 */ -#define MC24 0x0100 /* Enable Mailbox 24 */ -#define MC25 0x0200 /* Enable Mailbox 25 */ -#define MC26 0x0400 /* Enable Mailbox 26 */ -#define MC27 0x0800 /* Enable Mailbox 27 */ -#define MC28 0x1000 /* Enable Mailbox 28 */ -#define MC29 0x2000 /* Enable Mailbox 29 */ -#define MC30 0x4000 /* Enable Mailbox 30 */ -#define MC31 0x8000 /* Enable Mailbox 31 */ - -/* CAN_MD1 Masks */ -#define MD0 0x0001 /* Enable Mailbox 0 For Receive */ -#define MD1 0x0002 /* Enable Mailbox 1 For Receive */ -#define MD2 0x0004 /* Enable Mailbox 2 For Receive */ -#define MD3 0x0008 /* Enable Mailbox 3 For Receive */ -#define MD4 0x0010 /* Enable Mailbox 4 For Receive */ -#define MD5 0x0020 /* Enable Mailbox 5 For Receive */ -#define MD6 0x0040 /* Enable Mailbox 6 For Receive */ -#define MD7 0x0080 /* Enable Mailbox 7 For Receive */ -#define MD8 0x0100 /* Enable Mailbox 8 For Receive */ -#define MD9 0x0200 /* Enable Mailbox 9 For Receive */ -#define MD10 0x0400 /* Enable Mailbox 10 For Receive */ -#define MD11 0x0800 /* Enable Mailbox 11 For Receive */ -#define MD12 0x1000 /* Enable Mailbox 12 For Receive */ -#define MD13 0x2000 /* Enable Mailbox 13 For Receive */ -#define MD14 0x4000 /* Enable Mailbox 14 For Receive */ -#define MD15 0x8000 /* Enable Mailbox 15 For Receive */ - -/* CAN_MD2 Masks */ -#define MD16 0x0001 /* Enable Mailbox 16 For Receive */ -#define MD17 0x0002 /* Enable Mailbox 17 For Receive */ -#define MD18 0x0004 /* Enable Mailbox 18 For Receive */ -#define MD19 0x0008 /* Enable Mailbox 19 For Receive */ -#define MD20 0x0010 /* Enable Mailbox 20 For Receive */ -#define MD21 0x0020 /* Enable Mailbox 21 For Receive */ -#define MD22 0x0040 /* Enable Mailbox 22 For Receive */ -#define MD23 0x0080 /* Enable Mailbox 23 For Receive */ -#define MD24 0x0100 /* Enable Mailbox 24 For Receive */ -#define MD25 0x0200 /* Enable Mailbox 25 For Receive */ -#define MD26 0x0400 /* Enable Mailbox 26 For Receive */ -#define MD27 0x0800 /* Enable Mailbox 27 For Receive */ -#define MD28 0x1000 /* Enable Mailbox 28 For Receive */ -#define MD29 0x2000 /* Enable Mailbox 29 For Receive */ -#define MD30 0x4000 /* Enable Mailbox 30 For Receive */ -#define MD31 0x8000 /* Enable Mailbox 31 For Receive */ - -/* CAN_RMP1 Masks */ -#define RMP0 0x0001 /* RX Message Pending In Mailbox 0 */ -#define RMP1 0x0002 /* RX Message Pending In Mailbox 1 */ -#define RMP2 0x0004 /* RX Message Pending In Mailbox 2 */ -#define RMP3 0x0008 /* RX Message Pending In Mailbox 3 */ -#define RMP4 0x0010 /* RX Message Pending In Mailbox 4 */ -#define RMP5 0x0020 /* RX Message Pending In Mailbox 5 */ -#define RMP6 0x0040 /* RX Message Pending In Mailbox 6 */ -#define RMP7 0x0080 /* RX Message Pending In Mailbox 7 */ -#define RMP8 0x0100 /* RX Message Pending In Mailbox 8 */ -#define RMP9 0x0200 /* RX Message Pending In Mailbox 9 */ -#define RMP10 0x0400 /* RX Message Pending In Mailbox 10 */ -#define RMP11 0x0800 /* RX Message Pending In Mailbox 11 */ -#define RMP12 0x1000 /* RX Message Pending In Mailbox 12 */ -#define RMP13 0x2000 /* RX Message Pending In Mailbox 13 */ -#define RMP14 0x4000 /* RX Message Pending In Mailbox 14 */ -#define RMP15 0x8000 /* RX Message Pending In Mailbox 15 */ - -/* CAN_RMP2 Masks */ -#define RMP16 0x0001 /* RX Message Pending In Mailbox 16 */ -#define RMP17 0x0002 /* RX Message Pending In Mailbox 17 */ -#define RMP18 0x0004 /* RX Message Pending In Mailbox 18 */ -#define RMP19 0x0008 /* RX Message Pending In Mailbox 19 */ -#define RMP20 0x0010 /* RX Message Pending In Mailbox 20 */ -#define RMP21 0x0020 /* RX Message Pending In Mailbox 21 */ -#define RMP22 0x0040 /* RX Message Pending In Mailbox 22 */ -#define RMP23 0x0080 /* RX Message Pending In Mailbox 23 */ -#define RMP24 0x0100 /* RX Message Pending In Mailbox 24 */ -#define RMP25 0x0200 /* RX Message Pending In Mailbox 25 */ -#define RMP26 0x0400 /* RX Message Pending In Mailbox 26 */ -#define RMP27 0x0800 /* RX Message Pending In Mailbox 27 */ -#define RMP28 0x1000 /* RX Message Pending In Mailbox 28 */ -#define RMP29 0x2000 /* RX Message Pending In Mailbox 29 */ -#define RMP30 0x4000 /* RX Message Pending In Mailbox 30 */ -#define RMP31 0x8000 /* RX Message Pending In Mailbox 31 */ - -/* CAN_RML1 Masks */ -#define RML0 0x0001 /* RX Message Lost In Mailbox 0 */ -#define RML1 0x0002 /* RX Message Lost In Mailbox 1 */ -#define RML2 0x0004 /* RX Message Lost In Mailbox 2 */ -#define RML3 0x0008 /* RX Message Lost In Mailbox 3 */ -#define RML4 0x0010 /* RX Message Lost In Mailbox 4 */ -#define RML5 0x0020 /* RX Message Lost In Mailbox 5 */ -#define RML6 0x0040 /* RX Message Lost In Mailbox 6 */ -#define RML7 0x0080 /* RX Message Lost In Mailbox 7 */ -#define RML8 0x0100 /* RX Message Lost In Mailbox 8 */ -#define RML9 0x0200 /* RX Message Lost In Mailbox 9 */ -#define RML10 0x0400 /* RX Message Lost In Mailbox 10 */ -#define RML11 0x0800 /* RX Message Lost In Mailbox 11 */ -#define RML12 0x1000 /* RX Message Lost In Mailbox 12 */ -#define RML13 0x2000 /* RX Message Lost In Mailbox 13 */ -#define RML14 0x4000 /* RX Message Lost In Mailbox 14 */ -#define RML15 0x8000 /* RX Message Lost In Mailbox 15 */ - -/* CAN_RML2 Masks */ -#define RML16 0x0001 /* RX Message Lost In Mailbox 16 */ -#define RML17 0x0002 /* RX Message Lost In Mailbox 17 */ -#define RML18 0x0004 /* RX Message Lost In Mailbox 18 */ -#define RML19 0x0008 /* RX Message Lost In Mailbox 19 */ -#define RML20 0x0010 /* RX Message Lost In Mailbox 20 */ -#define RML21 0x0020 /* RX Message Lost In Mailbox 21 */ -#define RML22 0x0040 /* RX Message Lost In Mailbox 22 */ -#define RML23 0x0080 /* RX Message Lost In Mailbox 23 */ -#define RML24 0x0100 /* RX Message Lost In Mailbox 24 */ -#define RML25 0x0200 /* RX Message Lost In Mailbox 25 */ -#define RML26 0x0400 /* RX Message Lost In Mailbox 26 */ -#define RML27 0x0800 /* RX Message Lost In Mailbox 27 */ -#define RML28 0x1000 /* RX Message Lost In Mailbox 28 */ -#define RML29 0x2000 /* RX Message Lost In Mailbox 29 */ -#define RML30 0x4000 /* RX Message Lost In Mailbox 30 */ -#define RML31 0x8000 /* RX Message Lost In Mailbox 31 */ - -/* CAN_OPSS1 Masks */ -#define OPSS0 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 0 */ -#define OPSS1 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 1 */ -#define OPSS2 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 2 */ -#define OPSS3 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 3 */ -#define OPSS4 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 4 */ -#define OPSS5 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 5 */ -#define OPSS6 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 6 */ -#define OPSS7 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 7 */ -#define OPSS8 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 8 */ -#define OPSS9 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 9 */ -#define OPSS10 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 10 */ -#define OPSS11 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 11 */ -#define OPSS12 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 12 */ -#define OPSS13 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 13 */ -#define OPSS14 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 14 */ -#define OPSS15 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 15 */ - -/* CAN_OPSS2 Masks */ -#define OPSS16 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 16 */ -#define OPSS17 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 17 */ -#define OPSS18 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 18 */ -#define OPSS19 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 19 */ -#define OPSS20 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 20 */ -#define OPSS21 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 21 */ -#define OPSS22 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 22 */ -#define OPSS23 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 23 */ -#define OPSS24 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 24 */ -#define OPSS25 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 25 */ -#define OPSS26 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 26 */ -#define OPSS27 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 27 */ -#define OPSS28 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 28 */ -#define OPSS29 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 29 */ -#define OPSS30 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 30 */ -#define OPSS31 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 31 */ - -/* CAN_TRR1 Masks */ -#define TRR0 0x0001 /* Deny But Don't Lock Access To Mailbox 0 */ -#define TRR1 0x0002 /* Deny But Don't Lock Access To Mailbox 1 */ -#define TRR2 0x0004 /* Deny But Don't Lock Access To Mailbox 2 */ -#define TRR3 0x0008 /* Deny But Don't Lock Access To Mailbox 3 */ -#define TRR4 0x0010 /* Deny But Don't Lock Access To Mailbox 4 */ -#define TRR5 0x0020 /* Deny But Don't Lock Access To Mailbox 5 */ -#define TRR6 0x0040 /* Deny But Don't Lock Access To Mailbox 6 */ -#define TRR7 0x0080 /* Deny But Don't Lock Access To Mailbox 7 */ -#define TRR8 0x0100 /* Deny But Don't Lock Access To Mailbox 8 */ -#define TRR9 0x0200 /* Deny But Don't Lock Access To Mailbox 9 */ -#define TRR10 0x0400 /* Deny But Don't Lock Access To Mailbox 10 */ -#define TRR11 0x0800 /* Deny But Don't Lock Access To Mailbox 11 */ -#define TRR12 0x1000 /* Deny But Don't Lock Access To Mailbox 12 */ -#define TRR13 0x2000 /* Deny But Don't Lock Access To Mailbox 13 */ -#define TRR14 0x4000 /* Deny But Don't Lock Access To Mailbox 14 */ -#define TRR15 0x8000 /* Deny But Don't Lock Access To Mailbox 15 */ - -/* CAN_TRR2 Masks */ -#define TRR16 0x0001 /* Deny But Don't Lock Access To Mailbox 16 */ -#define TRR17 0x0002 /* Deny But Don't Lock Access To Mailbox 17 */ -#define TRR18 0x0004 /* Deny But Don't Lock Access To Mailbox 18 */ -#define TRR19 0x0008 /* Deny But Don't Lock Access To Mailbox 19 */ -#define TRR20 0x0010 /* Deny But Don't Lock Access To Mailbox 20 */ -#define TRR21 0x0020 /* Deny But Don't Lock Access To Mailbox 21 */ -#define TRR22 0x0040 /* Deny But Don't Lock Access To Mailbox 22 */ -#define TRR23 0x0080 /* Deny But Don't Lock Access To Mailbox 23 */ -#define TRR24 0x0100 /* Deny But Don't Lock Access To Mailbox 24 */ -#define TRR25 0x0200 /* Deny But Don't Lock Access To Mailbox 25 */ -#define TRR26 0x0400 /* Deny But Don't Lock Access To Mailbox 26 */ -#define TRR27 0x0800 /* Deny But Don't Lock Access To Mailbox 27 */ -#define TRR28 0x1000 /* Deny But Don't Lock Access To Mailbox 28 */ -#define TRR29 0x2000 /* Deny But Don't Lock Access To Mailbox 29 */ -#define TRR30 0x4000 /* Deny But Don't Lock Access To Mailbox 30 */ -#define TRR31 0x8000 /* Deny But Don't Lock Access To Mailbox 31 */ - -/* CAN_TRS1 Masks */ -#define TRS0 0x0001 /* Remote Frame Request For Mailbox 0 */ -#define TRS1 0x0002 /* Remote Frame Request For Mailbox 1 */ -#define TRS2 0x0004 /* Remote Frame Request For Mailbox 2 */ -#define TRS3 0x0008 /* Remote Frame Request For Mailbox 3 */ -#define TRS4 0x0010 /* Remote Frame Request For Mailbox 4 */ -#define TRS5 0x0020 /* Remote Frame Request For Mailbox 5 */ -#define TRS6 0x0040 /* Remote Frame Request For Mailbox 6 */ -#define TRS7 0x0080 /* Remote Frame Request For Mailbox 7 */ -#define TRS8 0x0100 /* Remote Frame Request For Mailbox 8 */ -#define TRS9 0x0200 /* Remote Frame Request For Mailbox 9 */ -#define TRS10 0x0400 /* Remote Frame Request For Mailbox 10 */ -#define TRS11 0x0800 /* Remote Frame Request For Mailbox 11 */ -#define TRS12 0x1000 /* Remote Frame Request For Mailbox 12 */ -#define TRS13 0x2000 /* Remote Frame Request For Mailbox 13 */ -#define TRS14 0x4000 /* Remote Frame Request For Mailbox 14 */ -#define TRS15 0x8000 /* Remote Frame Request For Mailbox 15 */ - -/* CAN_TRS2 Masks */ -#define TRS16 0x0001 /* Remote Frame Request For Mailbox 16 */ -#define TRS17 0x0002 /* Remote Frame Request For Mailbox 17 */ -#define TRS18 0x0004 /* Remote Frame Request For Mailbox 18 */ -#define TRS19 0x0008 /* Remote Frame Request For Mailbox 19 */ -#define TRS20 0x0010 /* Remote Frame Request For Mailbox 20 */ -#define TRS21 0x0020 /* Remote Frame Request For Mailbox 21 */ -#define TRS22 0x0040 /* Remote Frame Request For Mailbox 22 */ -#define TRS23 0x0080 /* Remote Frame Request For Mailbox 23 */ -#define TRS24 0x0100 /* Remote Frame Request For Mailbox 24 */ -#define TRS25 0x0200 /* Remote Frame Request For Mailbox 25 */ -#define TRS26 0x0400 /* Remote Frame Request For Mailbox 26 */ -#define TRS27 0x0800 /* Remote Frame Request For Mailbox 27 */ -#define TRS28 0x1000 /* Remote Frame Request For Mailbox 28 */ -#define TRS29 0x2000 /* Remote Frame Request For Mailbox 29 */ -#define TRS30 0x4000 /* Remote Frame Request For Mailbox 30 */ -#define TRS31 0x8000 /* Remote Frame Request For Mailbox 31 */ - -/* CAN_AA1 Masks */ -#define AA0 0x0001 /* Aborted Message In Mailbox 0 */ -#define AA1 0x0002 /* Aborted Message In Mailbox 1 */ -#define AA2 0x0004 /* Aborted Message In Mailbox 2 */ -#define AA3 0x0008 /* Aborted Message In Mailbox 3 */ -#define AA4 0x0010 /* Aborted Message In Mailbox 4 */ -#define AA5 0x0020 /* Aborted Message In Mailbox 5 */ -#define AA6 0x0040 /* Aborted Message In Mailbox 6 */ -#define AA7 0x0080 /* Aborted Message In Mailbox 7 */ -#define AA8 0x0100 /* Aborted Message In Mailbox 8 */ -#define AA9 0x0200 /* Aborted Message In Mailbox 9 */ -#define AA10 0x0400 /* Aborted Message In Mailbox 10 */ -#define AA11 0x0800 /* Aborted Message In Mailbox 11 */ -#define AA12 0x1000 /* Aborted Message In Mailbox 12 */ -#define AA13 0x2000 /* Aborted Message In Mailbox 13 */ -#define AA14 0x4000 /* Aborted Message In Mailbox 14 */ -#define AA15 0x8000 /* Aborted Message In Mailbox 15 */ - -/* CAN_AA2 Masks */ -#define AA16 0x0001 /* Aborted Message In Mailbox 16 */ -#define AA17 0x0002 /* Aborted Message In Mailbox 17 */ -#define AA18 0x0004 /* Aborted Message In Mailbox 18 */ -#define AA19 0x0008 /* Aborted Message In Mailbox 19 */ -#define AA20 0x0010 /* Aborted Message In Mailbox 20 */ -#define AA21 0x0020 /* Aborted Message In Mailbox 21 */ -#define AA22 0x0040 /* Aborted Message In Mailbox 22 */ -#define AA23 0x0080 /* Aborted Message In Mailbox 23 */ -#define AA24 0x0100 /* Aborted Message In Mailbox 24 */ -#define AA25 0x0200 /* Aborted Message In Mailbox 25 */ -#define AA26 0x0400 /* Aborted Message In Mailbox 26 */ -#define AA27 0x0800 /* Aborted Message In Mailbox 27 */ -#define AA28 0x1000 /* Aborted Message In Mailbox 28 */ -#define AA29 0x2000 /* Aborted Message In Mailbox 29 */ -#define AA30 0x4000 /* Aborted Message In Mailbox 30 */ -#define AA31 0x8000 /* Aborted Message In Mailbox 31 */ - -/* CAN_TA1 Masks */ -#define TA0 0x0001 /* Transmit Successful From Mailbox 0 */ -#define TA1 0x0002 /* Transmit Successful From Mailbox 1 */ -#define TA2 0x0004 /* Transmit Successful From Mailbox 2 */ -#define TA3 0x0008 /* Transmit Successful From Mailbox 3 */ -#define TA4 0x0010 /* Transmit Successful From Mailbox 4 */ -#define TA5 0x0020 /* Transmit Successful From Mailbox 5 */ -#define TA6 0x0040 /* Transmit Successful From Mailbox 6 */ -#define TA7 0x0080 /* Transmit Successful From Mailbox 7 */ -#define TA8 0x0100 /* Transmit Successful From Mailbox 8 */ -#define TA9 0x0200 /* Transmit Successful From Mailbox 9 */ -#define TA10 0x0400 /* Transmit Successful From Mailbox 10 */ -#define TA11 0x0800 /* Transmit Successful From Mailbox 11 */ -#define TA12 0x1000 /* Transmit Successful From Mailbox 12 */ -#define TA13 0x2000 /* Transmit Successful From Mailbox 13 */ -#define TA14 0x4000 /* Transmit Successful From Mailbox 14 */ -#define TA15 0x8000 /* Transmit Successful From Mailbox 15 */ - -/* CAN_TA2 Masks */ -#define TA16 0x0001 /* Transmit Successful From Mailbox 16 */ -#define TA17 0x0002 /* Transmit Successful From Mailbox 17 */ -#define TA18 0x0004 /* Transmit Successful From Mailbox 18 */ -#define TA19 0x0008 /* Transmit Successful From Mailbox 19 */ -#define TA20 0x0010 /* Transmit Successful From Mailbox 20 */ -#define TA21 0x0020 /* Transmit Successful From Mailbox 21 */ -#define TA22 0x0040 /* Transmit Successful From Mailbox 22 */ -#define TA23 0x0080 /* Transmit Successful From Mailbox 23 */ -#define TA24 0x0100 /* Transmit Successful From Mailbox 24 */ -#define TA25 0x0200 /* Transmit Successful From Mailbox 25 */ -#define TA26 0x0400 /* Transmit Successful From Mailbox 26 */ -#define TA27 0x0800 /* Transmit Successful From Mailbox 27 */ -#define TA28 0x1000 /* Transmit Successful From Mailbox 28 */ -#define TA29 0x2000 /* Transmit Successful From Mailbox 29 */ -#define TA30 0x4000 /* Transmit Successful From Mailbox 30 */ -#define TA31 0x8000 /* Transmit Successful From Mailbox 31 */ - -/* CAN_MBTD Masks */ -#define TDPTR 0x001F /* Mailbox To Temporarily Disable */ -#define TDA 0x0040 /* Temporary Disable Acknowledge */ -#define TDR 0x0080 /* Temporary Disable Request */ - -/* CAN_RFH1 Masks */ -#define RFH0 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 0 */ -#define RFH1 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 1 */ -#define RFH2 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 2 */ -#define RFH3 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 3 */ -#define RFH4 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 4 */ -#define RFH5 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 5 */ -#define RFH6 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 6 */ -#define RFH7 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 7 */ -#define RFH8 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 8 */ -#define RFH9 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 9 */ -#define RFH10 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 10 */ -#define RFH11 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 11 */ -#define RFH12 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 12 */ -#define RFH13 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 13 */ -#define RFH14 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 14 */ -#define RFH15 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 15 */ - -/* CAN_RFH2 Masks */ -#define RFH16 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 16 */ -#define RFH17 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 17 */ -#define RFH18 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 18 */ -#define RFH19 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 19 */ -#define RFH20 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 20 */ -#define RFH21 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 21 */ -#define RFH22 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 22 */ -#define RFH23 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 23 */ -#define RFH24 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 24 */ -#define RFH25 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 25 */ -#define RFH26 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 26 */ -#define RFH27 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 27 */ -#define RFH28 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 28 */ -#define RFH29 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 29 */ -#define RFH30 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 30 */ -#define RFH31 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 31 */ - -/* CAN_MBTIF1 Masks */ -#define MBTIF0 0x0001 /* TX Interrupt Active In Mailbox 0 */ -#define MBTIF1 0x0002 /* TX Interrupt Active In Mailbox 1 */ -#define MBTIF2 0x0004 /* TX Interrupt Active In Mailbox 2 */ -#define MBTIF3 0x0008 /* TX Interrupt Active In Mailbox 3 */ -#define MBTIF4 0x0010 /* TX Interrupt Active In Mailbox 4 */ -#define MBTIF5 0x0020 /* TX Interrupt Active In Mailbox 5 */ -#define MBTIF6 0x0040 /* TX Interrupt Active In Mailbox 6 */ -#define MBTIF7 0x0080 /* TX Interrupt Active In Mailbox 7 */ -#define MBTIF8 0x0100 /* TX Interrupt Active In Mailbox 8 */ -#define MBTIF9 0x0200 /* TX Interrupt Active In Mailbox 9 */ -#define MBTIF10 0x0400 /* TX Interrupt Active In Mailbox 10 */ -#define MBTIF11 0x0800 /* TX Interrupt Active In Mailbox 11 */ -#define MBTIF12 0x1000 /* TX Interrupt Active In Mailbox 12 */ -#define MBTIF13 0x2000 /* TX Interrupt Active In Mailbox 13 */ -#define MBTIF14 0x4000 /* TX Interrupt Active In Mailbox 14 */ -#define MBTIF15 0x8000 /* TX Interrupt Active In Mailbox 15 */ - -/* CAN_MBTIF2 Masks */ -#define MBTIF16 0x0001 /* TX Interrupt Active In Mailbox 16 */ -#define MBTIF17 0x0002 /* TX Interrupt Active In Mailbox 17 */ -#define MBTIF18 0x0004 /* TX Interrupt Active In Mailbox 18 */ -#define MBTIF19 0x0008 /* TX Interrupt Active In Mailbox 19 */ -#define MBTIF20 0x0010 /* TX Interrupt Active In Mailbox 20 */ -#define MBTIF21 0x0020 /* TX Interrupt Active In Mailbox 21 */ -#define MBTIF22 0x0040 /* TX Interrupt Active In Mailbox 22 */ -#define MBTIF23 0x0080 /* TX Interrupt Active In Mailbox 23 */ -#define MBTIF24 0x0100 /* TX Interrupt Active In Mailbox 24 */ -#define MBTIF25 0x0200 /* TX Interrupt Active In Mailbox 25 */ -#define MBTIF26 0x0400 /* TX Interrupt Active In Mailbox 26 */ -#define MBTIF27 0x0800 /* TX Interrupt Active In Mailbox 27 */ -#define MBTIF28 0x1000 /* TX Interrupt Active In Mailbox 28 */ -#define MBTIF29 0x2000 /* TX Interrupt Active In Mailbox 29 */ -#define MBTIF30 0x4000 /* TX Interrupt Active In Mailbox 30 */ -#define MBTIF31 0x8000 /* TX Interrupt Active In Mailbox 31 */ - -/* CAN_MBRIF1 Masks */ -#define MBRIF0 0x0001 /* RX Interrupt Active In Mailbox 0 */ -#define MBRIF1 0x0002 /* RX Interrupt Active In Mailbox 1 */ -#define MBRIF2 0x0004 /* RX Interrupt Active In Mailbox 2 */ -#define MBRIF3 0x0008 /* RX Interrupt Active In Mailbox 3 */ -#define MBRIF4 0x0010 /* RX Interrupt Active In Mailbox 4 */ -#define MBRIF5 0x0020 /* RX Interrupt Active In Mailbox 5 */ -#define MBRIF6 0x0040 /* RX Interrupt Active In Mailbox 6 */ -#define MBRIF7 0x0080 /* RX Interrupt Active In Mailbox 7 */ -#define MBRIF8 0x0100 /* RX Interrupt Active In Mailbox 8 */ -#define MBRIF9 0x0200 /* RX Interrupt Active In Mailbox 9 */ -#define MBRIF10 0x0400 /* RX Interrupt Active In Mailbox 10 */ -#define MBRIF11 0x0800 /* RX Interrupt Active In Mailbox 11 */ -#define MBRIF12 0x1000 /* RX Interrupt Active In Mailbox 12 */ -#define MBRIF13 0x2000 /* RX Interrupt Active In Mailbox 13 */ -#define MBRIF14 0x4000 /* RX Interrupt Active In Mailbox 14 */ -#define MBRIF15 0x8000 /* RX Interrupt Active In Mailbox 15 */ - -/* CAN_MBRIF2 Masks */ -#define MBRIF16 0x0001 /* RX Interrupt Active In Mailbox 16 */ -#define MBRIF17 0x0002 /* RX Interrupt Active In Mailbox 17 */ -#define MBRIF18 0x0004 /* RX Interrupt Active In Mailbox 18 */ -#define MBRIF19 0x0008 /* RX Interrupt Active In Mailbox 19 */ -#define MBRIF20 0x0010 /* RX Interrupt Active In Mailbox 20 */ -#define MBRIF21 0x0020 /* RX Interrupt Active In Mailbox 21 */ -#define MBRIF22 0x0040 /* RX Interrupt Active In Mailbox 22 */ -#define MBRIF23 0x0080 /* RX Interrupt Active In Mailbox 23 */ -#define MBRIF24 0x0100 /* RX Interrupt Active In Mailbox 24 */ -#define MBRIF25 0x0200 /* RX Interrupt Active In Mailbox 25 */ -#define MBRIF26 0x0400 /* RX Interrupt Active In Mailbox 26 */ -#define MBRIF27 0x0800 /* RX Interrupt Active In Mailbox 27 */ -#define MBRIF28 0x1000 /* RX Interrupt Active In Mailbox 28 */ -#define MBRIF29 0x2000 /* RX Interrupt Active In Mailbox 29 */ -#define MBRIF30 0x4000 /* RX Interrupt Active In Mailbox 30 */ -#define MBRIF31 0x8000 /* RX Interrupt Active In Mailbox 31 */ - -/* CAN_MBIM1 Masks */ -#define MBIM0 0x0001 /* Enable Interrupt For Mailbox 0 */ -#define MBIM1 0x0002 /* Enable Interrupt For Mailbox 1 */ -#define MBIM2 0x0004 /* Enable Interrupt For Mailbox 2 */ -#define MBIM3 0x0008 /* Enable Interrupt For Mailbox 3 */ -#define MBIM4 0x0010 /* Enable Interrupt For Mailbox 4 */ -#define MBIM5 0x0020 /* Enable Interrupt For Mailbox 5 */ -#define MBIM6 0x0040 /* Enable Interrupt For Mailbox 6 */ -#define MBIM7 0x0080 /* Enable Interrupt For Mailbox 7 */ -#define MBIM8 0x0100 /* Enable Interrupt For Mailbox 8 */ -#define MBIM9 0x0200 /* Enable Interrupt For Mailbox 9 */ -#define MBIM10 0x0400 /* Enable Interrupt For Mailbox 10 */ -#define MBIM11 0x0800 /* Enable Interrupt For Mailbox 11 */ -#define MBIM12 0x1000 /* Enable Interrupt For Mailbox 12 */ -#define MBIM13 0x2000 /* Enable Interrupt For Mailbox 13 */ -#define MBIM14 0x4000 /* Enable Interrupt For Mailbox 14 */ -#define MBIM15 0x8000 /* Enable Interrupt For Mailbox 15 */ - -/* CAN_MBIM2 Masks */ -#define MBIM16 0x0001 /* Enable Interrupt For Mailbox 16 */ -#define MBIM17 0x0002 /* Enable Interrupt For Mailbox 17 */ -#define MBIM18 0x0004 /* Enable Interrupt For Mailbox 18 */ -#define MBIM19 0x0008 /* Enable Interrupt For Mailbox 19 */ -#define MBIM20 0x0010 /* Enable Interrupt For Mailbox 20 */ -#define MBIM21 0x0020 /* Enable Interrupt For Mailbox 21 */ -#define MBIM22 0x0040 /* Enable Interrupt For Mailbox 22 */ -#define MBIM23 0x0080 /* Enable Interrupt For Mailbox 23 */ -#define MBIM24 0x0100 /* Enable Interrupt For Mailbox 24 */ -#define MBIM25 0x0200 /* Enable Interrupt For Mailbox 25 */ -#define MBIM26 0x0400 /* Enable Interrupt For Mailbox 26 */ -#define MBIM27 0x0800 /* Enable Interrupt For Mailbox 27 */ -#define MBIM28 0x1000 /* Enable Interrupt For Mailbox 28 */ -#define MBIM29 0x2000 /* Enable Interrupt For Mailbox 29 */ -#define MBIM30 0x4000 /* Enable Interrupt For Mailbox 30 */ -#define MBIM31 0x8000 /* Enable Interrupt For Mailbox 31 */ - -/* CAN_GIM Masks */ -#define EWTIM 0x0001 /* Enable TX Error Count Interrupt */ -#define EWRIM 0x0002 /* Enable RX Error Count Interrupt */ -#define EPIM 0x0004 /* Enable Error-Passive Mode Interrupt */ -#define BOIM 0x0008 /* Enable Bus Off Interrupt */ -#define WUIM 0x0010 /* Enable Wake-Up Interrupt */ -#define UIAIM 0x0020 /* Enable Access To Unimplemented Address Interrupt */ -#define AAIM 0x0040 /* Enable Abort Acknowledge Interrupt */ -#define RMLIM 0x0080 /* Enable RX Message Lost Interrupt */ -#define UCEIM 0x0100 /* Enable Universal Counter Overflow Interrupt */ -#define EXTIM 0x0200 /* Enable External Trigger Output Interrupt */ -#define ADIM 0x0400 /* Enable Access Denied Interrupt */ - -/* CAN_GIS Masks */ -#define EWTIS 0x0001 /* TX Error Count IRQ Status */ -#define EWRIS 0x0002 /* RX Error Count IRQ Status */ -#define EPIS 0x0004 /* Error-Passive Mode IRQ Status */ -#define BOIS 0x0008 /* Bus Off IRQ Status */ -#define WUIS 0x0010 /* Wake-Up IRQ Status */ -#define UIAIS 0x0020 /* Access To Unimplemented Address IRQ Status */ -#define AAIS 0x0040 /* Abort Acknowledge IRQ Status */ -#define RMLIS 0x0080 /* RX Message Lost IRQ Status */ -#define UCEIS 0x0100 /* Universal Counter Overflow IRQ Status */ -#define EXTIS 0x0200 /* External Trigger Output IRQ Status */ -#define ADIS 0x0400 /* Access Denied IRQ Status */ - -/* CAN_GIF Masks */ -#define EWTIF 0x0001 /* TX Error Count IRQ Flag */ -#define EWRIF 0x0002 /* RX Error Count IRQ Flag */ -#define EPIF 0x0004 /* Error-Passive Mode IRQ Flag */ -#define BOIF 0x0008 /* Bus Off IRQ Flag */ -#define WUIF 0x0010 /* Wake-Up IRQ Flag */ -#define UIAIF 0x0020 /* Access To Unimplemented Address IRQ Flag */ -#define AAIF 0x0040 /* Abort Acknowledge IRQ Flag */ -#define RMLIF 0x0080 /* RX Message Lost IRQ Flag */ -#define UCEIF 0x0100 /* Universal Counter Overflow IRQ Flag */ -#define EXTIF 0x0200 /* External Trigger Output IRQ Flag */ -#define ADIF 0x0400 /* Access Denied IRQ Flag */ - -/* CAN_UCCNF Masks */ -#define UCCNF 0x000F /* Universal Counter Mode */ -#define UC_STAMP 0x0001 /* Timestamp Mode */ -#define UC_WDOG 0x0002 /* Watchdog Mode */ -#define UC_AUTOTX 0x0003 /* Auto-Transmit Mode */ -#define UC_ERROR 0x0006 /* CAN Error Frame Count */ -#define UC_OVER 0x0007 /* CAN Overload Frame Count */ -#define UC_LOST 0x0008 /* Arbitration Lost During TX Count */ -#define UC_AA 0x0009 /* TX Abort Count */ -#define UC_TA 0x000A /* TX Successful Count */ -#define UC_REJECT 0x000B /* RX Message Rejected Count */ -#define UC_RML 0x000C /* RX Message Lost Count */ -#define UC_RX 0x000D /* Total Successful RX Messages Count */ -#define UC_RMP 0x000E /* Successful RX W/Matching ID Count */ -#define UC_ALL 0x000F /* Correct Message On CAN Bus Line Count */ -#define UCRC 0x0020 /* Universal Counter Reload/Clear */ -#define UCCT 0x0040 /* Universal Counter CAN Trigger */ -#define UCE 0x0080 /* Universal Counter Enable */ - -/* CAN_ESR Masks */ -#define ACKE 0x0004 /* Acknowledge Error */ -#define SER 0x0008 /* Stuff Error */ -#define CRCE 0x0010 /* CRC Error */ -#define SA0 0x0020 /* Stuck At Dominant Error */ -#define BEF 0x0040 /* Bit Error Flag */ -#define FER 0x0080 /* Form Error Flag */ - -/* CAN_EWR Masks */ -#define EWLREC 0x00FF /* RX Error Count Limit (For EWRIS) */ -#define EWLTEC 0xFF00 /* TX Error Count Limit (For EWTIS) */ - #endif /* _DEF_BF539_H */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index ab04d137fd8b..0ed06c2366fe 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h @@ -2104,677 +2104,6 @@ #define ECCCNT 0x3ff /* Transfer Count */ -/* Bit masks for CAN0_CONTROL */ - -#define SRS 0x1 /* Software Reset */ -#define DNM 0x2 /* DeviceNet Mode */ -#define ABO 0x4 /* Auto Bus On */ -#define WBA 0x10 /* Wakeup On CAN Bus Activity */ -#define SMR 0x20 /* Sleep Mode Request */ -#define CSR 0x40 /* CAN Suspend Mode Request */ -#define CCR 0x80 /* CAN Configuration Mode Request */ - -/* Bit masks for CAN0_STATUS */ - -#define WT 0x1 /* CAN Transmit Warning Flag */ -#define WR 0x2 /* CAN Receive Warning Flag */ -#define EP 0x4 /* CAN Error Passive Mode */ -#define EBO 0x8 /* CAN Error Bus Off Mode */ -#define CSA 0x40 /* CAN Suspend Mode Acknowledge */ -#define CCA 0x80 /* CAN Configuration Mode Acknowledge */ -#define MBPTR 0x1f00 /* Mailbox Pointer */ -#define TRM 0x4000 /* Transmit Mode Status */ -#define REC 0x8000 /* Receive Mode Status */ - -/* Bit masks for CAN0_DEBUG */ - -#define DEC 0x1 /* Disable Transmit/Receive Error Counters */ -#define DRI 0x2 /* Disable CANRX Input Pin */ -#define DTO 0x4 /* Disable CANTX Output Pin */ -#define DIL 0x8 /* Disable Internal Loop */ -#define MAA 0x10 /* Mode Auto-Acknowledge */ -#define MRB 0x20 /* Mode Read Back */ -#define CDE 0x8000 /* CAN Debug Mode Enable */ - -/* Bit masks for CAN0_CLOCK */ - -#define BRP 0x3ff /* CAN Bit Rate Prescaler */ - -/* Bit masks for CAN0_TIMING */ - -#define SJW 0x300 /* Synchronization Jump Width */ -#define SAM 0x80 /* Sampling */ -#define TSEG2 0x70 /* Time Segment 2 */ -#define TSEG1 0xf /* Time Segment 1 */ - -/* Bit masks for CAN0_INTR */ - -#define CANRX 0x80 /* Serial Input From Transceiver */ -#define CANTX 0x40 /* Serial Output To Transceiver */ -#define SMACK 0x8 /* Sleep Mode Acknowledge */ -#define GIRQ 0x4 /* Global Interrupt Request Status */ -#define MBTIRQ 0x2 /* Mailbox Transmit Interrupt Request */ -#define MBRIRQ 0x1 /* Mailbox Receive Interrupt Request */ - -/* Bit masks for CAN0_GIM */ - -#define EWTIM 0x1 /* Error Warning Transmit Interrupt Mask */ -#define EWRIM 0x2 /* Error Warning Receive Interrupt Mask */ -#define EPIM 0x4 /* Error Passive Interrupt Mask */ -#define BOIM 0x8 /* Bus Off Interrupt Mask */ -#define WUIM 0x10 /* Wakeup Interrupt Mask */ -#define UIAIM 0x20 /* Unimplemented Address Interrupt Mask */ -#define AAIM 0x40 /* Abort Acknowledge Interrupt Mask */ -#define RMLIM 0x80 /* Receive Message Lost Interrupt Mask */ -#define UCEIM 0x100 /* Universal Counter Exceeded Interrupt Mask */ -#define ADIM 0x400 /* Access Denied Interrupt Mask */ - -/* Bit masks for CAN0_GIS */ - -#define EWTIS 0x1 /* Error Warning Transmit Interrupt Status */ -#define EWRIS 0x2 /* Error Warning Receive Interrupt Status */ -#define EPIS 0x4 /* Error Passive Interrupt Status */ -#define BOIS 0x8 /* Bus Off Interrupt Status */ -#define WUIS 0x10 /* Wakeup Interrupt Status */ -#define UIAIS 0x20 /* Unimplemented Address Interrupt Status */ -#define AAIS 0x40 /* Abort Acknowledge Interrupt Status */ -#define RMLIS 0x80 /* Receive Message Lost Interrupt Status */ -#define UCEIS 0x100 /* Universal Counter Exceeded Interrupt Status */ -#define ADIS 0x400 /* Access Denied Interrupt Status */ - -/* Bit masks for CAN0_GIF */ - -#define EWTIF 0x1 /* Error Warning Transmit Interrupt Flag */ -#define EWRIF 0x2 /* Error Warning Receive Interrupt Flag */ -#define EPIF 0x4 /* Error Passive Interrupt Flag */ -#define BOIF 0x8 /* Bus Off Interrupt Flag */ -#define WUIF 0x10 /* Wakeup Interrupt Flag */ -#define UIAIF 0x20 /* Unimplemented Address Interrupt Flag */ -#define AAIF 0x40 /* Abort Acknowledge Interrupt Flag */ -#define RMLIF 0x80 /* Receive Message Lost Interrupt Flag */ -#define UCEIF 0x100 /* Universal Counter Exceeded Interrupt Flag */ -#define ADIF 0x400 /* Access Denied Interrupt Flag */ - -/* Bit masks for CAN0_MBTD */ - -#define TDR 0x80 /* Temporary Disable Request */ -#define TDA 0x40 /* Temporary Disable Acknowledge */ -#define TDPTR 0x1f /* Temporary Disable Pointer */ - -/* Bit masks for CAN0_UCCNF */ - -#define UCCNF 0xf /* Universal Counter Configuration */ -#define UCRC 0x20 /* Universal Counter Reload/Clear */ -#define UCCT 0x40 /* Universal Counter CAN Trigger */ -#define UCE 0x80 /* Universal Counter Enable */ - -/* Bit masks for CAN0_CEC */ - -#define RXECNT 0xff /* Receive Error Counter */ -#define TXECNT 0xff00 /* Transmit Error Counter */ - -/* Bit masks for CAN0_ESR */ - -#define FER 0x80 /* Form Error */ -#define BEF 0x40 /* Bit Error Flag */ -#define SA0 0x20 /* Stuck At Dominant */ -#define CRCE 0x10 /* CRC Error */ -#define SER 0x8 /* Stuff Bit Error */ -#define ACKE 0x4 /* Acknowledge Error */ - -/* Bit masks for CAN0_EWR */ - -#define EWLTEC 0xff00 /* Transmit Error Warning Limit */ -#define EWLREC 0xff /* Receive Error Warning Limit */ - -/* Bit masks for CAN0_AMxx_H */ - -#define FDF 0x8000 /* Filter On Data Field */ -#define FMD 0x4000 /* Full Mask Data */ -#define AMIDE 0x2000 /* Acceptance Mask Identifier Extension */ -#define BASEID 0x1ffc /* Base Identifier */ -#define EXTID_HI 0x3 /* Extended Identifier High Bits */ - -/* Bit masks for CAN0_AMxx_L */ - -#define EXTID_LO 0xffff /* Extended Identifier Low Bits */ -#define DFM 0xffff /* Data Field Mask */ - -/* Bit masks for CAN0_MBxx_ID1 */ - -#define AME 0x8000 /* Acceptance Mask Enable */ -#define RTR 0x4000 /* Remote Transmission Request */ -#define IDE 0x2000 /* Identifier Extension */ -#define BASEID 0x1ffc /* Base Identifier */ -#define EXTID_HI 0x3 /* Extended Identifier High Bits */ - -/* Bit masks for CAN0_MBxx_ID0 */ - -#define EXTID_LO 0xffff /* Extended Identifier Low Bits */ -#define DFM 0xffff /* Data Field Mask */ - -/* Bit masks for CAN0_MBxx_TIMESTAMP */ - -#define TSV 0xffff /* Time Stamp Value */ - -/* Bit masks for CAN0_MBxx_LENGTH */ - -#define DLC 0xf /* Data Length Code */ - -/* Bit masks for CAN0_MBxx_DATA3 */ - -#define CAN_BYTE0 0xff00 /* Data Field Byte 0 */ -#define CAN_BYTE1 0xff /* Data Field Byte 1 */ - -/* Bit masks for CAN0_MBxx_DATA2 */ - -#define CAN_BYTE2 0xff00 /* Data Field Byte 2 */ -#define CAN_BYTE3 0xff /* Data Field Byte 3 */ - -/* Bit masks for CAN0_MBxx_DATA1 */ - -#define CAN_BYTE4 0xff00 /* Data Field Byte 4 */ -#define CAN_BYTE5 0xff /* Data Field Byte 5 */ - -/* Bit masks for CAN0_MBxx_DATA0 */ - -#define CAN_BYTE6 0xff00 /* Data Field Byte 6 */ -#define CAN_BYTE7 0xff /* Data Field Byte 7 */ - -/* Bit masks for CAN0_MC1 */ - -#define MC0 0x1 /* Mailbox 0 Enable */ -#define MC1 0x2 /* Mailbox 1 Enable */ -#define MC2 0x4 /* Mailbox 2 Enable */ -#define MC3 0x8 /* Mailbox 3 Enable */ -#define MC4 0x10 /* Mailbox 4 Enable */ -#define MC5 0x20 /* Mailbox 5 Enable */ -#define MC6 0x40 /* Mailbox 6 Enable */ -#define MC7 0x80 /* Mailbox 7 Enable */ -#define MC8 0x100 /* Mailbox 8 Enable */ -#define MC9 0x200 /* Mailbox 9 Enable */ -#define MC10 0x400 /* Mailbox 10 Enable */ -#define MC11 0x800 /* Mailbox 11 Enable */ -#define MC12 0x1000 /* Mailbox 12 Enable */ -#define MC13 0x2000 /* Mailbox 13 Enable */ -#define MC14 0x4000 /* Mailbox 14 Enable */ -#define MC15 0x8000 /* Mailbox 15 Enable */ - -/* Bit masks for CAN0_MC2 */ - -#define MC16 0x1 /* Mailbox 16 Enable */ -#define MC17 0x2 /* Mailbox 17 Enable */ -#define MC18 0x4 /* Mailbox 18 Enable */ -#define MC19 0x8 /* Mailbox 19 Enable */ -#define MC20 0x10 /* Mailbox 20 Enable */ -#define MC21 0x20 /* Mailbox 21 Enable */ -#define MC22 0x40 /* Mailbox 22 Enable */ -#define MC23 0x80 /* Mailbox 23 Enable */ -#define MC24 0x100 /* Mailbox 24 Enable */ -#define MC25 0x200 /* Mailbox 25 Enable */ -#define MC26 0x400 /* Mailbox 26 Enable */ -#define MC27 0x800 /* Mailbox 27 Enable */ -#define MC28 0x1000 /* Mailbox 28 Enable */ -#define MC29 0x2000 /* Mailbox 29 Enable */ -#define MC30 0x4000 /* Mailbox 30 Enable */ -#define MC31 0x8000 /* Mailbox 31 Enable */ - -/* Bit masks for CAN0_MD1 */ - -#define MD0 0x1 /* Mailbox 0 Receive Enable */ -#define MD1 0x2 /* Mailbox 1 Receive Enable */ -#define MD2 0x4 /* Mailbox 2 Receive Enable */ -#define MD3 0x8 /* Mailbox 3 Receive Enable */ -#define MD4 0x10 /* Mailbox 4 Receive Enable */ -#define MD5 0x20 /* Mailbox 5 Receive Enable */ -#define MD6 0x40 /* Mailbox 6 Receive Enable */ -#define MD7 0x80 /* Mailbox 7 Receive Enable */ -#define MD8 0x100 /* Mailbox 8 Receive Enable */ -#define MD9 0x200 /* Mailbox 9 Receive Enable */ -#define MD10 0x400 /* Mailbox 10 Receive Enable */ -#define MD11 0x800 /* Mailbox 11 Receive Enable */ -#define MD12 0x1000 /* Mailbox 12 Receive Enable */ -#define MD13 0x2000 /* Mailbox 13 Receive Enable */ -#define MD14 0x4000 /* Mailbox 14 Receive Enable */ -#define MD15 0x8000 /* Mailbox 15 Receive Enable */ - -/* Bit masks for CAN0_MD2 */ - -#define MD16 0x1 /* Mailbox 16 Receive Enable */ -#define MD17 0x2 /* Mailbox 17 Receive Enable */ -#define MD18 0x4 /* Mailbox 18 Receive Enable */ -#define MD19 0x8 /* Mailbox 19 Receive Enable */ -#define MD20 0x10 /* Mailbox 20 Receive Enable */ -#define MD21 0x20 /* Mailbox 21 Receive Enable */ -#define MD22 0x40 /* Mailbox 22 Receive Enable */ -#define MD23 0x80 /* Mailbox 23 Receive Enable */ -#define MD24 0x100 /* Mailbox 24 Receive Enable */ -#define MD25 0x200 /* Mailbox 25 Receive Enable */ -#define MD26 0x400 /* Mailbox 26 Receive Enable */ -#define MD27 0x800 /* Mailbox 27 Receive Enable */ -#define MD28 0x1000 /* Mailbox 28 Receive Enable */ -#define MD29 0x2000 /* Mailbox 29 Receive Enable */ -#define MD30 0x4000 /* Mailbox 30 Receive Enable */ -#define MD31 0x8000 /* Mailbox 31 Receive Enable */ - -/* Bit masks for CAN0_RMP1 */ - -#define RMP0 0x1 /* Mailbox 0 Receive Message Pending */ -#define RMP1 0x2 /* Mailbox 1 Receive Message Pending */ -#define RMP2 0x4 /* Mailbox 2 Receive Message Pending */ -#define RMP3 0x8 /* Mailbox 3 Receive Message Pending */ -#define RMP4 0x10 /* Mailbox 4 Receive Message Pending */ -#define RMP5 0x20 /* Mailbox 5 Receive Message Pending */ -#define RMP6 0x40 /* Mailbox 6 Receive Message Pending */ -#define RMP7 0x80 /* Mailbox 7 Receive Message Pending */ -#define RMP8 0x100 /* Mailbox 8 Receive Message Pending */ -#define RMP9 0x200 /* Mailbox 9 Receive Message Pending */ -#define RMP10 0x400 /* Mailbox 10 Receive Message Pending */ -#define RMP11 0x800 /* Mailbox 11 Receive Message Pending */ -#define RMP12 0x1000 /* Mailbox 12 Receive Message Pending */ -#define RMP13 0x2000 /* Mailbox 13 Receive Message Pending */ -#define RMP14 0x4000 /* Mailbox 14 Receive Message Pending */ -#define RMP15 0x8000 /* Mailbox 15 Receive Message Pending */ - -/* Bit masks for CAN0_RMP2 */ - -#define RMP16 0x1 /* Mailbox 16 Receive Message Pending */ -#define RMP17 0x2 /* Mailbox 17 Receive Message Pending */ -#define RMP18 0x4 /* Mailbox 18 Receive Message Pending */ -#define RMP19 0x8 /* Mailbox 19 Receive Message Pending */ -#define RMP20 0x10 /* Mailbox 20 Receive Message Pending */ -#define RMP21 0x20 /* Mailbox 21 Receive Message Pending */ -#define RMP22 0x40 /* Mailbox 22 Receive Message Pending */ -#define RMP23 0x80 /* Mailbox 23 Receive Message Pending */ -#define RMP24 0x100 /* Mailbox 24 Receive Message Pending */ -#define RMP25 0x200 /* Mailbox 25 Receive Message Pending */ -#define RMP26 0x400 /* Mailbox 26 Receive Message Pending */ -#define RMP27 0x800 /* Mailbox 27 Receive Message Pending */ -#define RMP28 0x1000 /* Mailbox 28 Receive Message Pending */ -#define RMP29 0x2000 /* Mailbox 29 Receive Message Pending */ -#define RMP30 0x4000 /* Mailbox 30 Receive Message Pending */ -#define RMP31 0x8000 /* Mailbox 31 Receive Message Pending */ - -/* Bit masks for CAN0_RML1 */ - -#define RML0 0x1 /* Mailbox 0 Receive Message Lost */ -#define RML1 0x2 /* Mailbox 1 Receive Message Lost */ -#define RML2 0x4 /* Mailbox 2 Receive Message Lost */ -#define RML3 0x8 /* Mailbox 3 Receive Message Lost */ -#define RML4 0x10 /* Mailbox 4 Receive Message Lost */ -#define RML5 0x20 /* Mailbox 5 Receive Message Lost */ -#define RML6 0x40 /* Mailbox 6 Receive Message Lost */ -#define RML7 0x80 /* Mailbox 7 Receive Message Lost */ -#define RML8 0x100 /* Mailbox 8 Receive Message Lost */ -#define RML9 0x200 /* Mailbox 9 Receive Message Lost */ -#define RML10 0x400 /* Mailbox 10 Receive Message Lost */ -#define RML11 0x800 /* Mailbox 11 Receive Message Lost */ -#define RML12 0x1000 /* Mailbox 12 Receive Message Lost */ -#define RML13 0x2000 /* Mailbox 13 Receive Message Lost */ -#define RML14 0x4000 /* Mailbox 14 Receive Message Lost */ -#define RML15 0x8000 /* Mailbox 15 Receive Message Lost */ - -/* Bit masks for CAN0_RML2 */ - -#define RML16 0x1 /* Mailbox 16 Receive Message Lost */ -#define RML17 0x2 /* Mailbox 17 Receive Message Lost */ -#define RML18 0x4 /* Mailbox 18 Receive Message Lost */ -#define RML19 0x8 /* Mailbox 19 Receive Message Lost */ -#define RML20 0x10 /* Mailbox 20 Receive Message Lost */ -#define RML21 0x20 /* Mailbox 21 Receive Message Lost */ -#define RML22 0x40 /* Mailbox 22 Receive Message Lost */ -#define RML23 0x80 /* Mailbox 23 Receive Message Lost */ -#define RML24 0x100 /* Mailbox 24 Receive Message Lost */ -#define RML25 0x200 /* Mailbox 25 Receive Message Lost */ -#define RML26 0x400 /* Mailbox 26 Receive Message Lost */ -#define RML27 0x800 /* Mailbox 27 Receive Message Lost */ -#define RML28 0x1000 /* Mailbox 28 Receive Message Lost */ -#define RML29 0x2000 /* Mailbox 29 Receive Message Lost */ -#define RML30 0x4000 /* Mailbox 30 Receive Message Lost */ -#define RML31 0x8000 /* Mailbox 31 Receive Message Lost */ - -/* Bit masks for CAN0_OPSS1 */ - -#define OPSS0 0x1 /* Mailbox 0 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS1 0x2 /* Mailbox 1 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS2 0x4 /* Mailbox 2 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS3 0x8 /* Mailbox 3 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS4 0x10 /* Mailbox 4 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS5 0x20 /* Mailbox 5 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS6 0x40 /* Mailbox 6 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS7 0x80 /* Mailbox 7 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS8 0x100 /* Mailbox 8 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS9 0x200 /* Mailbox 9 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS10 0x400 /* Mailbox 10 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS11 0x800 /* Mailbox 11 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS12 0x1000 /* Mailbox 12 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS13 0x2000 /* Mailbox 13 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS14 0x4000 /* Mailbox 14 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS15 0x8000 /* Mailbox 15 Overwrite Protection/Single-Shot Transmission Enable */ - -/* Bit masks for CAN0_OPSS2 */ - -#define OPSS16 0x1 /* Mailbox 16 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS17 0x2 /* Mailbox 17 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS18 0x4 /* Mailbox 18 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS19 0x8 /* Mailbox 19 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS20 0x10 /* Mailbox 20 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS21 0x20 /* Mailbox 21 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS22 0x40 /* Mailbox 22 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS23 0x80 /* Mailbox 23 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS24 0x100 /* Mailbox 24 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS25 0x200 /* Mailbox 25 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS26 0x400 /* Mailbox 26 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS27 0x800 /* Mailbox 27 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS28 0x1000 /* Mailbox 28 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS29 0x2000 /* Mailbox 29 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS30 0x4000 /* Mailbox 30 Overwrite Protection/Single-Shot Transmission Enable */ -#define OPSS31 0x8000 /* Mailbox 31 Overwrite Protection/Single-Shot Transmission Enable */ - -/* Bit masks for CAN0_TRS1 */ - -#define TRS0 0x1 /* Mailbox 0 Transmit Request Set */ -#define TRS1 0x2 /* Mailbox 1 Transmit Request Set */ -#define TRS2 0x4 /* Mailbox 2 Transmit Request Set */ -#define TRS3 0x8 /* Mailbox 3 Transmit Request Set */ -#define TRS4 0x10 /* Mailbox 4 Transmit Request Set */ -#define TRS5 0x20 /* Mailbox 5 Transmit Request Set */ -#define TRS6 0x40 /* Mailbox 6 Transmit Request Set */ -#define TRS7 0x80 /* Mailbox 7 Transmit Request Set */ -#define TRS8 0x100 /* Mailbox 8 Transmit Request Set */ -#define TRS9 0x200 /* Mailbox 9 Transmit Request Set */ -#define TRS10 0x400 /* Mailbox 10 Transmit Request Set */ -#define TRS11 0x800 /* Mailbox 11 Transmit Request Set */ -#define TRS12 0x1000 /* Mailbox 12 Transmit Request Set */ -#define TRS13 0x2000 /* Mailbox 13 Transmit Request Set */ -#define TRS14 0x4000 /* Mailbox 14 Transmit Request Set */ -#define TRS15 0x8000 /* Mailbox 15 Transmit Request Set */ - -/* Bit masks for CAN0_TRS2 */ - -#define TRS16 0x1 /* Mailbox 16 Transmit Request Set */ -#define TRS17 0x2 /* Mailbox 17 Transmit Request Set */ -#define TRS18 0x4 /* Mailbox 18 Transmit Request Set */ -#define TRS19 0x8 /* Mailbox 19 Transmit Request Set */ -#define TRS20 0x10 /* Mailbox 20 Transmit Request Set */ -#define TRS21 0x20 /* Mailbox 21 Transmit Request Set */ -#define TRS22 0x40 /* Mailbox 22 Transmit Request Set */ -#define TRS23 0x80 /* Mailbox 23 Transmit Request Set */ -#define TRS24 0x100 /* Mailbox 24 Transmit Request Set */ -#define TRS25 0x200 /* Mailbox 25 Transmit Request Set */ -#define TRS26 0x400 /* Mailbox 26 Transmit Request Set */ -#define TRS27 0x800 /* Mailbox 27 Transmit Request Set */ -#define TRS28 0x1000 /* Mailbox 28 Transmit Request Set */ -#define TRS29 0x2000 /* Mailbox 29 Transmit Request Set */ -#define TRS30 0x4000 /* Mailbox 30 Transmit Request Set */ -#define TRS31 0x8000 /* Mailbox 31 Transmit Request Set */ - -/* Bit masks for CAN0_TRR1 */ - -#define TRR0 0x1 /* Mailbox 0 Transmit Request Reset */ -#define TRR1 0x2 /* Mailbox 1 Transmit Request Reset */ -#define TRR2 0x4 /* Mailbox 2 Transmit Request Reset */ -#define TRR3 0x8 /* Mailbox 3 Transmit Request Reset */ -#define TRR4 0x10 /* Mailbox 4 Transmit Request Reset */ -#define TRR5 0x20 /* Mailbox 5 Transmit Request Reset */ -#define TRR6 0x40 /* Mailbox 6 Transmit Request Reset */ -#define TRR7 0x80 /* Mailbox 7 Transmit Request Reset */ -#define TRR8 0x100 /* Mailbox 8 Transmit Request Reset */ -#define TRR9 0x200 /* Mailbox 9 Transmit Request Reset */ -#define TRR10 0x400 /* Mailbox 10 Transmit Request Reset */ -#define TRR11 0x800 /* Mailbox 11 Transmit Request Reset */ -#define TRR12 0x1000 /* Mailbox 12 Transmit Request Reset */ -#define TRR13 0x2000 /* Mailbox 13 Transmit Request Reset */ -#define TRR14 0x4000 /* Mailbox 14 Transmit Request Reset */ -#define TRR15 0x8000 /* Mailbox 15 Transmit Request Reset */ - -/* Bit masks for CAN0_TRR2 */ - -#define TRR16 0x1 /* Mailbox 16 Transmit Request Reset */ -#define TRR17 0x2 /* Mailbox 17 Transmit Request Reset */ -#define TRR18 0x4 /* Mailbox 18 Transmit Request Reset */ -#define TRR19 0x8 /* Mailbox 19 Transmit Request Reset */ -#define TRR20 0x10 /* Mailbox 20 Transmit Request Reset */ -#define TRR21 0x20 /* Mailbox 21 Transmit Request Reset */ -#define TRR22 0x40 /* Mailbox 22 Transmit Request Reset */ -#define TRR23 0x80 /* Mailbox 23 Transmit Request Reset */ -#define TRR24 0x100 /* Mailbox 24 Transmit Request Reset */ -#define TRR25 0x200 /* Mailbox 25 Transmit Request Reset */ -#define TRR26 0x400 /* Mailbox 26 Transmit Request Reset */ -#define TRR27 0x800 /* Mailbox 27 Transmit Request Reset */ -#define TRR28 0x1000 /* Mailbox 28 Transmit Request Reset */ -#define TRR29 0x2000 /* Mailbox 29 Transmit Request Reset */ -#define TRR30 0x4000 /* Mailbox 30 Transmit Request Reset */ -#define TRR31 0x8000 /* Mailbox 31 Transmit Request Reset */ - -/* Bit masks for CAN0_AA1 */ - -#define AA0 0x1 /* Mailbox 0 Abort Acknowledge */ -#define AA1 0x2 /* Mailbox 1 Abort Acknowledge */ -#define AA2 0x4 /* Mailbox 2 Abort Acknowledge */ -#define AA3 0x8 /* Mailbox 3 Abort Acknowledge */ -#define AA4 0x10 /* Mailbox 4 Abort Acknowledge */ -#define AA5 0x20 /* Mailbox 5 Abort Acknowledge */ -#define AA6 0x40 /* Mailbox 6 Abort Acknowledge */ -#define AA7 0x80 /* Mailbox 7 Abort Acknowledge */ -#define AA8 0x100 /* Mailbox 8 Abort Acknowledge */ -#define AA9 0x200 /* Mailbox 9 Abort Acknowledge */ -#define AA10 0x400 /* Mailbox 10 Abort Acknowledge */ -#define AA11 0x800 /* Mailbox 11 Abort Acknowledge */ -#define AA12 0x1000 /* Mailbox 12 Abort Acknowledge */ -#define AA13 0x2000 /* Mailbox 13 Abort Acknowledge */ -#define AA14 0x4000 /* Mailbox 14 Abort Acknowledge */ -#define AA15 0x8000 /* Mailbox 15 Abort Acknowledge */ - -/* Bit masks for CAN0_AA2 */ - -#define AA16 0x1 /* Mailbox 16 Abort Acknowledge */ -#define AA17 0x2 /* Mailbox 17 Abort Acknowledge */ -#define AA18 0x4 /* Mailbox 18 Abort Acknowledge */ -#define AA19 0x8 /* Mailbox 19 Abort Acknowledge */ -#define AA20 0x10 /* Mailbox 20 Abort Acknowledge */ -#define AA21 0x20 /* Mailbox 21 Abort Acknowledge */ -#define AA22 0x40 /* Mailbox 22 Abort Acknowledge */ -#define AA23 0x80 /* Mailbox 23 Abort Acknowledge */ -#define AA24 0x100 /* Mailbox 24 Abort Acknowledge */ -#define AA25 0x200 /* Mailbox 25 Abort Acknowledge */ -#define AA26 0x400 /* Mailbox 26 Abort Acknowledge */ -#define AA27 0x800 /* Mailbox 27 Abort Acknowledge */ -#define AA28 0x1000 /* Mailbox 28 Abort Acknowledge */ -#define AA29 0x2000 /* Mailbox 29 Abort Acknowledge */ -#define AA30 0x4000 /* Mailbox 30 Abort Acknowledge */ -#define AA31 0x8000 /* Mailbox 31 Abort Acknowledge */ - -/* Bit masks for CAN0_TA1 */ - -#define TA0 0x1 /* Mailbox 0 Transmit Acknowledge */ -#define TA1 0x2 /* Mailbox 1 Transmit Acknowledge */ -#define TA2 0x4 /* Mailbox 2 Transmit Acknowledge */ -#define TA3 0x8 /* Mailbox 3 Transmit Acknowledge */ -#define TA4 0x10 /* Mailbox 4 Transmit Acknowledge */ -#define TA5 0x20 /* Mailbox 5 Transmit Acknowledge */ -#define TA6 0x40 /* Mailbox 6 Transmit Acknowledge */ -#define TA7 0x80 /* Mailbox 7 Transmit Acknowledge */ -#define TA8 0x100 /* Mailbox 8 Transmit Acknowledge */ -#define TA9 0x200 /* Mailbox 9 Transmit Acknowledge */ -#define TA10 0x400 /* Mailbox 10 Transmit Acknowledge */ -#define TA11 0x800 /* Mailbox 11 Transmit Acknowledge */ -#define TA12 0x1000 /* Mailbox 12 Transmit Acknowledge */ -#define TA13 0x2000 /* Mailbox 13 Transmit Acknowledge */ -#define TA14 0x4000 /* Mailbox 14 Transmit Acknowledge */ -#define TA15 0x8000 /* Mailbox 15 Transmit Acknowledge */ - -/* Bit masks for CAN0_TA2 */ - -#define TA16 0x1 /* Mailbox 16 Transmit Acknowledge */ -#define TA17 0x2 /* Mailbox 17 Transmit Acknowledge */ -#define TA18 0x4 /* Mailbox 18 Transmit Acknowledge */ -#define TA19 0x8 /* Mailbox 19 Transmit Acknowledge */ -#define TA20 0x10 /* Mailbox 20 Transmit Acknowledge */ -#define TA21 0x20 /* Mailbox 21 Transmit Acknowledge */ -#define TA22 0x40 /* Mailbox 22 Transmit Acknowledge */ -#define TA23 0x80 /* Mailbox 23 Transmit Acknowledge */ -#define TA24 0x100 /* Mailbox 24 Transmit Acknowledge */ -#define TA25 0x200 /* Mailbox 25 Transmit Acknowledge */ -#define TA26 0x400 /* Mailbox 26 Transmit Acknowledge */ -#define TA27 0x800 /* Mailbox 27 Transmit Acknowledge */ -#define TA28 0x1000 /* Mailbox 28 Transmit Acknowledge */ -#define TA29 0x2000 /* Mailbox 29 Transmit Acknowledge */ -#define TA30 0x4000 /* Mailbox 30 Transmit Acknowledge */ -#define TA31 0x8000 /* Mailbox 31 Transmit Acknowledge */ - -/* Bit masks for CAN0_RFH1 */ - -#define RFH0 0x1 /* Mailbox 0 Remote Frame Handling Enable */ -#define RFH1 0x2 /* Mailbox 1 Remote Frame Handling Enable */ -#define RFH2 0x4 /* Mailbox 2 Remote Frame Handling Enable */ -#define RFH3 0x8 /* Mailbox 3 Remote Frame Handling Enable */ -#define RFH4 0x10 /* Mailbox 4 Remote Frame Handling Enable */ -#define RFH5 0x20 /* Mailbox 5 Remote Frame Handling Enable */ -#define RFH6 0x40 /* Mailbox 6 Remote Frame Handling Enable */ -#define RFH7 0x80 /* Mailbox 7 Remote Frame Handling Enable */ -#define RFH8 0x100 /* Mailbox 8 Remote Frame Handling Enable */ -#define RFH9 0x200 /* Mailbox 9 Remote Frame Handling Enable */ -#define RFH10 0x400 /* Mailbox 10 Remote Frame Handling Enable */ -#define RFH11 0x800 /* Mailbox 11 Remote Frame Handling Enable */ -#define RFH12 0x1000 /* Mailbox 12 Remote Frame Handling Enable */ -#define RFH13 0x2000 /* Mailbox 13 Remote Frame Handling Enable */ -#define RFH14 0x4000 /* Mailbox 14 Remote Frame Handling Enable */ -#define RFH15 0x8000 /* Mailbox 15 Remote Frame Handling Enable */ - -/* Bit masks for CAN0_RFH2 */ - -#define RFH16 0x1 /* Mailbox 16 Remote Frame Handling Enable */ -#define RFH17 0x2 /* Mailbox 17 Remote Frame Handling Enable */ -#define RFH18 0x4 /* Mailbox 18 Remote Frame Handling Enable */ -#define RFH19 0x8 /* Mailbox 19 Remote Frame Handling Enable */ -#define RFH20 0x10 /* Mailbox 20 Remote Frame Handling Enable */ -#define RFH21 0x20 /* Mailbox 21 Remote Frame Handling Enable */ -#define RFH22 0x40 /* Mailbox 22 Remote Frame Handling Enable */ -#define RFH23 0x80 /* Mailbox 23 Remote Frame Handling Enable */ -#define RFH24 0x100 /* Mailbox 24 Remote Frame Handling Enable */ -#define RFH25 0x200 /* Mailbox 25 Remote Frame Handling Enable */ -#define RFH26 0x400 /* Mailbox 26 Remote Frame Handling Enable */ -#define RFH27 0x800 /* Mailbox 27 Remote Frame Handling Enable */ -#define RFH28 0x1000 /* Mailbox 28 Remote Frame Handling Enable */ -#define RFH29 0x2000 /* Mailbox 29 Remote Frame Handling Enable */ -#define RFH30 0x4000 /* Mailbox 30 Remote Frame Handling Enable */ -#define RFH31 0x8000 /* Mailbox 31 Remote Frame Handling Enable */ - -/* Bit masks for CAN0_MBIM1 */ - -#define MBIM0 0x1 /* Mailbox 0 Mailbox Interrupt Mask */ -#define MBIM1 0x2 /* Mailbox 1 Mailbox Interrupt Mask */ -#define MBIM2 0x4 /* Mailbox 2 Mailbox Interrupt Mask */ -#define MBIM3 0x8 /* Mailbox 3 Mailbox Interrupt Mask */ -#define MBIM4 0x10 /* Mailbox 4 Mailbox Interrupt Mask */ -#define MBIM5 0x20 /* Mailbox 5 Mailbox Interrupt Mask */ -#define MBIM6 0x40 /* Mailbox 6 Mailbox Interrupt Mask */ -#define MBIM7 0x80 /* Mailbox 7 Mailbox Interrupt Mask */ -#define MBIM8 0x100 /* Mailbox 8 Mailbox Interrupt Mask */ -#define MBIM9 0x200 /* Mailbox 9 Mailbox Interrupt Mask */ -#define MBIM10 0x400 /* Mailbox 10 Mailbox Interrupt Mask */ -#define MBIM11 0x800 /* Mailbox 11 Mailbox Interrupt Mask */ -#define MBIM12 0x1000 /* Mailbox 12 Mailbox Interrupt Mask */ -#define MBIM13 0x2000 /* Mailbox 13 Mailbox Interrupt Mask */ -#define MBIM14 0x4000 /* Mailbox 14 Mailbox Interrupt Mask */ -#define MBIM15 0x8000 /* Mailbox 15 Mailbox Interrupt Mask */ - -/* Bit masks for CAN0_MBIM2 */ - -#define MBIM16 0x1 /* Mailbox 16 Mailbox Interrupt Mask */ -#define MBIM17 0x2 /* Mailbox 17 Mailbox Interrupt Mask */ -#define MBIM18 0x4 /* Mailbox 18 Mailbox Interrupt Mask */ -#define MBIM19 0x8 /* Mailbox 19 Mailbox Interrupt Mask */ -#define MBIM20 0x10 /* Mailbox 20 Mailbox Interrupt Mask */ -#define MBIM21 0x20 /* Mailbox 21 Mailbox Interrupt Mask */ -#define MBIM22 0x40 /* Mailbox 22 Mailbox Interrupt Mask */ -#define MBIM23 0x80 /* Mailbox 23 Mailbox Interrupt Mask */ -#define MBIM24 0x100 /* Mailbox 24 Mailbox Interrupt Mask */ -#define MBIM25 0x200 /* Mailbox 25 Mailbox Interrupt Mask */ -#define MBIM26 0x400 /* Mailbox 26 Mailbox Interrupt Mask */ -#define MBIM27 0x800 /* Mailbox 27 Mailbox Interrupt Mask */ -#define MBIM28 0x1000 /* Mailbox 28 Mailbox Interrupt Mask */ -#define MBIM29 0x2000 /* Mailbox 29 Mailbox Interrupt Mask */ -#define MBIM30 0x4000 /* Mailbox 30 Mailbox Interrupt Mask */ -#define MBIM31 0x8000 /* Mailbox 31 Mailbox Interrupt Mask */ - -/* Bit masks for CAN0_MBTIF1 */ - -#define MBTIF0 0x1 /* Mailbox 0 Mailbox Transmit Interrupt Flag */ -#define MBTIF1 0x2 /* Mailbox 1 Mailbox Transmit Interrupt Flag */ -#define MBTIF2 0x4 /* Mailbox 2 Mailbox Transmit Interrupt Flag */ -#define MBTIF3 0x8 /* Mailbox 3 Mailbox Transmit Interrupt Flag */ -#define MBTIF4 0x10 /* Mailbox 4 Mailbox Transmit Interrupt Flag */ -#define MBTIF5 0x20 /* Mailbox 5 Mailbox Transmit Interrupt Flag */ -#define MBTIF6 0x40 /* Mailbox 6 Mailbox Transmit Interrupt Flag */ -#define MBTIF7 0x80 /* Mailbox 7 Mailbox Transmit Interrupt Flag */ -#define MBTIF8 0x100 /* Mailbox 8 Mailbox Transmit Interrupt Flag */ -#define MBTIF9 0x200 /* Mailbox 9 Mailbox Transmit Interrupt Flag */ -#define MBTIF10 0x400 /* Mailbox 10 Mailbox Transmit Interrupt Flag */ -#define MBTIF11 0x800 /* Mailbox 11 Mailbox Transmit Interrupt Flag */ -#define MBTIF12 0x1000 /* Mailbox 12 Mailbox Transmit Interrupt Flag */ -#define MBTIF13 0x2000 /* Mailbox 13 Mailbox Transmit Interrupt Flag */ -#define MBTIF14 0x4000 /* Mailbox 14 Mailbox Transmit Interrupt Flag */ -#define MBTIF15 0x8000 /* Mailbox 15 Mailbox Transmit Interrupt Flag */ - -/* Bit masks for CAN0_MBTIF2 */ - -#define MBTIF16 0x1 /* Mailbox 16 Mailbox Transmit Interrupt Flag */ -#define MBTIF17 0x2 /* Mailbox 17 Mailbox Transmit Interrupt Flag */ -#define MBTIF18 0x4 /* Mailbox 18 Mailbox Transmit Interrupt Flag */ -#define MBTIF19 0x8 /* Mailbox 19 Mailbox Transmit Interrupt Flag */ -#define MBTIF20 0x10 /* Mailbox 20 Mailbox Transmit Interrupt Flag */ -#define MBTIF21 0x20 /* Mailbox 21 Mailbox Transmit Interrupt Flag */ -#define MBTIF22 0x40 /* Mailbox 22 Mailbox Transmit Interrupt Flag */ -#define MBTIF23 0x80 /* Mailbox 23 Mailbox Transmit Interrupt Flag */ -#define MBTIF24 0x100 /* Mailbox 24 Mailbox Transmit Interrupt Flag */ -#define MBTIF25 0x200 /* Mailbox 25 Mailbox Transmit Interrupt Flag */ -#define MBTIF26 0x400 /* Mailbox 26 Mailbox Transmit Interrupt Flag */ -#define MBTIF27 0x800 /* Mailbox 27 Mailbox Transmit Interrupt Flag */ -#define MBTIF28 0x1000 /* Mailbox 28 Mailbox Transmit Interrupt Flag */ -#define MBTIF29 0x2000 /* Mailbox 29 Mailbox Transmit Interrupt Flag */ -#define MBTIF30 0x4000 /* Mailbox 30 Mailbox Transmit Interrupt Flag */ -#define MBTIF31 0x8000 /* Mailbox 31 Mailbox Transmit Interrupt Flag */ - -/* Bit masks for CAN0_MBRIF1 */ - -#define MBRIF0 0x1 /* Mailbox 0 Mailbox Receive Interrupt Flag */ -#define MBRIF1 0x2 /* Mailbox 1 Mailbox Receive Interrupt Flag */ -#define MBRIF2 0x4 /* Mailbox 2 Mailbox Receive Interrupt Flag */ -#define MBRIF3 0x8 /* Mailbox 3 Mailbox Receive Interrupt Flag */ -#define MBRIF4 0x10 /* Mailbox 4 Mailbox Receive Interrupt Flag */ -#define MBRIF5 0x20 /* Mailbox 5 Mailbox Receive Interrupt Flag */ -#define MBRIF6 0x40 /* Mailbox 6 Mailbox Receive Interrupt Flag */ -#define MBRIF7 0x80 /* Mailbox 7 Mailbox Receive Interrupt Flag */ -#define MBRIF8 0x100 /* Mailbox 8 Mailbox Receive Interrupt Flag */ -#define MBRIF9 0x200 /* Mailbox 9 Mailbox Receive Interrupt Flag */ -#define MBRIF10 0x400 /* Mailbox 10 Mailbox Receive Interrupt Flag */ -#define MBRIF11 0x800 /* Mailbox 11 Mailbox Receive Interrupt Flag */ -#define MBRIF12 0x1000 /* Mailbox 12 Mailbox Receive Interrupt Flag */ -#define MBRIF13 0x2000 /* Mailbox 13 Mailbox Receive Interrupt Flag */ -#define MBRIF14 0x4000 /* Mailbox 14 Mailbox Receive Interrupt Flag */ -#define MBRIF15 0x8000 /* Mailbox 15 Mailbox Receive Interrupt Flag */ - -/* Bit masks for CAN0_MBRIF2 */ - -#define MBRIF16 0x1 /* Mailbox 16 Mailbox Receive Interrupt Flag */ -#define MBRIF17 0x2 /* Mailbox 17 Mailbox Receive Interrupt Flag */ -#define MBRIF18 0x4 /* Mailbox 18 Mailbox Receive Interrupt Flag */ -#define MBRIF19 0x8 /* Mailbox 19 Mailbox Receive Interrupt Flag */ -#define MBRIF20 0x10 /* Mailbox 20 Mailbox Receive Interrupt Flag */ -#define MBRIF21 0x20 /* Mailbox 21 Mailbox Receive Interrupt Flag */ -#define MBRIF22 0x40 /* Mailbox 22 Mailbox Receive Interrupt Flag */ -#define MBRIF23 0x80 /* Mailbox 23 Mailbox Receive Interrupt Flag */ -#define MBRIF24 0x100 /* Mailbox 24 Mailbox Receive Interrupt Flag */ -#define MBRIF25 0x200 /* Mailbox 25 Mailbox Receive Interrupt Flag */ -#define MBRIF26 0x400 /* Mailbox 26 Mailbox Receive Interrupt Flag */ -#define MBRIF27 0x800 /* Mailbox 27 Mailbox Receive Interrupt Flag */ -#define MBRIF28 0x1000 /* Mailbox 28 Mailbox Receive Interrupt Flag */ -#define MBRIF29 0x2000 /* Mailbox 29 Mailbox Receive Interrupt Flag */ -#define MBRIF30 0x4000 /* Mailbox 30 Mailbox Receive Interrupt Flag */ -#define MBRIF31 0x8000 /* Mailbox 31 Mailbox Receive Interrupt Flag */ - /* Bit masks for EPPIx_STATUS */ #define CFIFO_ERR 0x1 /* Chroma FIFO Error */ -- cgit v1.2.3-59-g8ed1b From 85eb0e4b15efc8034cbae193c99536dae7896701 Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Fri, 22 Jan 2010 04:02:46 +0000 Subject: Blackfin: mark MUSB VRSEL as active high for appropriate boards These boards all have the GPIO VRSEL hooked up as an active high. Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger --- arch/blackfin/mach-bf527/boards/cm_bf527.c | 4 ++++ arch/blackfin/mach-bf527/boards/ezbrd.c | 4 ++++ arch/blackfin/mach-bf527/boards/ezkit.c | 4 ++++ arch/blackfin/mach-bf548/boards/cm_bf548.c | 4 ++++ arch/blackfin/mach-bf548/boards/ezkit.c | 4 ++++ 5 files changed, 20 insertions(+) (limited to 'arch') diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index ebe76d1e874a..f392af641657 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -98,6 +98,10 @@ static struct musb_hdrc_config musb_config = { .num_eps = 8, .dma_channels = 8, .gpio_vrsel = GPIO_PF11, + /* Some custom boards need to be active low, just set it to "0" + * if it is the case. + */ + .gpio_vrsel_active = 1, }; static struct musb_hdrc_platform_data musb_plat = { diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index 55069af4f67d..606eb36b9d6e 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -62,6 +62,10 @@ static struct musb_hdrc_config musb_config = { .num_eps = 8, .dma_channels = 8, .gpio_vrsel = GPIO_PG13, + /* Some custom boards need to be active low, just set it to "0" + * if it is the case. + */ + .gpio_vrsel_active = 1, }; static struct musb_hdrc_platform_data musb_plat = { diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 923383386aa1..a05c967a24cf 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -102,6 +102,10 @@ static struct musb_hdrc_config musb_config = { .num_eps = 8, .dma_channels = 8, .gpio_vrsel = GPIO_PG13, + /* Some custom boards need to be active low, just set it to "0" + * if it is the case. + */ + .gpio_vrsel_active = 1, }; static struct musb_hdrc_platform_data musb_plat = { diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c index f60c333fec66..dbb6b1d83f6d 100644 --- a/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c @@ -498,6 +498,10 @@ static struct musb_hdrc_config musb_config = { .num_eps = 8, .dma_channels = 8, .gpio_vrsel = GPIO_PH6, + /* Some custom boards need to be active low, just set it to "0" + * if it is the case. + */ + .gpio_vrsel_active = 1, }; static struct musb_hdrc_platform_data musb_plat = { diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 06919db00a74..6fcfb9187c35 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -603,6 +603,10 @@ static struct musb_hdrc_config musb_config = { .num_eps = 8, .dma_channels = 8, .gpio_vrsel = GPIO_PE7, + /* Some custom boards need to be active low, just set it to "0" + * if it is the case. + */ + .gpio_vrsel_active = 1, }; static struct musb_hdrc_platform_data musb_plat = { -- cgit v1.2.3-59-g8ed1b From bb84dbf69b0730fcc78c275f900ed74b2b8453a5 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 10 Mar 2010 14:26:06 +0000 Subject: Blackfin: punt Blackfin-specific GPIO wakeup API This patch removes a custom GPIO wakeup API which allowed GPIOs to act as wakeup sources, which are not configured as Interrupts. This API is a leftover from the time before irq_wake was established. From now on people must use enable_irq_wake(GPIO_IRQx) and the GPIO in question needs to be configured as Interrupt. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger --- arch/blackfin/Kconfig | 26 ------ arch/blackfin/include/asm/gpio.h | 22 ++--- arch/blackfin/kernel/bfin_gpio.c | 131 +++--------------------------- arch/blackfin/mach-common/ints-priority.c | 9 +- arch/blackfin/mach-common/pm.c | 24 ------ 5 files changed, 24 insertions(+), 188 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index c078849df7f9..405bdaa17333 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -1187,32 +1187,6 @@ config PM_BFIN_SLEEP If unsure, select "Sleep Deeper". endchoice -config PM_WAKEUP_BY_GPIO - bool "Allow Wakeup from Standby by GPIO" - depends on PM && !BF54x - -config PM_WAKEUP_GPIO_NUMBER - int "GPIO number" - range 0 47 - depends on PM_WAKEUP_BY_GPIO - default 2 - -choice - prompt "GPIO Polarity" - depends on PM_WAKEUP_BY_GPIO - default PM_WAKEUP_GPIO_POLAR_H -config PM_WAKEUP_GPIO_POLAR_H - bool "Active High" -config PM_WAKEUP_GPIO_POLAR_L - bool "Active Low" -config PM_WAKEUP_GPIO_POLAR_EDGE_F - bool "Falling EDGE" -config PM_WAKEUP_GPIO_POLAR_EDGE_R - bool "Rising EDGE" -config PM_WAKEUP_GPIO_POLAR_EDGE_B - bool "Both EDGE" -endchoice - comment "Possible Suspend Mem / Hibernate Wake-Up Sources" depends on PM diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 91bd2d7b9d55..01b19d0cf509 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h @@ -167,23 +167,23 @@ int bfin_special_gpio_request(unsigned gpio, const char *label); #endif #ifdef CONFIG_PM +int bfin_pm_standby_ctrl(unsigned ctrl); -unsigned int bfin_pm_standby_setup(void); -void bfin_pm_standby_restore(void); +static inline int bfin_pm_standby_setup(void) +{ + return bfin_pm_standby_ctrl(1); +} + +static inline void bfin_pm_standby_restore(void) +{ + bfin_pm_standby_ctrl(0); +} void bfin_gpio_pm_hibernate_restore(void); void bfin_gpio_pm_hibernate_suspend(void); #ifndef CONFIG_BF54x -#define PM_WAKE_RISING 0x1 -#define PM_WAKE_FALLING 0x2 -#define PM_WAKE_HIGH 0x4 -#define PM_WAKE_LOW 0x8 -#define PM_WAKE_BOTH_EDGES (PM_WAKE_RISING | PM_WAKE_FALLING) -#define PM_WAKE_IGNORE 0xF0 - -int gpio_pm_wakeup_request(unsigned gpio, unsigned char type); -void gpio_pm_wakeup_free(unsigned gpio); +int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl); struct gpio_port_s { unsigned short data; diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index e35e20f00d9b..42833ee2b308 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -475,9 +475,7 @@ GET_GPIO_P(maskb) #ifdef CONFIG_PM - static unsigned short wakeup_map[GPIO_BANK_NUM]; -static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; static const unsigned int sic_iwr_irqs[] = { #if defined(BF533_FAMILY) @@ -514,112 +512,26 @@ static const unsigned int sic_iwr_irqs[] = { ************************************************************* * MODIFICATION HISTORY : **************************************************************/ -int gpio_pm_wakeup_request(unsigned gpio, unsigned char type) -{ - unsigned long flags; - - if ((check_gpio(gpio) < 0) || !type) - return -EINVAL; - - local_irq_save_hw(flags); - wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); - wakeup_flags_map[gpio] = type; - local_irq_restore_hw(flags); - - return 0; -} -EXPORT_SYMBOL(gpio_pm_wakeup_request); - -void gpio_pm_wakeup_free(unsigned gpio) +int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) { unsigned long flags; if (check_gpio(gpio) < 0) - return; + return -EINVAL; local_irq_save_hw(flags); - - wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); - - local_irq_restore_hw(flags); -} -EXPORT_SYMBOL(gpio_pm_wakeup_free); - -static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type) -{ - port_setup(gpio, GPIO_USAGE); - set_gpio_dir(gpio, 0); - set_gpio_inen(gpio, 1); - - if (type & (PM_WAKE_RISING | PM_WAKE_FALLING)) - set_gpio_edge(gpio, 1); - else - set_gpio_edge(gpio, 0); - - if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES)) - set_gpio_both(gpio, 1); + if (ctrl) + wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); else - set_gpio_both(gpio, 0); - - if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW))) - set_gpio_polar(gpio, 1); - else - set_gpio_polar(gpio, 0); + wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); - SSYNC(); - - return 0; -} - -u32 bfin_pm_standby_setup(void) -{ - u16 bank, mask, i, gpio; - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - mask = wakeup_map[gpio_bank(i)]; - bank = gpio_bank(i); - - gpio_bank_saved[bank].maskb = gpio_array[bank]->maskb; - gpio_array[bank]->maskb = 0; - - if (mask) { -#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) - gpio_bank_saved[bank].fer = *port_fer[bank]; -#endif - gpio_bank_saved[bank].inen = gpio_array[bank]->inen; - gpio_bank_saved[bank].polar = gpio_array[bank]->polar; - gpio_bank_saved[bank].dir = gpio_array[bank]->dir; - gpio_bank_saved[bank].edge = gpio_array[bank]->edge; - gpio_bank_saved[bank].both = gpio_array[bank]->both; - gpio_bank_saved[bank].reserved = - reserved_gpio_map[bank]; - - gpio = i; - - while (mask) { - if ((mask & 1) && (wakeup_flags_map[gpio] != - PM_WAKE_IGNORE)) { - reserved_gpio_map[gpio_bank(gpio)] |= - gpio_bit(gpio); - bfin_gpio_wakeup_type(gpio, - wakeup_flags_map[gpio]); - set_gpio_data(gpio, 0); /*Clear*/ - } - gpio++; - mask >>= 1; - } - - bfin_internal_set_wake(sic_iwr_irqs[bank], 1); - gpio_array[bank]->maskb_set = wakeup_map[gpio_bank(i)]; - } - } - - AWA_DUMMY_READ(maskb_set); + set_gpio_maskb(gpio, ctrl); + local_irq_restore_hw(flags); return 0; } -void bfin_pm_standby_restore(void) +int bfin_pm_standby_ctrl(unsigned ctrl) { u16 bank, mask, i; @@ -627,24 +539,10 @@ void bfin_pm_standby_restore(void) mask = wakeup_map[gpio_bank(i)]; bank = gpio_bank(i); - if (mask) { -#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) - *port_fer[bank] = gpio_bank_saved[bank].fer; -#endif - gpio_array[bank]->inen = gpio_bank_saved[bank].inen; - gpio_array[bank]->dir = gpio_bank_saved[bank].dir; - gpio_array[bank]->polar = gpio_bank_saved[bank].polar; - gpio_array[bank]->edge = gpio_bank_saved[bank].edge; - gpio_array[bank]->both = gpio_bank_saved[bank].both; - - reserved_gpio_map[bank] = - gpio_bank_saved[bank].reserved; - bfin_internal_set_wake(sic_iwr_irqs[bank], 0); - } - - gpio_array[bank]->maskb = gpio_bank_saved[bank].maskb; + if (mask) + bfin_internal_set_wake(sic_iwr_irqs[bank], ctrl); } - AWA_DUMMY_READ(maskb); + return 0; } void bfin_gpio_pm_hibernate_suspend(void) @@ -708,16 +606,11 @@ void bfin_gpio_pm_hibernate_restore(void) #else /* CONFIG_BF54x */ #ifdef CONFIG_PM -u32 bfin_pm_standby_setup(void) +int bfin_pm_standby_ctrl(unsigned ctrl) { return 0; } -void bfin_pm_standby_restore(void) -{ - -} - void bfin_gpio_pm_hibernate_suspend(void) { int i, bank; diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 7ad8878bfa18..ce988713445d 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -662,14 +662,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) #ifdef CONFIG_PM int bfin_gpio_set_wake(unsigned int irq, unsigned int state) { - unsigned gpio = irq_to_gpio(irq); - - if (state) - gpio_pm_wakeup_request(gpio, PM_WAKE_IGNORE); - else - gpio_pm_wakeup_free(gpio); - - return 0; + return gpio_pm_wakeup_ctrl(irq_to_gpio(irq), state); } #endif diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index c1f1ccc846f0..ea7f95f6bb4c 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c @@ -20,35 +20,11 @@ #include #include -#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H -#define WAKEUP_TYPE PM_WAKE_HIGH -#endif - -#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_L -#define WAKEUP_TYPE PM_WAKE_LOW -#endif - -#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_F -#define WAKEUP_TYPE PM_WAKE_FALLING -#endif - -#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_R -#define WAKEUP_TYPE PM_WAKE_RISING -#endif - -#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_B -#define WAKEUP_TYPE PM_WAKE_BOTH_EDGES -#endif - void bfin_pm_suspend_standby_enter(void) { unsigned long flags; -#ifdef CONFIG_PM_WAKEUP_BY_GPIO - gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE); -#endif - local_irq_save_hw(flags); bfin_pm_standby_setup(); -- cgit v1.2.3-59-g8ed1b From 2a12c4632db1c0c548a7023e63869b27c7789a92 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Thu, 11 Mar 2010 16:24:18 +0000 Subject: Blackfin: split kernel/traps.c The current kernel/traps.c file has grown a bit unwieldy as more debugging functionality has been added over time, so split it up into more logical files. There should be no functional changes here, just minor whitespace tweaking. This should make future extensions easier to manage. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/trace.h | 2 + arch/blackfin/kernel/Makefile | 3 +- arch/blackfin/kernel/dumpstack.c | 181 ++++++++ arch/blackfin/kernel/exception.c | 45 ++ arch/blackfin/kernel/sys_bfin.c | 23 + arch/blackfin/kernel/trace.c | 594 ++++++++++++++++++++++++++ arch/blackfin/kernel/traps.c | 875 ++------------------------------------ 7 files changed, 887 insertions(+), 836 deletions(-) create mode 100644 arch/blackfin/kernel/dumpstack.c create mode 100644 arch/blackfin/kernel/exception.c create mode 100644 arch/blackfin/kernel/trace.c (limited to 'arch') diff --git a/arch/blackfin/include/asm/trace.h b/arch/blackfin/include/asm/trace.h index dc0aa55ae773..395decd8bc3b 100644 --- a/arch/blackfin/include/asm/trace.h +++ b/arch/blackfin/include/asm/trace.h @@ -23,6 +23,8 @@ #ifndef __ASSEMBLY__ extern unsigned long trace_buff_offset; extern unsigned long software_trace_buff[]; +extern void decode_address(char *buf, unsigned long address); +extern bool get_instruction(unsigned short *val, unsigned short *address); /* Trace Macros for C files */ diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 346a421f1562..b32a04a95d99 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -7,7 +7,8 @@ extra-y := init_task.o vmlinux.lds obj-y := \ entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ sys_bfin.o traps.o irqchip.o dma-mapping.o flat.o \ - fixed_code.o reboot.o bfin_gpio.o bfin_dma_5xx.o + fixed_code.o reboot.o bfin_gpio.o bfin_dma_5xx.o \ + trace.o exception.o dumpstack.o ifeq ($(CONFIG_GENERIC_CLOCKEVENTS),y) obj-y += time-ts.o diff --git a/arch/blackfin/kernel/dumpstack.c b/arch/blackfin/kernel/dumpstack.c new file mode 100644 index 000000000000..e81392c9d1db --- /dev/null +++ b/arch/blackfin/kernel/dumpstack.c @@ -0,0 +1,181 @@ +/* Provide basic stack dumping functions + * + * Copyright 2004-2009 Analog Devices Inc. + * + * Licensed under the GPL-2 or later + */ + +#include +#include +#include +#include +#include +#include + +/* + * Checks to see if the address pointed to is either a + * 16-bit CALL instruction, or a 32-bit CALL instruction + */ +static bool is_bfin_call(unsigned short *addr) +{ + unsigned short opcode = 0, *ins_addr; + ins_addr = (unsigned short *)addr; + + if (!get_instruction(&opcode, ins_addr)) + return false; + + if ((opcode >= 0x0060 && opcode <= 0x0067) || + (opcode >= 0x0070 && opcode <= 0x0077)) + return true; + + ins_addr--; + if (!get_instruction(&opcode, ins_addr)) + return false; + + if (opcode >= 0xE300 && opcode <= 0xE3FF) + return true; + + return false; + +} + +void show_stack(struct task_struct *task, unsigned long *stack) +{ +#ifdef CONFIG_PRINTK + unsigned int *addr, *endstack, *fp = 0, *frame; + unsigned short *ins_addr; + char buf[150]; + unsigned int i, j, ret_addr, frame_no = 0; + + /* + * If we have been passed a specific stack, use that one otherwise + * if we have been passed a task structure, use that, otherwise + * use the stack of where the variable "stack" exists + */ + + if (stack == NULL) { + if (task) { + /* We know this is a kernel stack, so this is the start/end */ + stack = (unsigned long *)task->thread.ksp; + endstack = (unsigned int *)(((unsigned int)(stack) & ~(THREAD_SIZE - 1)) + THREAD_SIZE); + } else { + /* print out the existing stack info */ + stack = (unsigned long *)&stack; + endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); + } + } else + endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); + + printk(KERN_NOTICE "Stack info:\n"); + decode_address(buf, (unsigned int)stack); + printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); + + if (!access_ok(VERIFY_READ, stack, (unsigned int)endstack - (unsigned int)stack)) { + printk(KERN_NOTICE "Invalid stack pointer\n"); + return; + } + + /* First thing is to look for a frame pointer */ + for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { + if (*addr & 0x1) + continue; + ins_addr = (unsigned short *)*addr; + ins_addr--; + if (is_bfin_call(ins_addr)) + fp = addr - 1; + + if (fp) { + /* Let's check to see if it is a frame pointer */ + while (fp >= (addr - 1) && fp < endstack + && fp && ((unsigned int) fp & 0x3) == 0) + fp = (unsigned int *)*fp; + if (fp == 0 || fp == endstack) { + fp = addr - 1; + break; + } + fp = 0; + } + } + if (fp) { + frame = fp; + printk(KERN_NOTICE " FP: (0x%p)\n", fp); + } else + frame = 0; + + /* + * Now that we think we know where things are, we + * walk the stack again, this time printing things out + * incase there is no frame pointer, we still look for + * valid return addresses + */ + + /* First time print out data, next time, print out symbols */ + for (j = 0; j <= 1; j++) { + if (j) + printk(KERN_NOTICE "Return addresses in stack:\n"); + else + printk(KERN_NOTICE " Memory from 0x%08lx to %p", ((long unsigned int)stack & ~0xF), endstack); + + fp = frame; + frame_no = 0; + + for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; + addr < endstack; addr++, i++) { + + ret_addr = 0; + if (!j && i % 8 == 0) + printk(KERN_NOTICE "%p:", addr); + + /* if it is an odd address, or zero, just skip it */ + if (*addr & 0x1 || !*addr) + goto print; + + ins_addr = (unsigned short *)*addr; + + /* Go back one instruction, and see if it is a CALL */ + ins_addr--; + ret_addr = is_bfin_call(ins_addr); + print: + if (!j && stack == (unsigned long *)addr) + printk("[%08x]", *addr); + else if (ret_addr) + if (j) { + decode_address(buf, (unsigned int)*addr); + if (frame == addr) { + printk(KERN_NOTICE " frame %2i : %s\n", frame_no, buf); + continue; + } + printk(KERN_NOTICE " address : %s\n", buf); + } else + printk("<%08x>", *addr); + else if (fp == addr) { + if (j) + frame = addr+1; + else + printk("(%08x)", *addr); + + fp = (unsigned int *)*addr; + frame_no++; + + } else if (!j) + printk(" %08x ", *addr); + } + if (!j) + printk("\n"); + } +#endif +} +EXPORT_SYMBOL(show_stack); + +void dump_stack(void) +{ + unsigned long stack; +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON + int tflags; +#endif + trace_buffer_save(tflags); + dump_bfin_trace_buffer(); + show_stack(current, &stack); + trace_buffer_restore(tflags); +} +EXPORT_SYMBOL(dump_stack); diff --git a/arch/blackfin/kernel/exception.c b/arch/blackfin/kernel/exception.c new file mode 100644 index 000000000000..9208b5fd5186 --- /dev/null +++ b/arch/blackfin/kernel/exception.c @@ -0,0 +1,45 @@ +/* Basic functions for adding/removing custom exception handlers + * + * Copyright 2004-2009 Analog Devices Inc. + * + * Licensed under the GPL-2 or later + */ + +#include +#include + +int bfin_request_exception(unsigned int exception, void (*handler)(void)) +{ + void (*curr_handler)(void); + + if (exception > 0x3F) + return -EINVAL; + + curr_handler = ex_table[exception]; + + if (curr_handler != ex_replaceable) + return -EBUSY; + + ex_table[exception] = handler; + + return 0; +} +EXPORT_SYMBOL(bfin_request_exception); + +int bfin_free_exception(unsigned int exception, void (*handler)(void)) +{ + void (*curr_handler)(void); + + if (exception > 0x3F) + return -EINVAL; + + curr_handler = ex_table[exception]; + + if (curr_handler != handler) + return -EBUSY; + + ex_table[exception] = ex_replaceable; + + return 0; +} +EXPORT_SYMBOL(bfin_free_exception); diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c index 2e7f8e10bf87..bdc1e2f0da32 100644 --- a/arch/blackfin/kernel/sys_bfin.c +++ b/arch/blackfin/kernel/sys_bfin.c @@ -47,3 +47,26 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, } EXPORT_SYMBOL(get_fb_unmapped_area); #endif + +/* Needed for legacy userspace atomic emulation */ +static DEFINE_SPINLOCK(bfin_spinlock_lock); + +#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1 +__attribute__((l1_text)) +#endif +asmlinkage int sys_bfin_spinlock(int *p) +{ + int ret, tmp = 0; + + spin_lock(&bfin_spinlock_lock); /* This would also hold kernel preemption. */ + ret = get_user(tmp, p); + if (likely(ret == 0)) { + if (unlikely(tmp)) + ret = 1; + else + put_user(1, p); + } + spin_unlock(&bfin_spinlock_lock); + + return ret; +} diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c new file mode 100644 index 000000000000..3a268c3ed47e --- /dev/null +++ b/arch/blackfin/kernel/trace.c @@ -0,0 +1,594 @@ +/* provide some functions which dump the trace buffer, in a nice way for people + * to read it, and understand what is going on + * + * Copyright 2004-2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_DEBUG_VERBOSE +#define verbose_printk(fmt, arg...) \ + printk(fmt, ##arg) +#else +#define verbose_printk(fmt, arg...) \ + ({ if (0) printk(fmt, ##arg); 0; }) +#endif + + +void decode_address(char *buf, unsigned long address) +{ +#ifdef CONFIG_DEBUG_VERBOSE + struct task_struct *p; + struct mm_struct *mm; + unsigned long flags, offset; + unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); + struct rb_node *n; + +#ifdef CONFIG_KALLSYMS + unsigned long symsize; + const char *symname; + char *modname; + char *delim = ":"; + char namebuf[128]; +#endif + + buf += sprintf(buf, "<0x%08lx> ", address); + +#ifdef CONFIG_KALLSYMS + /* look up the address and see if we are in kernel space */ + symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); + + if (symname) { + /* yeah! kernel space! */ + if (!modname) + modname = delim = ""; + sprintf(buf, "{ %s%s%s%s + 0x%lx }", + delim, modname, delim, symname, + (unsigned long)offset); + return; + } +#endif + + if (address >= FIXED_CODE_START && address < FIXED_CODE_END) { + /* Problem in fixed code section? */ + strcat(buf, "/* Maybe fixed code section */"); + return; + + } else if (address < CONFIG_BOOT_LOAD) { + /* Problem somewhere before the kernel start address */ + strcat(buf, "/* Maybe null pointer? */"); + return; + + } else if (address >= COREMMR_BASE) { + strcat(buf, "/* core mmrs */"); + return; + + } else if (address >= SYSMMR_BASE) { + strcat(buf, "/* system mmrs */"); + return; + + } else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) { + strcat(buf, "/* on-chip L1 ROM */"); + return; + } + + /* + * Don't walk any of the vmas if we are oopsing, it has been known + * to cause problems - corrupt vmas (kernel crashes) cause double faults + */ + if (oops_in_progress) { + strcat(buf, "/* kernel dynamic memory (maybe user-space) */"); + return; + } + + /* looks like we're off in user-land, so let's walk all the + * mappings of all our processes and see if we can't be a whee + * bit more specific + */ + write_lock_irqsave(&tasklist_lock, flags); + for_each_process(p) { + mm = (in_atomic ? p->mm : get_task_mm(p)); + if (!mm) + continue; + + if (!down_read_trylock(&mm->mmap_sem)) { + if (!in_atomic) + mmput(mm); + continue; + } + + for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) { + struct vm_area_struct *vma; + + vma = rb_entry(n, struct vm_area_struct, vm_rb); + + if (address >= vma->vm_start && address < vma->vm_end) { + char _tmpbuf[256]; + char *name = p->comm; + struct file *file = vma->vm_file; + + if (file) { + char *d_name = d_path(&file->f_path, _tmpbuf, + sizeof(_tmpbuf)); + if (!IS_ERR(d_name)) + name = d_name; + } + + /* FLAT does not have its text aligned to the start of + * the map while FDPIC ELF does ... + */ + + /* before we can check flat/fdpic, we need to + * make sure current is valid + */ + if ((unsigned long)current >= FIXED_CODE_START && + !((unsigned long)current & 0x3)) { + if (current->mm && + (address > current->mm->start_code) && + (address < current->mm->end_code)) + offset = address - current->mm->start_code; + else + offset = (address - vma->vm_start) + + (vma->vm_pgoff << PAGE_SHIFT); + + sprintf(buf, "[ %s + 0x%lx ]", name, offset); + } else + sprintf(buf, "[ %s vma:0x%lx-0x%lx]", + name, vma->vm_start, vma->vm_end); + + up_read(&mm->mmap_sem); + if (!in_atomic) + mmput(mm); + + if (buf[0] == '\0') + sprintf(buf, "[ %s ] dynamic memory", name); + + goto done; + } + } + + up_read(&mm->mmap_sem); + if (!in_atomic) + mmput(mm); + } + + /* + * we were unable to find this address anywhere, + * or some MMs were skipped because they were in use. + */ + sprintf(buf, "/* kernel dynamic memory */"); + +done: + write_unlock_irqrestore(&tasklist_lock, flags); +#else + sprintf(buf, " "); +#endif +} + +#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) + +/* + * Similar to get_user, do some address checking, then dereference + * Return true on success, false on bad address + */ +bool get_instruction(unsigned short *val, unsigned short *address) +{ + unsigned long addr = (unsigned long)address; + + /* Check for odd addresses */ + if (addr & 0x1) + return false; + + /* MMR region will never have instructions */ + if (addr >= SYSMMR_BASE) + return false; + + switch (bfin_mem_access_type(addr, 2)) { + case BFIN_MEM_ACCESS_CORE: + case BFIN_MEM_ACCESS_CORE_ONLY: + *val = *address; + return true; + case BFIN_MEM_ACCESS_DMA: + dma_memcpy(val, address, 2); + return true; + case BFIN_MEM_ACCESS_ITEST: + isram_memcpy(val, address, 2); + return true; + default: /* invalid access */ + return false; + } +} + +/* + * decode the instruction if we are printing out the trace, as it + * makes things easier to follow, without running it through objdump + * These are the normal instructions which cause change of flow, which + * would be at the source of the trace buffer + */ +#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) +static void decode_instruction(unsigned short *address) +{ + unsigned short opcode; + + if (get_instruction(&opcode, address)) { + if (opcode == 0x0010) + verbose_printk("RTS"); + else if (opcode == 0x0011) + verbose_printk("RTI"); + else if (opcode == 0x0012) + verbose_printk("RTX"); + else if (opcode == 0x0013) + verbose_printk("RTN"); + else if (opcode == 0x0014) + verbose_printk("RTE"); + else if (opcode == 0x0025) + verbose_printk("EMUEXCPT"); + else if (opcode >= 0x0040 && opcode <= 0x0047) + verbose_printk("STI R%i", opcode & 7); + else if (opcode >= 0x0050 && opcode <= 0x0057) + verbose_printk("JUMP (P%i)", opcode & 7); + else if (opcode >= 0x0060 && opcode <= 0x0067) + verbose_printk("CALL (P%i)", opcode & 7); + else if (opcode >= 0x0070 && opcode <= 0x0077) + verbose_printk("CALL (PC+P%i)", opcode & 7); + else if (opcode >= 0x0080 && opcode <= 0x0087) + verbose_printk("JUMP (PC+P%i)", opcode & 7); + else if (opcode >= 0x0090 && opcode <= 0x009F) + verbose_printk("RAISE 0x%x", opcode & 0xF); + else if (opcode >= 0x00A0 && opcode <= 0x00AF) + verbose_printk("EXCPT 0x%x", opcode & 0xF); + else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) + verbose_printk("IF !CC JUMP"); + else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) + verbose_printk("IF CC JUMP"); + else if (opcode >= 0x2000 && opcode <= 0x2fff) + verbose_printk("JUMP.S"); + else if (opcode >= 0xe080 && opcode <= 0xe0ff) + verbose_printk("LSETUP"); + else if (opcode >= 0xe200 && opcode <= 0xe2ff) + verbose_printk("JUMP.L"); + else if (opcode >= 0xe300 && opcode <= 0xe3ff) + verbose_printk("CALL pcrel"); + else + verbose_printk("0x%04x", opcode); + } + +} +#endif + +void dump_bfin_trace_buffer(void) +{ +#ifdef CONFIG_DEBUG_VERBOSE +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON + int tflags, i = 0; + char buf[150]; + unsigned short *addr; +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND + int j, index; +#endif + + trace_buffer_save(tflags); + + printk(KERN_NOTICE "Hardware Trace:\n"); + +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND + printk(KERN_NOTICE "WARNING: Expanded trace turned on - can not trace exceptions\n"); +#endif + + if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { + for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { + decode_address(buf, (unsigned long)bfin_read_TBUF()); + printk(KERN_NOTICE "%4i Target : %s\n", i, buf); + addr = (unsigned short *)bfin_read_TBUF(); + decode_address(buf, (unsigned long)addr); + printk(KERN_NOTICE " Source : %s ", buf); + decode_instruction(addr); + printk("\n"); + } + } + +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND + if (trace_buff_offset) + index = trace_buff_offset / 4; + else + index = EXPAND_LEN; + + j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128; + while (j) { + decode_address(buf, software_trace_buff[index]); + printk(KERN_NOTICE "%4i Target : %s\n", i, buf); + index -= 1; + if (index < 0) + index = EXPAND_LEN; + decode_address(buf, software_trace_buff[index]); + printk(KERN_NOTICE " Source : %s ", buf); + decode_instruction((unsigned short *)software_trace_buff[index]); + printk("\n"); + index -= 1; + if (index < 0) + index = EXPAND_LEN; + j--; + i++; + } +#endif + + trace_buffer_restore(tflags); +#endif +#endif +} +EXPORT_SYMBOL(dump_bfin_trace_buffer); + +void dump_bfin_process(struct pt_regs *fp) +{ +#ifdef CONFIG_DEBUG_VERBOSE + /* We should be able to look at fp->ipend, but we don't push it on the + * stack all the time, so do this until we fix that */ + unsigned int context = bfin_read_IPEND(); + + if (oops_in_progress) + verbose_printk(KERN_EMERG "Kernel OOPS in progress\n"); + + if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) + verbose_printk(KERN_NOTICE "HW Error context\n"); + else if (context & 0x0020) + verbose_printk(KERN_NOTICE "Deferred Exception context\n"); + else if (context & 0x3FC0) + verbose_printk(KERN_NOTICE "Interrupt context\n"); + else if (context & 0x4000) + verbose_printk(KERN_NOTICE "Deferred Interrupt context\n"); + else if (context & 0x8000) + verbose_printk(KERN_NOTICE "Kernel process context\n"); + + /* Because we are crashing, and pointers could be bad, we check things + * pretty closely before we use them + */ + if ((unsigned long)current >= FIXED_CODE_START && + !((unsigned long)current & 0x3) && current->pid) { + verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); + if (current->comm >= (char *)FIXED_CODE_START) + verbose_printk(KERN_NOTICE "COMM=%s PID=%d", + current->comm, current->pid); + else + verbose_printk(KERN_NOTICE "COMM= invalid"); + + printk(KERN_CONT " CPU=%d\n", current_thread_info()->cpu); + if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) + verbose_printk(KERN_NOTICE + "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" + " BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", + (void *)current->mm->start_code, + (void *)current->mm->end_code, + (void *)current->mm->start_data, + (void *)current->mm->end_data, + (void *)current->mm->end_data, + (void *)current->mm->brk, + (void *)current->mm->start_stack); + else + verbose_printk(KERN_NOTICE "invalid mm\n"); + } else + verbose_printk(KERN_NOTICE + "No Valid process in current context\n"); +#endif +} + +void dump_bfin_mem(struct pt_regs *fp) +{ +#ifdef CONFIG_DEBUG_VERBOSE + unsigned short *addr, *erraddr, val = 0, err = 0; + char sti = 0, buf[6]; + + erraddr = (void *)fp->pc; + + verbose_printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); + + for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10; + addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10; + addr++) { + if (!((unsigned long)addr & 0xF)) + verbose_printk(KERN_NOTICE "0x%p: ", addr); + + if (!get_instruction(&val, addr)) { + val = 0; + sprintf(buf, "????"); + } else + sprintf(buf, "%04x", val); + + if (addr == erraddr) { + verbose_printk("[%s]", buf); + err = val; + } else + verbose_printk(" %s ", buf); + + /* Do any previous instructions turn on interrupts? */ + if (addr <= erraddr && /* in the past */ + ((val >= 0x0040 && val <= 0x0047) || /* STI instruction */ + val == 0x017b)) /* [SP++] = RETI */ + sti = 1; + } + + verbose_printk("\n"); + + /* Hardware error interrupts can be deferred */ + if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR && + oops_in_progress)){ + verbose_printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); +#ifndef CONFIG_DEBUG_HWERR + verbose_printk(KERN_NOTICE +"The remaining message may be meaningless\n" +"You should enable CONFIG_DEBUG_HWERR to get a better idea where it came from\n"); +#else + /* If we are handling only one peripheral interrupt + * and current mm and pid are valid, and the last error + * was in that user space process's text area + * print it out - because that is where the problem exists + */ + if ((!(((fp)->ipend & ~0x30) & (((fp)->ipend & ~0x30) - 1))) && + (current->pid && current->mm)) { + /* And the last RETI points to the current userspace context */ + if ((fp + 1)->pc >= current->mm->start_code && + (fp + 1)->pc <= current->mm->end_code) { + verbose_printk(KERN_NOTICE "It might be better to look around here :\n"); + verbose_printk(KERN_NOTICE "-------------------------------------------\n"); + show_regs(fp + 1); + verbose_printk(KERN_NOTICE "-------------------------------------------\n"); + } + } +#endif + } +#endif +} + +void show_regs(struct pt_regs *fp) +{ +#ifdef CONFIG_DEBUG_VERBOSE + char buf[150]; + struct irqaction *action; + unsigned int i; + unsigned long flags = 0; + unsigned int cpu = raw_smp_processor_id(); + unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); + + verbose_printk(KERN_NOTICE "\n"); + if (CPUID != bfin_cpuid()) + verbose_printk(KERN_NOTICE "Compiled for cpu family 0x%04x (Rev %d), " + "but running on:0x%04x (Rev %d)\n", + CPUID, bfin_compiled_revid(), bfin_cpuid(), bfin_revid()); + + verbose_printk(KERN_NOTICE "ADSP-%s-0.%d", + CPU, bfin_compiled_revid()); + + if (bfin_compiled_revid() != bfin_revid()) + verbose_printk("(Detected 0.%d)", bfin_revid()); + + verbose_printk(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", + get_cclk()/1000000, get_sclk()/1000000, +#ifdef CONFIG_MPU + "mpu on" +#else + "mpu off" +#endif + ); + + verbose_printk(KERN_NOTICE "%s", linux_banner); + + verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted()); + verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n", + (long)fp->seqstat, fp->ipend, cpu_pda[raw_smp_processor_id()].ex_imask, fp->syscfg); + if (fp->ipend & EVT_IRPTEN) + verbose_printk(KERN_NOTICE " Global Interrupts Disabled (IPEND[4])\n"); + if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 | + EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR))) + verbose_printk(KERN_NOTICE " Peripheral interrupts masked off\n"); + if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14))) + verbose_printk(KERN_NOTICE " Kernel interrupts masked off\n"); + if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { + verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", + (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); +#ifdef EBIU_ERRMST + /* If the error was from the EBIU, print it out */ + if (bfin_read_EBIU_ERRMST() & CORE_ERROR) { + verbose_printk(KERN_NOTICE " EBIU Error Reason : 0x%04x\n", + bfin_read_EBIU_ERRMST()); + verbose_printk(KERN_NOTICE " EBIU Error Address : 0x%08x\n", + bfin_read_EBIU_ERRADD()); + } +#endif + } + verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", + fp->seqstat & SEQSTAT_EXCAUSE); + for (i = 2; i <= 15 ; i++) { + if (fp->ipend & (1 << i)) { + if (i != 4) { + decode_address(buf, bfin_read32(EVT0 + 4*i)); + verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); + } else + verbose_printk(KERN_NOTICE " interrupts disabled\n"); + } + } + + /* if no interrupts are going off, don't print this out */ + if (fp->ipend & ~0x3F) { + for (i = 0; i < (NR_IRQS - 1); i++) { + if (!in_atomic) + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); + + action = irq_desc[i].action; + if (!action) + goto unlock; + + decode_address(buf, (unsigned int)action->handler); + verbose_printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); + for (action = action->next; action; action = action->next) { + decode_address(buf, (unsigned int)action->handler); + verbose_printk(", %s", buf); + } + verbose_printk("\n"); +unlock: + if (!in_atomic) + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); + } + } + + decode_address(buf, fp->rete); + verbose_printk(KERN_NOTICE " RETE: %s\n", buf); + decode_address(buf, fp->retn); + verbose_printk(KERN_NOTICE " RETN: %s\n", buf); + decode_address(buf, fp->retx); + verbose_printk(KERN_NOTICE " RETX: %s\n", buf); + decode_address(buf, fp->rets); + verbose_printk(KERN_NOTICE " RETS: %s\n", buf); + decode_address(buf, fp->pc); + verbose_printk(KERN_NOTICE " PC : %s\n", buf); + + if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && + (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { + decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); + verbose_printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); + decode_address(buf, cpu_pda[cpu].icplb_fault_addr); + verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); + } + + verbose_printk(KERN_NOTICE "PROCESSOR STATE:\n"); + verbose_printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", + fp->r0, fp->r1, fp->r2, fp->r3); + verbose_printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", + fp->r4, fp->r5, fp->r6, fp->r7); + verbose_printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", + fp->p0, fp->p1, fp->p2, fp->p3); + verbose_printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", + fp->p4, fp->p5, fp->fp, (long)fp); + verbose_printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", + fp->lb0, fp->lt0, fp->lc0); + verbose_printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", + fp->lb1, fp->lt1, fp->lc1); + verbose_printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", + fp->b0, fp->l0, fp->m0, fp->i0); + verbose_printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", + fp->b1, fp->l1, fp->m1, fp->i1); + verbose_printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", + fp->b2, fp->l2, fp->m2, fp->i2); + verbose_printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", + fp->b3, fp->l3, fp->m3, fp->i3); + verbose_printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", + fp->a0w, fp->a0x, fp->a1w, fp->a1x); + + verbose_printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", + rdusp(), fp->astat); + + verbose_printk(KERN_NOTICE "\n"); +#endif +} diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index ba70c4bc2699..891cc39f7eec 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -1,20 +1,16 @@ /* - * Copyright 2004-2009 Analog Devices Inc. + * Main exception handling logic. + * + * Copyright 2004-2010 Analog Devices Inc. * * Licensed under the GPL-2 or later */ #include #include -#include #include -#include -#include -#include #include -#include #include -#include #include #include #include @@ -62,194 +58,6 @@ void __init trap_init(void) CSYNC(); } -static void decode_address(char *buf, unsigned long address) -{ -#ifdef CONFIG_DEBUG_VERBOSE - struct task_struct *p; - struct mm_struct *mm; - unsigned long flags, offset; - unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); - struct rb_node *n; - -#ifdef CONFIG_KALLSYMS - unsigned long symsize; - const char *symname; - char *modname; - char *delim = ":"; - char namebuf[128]; -#endif - - buf += sprintf(buf, "<0x%08lx> ", address); - -#ifdef CONFIG_KALLSYMS - /* look up the address and see if we are in kernel space */ - symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); - - if (symname) { - /* yeah! kernel space! */ - if (!modname) - modname = delim = ""; - sprintf(buf, "{ %s%s%s%s + 0x%lx }", - delim, modname, delim, symname, - (unsigned long)offset); - return; - } -#endif - - if (address >= FIXED_CODE_START && address < FIXED_CODE_END) { - /* Problem in fixed code section? */ - strcat(buf, "/* Maybe fixed code section */"); - return; - - } else if (address < CONFIG_BOOT_LOAD) { - /* Problem somewhere before the kernel start address */ - strcat(buf, "/* Maybe null pointer? */"); - return; - - } else if (address >= COREMMR_BASE) { - strcat(buf, "/* core mmrs */"); - return; - - } else if (address >= SYSMMR_BASE) { - strcat(buf, "/* system mmrs */"); - return; - - } else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) { - strcat(buf, "/* on-chip L1 ROM */"); - return; - } - - /* - * Don't walk any of the vmas if we are oopsing, it has been known - * to cause problems - corrupt vmas (kernel crashes) cause double faults - */ - if (oops_in_progress) { - strcat(buf, "/* kernel dynamic memory (maybe user-space) */"); - return; - } - - /* looks like we're off in user-land, so let's walk all the - * mappings of all our processes and see if we can't be a whee - * bit more specific - */ - write_lock_irqsave(&tasklist_lock, flags); - for_each_process(p) { - mm = (in_atomic ? p->mm : get_task_mm(p)); - if (!mm) - continue; - - if (!down_read_trylock(&mm->mmap_sem)) { - if (!in_atomic) - mmput(mm); - continue; - } - - for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) { - struct vm_area_struct *vma; - - vma = rb_entry(n, struct vm_area_struct, vm_rb); - - if (address >= vma->vm_start && address < vma->vm_end) { - char _tmpbuf[256]; - char *name = p->comm; - struct file *file = vma->vm_file; - - if (file) { - char *d_name = d_path(&file->f_path, _tmpbuf, - sizeof(_tmpbuf)); - if (!IS_ERR(d_name)) - name = d_name; - } - - /* FLAT does not have its text aligned to the start of - * the map while FDPIC ELF does ... - */ - - /* before we can check flat/fdpic, we need to - * make sure current is valid - */ - if ((unsigned long)current >= FIXED_CODE_START && - !((unsigned long)current & 0x3)) { - if (current->mm && - (address > current->mm->start_code) && - (address < current->mm->end_code)) - offset = address - current->mm->start_code; - else - offset = (address - vma->vm_start) + - (vma->vm_pgoff << PAGE_SHIFT); - - sprintf(buf, "[ %s + 0x%lx ]", name, offset); - } else - sprintf(buf, "[ %s vma:0x%lx-0x%lx]", - name, vma->vm_start, vma->vm_end); - - up_read(&mm->mmap_sem); - if (!in_atomic) - mmput(mm); - - if (buf[0] == '\0') - sprintf(buf, "[ %s ] dynamic memory", name); - - goto done; - } - } - - up_read(&mm->mmap_sem); - if (!in_atomic) - mmput(mm); - } - - /* - * we were unable to find this address anywhere, - * or some MMs were skipped because they were in use. - */ - sprintf(buf, "/* kernel dynamic memory */"); - -done: - write_unlock_irqrestore(&tasklist_lock, flags); -#else - sprintf(buf, " "); -#endif -} - -asmlinkage void double_fault_c(struct pt_regs *fp) -{ -#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON - int j; - trace_buffer_save(j); -#endif - - console_verbose(); - oops_in_progress = 1; -#ifdef CONFIG_DEBUG_VERBOSE - printk(KERN_EMERG "Double Fault\n"); -#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT - if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { - unsigned int cpu = raw_smp_processor_id(); - char buf[150]; - decode_address(buf, cpu_pda[cpu].retx_doublefault); - printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", - (unsigned int)cpu_pda[cpu].seqstat_doublefault & SEQSTAT_EXCAUSE, buf); - decode_address(buf, cpu_pda[cpu].dcplb_doublefault_addr); - printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); - decode_address(buf, cpu_pda[cpu].icplb_doublefault_addr); - printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); - - decode_address(buf, fp->retx); - printk(KERN_NOTICE "The instruction at %s caused a double exception\n", buf); - } else -#endif - { - dump_bfin_process(fp); - dump_bfin_mem(fp); - show_regs(fp); - dump_bfin_trace_buffer(); - } -#endif - panic("Double Fault - unrecoverable event"); - -} - static int kernel_mode_regs(struct pt_regs *regs) { return regs->ipend & 0xffc0; @@ -672,659 +480,44 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) trace_buffer_restore(j); } -/* Typical exception handling routines */ - -#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) - -/* - * Similar to get_user, do some address checking, then dereference - * Return true on success, false on bad address - */ -static bool get_instruction(unsigned short *val, unsigned short *address) -{ - unsigned long addr = (unsigned long)address; - - /* Check for odd addresses */ - if (addr & 0x1) - return false; - - /* MMR region will never have instructions */ - if (addr >= SYSMMR_BASE) - return false; - - switch (bfin_mem_access_type(addr, 2)) { - case BFIN_MEM_ACCESS_CORE: - case BFIN_MEM_ACCESS_CORE_ONLY: - *val = *address; - return true; - case BFIN_MEM_ACCESS_DMA: - dma_memcpy(val, address, 2); - return true; - case BFIN_MEM_ACCESS_ITEST: - isram_memcpy(val, address, 2); - return true; - default: /* invalid access */ - return false; - } -} - -/* - * decode the instruction if we are printing out the trace, as it - * makes things easier to follow, without running it through objdump - * These are the normal instructions which cause change of flow, which - * would be at the source of the trace buffer - */ -#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) -static void decode_instruction(unsigned short *address) -{ - unsigned short opcode; - - if (get_instruction(&opcode, address)) { - if (opcode == 0x0010) - verbose_printk("RTS"); - else if (opcode == 0x0011) - verbose_printk("RTI"); - else if (opcode == 0x0012) - verbose_printk("RTX"); - else if (opcode == 0x0013) - verbose_printk("RTN"); - else if (opcode == 0x0014) - verbose_printk("RTE"); - else if (opcode == 0x0025) - verbose_printk("EMUEXCPT"); - else if (opcode >= 0x0040 && opcode <= 0x0047) - verbose_printk("STI R%i", opcode & 7); - else if (opcode >= 0x0050 && opcode <= 0x0057) - verbose_printk("JUMP (P%i)", opcode & 7); - else if (opcode >= 0x0060 && opcode <= 0x0067) - verbose_printk("CALL (P%i)", opcode & 7); - else if (opcode >= 0x0070 && opcode <= 0x0077) - verbose_printk("CALL (PC+P%i)", opcode & 7); - else if (opcode >= 0x0080 && opcode <= 0x0087) - verbose_printk("JUMP (PC+P%i)", opcode & 7); - else if (opcode >= 0x0090 && opcode <= 0x009F) - verbose_printk("RAISE 0x%x", opcode & 0xF); - else if (opcode >= 0x00A0 && opcode <= 0x00AF) - verbose_printk("EXCPT 0x%x", opcode & 0xF); - else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) - verbose_printk("IF !CC JUMP"); - else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) - verbose_printk("IF CC JUMP"); - else if (opcode >= 0x2000 && opcode <= 0x2fff) - verbose_printk("JUMP.S"); - else if (opcode >= 0xe080 && opcode <= 0xe0ff) - verbose_printk("LSETUP"); - else if (opcode >= 0xe200 && opcode <= 0xe2ff) - verbose_printk("JUMP.L"); - else if (opcode >= 0xe300 && opcode <= 0xe3ff) - verbose_printk("CALL pcrel"); - else - verbose_printk("0x%04x", opcode); - } - -} -#endif - -void dump_bfin_trace_buffer(void) -{ -#ifdef CONFIG_DEBUG_VERBOSE -#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON - int tflags, i = 0; - char buf[150]; - unsigned short *addr; -#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND - int j, index; -#endif - - trace_buffer_save(tflags); - - printk(KERN_NOTICE "Hardware Trace:\n"); - -#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND - printk(KERN_NOTICE "WARNING: Expanded trace turned on - can not trace exceptions\n"); -#endif - - if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { - for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { - decode_address(buf, (unsigned long)bfin_read_TBUF()); - printk(KERN_NOTICE "%4i Target : %s\n", i, buf); - addr = (unsigned short *)bfin_read_TBUF(); - decode_address(buf, (unsigned long)addr); - printk(KERN_NOTICE " Source : %s ", buf); - decode_instruction(addr); - printk("\n"); - } - } - -#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND - if (trace_buff_offset) - index = trace_buff_offset / 4; - else - index = EXPAND_LEN; - - j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128; - while (j) { - decode_address(buf, software_trace_buff[index]); - printk(KERN_NOTICE "%4i Target : %s\n", i, buf); - index -= 1; - if (index < 0 ) - index = EXPAND_LEN; - decode_address(buf, software_trace_buff[index]); - printk(KERN_NOTICE " Source : %s ", buf); - decode_instruction((unsigned short *)software_trace_buff[index]); - printk("\n"); - index -= 1; - if (index < 0) - index = EXPAND_LEN; - j--; - i++; - } -#endif - - trace_buffer_restore(tflags); -#endif -#endif -} -EXPORT_SYMBOL(dump_bfin_trace_buffer); - -#ifdef CONFIG_BUG -int is_valid_bugaddr(unsigned long addr) -{ - unsigned short opcode; - - if (!get_instruction(&opcode, (unsigned short *)addr)) - return 0; - - return opcode == BFIN_BUG_OPCODE; -} -#endif - -/* - * Checks to see if the address pointed to is either a - * 16-bit CALL instruction, or a 32-bit CALL instruction - */ -static bool is_bfin_call(unsigned short *addr) -{ - unsigned short opcode = 0, *ins_addr; - ins_addr = (unsigned short *)addr; - - if (!get_instruction(&opcode, ins_addr)) - return false; - - if ((opcode >= 0x0060 && opcode <= 0x0067) || - (opcode >= 0x0070 && opcode <= 0x0077)) - return true; - - ins_addr--; - if (!get_instruction(&opcode, ins_addr)) - return false; - - if (opcode >= 0xE300 && opcode <= 0xE3FF) - return true; - - return false; - -} - -void show_stack(struct task_struct *task, unsigned long *stack) -{ -#ifdef CONFIG_PRINTK - unsigned int *addr, *endstack, *fp = 0, *frame; - unsigned short *ins_addr; - char buf[150]; - unsigned int i, j, ret_addr, frame_no = 0; - - /* - * If we have been passed a specific stack, use that one otherwise - * if we have been passed a task structure, use that, otherwise - * use the stack of where the variable "stack" exists - */ - - if (stack == NULL) { - if (task) { - /* We know this is a kernel stack, so this is the start/end */ - stack = (unsigned long *)task->thread.ksp; - endstack = (unsigned int *)(((unsigned int)(stack) & ~(THREAD_SIZE - 1)) + THREAD_SIZE); - } else { - /* print out the existing stack info */ - stack = (unsigned long *)&stack; - endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); - } - } else - endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); - - printk(KERN_NOTICE "Stack info:\n"); - decode_address(buf, (unsigned int)stack); - printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); - - if (!access_ok(VERIFY_READ, stack, (unsigned int)endstack - (unsigned int)stack)) { - printk(KERN_NOTICE "Invalid stack pointer\n"); - return; - } - - /* First thing is to look for a frame pointer */ - for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { - if (*addr & 0x1) - continue; - ins_addr = (unsigned short *)*addr; - ins_addr--; - if (is_bfin_call(ins_addr)) - fp = addr - 1; - - if (fp) { - /* Let's check to see if it is a frame pointer */ - while (fp >= (addr - 1) && fp < endstack - && fp && ((unsigned int) fp & 0x3) == 0) - fp = (unsigned int *)*fp; - if (fp == 0 || fp == endstack) { - fp = addr - 1; - break; - } - fp = 0; - } - } - if (fp) { - frame = fp; - printk(KERN_NOTICE " FP: (0x%p)\n", fp); - } else - frame = 0; - - /* - * Now that we think we know where things are, we - * walk the stack again, this time printing things out - * incase there is no frame pointer, we still look for - * valid return addresses - */ - - /* First time print out data, next time, print out symbols */ - for (j = 0; j <= 1; j++) { - if (j) - printk(KERN_NOTICE "Return addresses in stack:\n"); - else - printk(KERN_NOTICE " Memory from 0x%08lx to %p", ((long unsigned int)stack & ~0xF), endstack); - - fp = frame; - frame_no = 0; - - for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; - addr < endstack; addr++, i++) { - - ret_addr = 0; - if (!j && i % 8 == 0) - printk(KERN_NOTICE "%p:",addr); - - /* if it is an odd address, or zero, just skip it */ - if (*addr & 0x1 || !*addr) - goto print; - - ins_addr = (unsigned short *)*addr; - - /* Go back one instruction, and see if it is a CALL */ - ins_addr--; - ret_addr = is_bfin_call(ins_addr); - print: - if (!j && stack == (unsigned long *)addr) - printk("[%08x]", *addr); - else if (ret_addr) - if (j) { - decode_address(buf, (unsigned int)*addr); - if (frame == addr) { - printk(KERN_NOTICE " frame %2i : %s\n", frame_no, buf); - continue; - } - printk(KERN_NOTICE " address : %s\n", buf); - } else - printk("<%08x>", *addr); - else if (fp == addr) { - if (j) - frame = addr+1; - else - printk("(%08x)", *addr); - - fp = (unsigned int *)*addr; - frame_no++; - - } else if (!j) - printk(" %08x ", *addr); - } - if (!j) - printk("\n"); - } -#endif -} -EXPORT_SYMBOL(show_stack); - -void dump_stack(void) +asmlinkage void double_fault_c(struct pt_regs *fp) { - unsigned long stack; #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON - int tflags; + int j; + trace_buffer_save(j); #endif - trace_buffer_save(tflags); - dump_bfin_trace_buffer(); - show_stack(current, &stack); - trace_buffer_restore(tflags); -} -EXPORT_SYMBOL(dump_stack); -void dump_bfin_process(struct pt_regs *fp) -{ + console_verbose(); + oops_in_progress = 1; #ifdef CONFIG_DEBUG_VERBOSE - /* We should be able to look at fp->ipend, but we don't push it on the - * stack all the time, so do this until we fix that */ - unsigned int context = bfin_read_IPEND(); - - if (oops_in_progress) - verbose_printk(KERN_EMERG "Kernel OOPS in progress\n"); - - if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) - verbose_printk(KERN_NOTICE "HW Error context\n"); - else if (context & 0x0020) - verbose_printk(KERN_NOTICE "Deferred Exception context\n"); - else if (context & 0x3FC0) - verbose_printk(KERN_NOTICE "Interrupt context\n"); - else if (context & 0x4000) - verbose_printk(KERN_NOTICE "Deferred Interrupt context\n"); - else if (context & 0x8000) - verbose_printk(KERN_NOTICE "Kernel process context\n"); - - /* Because we are crashing, and pointers could be bad, we check things - * pretty closely before we use them - */ - if ((unsigned long)current >= FIXED_CODE_START && - !((unsigned long)current & 0x3) && current->pid) { - verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); - if (current->comm >= (char *)FIXED_CODE_START) - verbose_printk(KERN_NOTICE "COMM=%s PID=%d", - current->comm, current->pid); - else - verbose_printk(KERN_NOTICE "COMM= invalid"); + printk(KERN_EMERG "Double Fault\n"); +#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT + if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { + unsigned int cpu = raw_smp_processor_id(); + char buf[150]; + decode_address(buf, cpu_pda[cpu].retx_doublefault); + printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", + (unsigned int)cpu_pda[cpu].seqstat_doublefault & SEQSTAT_EXCAUSE, buf); + decode_address(buf, cpu_pda[cpu].dcplb_doublefault_addr); + printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); + decode_address(buf, cpu_pda[cpu].icplb_doublefault_addr); + printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); - printk(KERN_CONT " CPU=%d\n", current_thread_info()->cpu); - if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) - verbose_printk(KERN_NOTICE - "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" - " BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", - (void *)current->mm->start_code, - (void *)current->mm->end_code, - (void *)current->mm->start_data, - (void *)current->mm->end_data, - (void *)current->mm->end_data, - (void *)current->mm->brk, - (void *)current->mm->start_stack); - else - verbose_printk(KERN_NOTICE "invalid mm\n"); + decode_address(buf, fp->retx); + printk(KERN_NOTICE "The instruction at %s caused a double exception\n", buf); } else - verbose_printk(KERN_NOTICE - "No Valid process in current context\n"); -#endif -} - -void dump_bfin_mem(struct pt_regs *fp) -{ -#ifdef CONFIG_DEBUG_VERBOSE - unsigned short *addr, *erraddr, val = 0, err = 0; - char sti = 0, buf[6]; - - erraddr = (void *)fp->pc; - - verbose_printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); - - for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10; - addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10; - addr++) { - if (!((unsigned long)addr & 0xF)) - verbose_printk(KERN_NOTICE "0x%p: ", addr); - - if (!get_instruction(&val, addr)) { - val = 0; - sprintf(buf, "????"); - } else - sprintf(buf, "%04x", val); - - if (addr == erraddr) { - verbose_printk("[%s]", buf); - err = val; - } else - verbose_printk(" %s ", buf); - - /* Do any previous instructions turn on interrupts? */ - if (addr <= erraddr && /* in the past */ - ((val >= 0x0040 && val <= 0x0047) || /* STI instruction */ - val == 0x017b)) /* [SP++] = RETI */ - sti = 1; - } - - verbose_printk("\n"); - - /* Hardware error interrupts can be deferred */ - if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR && - oops_in_progress)){ - verbose_printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); -#ifndef CONFIG_DEBUG_HWERR - verbose_printk(KERN_NOTICE -"The remaining message may be meaningless\n" -"You should enable CONFIG_DEBUG_HWERR to get a better idea where it came from\n"); -#else - /* If we are handling only one peripheral interrupt - * and current mm and pid are valid, and the last error - * was in that user space process's text area - * print it out - because that is where the problem exists - */ - if ((!(((fp)->ipend & ~0x30) & (((fp)->ipend & ~0x30) - 1))) && - (current->pid && current->mm)) { - /* And the last RETI points to the current userspace context */ - if ((fp + 1)->pc >= current->mm->start_code && - (fp + 1)->pc <= current->mm->end_code) { - verbose_printk(KERN_NOTICE "It might be better to look around here :\n"); - verbose_printk(KERN_NOTICE "-------------------------------------------\n"); - show_regs(fp + 1); - verbose_printk(KERN_NOTICE "-------------------------------------------\n"); - } - } -#endif - } -#endif -} - -void show_regs(struct pt_regs *fp) -{ -#ifdef CONFIG_DEBUG_VERBOSE - char buf [150]; - struct irqaction *action; - unsigned int i; - unsigned long flags = 0; - unsigned int cpu = raw_smp_processor_id(); - unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); - - verbose_printk(KERN_NOTICE "\n"); - if (CPUID != bfin_cpuid()) - verbose_printk(KERN_NOTICE "Compiled for cpu family 0x%04x (Rev %d), " - "but running on:0x%04x (Rev %d)\n", - CPUID, bfin_compiled_revid(), bfin_cpuid(), bfin_revid()); - - verbose_printk(KERN_NOTICE "ADSP-%s-0.%d", - CPU, bfin_compiled_revid()); - - if (bfin_compiled_revid() != bfin_revid()) - verbose_printk("(Detected 0.%d)", bfin_revid()); - - verbose_printk(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", - get_cclk()/1000000, get_sclk()/1000000, -#ifdef CONFIG_MPU - "mpu on" -#else - "mpu off" #endif - ); - - verbose_printk(KERN_NOTICE "%s", linux_banner); - - verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted()); - verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n", - (long)fp->seqstat, fp->ipend, cpu_pda[raw_smp_processor_id()].ex_imask, fp->syscfg); - if (fp->ipend & EVT_IRPTEN) - verbose_printk(KERN_NOTICE " Global Interrupts Disabled (IPEND[4])\n"); - if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 | - EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR))) - verbose_printk(KERN_NOTICE " Peripheral interrupts masked off\n"); - if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14))) - verbose_printk(KERN_NOTICE " Kernel interrupts masked off\n"); - if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { - verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", - (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); -#ifdef EBIU_ERRMST - /* If the error was from the EBIU, print it out */ - if (bfin_read_EBIU_ERRMST() & CORE_ERROR) { - verbose_printk(KERN_NOTICE " EBIU Error Reason : 0x%04x\n", - bfin_read_EBIU_ERRMST()); - verbose_printk(KERN_NOTICE " EBIU Error Address : 0x%08x\n", - bfin_read_EBIU_ERRADD()); - } -#endif - } - verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", - fp->seqstat & SEQSTAT_EXCAUSE); - for (i = 2; i <= 15 ; i++) { - if (fp->ipend & (1 << i)) { - if (i != 4) { - decode_address(buf, bfin_read32(EVT0 + 4*i)); - verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); - } else - verbose_printk(KERN_NOTICE " interrupts disabled\n"); - } - } - - /* if no interrupts are going off, don't print this out */ - if (fp->ipend & ~0x3F) { - for (i = 0; i < (NR_IRQS - 1); i++) { - if (!in_atomic) - raw_spin_lock_irqsave(&irq_desc[i].lock, flags); - - action = irq_desc[i].action; - if (!action) - goto unlock; - - decode_address(buf, (unsigned int)action->handler); - verbose_printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); - for (action = action->next; action; action = action->next) { - decode_address(buf, (unsigned int)action->handler); - verbose_printk(", %s", buf); - } - verbose_printk("\n"); -unlock: - if (!in_atomic) - raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } - } - - decode_address(buf, fp->rete); - verbose_printk(KERN_NOTICE " RETE: %s\n", buf); - decode_address(buf, fp->retn); - verbose_printk(KERN_NOTICE " RETN: %s\n", buf); - decode_address(buf, fp->retx); - verbose_printk(KERN_NOTICE " RETX: %s\n", buf); - decode_address(buf, fp->rets); - verbose_printk(KERN_NOTICE " RETS: %s\n", buf); - decode_address(buf, fp->pc); - verbose_printk(KERN_NOTICE " PC : %s\n", buf); - - if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && - (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { - decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); - verbose_printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); - decode_address(buf, cpu_pda[cpu].icplb_fault_addr); - verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); + { + dump_bfin_process(fp); + dump_bfin_mem(fp); + show_regs(fp); + dump_bfin_trace_buffer(); } - - verbose_printk(KERN_NOTICE "PROCESSOR STATE:\n"); - verbose_printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", - fp->r0, fp->r1, fp->r2, fp->r3); - verbose_printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", - fp->r4, fp->r5, fp->r6, fp->r7); - verbose_printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", - fp->p0, fp->p1, fp->p2, fp->p3); - verbose_printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", - fp->p4, fp->p5, fp->fp, (long)fp); - verbose_printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", - fp->lb0, fp->lt0, fp->lc0); - verbose_printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", - fp->lb1, fp->lt1, fp->lc1); - verbose_printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", - fp->b0, fp->l0, fp->m0, fp->i0); - verbose_printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", - fp->b1, fp->l1, fp->m1, fp->i1); - verbose_printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", - fp->b2, fp->l2, fp->m2, fp->i2); - verbose_printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", - fp->b3, fp->l3, fp->m3, fp->i3); - verbose_printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", - fp->a0w, fp->a0x, fp->a1w, fp->a1x); - - verbose_printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", - rdusp(), fp->astat); - - verbose_printk(KERN_NOTICE "\n"); -#endif -} - -#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1 -asmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text)); #endif + panic("Double Fault - unrecoverable event"); -static DEFINE_SPINLOCK(bfin_spinlock_lock); - -asmlinkage int sys_bfin_spinlock(int *p) -{ - int ret, tmp = 0; - - spin_lock(&bfin_spinlock_lock); /* This would also hold kernel preemption. */ - ret = get_user(tmp, p); - if (likely(ret == 0)) { - if (unlikely(tmp)) - ret = 1; - else - put_user(1, p); - } - spin_unlock(&bfin_spinlock_lock); - return ret; } -int bfin_request_exception(unsigned int exception, void (*handler)(void)) -{ - void (*curr_handler)(void); - - if (exception > 0x3F) - return -EINVAL; - - curr_handler = ex_table[exception]; - - if (curr_handler != ex_replaceable) - return -EBUSY; - - ex_table[exception] = handler; - - return 0; -} -EXPORT_SYMBOL(bfin_request_exception); - -int bfin_free_exception(unsigned int exception, void (*handler)(void)) -{ - void (*curr_handler)(void); - - if (exception > 0x3F) - return -EINVAL; - - curr_handler = ex_table[exception]; - - if (curr_handler != handler) - return -EBUSY; - - ex_table[exception] = ex_replaceable; - - return 0; -} -EXPORT_SYMBOL(bfin_free_exception); void panic_cplb_error(int cplb_panic, struct pt_regs *fp) { @@ -1349,3 +542,15 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp) dump_stack(); panic("Unrecoverable event"); } + +#ifdef CONFIG_BUG +int is_valid_bugaddr(unsigned long addr) +{ + unsigned short opcode; + + if (!get_instruction(&opcode, (unsigned short *)addr)) + return 0; + + return opcode == BFIN_BUG_OPCODE; +} +#endif -- cgit v1.2.3-59-g8ed1b From d28cff4b615c2da274922311cef024d52c839870 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Thu, 11 Mar 2010 19:26:38 +0000 Subject: Blackfin: remove CONFIG_DEBUG_VERBOSE from trace.c Now that the split traps code has moved all the verbose output to the trace.c file, we can unify all the CONFIG_DEBUG_VERBOSE handling. This gets rid of much of the crappy ifdef forest and enables usage of normal pr_xxx functions so checkpatch stops complaining. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/bfin-global.h | 6 + arch/blackfin/include/asm/trace.h | 5 + arch/blackfin/kernel/Makefile | 3 +- arch/blackfin/kernel/trace.c | 221 ++++++++++++++------------------ arch/blackfin/kernel/traps.c | 8 ++ 5 files changed, 120 insertions(+), 123 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h index e6485c305ea6..121cc04d877d 100644 --- a/arch/blackfin/include/asm/bfin-global.h +++ b/arch/blackfin/include/asm/bfin-global.h @@ -39,9 +39,15 @@ extern unsigned long sclk_to_usecs(unsigned long sclk); extern unsigned long usecs_to_sclk(unsigned long usecs); struct pt_regs; +#if defined(CONFIG_DEBUG_VERBOSE) extern void dump_bfin_process(struct pt_regs *regs); extern void dump_bfin_mem(struct pt_regs *regs); extern void dump_bfin_trace_buffer(void); +#else +#define dump_bfin_process(regs) +#define dump_bfin_mem(regs) +#define dump_bfin_trace_buffer() +#endif /* init functions only */ extern int init_arch_irq(void); diff --git a/arch/blackfin/include/asm/trace.h b/arch/blackfin/include/asm/trace.h index 395decd8bc3b..91179395baa8 100644 --- a/arch/blackfin/include/asm/trace.h +++ b/arch/blackfin/include/asm/trace.h @@ -23,8 +23,13 @@ #ifndef __ASSEMBLY__ extern unsigned long trace_buff_offset; extern unsigned long software_trace_buff[]; +#if defined(CONFIG_DEBUG_VERBOSE) extern void decode_address(char *buf, unsigned long address); extern bool get_instruction(unsigned short *val, unsigned short *address); +#else +#define decode_address(buf, address) +#define get_instruction(val, address) 0 +#endif /* Trace Macros for C files */ diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index b32a04a95d99..2fc7f32ae32f 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -8,7 +8,7 @@ obj-y := \ entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ sys_bfin.o traps.o irqchip.o dma-mapping.o flat.o \ fixed_code.o reboot.o bfin_gpio.o bfin_dma_5xx.o \ - trace.o exception.o dumpstack.o + exception.o dumpstack.o ifeq ($(CONFIG_GENERIC_CLOCKEVENTS),y) obj-y += time-ts.o @@ -30,6 +30,7 @@ obj-$(CONFIG_NMI_WATCHDOG) += nmi.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_EARLY_PRINTK) += shadow_console.o obj-$(CONFIG_STACKTRACE) += stacktrace.o +obj-$(CONFIG_DEBUG_VERBOSE) += trace.o # the kgdb test puts code into L2 and without linker # relaxation, we need to force long calls to/from it diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c index 3a268c3ed47e..6e37a8765bc0 100644 --- a/arch/blackfin/kernel/trace.c +++ b/arch/blackfin/kernel/trace.c @@ -20,18 +20,8 @@ #include #include -#ifdef CONFIG_DEBUG_VERBOSE -#define verbose_printk(fmt, arg...) \ - printk(fmt, ##arg) -#else -#define verbose_printk(fmt, arg...) \ - ({ if (0) printk(fmt, ##arg); 0; }) -#endif - - void decode_address(char *buf, unsigned long address) { -#ifdef CONFIG_DEBUG_VERBOSE struct task_struct *p; struct mm_struct *mm; unsigned long flags, offset; @@ -174,9 +164,6 @@ void decode_address(char *buf, unsigned long address) done: write_unlock_irqrestore(&tasklist_lock, flags); -#else - sprintf(buf, " "); -#endif } #define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) @@ -219,52 +206,52 @@ bool get_instruction(unsigned short *val, unsigned short *address) * These are the normal instructions which cause change of flow, which * would be at the source of the trace buffer */ -#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) +#if defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) static void decode_instruction(unsigned short *address) { unsigned short opcode; if (get_instruction(&opcode, address)) { if (opcode == 0x0010) - verbose_printk("RTS"); + pr_cont("RTS"); else if (opcode == 0x0011) - verbose_printk("RTI"); + pr_cont("RTI"); else if (opcode == 0x0012) - verbose_printk("RTX"); + pr_cont("RTX"); else if (opcode == 0x0013) - verbose_printk("RTN"); + pr_cont("RTN"); else if (opcode == 0x0014) - verbose_printk("RTE"); + pr_cont("RTE"); else if (opcode == 0x0025) - verbose_printk("EMUEXCPT"); + pr_cont("EMUEXCPT"); else if (opcode >= 0x0040 && opcode <= 0x0047) - verbose_printk("STI R%i", opcode & 7); + pr_cont("STI R%i", opcode & 7); else if (opcode >= 0x0050 && opcode <= 0x0057) - verbose_printk("JUMP (P%i)", opcode & 7); + pr_cont("JUMP (P%i)", opcode & 7); else if (opcode >= 0x0060 && opcode <= 0x0067) - verbose_printk("CALL (P%i)", opcode & 7); + pr_cont("CALL (P%i)", opcode & 7); else if (opcode >= 0x0070 && opcode <= 0x0077) - verbose_printk("CALL (PC+P%i)", opcode & 7); + pr_cont("CALL (PC+P%i)", opcode & 7); else if (opcode >= 0x0080 && opcode <= 0x0087) - verbose_printk("JUMP (PC+P%i)", opcode & 7); + pr_cont("JUMP (PC+P%i)", opcode & 7); else if (opcode >= 0x0090 && opcode <= 0x009F) - verbose_printk("RAISE 0x%x", opcode & 0xF); + pr_cont("RAISE 0x%x", opcode & 0xF); else if (opcode >= 0x00A0 && opcode <= 0x00AF) - verbose_printk("EXCPT 0x%x", opcode & 0xF); + pr_cont("EXCPT 0x%x", opcode & 0xF); else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) - verbose_printk("IF !CC JUMP"); + pr_cont("IF !CC JUMP"); else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) - verbose_printk("IF CC JUMP"); + pr_cont("IF CC JUMP"); else if (opcode >= 0x2000 && opcode <= 0x2fff) - verbose_printk("JUMP.S"); + pr_cont("JUMP.S"); else if (opcode >= 0xe080 && opcode <= 0xe0ff) - verbose_printk("LSETUP"); + pr_cont("LSETUP"); else if (opcode >= 0xe200 && opcode <= 0xe2ff) - verbose_printk("JUMP.L"); + pr_cont("JUMP.L"); else if (opcode >= 0xe300 && opcode <= 0xe3ff) - verbose_printk("CALL pcrel"); + pr_cont("CALL pcrel"); else - verbose_printk("0x%04x", opcode); + pr_cont("0x%04x", opcode); } } @@ -272,7 +259,6 @@ static void decode_instruction(unsigned short *address) void dump_bfin_trace_buffer(void) { -#ifdef CONFIG_DEBUG_VERBOSE #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON int tflags, i = 0; char buf[150]; @@ -283,21 +269,21 @@ void dump_bfin_trace_buffer(void) trace_buffer_save(tflags); - printk(KERN_NOTICE "Hardware Trace:\n"); + pr_notice("Hardware Trace:\n"); #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND - printk(KERN_NOTICE "WARNING: Expanded trace turned on - can not trace exceptions\n"); + pr_notice("WARNING: Expanded trace turned on - can not trace exceptions\n"); #endif if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { decode_address(buf, (unsigned long)bfin_read_TBUF()); - printk(KERN_NOTICE "%4i Target : %s\n", i, buf); + pr_notice("%4i Target : %s\n", i, buf); addr = (unsigned short *)bfin_read_TBUF(); decode_address(buf, (unsigned long)addr); - printk(KERN_NOTICE " Source : %s ", buf); + pr_notice(" Source : %s ", buf); decode_instruction(addr); - printk("\n"); + pr_cont("\n"); } } @@ -310,14 +296,14 @@ void dump_bfin_trace_buffer(void) j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128; while (j) { decode_address(buf, software_trace_buff[index]); - printk(KERN_NOTICE "%4i Target : %s\n", i, buf); + pr_notice("%4i Target : %s\n", i, buf); index -= 1; if (index < 0) index = EXPAND_LEN; decode_address(buf, software_trace_buff[index]); - printk(KERN_NOTICE " Source : %s ", buf); + pr_notice(" Source : %s ", buf); decode_instruction((unsigned short *)software_trace_buff[index]); - printk("\n"); + pr_cont("\n"); index -= 1; if (index < 0) index = EXPAND_LEN; @@ -328,78 +314,73 @@ void dump_bfin_trace_buffer(void) trace_buffer_restore(tflags); #endif -#endif } EXPORT_SYMBOL(dump_bfin_trace_buffer); void dump_bfin_process(struct pt_regs *fp) { -#ifdef CONFIG_DEBUG_VERBOSE /* We should be able to look at fp->ipend, but we don't push it on the * stack all the time, so do this until we fix that */ unsigned int context = bfin_read_IPEND(); if (oops_in_progress) - verbose_printk(KERN_EMERG "Kernel OOPS in progress\n"); + pr_emerg("Kernel OOPS in progress\n"); if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) - verbose_printk(KERN_NOTICE "HW Error context\n"); + pr_notice("HW Error context\n"); else if (context & 0x0020) - verbose_printk(KERN_NOTICE "Deferred Exception context\n"); + pr_notice("Deferred Exception context\n"); else if (context & 0x3FC0) - verbose_printk(KERN_NOTICE "Interrupt context\n"); + pr_notice("Interrupt context\n"); else if (context & 0x4000) - verbose_printk(KERN_NOTICE "Deferred Interrupt context\n"); + pr_notice("Deferred Interrupt context\n"); else if (context & 0x8000) - verbose_printk(KERN_NOTICE "Kernel process context\n"); + pr_notice("Kernel process context\n"); /* Because we are crashing, and pointers could be bad, we check things * pretty closely before we use them */ if ((unsigned long)current >= FIXED_CODE_START && !((unsigned long)current & 0x3) && current->pid) { - verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); + pr_notice("CURRENT PROCESS:\n"); if (current->comm >= (char *)FIXED_CODE_START) - verbose_printk(KERN_NOTICE "COMM=%s PID=%d", + pr_notice("COMM=%s PID=%d", current->comm, current->pid); else - verbose_printk(KERN_NOTICE "COMM= invalid"); + pr_notice("COMM= invalid"); - printk(KERN_CONT " CPU=%d\n", current_thread_info()->cpu); - if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) - verbose_printk(KERN_NOTICE - "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" - " BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", + pr_cont(" CPU=%d\n", current_thread_info()->cpu); + if (!((unsigned long)current->mm & 0x3) && + (unsigned long)current->mm >= FIXED_CODE_START) { + pr_notice("TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n", (void *)current->mm->start_code, (void *)current->mm->end_code, (void *)current->mm->start_data, - (void *)current->mm->end_data, + (void *)current->mm->end_data); + pr_notice(" BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", (void *)current->mm->end_data, (void *)current->mm->brk, (void *)current->mm->start_stack); - else - verbose_printk(KERN_NOTICE "invalid mm\n"); + } else + pr_notice("invalid mm\n"); } else - verbose_printk(KERN_NOTICE - "No Valid process in current context\n"); -#endif + pr_notice("No Valid process in current context\n"); } void dump_bfin_mem(struct pt_regs *fp) { -#ifdef CONFIG_DEBUG_VERBOSE unsigned short *addr, *erraddr, val = 0, err = 0; char sti = 0, buf[6]; erraddr = (void *)fp->pc; - verbose_printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); + pr_notice("return address: [0x%p]; contents of:", erraddr); for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10; addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10; addr++) { if (!((unsigned long)addr & 0xF)) - verbose_printk(KERN_NOTICE "0x%p: ", addr); + pr_notice("0x%p: ", addr); if (!get_instruction(&val, addr)) { val = 0; @@ -408,10 +389,10 @@ void dump_bfin_mem(struct pt_regs *fp) sprintf(buf, "%04x", val); if (addr == erraddr) { - verbose_printk("[%s]", buf); + pr_cont("[%s]", buf); err = val; } else - verbose_printk(" %s ", buf); + pr_cont(" %s ", buf); /* Do any previous instructions turn on interrupts? */ if (addr <= erraddr && /* in the past */ @@ -420,16 +401,15 @@ void dump_bfin_mem(struct pt_regs *fp) sti = 1; } - verbose_printk("\n"); + pr_cont("\n"); /* Hardware error interrupts can be deferred */ if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR && oops_in_progress)){ - verbose_printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); + pr_notice("Looks like this was a deferred error - sorry\n"); #ifndef CONFIG_DEBUG_HWERR - verbose_printk(KERN_NOTICE -"The remaining message may be meaningless\n" -"You should enable CONFIG_DEBUG_HWERR to get a better idea where it came from\n"); + pr_notice("The remaining message may be meaningless\n"); + pr_notice("You should enable CONFIG_DEBUG_HWERR to get a better idea where it came from\n"); #else /* If we are handling only one peripheral interrupt * and current mm and pid are valid, and the last error @@ -441,20 +421,18 @@ void dump_bfin_mem(struct pt_regs *fp) /* And the last RETI points to the current userspace context */ if ((fp + 1)->pc >= current->mm->start_code && (fp + 1)->pc <= current->mm->end_code) { - verbose_printk(KERN_NOTICE "It might be better to look around here :\n"); - verbose_printk(KERN_NOTICE "-------------------------------------------\n"); + pr_notice("It might be better to look around here :\n"); + pr_notice("-------------------------------------------\n"); show_regs(fp + 1); - verbose_printk(KERN_NOTICE "-------------------------------------------\n"); + pr_notice("-------------------------------------------\n"); } } #endif } -#endif } void show_regs(struct pt_regs *fp) { -#ifdef CONFIG_DEBUG_VERBOSE char buf[150]; struct irqaction *action; unsigned int i; @@ -462,19 +440,19 @@ void show_regs(struct pt_regs *fp) unsigned int cpu = raw_smp_processor_id(); unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); - verbose_printk(KERN_NOTICE "\n"); + pr_notice("\n"); if (CPUID != bfin_cpuid()) - verbose_printk(KERN_NOTICE "Compiled for cpu family 0x%04x (Rev %d), " + pr_notice("Compiled for cpu family 0x%04x (Rev %d), " "but running on:0x%04x (Rev %d)\n", CPUID, bfin_compiled_revid(), bfin_cpuid(), bfin_revid()); - verbose_printk(KERN_NOTICE "ADSP-%s-0.%d", + pr_notice("ADSP-%s-0.%d", CPU, bfin_compiled_revid()); if (bfin_compiled_revid() != bfin_revid()) - verbose_printk("(Detected 0.%d)", bfin_revid()); + pr_cont("(Detected 0.%d)", bfin_revid()); - verbose_printk(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", + pr_cont(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", get_cclk()/1000000, get_sclk()/1000000, #ifdef CONFIG_MPU "mpu on" @@ -483,40 +461,40 @@ void show_regs(struct pt_regs *fp) #endif ); - verbose_printk(KERN_NOTICE "%s", linux_banner); + pr_notice("%s", linux_banner); - verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted()); - verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n", + pr_notice("\nSEQUENCER STATUS:\t\t%s\n", print_tainted()); + pr_notice(" SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n", (long)fp->seqstat, fp->ipend, cpu_pda[raw_smp_processor_id()].ex_imask, fp->syscfg); if (fp->ipend & EVT_IRPTEN) - verbose_printk(KERN_NOTICE " Global Interrupts Disabled (IPEND[4])\n"); + pr_notice(" Global Interrupts Disabled (IPEND[4])\n"); if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 | EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR))) - verbose_printk(KERN_NOTICE " Peripheral interrupts masked off\n"); + pr_notice(" Peripheral interrupts masked off\n"); if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14))) - verbose_printk(KERN_NOTICE " Kernel interrupts masked off\n"); + pr_notice(" Kernel interrupts masked off\n"); if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { - verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", + pr_notice(" HWERRCAUSE: 0x%lx\n", (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); #ifdef EBIU_ERRMST /* If the error was from the EBIU, print it out */ if (bfin_read_EBIU_ERRMST() & CORE_ERROR) { - verbose_printk(KERN_NOTICE " EBIU Error Reason : 0x%04x\n", + pr_notice(" EBIU Error Reason : 0x%04x\n", bfin_read_EBIU_ERRMST()); - verbose_printk(KERN_NOTICE " EBIU Error Address : 0x%08x\n", + pr_notice(" EBIU Error Address : 0x%08x\n", bfin_read_EBIU_ERRADD()); } #endif } - verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", + pr_notice(" EXCAUSE : 0x%lx\n", fp->seqstat & SEQSTAT_EXCAUSE); for (i = 2; i <= 15 ; i++) { if (fp->ipend & (1 << i)) { if (i != 4) { decode_address(buf, bfin_read32(EVT0 + 4*i)); - verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); + pr_notice(" physical IVG%i asserted : %s\n", i, buf); } else - verbose_printk(KERN_NOTICE " interrupts disabled\n"); + pr_notice(" interrupts disabled\n"); } } @@ -531,12 +509,12 @@ void show_regs(struct pt_regs *fp) goto unlock; decode_address(buf, (unsigned int)action->handler); - verbose_printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); + pr_notice(" logical irq %3d mapped : %s", i, buf); for (action = action->next; action; action = action->next) { decode_address(buf, (unsigned int)action->handler); - verbose_printk(", %s", buf); + pr_cont(", %s", buf); } - verbose_printk("\n"); + pr_cont("\n"); unlock: if (!in_atomic) raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); @@ -544,51 +522,50 @@ unlock: } decode_address(buf, fp->rete); - verbose_printk(KERN_NOTICE " RETE: %s\n", buf); + pr_notice(" RETE: %s\n", buf); decode_address(buf, fp->retn); - verbose_printk(KERN_NOTICE " RETN: %s\n", buf); + pr_notice(" RETN: %s\n", buf); decode_address(buf, fp->retx); - verbose_printk(KERN_NOTICE " RETX: %s\n", buf); + pr_notice(" RETX: %s\n", buf); decode_address(buf, fp->rets); - verbose_printk(KERN_NOTICE " RETS: %s\n", buf); + pr_notice(" RETS: %s\n", buf); decode_address(buf, fp->pc); - verbose_printk(KERN_NOTICE " PC : %s\n", buf); + pr_notice(" PC : %s\n", buf); if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); - verbose_printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); + pr_notice("DCPLB_FAULT_ADDR: %s\n", buf); decode_address(buf, cpu_pda[cpu].icplb_fault_addr); - verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); + pr_notice("ICPLB_FAULT_ADDR: %s\n", buf); } - verbose_printk(KERN_NOTICE "PROCESSOR STATE:\n"); - verbose_printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", + pr_notice("PROCESSOR STATE:\n"); + pr_notice(" R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", fp->r0, fp->r1, fp->r2, fp->r3); - verbose_printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", + pr_notice(" R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", fp->r4, fp->r5, fp->r6, fp->r7); - verbose_printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", + pr_notice(" P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", fp->p0, fp->p1, fp->p2, fp->p3); - verbose_printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", + pr_notice(" P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", fp->p4, fp->p5, fp->fp, (long)fp); - verbose_printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", + pr_notice(" LB0: %08lx LT0: %08lx LC0: %08lx\n", fp->lb0, fp->lt0, fp->lc0); - verbose_printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", + pr_notice(" LB1: %08lx LT1: %08lx LC1: %08lx\n", fp->lb1, fp->lt1, fp->lc1); - verbose_printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", + pr_notice(" B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", fp->b0, fp->l0, fp->m0, fp->i0); - verbose_printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", + pr_notice(" B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", fp->b1, fp->l1, fp->m1, fp->i1); - verbose_printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", + pr_notice(" B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", fp->b2, fp->l2, fp->m2, fp->i2); - verbose_printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", + pr_notice(" B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", fp->b3, fp->l3, fp->m3, fp->i3); - verbose_printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", + pr_notice("A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", fp->a0w, fp->a0x, fp->a1w, fp->a1x); - verbose_printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", + pr_notice("USP : %08lx ASTAT: %08lx\n", rdusp(), fp->astat); - verbose_printk(KERN_NOTICE "\n"); -#endif + pr_notice("\n"); } diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 891cc39f7eec..7c31a3d7af22 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -554,3 +554,11 @@ int is_valid_bugaddr(unsigned long addr) return opcode == BFIN_BUG_OPCODE; } #endif + +/* stub this out */ +#ifndef CONFIG_DEBUG_VERBOSE +void show_regs(struct pt_regs *fp) +{ + +} +#endif -- cgit v1.2.3-59-g8ed1b From d60805ad470aef52465f3dc982212f559d9f661b Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Fri, 12 Mar 2010 21:17:44 +0000 Subject: Blackfin: print out the faulting insn in the trace output Print out the faulting instruction so when people send traces as part of bug reports, we have a better idea of what is going on. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/kernel/trace.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c index 6e37a8765bc0..5aa0d5e4e704 100644 --- a/arch/blackfin/kernel/trace.c +++ b/arch/blackfin/kernel/trace.c @@ -19,6 +19,7 @@ #include #include #include +#include void decode_address(char *buf, unsigned long address) { @@ -260,9 +261,10 @@ static void decode_instruction(unsigned short *address) void dump_bfin_trace_buffer(void) { #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON - int tflags, i = 0; + int tflags, i = 0, fault = 0; char buf[150]; unsigned short *addr; + unsigned int cpu = raw_smp_processor_id(); #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND int j, index; #endif @@ -277,8 +279,21 @@ void dump_bfin_trace_buffer(void) if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { - decode_address(buf, (unsigned long)bfin_read_TBUF()); + addr = (unsigned short *)bfin_read_TBUF(); + decode_address(buf, (unsigned long)addr); pr_notice("%4i Target : %s\n", i, buf); + /* Normally, the faulting instruction doesn't go into + * the trace buffer, (since it doesn't commit), so + * we print out the fault address here + */ + if (!fault && addr == (unsigned short *)trap && + (cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE) > VEC_EXCPT15) { + decode_address(buf, cpu_pda[cpu].icplb_fault_addr); + pr_notice(" FAULT : %s ", buf); + decode_instruction((unsigned short *)cpu_pda[cpu].icplb_fault_addr); + pr_cont("\n"); + fault = 1; + } addr = (unsigned short *)bfin_read_TBUF(); decode_address(buf, (unsigned long)addr); pr_notice(" Source : %s ", buf); -- cgit v1.2.3-59-g8ed1b From 9a95e2f1008ee433c496a81628cdde67acc8e4b1 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Mon, 15 Mar 2010 17:42:07 +0000 Subject: Blackfin: make hardware trace output a little more useful Decode the vast majority of insns that appear in the trace buffer to get a better idea of what's going on at a glance. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/trace.h | 6 +- arch/blackfin/kernel/dumpstack.c | 15 +- arch/blackfin/kernel/trace.c | 490 ++++++++++++++++++++++++++++++++++---- arch/blackfin/kernel/traps.c | 2 +- 4 files changed, 446 insertions(+), 67 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/include/asm/trace.h b/arch/blackfin/include/asm/trace.h index 91179395baa8..33589a29b8d8 100644 --- a/arch/blackfin/include/asm/trace.h +++ b/arch/blackfin/include/asm/trace.h @@ -25,10 +25,10 @@ extern unsigned long trace_buff_offset; extern unsigned long software_trace_buff[]; #if defined(CONFIG_DEBUG_VERBOSE) extern void decode_address(char *buf, unsigned long address); -extern bool get_instruction(unsigned short *val, unsigned short *address); +extern bool get_instruction(unsigned int *val, unsigned short *address); #else -#define decode_address(buf, address) -#define get_instruction(val, address) 0 +static inline void decode_address(char *buf, unsigned long address) { } +static inline bool get_instruction(unsigned int *val, unsigned short *address) { return false; } #endif /* Trace Macros for C files */ diff --git a/arch/blackfin/kernel/dumpstack.c b/arch/blackfin/kernel/dumpstack.c index e81392c9d1db..5cfbaa298211 100644 --- a/arch/blackfin/kernel/dumpstack.c +++ b/arch/blackfin/kernel/dumpstack.c @@ -18,21 +18,14 @@ */ static bool is_bfin_call(unsigned short *addr) { - unsigned short opcode = 0, *ins_addr; - ins_addr = (unsigned short *)addr; + unsigned int opcode; - if (!get_instruction(&opcode, ins_addr)) + if (!get_instruction(&opcode, addr)) return false; if ((opcode >= 0x0060 && opcode <= 0x0067) || - (opcode >= 0x0070 && opcode <= 0x0077)) - return true; - - ins_addr--; - if (!get_instruction(&opcode, ins_addr)) - return false; - - if (opcode >= 0xE300 && opcode <= 0xE3FF) + (opcode >= 0x0070 && opcode <= 0x0077) || + (opcode >= 0xE3000000 && opcode <= 0xE3FFFFFF)) return true; return false; diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c index 5aa0d5e4e704..317d4273ca60 100644 --- a/arch/blackfin/kernel/trace.c +++ b/arch/blackfin/kernel/trace.c @@ -75,6 +75,26 @@ void decode_address(char *buf, unsigned long address) } else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) { strcat(buf, "/* on-chip L1 ROM */"); return; + + } else if (address >= L1_SCRATCH_START && address < L1_SCRATCH_START + L1_SCRATCH_LENGTH) { + strcat(buf, "/* on-chip scratchpad */"); + return; + + } else if (address >= physical_mem_end && address < ASYNC_BANK0_BASE) { + strcat(buf, "/* unconnected memory */"); + return; + + } else if (address >= ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE && address < BOOT_ROM_START) { + strcat(buf, "/* reserved memory */"); + return; + + } else if (address >= L1_DATA_A_START && address < L1_DATA_A_START + L1_DATA_A_LENGTH) { + strcat(buf, "/* on-chip Data Bank A */"); + return; + + } else if (address >= L1_DATA_B_START && address < L1_DATA_B_START + L1_DATA_B_LENGTH) { + strcat(buf, "/* on-chip Data Bank B */"); + return; } /* @@ -173,7 +193,7 @@ done: * Similar to get_user, do some address checking, then dereference * Return true on success, false on bad address */ -bool get_instruction(unsigned short *val, unsigned short *address) +bool get_mem16(unsigned short *val, unsigned short *address) { unsigned long addr = (unsigned long)address; @@ -181,10 +201,6 @@ bool get_instruction(unsigned short *val, unsigned short *address) if (addr & 0x1) return false; - /* MMR region will never have instructions */ - if (addr >= SYSMMR_BASE) - return false; - switch (bfin_mem_access_type(addr, 2)) { case BFIN_MEM_ACCESS_CORE: case BFIN_MEM_ACCESS_CORE_ONLY: @@ -201,60 +217,430 @@ bool get_instruction(unsigned short *val, unsigned short *address) } } +bool get_instruction(unsigned int *val, unsigned short *address) +{ + unsigned long addr = (unsigned long)address; + unsigned short opcode0, opcode1; + + /* Check for odd addresses */ + if (addr & 0x1) + return false; + + /* MMR region will never have instructions */ + if (addr >= SYSMMR_BASE) + return false; + + /* Scratchpad will never have instructions */ + if (addr >= L1_SCRATCH_START && addr < L1_SCRATCH_START + L1_SCRATCH_LENGTH) + return false; + + /* Data banks will never have instructions */ + if (addr >= BOOT_ROM_START + BOOT_ROM_LENGTH && addr < L1_CODE_START) + return false; + + if (!get_mem16(&opcode0, address)) + return false; + + /* was this a 32-bit instruction? If so, get the next 16 bits */ + if ((opcode0 & 0xc000) == 0xc000) { + if (!get_mem16(&opcode1, address + 1)) + return false; + *val = (opcode0 << 16) + opcode1; + } else + *val = opcode0; + + return true; +} + +#if defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) /* * decode the instruction if we are printing out the trace, as it * makes things easier to follow, without running it through objdump - * These are the normal instructions which cause change of flow, which - * would be at the source of the trace buffer + * Decode the change of flow, and the common load/store instructions + * which are the main cause for faults, and discontinuities in the trace + * buffer. */ -#if defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) -static void decode_instruction(unsigned short *address) + +#define ProgCtrl_opcode 0x0000 +#define ProgCtrl_poprnd_bits 0 +#define ProgCtrl_poprnd_mask 0xf +#define ProgCtrl_prgfunc_bits 4 +#define ProgCtrl_prgfunc_mask 0xf +#define ProgCtrl_code_bits 8 +#define ProgCtrl_code_mask 0xff + +static void decode_ProgCtrl_0(unsigned int opcode) +{ + int poprnd = ((opcode >> ProgCtrl_poprnd_bits) & ProgCtrl_poprnd_mask); + int prgfunc = ((opcode >> ProgCtrl_prgfunc_bits) & ProgCtrl_prgfunc_mask); + + if (prgfunc == 0 && poprnd == 0) + pr_cont("NOP"); + else if (prgfunc == 1 && poprnd == 0) + pr_cont("RTS"); + else if (prgfunc == 1 && poprnd == 1) + pr_cont("RTI"); + else if (prgfunc == 1 && poprnd == 2) + pr_cont("RTX"); + else if (prgfunc == 1 && poprnd == 3) + pr_cont("RTN"); + else if (prgfunc == 1 && poprnd == 4) + pr_cont("RTE"); + else if (prgfunc == 2 && poprnd == 0) + pr_cont("IDLE"); + else if (prgfunc == 2 && poprnd == 3) + pr_cont("CSYNC"); + else if (prgfunc == 2 && poprnd == 4) + pr_cont("SSYNC"); + else if (prgfunc == 2 && poprnd == 5) + pr_cont("EMUEXCPT"); + else if (prgfunc == 3) + pr_cont("CLI R%i", poprnd); + else if (prgfunc == 4) + pr_cont("STI R%i", poprnd); + else if (prgfunc == 5) + pr_cont("JUMP (P%i)", poprnd); + else if (prgfunc == 6) + pr_cont("CALL (P%i)", poprnd); + else if (prgfunc == 7) + pr_cont("CALL (PC + P%i)", poprnd); + else if (prgfunc == 8) + pr_cont("JUMP (PC + P%i", poprnd); + else if (prgfunc == 9) + pr_cont("RAISE %i", poprnd); + else if (prgfunc == 10) + pr_cont("EXCPT %i", poprnd); + else + pr_cont("0x%04x", opcode); + +} + +#define BRCC_opcode 0x1000 +#define BRCC_offset_bits 0 +#define BRCC_offset_mask 0x3ff +#define BRCC_B_bits 10 +#define BRCC_B_mask 0x1 +#define BRCC_T_bits 11 +#define BRCC_T_mask 0x1 +#define BRCC_code_bits 12 +#define BRCC_code_mask 0xf + +static void decode_BRCC_0(unsigned int opcode) { - unsigned short opcode; - - if (get_instruction(&opcode, address)) { - if (opcode == 0x0010) - pr_cont("RTS"); - else if (opcode == 0x0011) - pr_cont("RTI"); - else if (opcode == 0x0012) - pr_cont("RTX"); - else if (opcode == 0x0013) - pr_cont("RTN"); - else if (opcode == 0x0014) - pr_cont("RTE"); - else if (opcode == 0x0025) - pr_cont("EMUEXCPT"); - else if (opcode >= 0x0040 && opcode <= 0x0047) - pr_cont("STI R%i", opcode & 7); - else if (opcode >= 0x0050 && opcode <= 0x0057) - pr_cont("JUMP (P%i)", opcode & 7); - else if (opcode >= 0x0060 && opcode <= 0x0067) - pr_cont("CALL (P%i)", opcode & 7); - else if (opcode >= 0x0070 && opcode <= 0x0077) - pr_cont("CALL (PC+P%i)", opcode & 7); - else if (opcode >= 0x0080 && opcode <= 0x0087) - pr_cont("JUMP (PC+P%i)", opcode & 7); - else if (opcode >= 0x0090 && opcode <= 0x009F) - pr_cont("RAISE 0x%x", opcode & 0xF); - else if (opcode >= 0x00A0 && opcode <= 0x00AF) - pr_cont("EXCPT 0x%x", opcode & 0xF); - else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) - pr_cont("IF !CC JUMP"); - else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) - pr_cont("IF CC JUMP"); - else if (opcode >= 0x2000 && opcode <= 0x2fff) - pr_cont("JUMP.S"); - else if (opcode >= 0xe080 && opcode <= 0xe0ff) - pr_cont("LSETUP"); - else if (opcode >= 0xe200 && opcode <= 0xe2ff) - pr_cont("JUMP.L"); - else if (opcode >= 0xe300 && opcode <= 0xe3ff) - pr_cont("CALL pcrel"); + int B = ((opcode >> BRCC_B_bits) & BRCC_B_mask); + int T = ((opcode >> BRCC_T_bits) & BRCC_T_mask); + + pr_cont("IF %sCC JUMP pcrel %s", T ? "" : "!", B ? "(BP)" : ""); +} + +#define CALLa_opcode 0xe2000000 +#define CALLa_addr_bits 0 +#define CALLa_addr_mask 0xffffff +#define CALLa_S_bits 24 +#define CALLa_S_mask 0x1 +#define CALLa_code_bits 25 +#define CALLa_code_mask 0x7f + +static void decode_CALLa_0(unsigned int opcode) +{ + int S = ((opcode >> (CALLa_S_bits - 16)) & CALLa_S_mask); + + if (S) + pr_cont("CALL pcrel"); + else + pr_cont("JUMP.L"); +} + +#define LoopSetup_opcode 0xe0800000 +#define LoopSetup_eoffset_bits 0 +#define LoopSetup_eoffset_mask 0x3ff +#define LoopSetup_dontcare_bits 10 +#define LoopSetup_dontcare_mask 0x3 +#define LoopSetup_reg_bits 12 +#define LoopSetup_reg_mask 0xf +#define LoopSetup_soffset_bits 16 +#define LoopSetup_soffset_mask 0xf +#define LoopSetup_c_bits 20 +#define LoopSetup_c_mask 0x1 +#define LoopSetup_rop_bits 21 +#define LoopSetup_rop_mask 0x3 +#define LoopSetup_code_bits 23 +#define LoopSetup_code_mask 0x1ff + +static void decode_LoopSetup_0(unsigned int opcode) +{ + int c = ((opcode >> LoopSetup_c_bits) & LoopSetup_c_mask); + int reg = ((opcode >> LoopSetup_reg_bits) & LoopSetup_reg_mask); + int rop = ((opcode >> LoopSetup_rop_bits) & LoopSetup_rop_mask); + + pr_cont("LSETUP <> LC%i", c); + if ((rop & 1) == 1) + pr_cont("= P%i", reg); + if ((rop & 2) == 2) + pr_cont(" >> 0x1"); +} + +#define DspLDST_opcode 0x9c00 +#define DspLDST_reg_bits 0 +#define DspLDST_reg_mask 0x7 +#define DspLDST_i_bits 3 +#define DspLDST_i_mask 0x3 +#define DspLDST_m_bits 5 +#define DspLDST_m_mask 0x3 +#define DspLDST_aop_bits 7 +#define DspLDST_aop_mask 0x3 +#define DspLDST_W_bits 9 +#define DspLDST_W_mask 0x1 +#define DspLDST_code_bits 10 +#define DspLDST_code_mask 0x3f + +static void decode_dspLDST_0(unsigned int opcode) +{ + int i = ((opcode >> DspLDST_i_bits) & DspLDST_i_mask); + int m = ((opcode >> DspLDST_m_bits) & DspLDST_m_mask); + int W = ((opcode >> DspLDST_W_bits) & DspLDST_W_mask); + int aop = ((opcode >> DspLDST_aop_bits) & DspLDST_aop_mask); + int reg = ((opcode >> DspLDST_reg_bits) & DspLDST_reg_mask); + + if (W == 0) { + pr_cont("R%i", reg); + switch (m) { + case 0: + pr_cont(" = "); + break; + case 1: + pr_cont(".L = "); + break; + case 2: + pr_cont(".W = "); + break; + } + } + + pr_cont("[ I%i", i); + + switch (aop) { + case 0: + pr_cont("++ ]"); + break; + case 1: + pr_cont("-- ]"); + break; + } + + if (W == 1) { + pr_cont(" = R%i", reg); + switch (m) { + case 1: + pr_cont(".L = "); + break; + case 2: + pr_cont(".W = "); + break; + } + } +} + +#define LDST_opcode 0x9000 +#define LDST_reg_bits 0 +#define LDST_reg_mask 0x7 +#define LDST_ptr_bits 3 +#define LDST_ptr_mask 0x7 +#define LDST_Z_bits 6 +#define LDST_Z_mask 0x1 +#define LDST_aop_bits 7 +#define LDST_aop_mask 0x3 +#define LDST_W_bits 9 +#define LDST_W_mask 0x1 +#define LDST_sz_bits 10 +#define LDST_sz_mask 0x3 +#define LDST_code_bits 12 +#define LDST_code_mask 0xf + +static void decode_LDST_0(unsigned int opcode) +{ + int Z = ((opcode >> LDST_Z_bits) & LDST_Z_mask); + int W = ((opcode >> LDST_W_bits) & LDST_W_mask); + int sz = ((opcode >> LDST_sz_bits) & LDST_sz_mask); + int aop = ((opcode >> LDST_aop_bits) & LDST_aop_mask); + int reg = ((opcode >> LDST_reg_bits) & LDST_reg_mask); + int ptr = ((opcode >> LDST_ptr_bits) & LDST_ptr_mask); + + if (W == 0) + pr_cont("%s%i = ", (sz == 0 && Z == 1) ? "P" : "R", reg); + + switch (sz) { + case 1: + pr_cont("W"); + break; + case 2: + pr_cont("B"); + break; + } + + pr_cont("[P%i", ptr); + + switch (aop) { + case 0: + pr_cont("++"); + break; + case 1: + pr_cont("--"); + break; + } + pr_cont("]"); + + if (W == 1) + pr_cont(" = %s%i ", (sz == 0 && Z == 1) ? "P" : "R", reg); + + if (sz) { + if (Z) + pr_cont(" (X)"); + else + pr_cont(" (Z)"); + } +} + +#define LDSTii_opcode 0xa000 +#define LDSTii_reg_bit 0 +#define LDSTii_reg_mask 0x7 +#define LDSTii_ptr_bit 3 +#define LDSTii_ptr_mask 0x7 +#define LDSTii_offset_bit 6 +#define LDSTii_offset_mask 0xf +#define LDSTii_op_bit 10 +#define LDSTii_op_mask 0x3 +#define LDSTii_W_bit 12 +#define LDSTii_W_mask 0x1 +#define LDSTii_code_bit 13 +#define LDSTii_code_mask 0x7 + +static void decode_LDSTii_0(unsigned int opcode) +{ + int reg = ((opcode >> LDSTii_reg_bit) & LDSTii_reg_mask); + int ptr = ((opcode >> LDSTii_ptr_bit) & LDSTii_ptr_mask); + int offset = ((opcode >> LDSTii_offset_bit) & LDSTii_offset_mask); + int op = ((opcode >> LDSTii_op_bit) & LDSTii_op_mask); + int W = ((opcode >> LDSTii_W_bit) & LDSTii_W_mask); + + if (W == 0) { + pr_cont("%s%i = %s[P%i + %i]", op == 3 ? "R" : "P", reg, + op == 1 || op == 2 ? "" : "W", ptr, offset); + if (op == 2) + pr_cont("(Z)"); + if (op == 3) + pr_cont("(X)"); + } else { + pr_cont("%s[P%i + %i] = %s%i", op == 0 ? "" : "W", ptr, + offset, op == 3 ? "P" : "R", reg); + } +} + +#define LDSTidxI_opcode 0xe4000000 +#define LDSTidxI_offset_bits 0 +#define LDSTidxI_offset_mask 0xffff +#define LDSTidxI_reg_bits 16 +#define LDSTidxI_reg_mask 0x7 +#define LDSTidxI_ptr_bits 19 +#define LDSTidxI_ptr_mask 0x7 +#define LDSTidxI_sz_bits 22 +#define LDSTidxI_sz_mask 0x3 +#define LDSTidxI_Z_bits 24 +#define LDSTidxI_Z_mask 0x1 +#define LDSTidxI_W_bits 25 +#define LDSTidxI_W_mask 0x1 +#define LDSTidxI_code_bits 26 +#define LDSTidxI_code_mask 0x3f + +static void decode_LDSTidxI_0(unsigned int opcode) +{ + int Z = ((opcode >> LDSTidxI_Z_bits) & LDSTidxI_Z_mask); + int W = ((opcode >> LDSTidxI_W_bits) & LDSTidxI_W_mask); + int sz = ((opcode >> LDSTidxI_sz_bits) & LDSTidxI_sz_mask); + int reg = ((opcode >> LDSTidxI_reg_bits) & LDSTidxI_reg_mask); + int ptr = ((opcode >> LDSTidxI_ptr_bits) & LDSTidxI_ptr_mask); + int offset = ((opcode >> LDSTidxI_offset_bits) & LDSTidxI_offset_mask); + + if (W == 0) + pr_cont("%s%i = ", sz == 0 && Z == 1 ? "P" : "R", reg); + + if (sz == 1) + pr_cont("W"); + if (sz == 2) + pr_cont("B"); + + pr_cont("[P%i + %s0x%x]", ptr, offset & 0x20 ? "-" : "", + (offset & 0x1f) << 2); + + if (W == 0 && sz != 0) { + if (Z) + pr_cont("(X)"); else - pr_cont("0x%04x", opcode); + pr_cont("(Z)"); } + if (W == 1) + pr_cont("= %s%i", (sz == 0 && Z == 1) ? "P" : "R", reg); + +} + +static void decode_opcode(unsigned int opcode) +{ +#ifdef CONFIG_BUG + if (opcode == BFIN_BUG_OPCODE) + pr_cont("BUG"); + else +#endif + if ((opcode & 0xffffff00) == ProgCtrl_opcode) + decode_ProgCtrl_0(opcode); + else if ((opcode & 0xfffff000) == BRCC_opcode) + decode_BRCC_0(opcode); + else if ((opcode & 0xfffff000) == 0x2000) + pr_cont("JUMP.S"); + else if ((opcode & 0xfe000000) == CALLa_opcode) + decode_CALLa_0(opcode); + else if ((opcode & 0xff8000C0) == LoopSetup_opcode) + decode_LoopSetup_0(opcode); + else if ((opcode & 0xfffffc00) == DspLDST_opcode) + decode_dspLDST_0(opcode); + else if ((opcode & 0xfffff000) == LDST_opcode) + decode_LDST_0(opcode); + else if ((opcode & 0xffffe000) == LDSTii_opcode) + decode_LDSTii_0(opcode); + else if ((opcode & 0xfc000000) == LDSTidxI_opcode) + decode_LDSTidxI_0(opcode); + else if (opcode & 0xffff0000) + pr_cont("0x%08x", opcode); + else + pr_cont("0x%04x", opcode); +} + +#define BIT_MULTI_INS 0x08000000 +static void decode_instruction(unsigned short *address) +{ + unsigned int opcode; + + if (!get_instruction(&opcode, address)) + return; + + decode_opcode(opcode); + + /* If things are a 32-bit instruction, it has the possibility of being + * a multi-issue instruction (a 32-bit, and 2 16 bit instrucitions) + * This test collidates with the unlink instruction, so disallow that + */ + if ((opcode & 0xc0000000) == 0xc0000000 && + (opcode & BIT_MULTI_INS) && + (opcode & 0xe8000000) != 0xe8000000) { + pr_cont(" || "); + if (!get_instruction(&opcode, address + 2)) + return; + decode_opcode(opcode); + pr_cont(" || "); + if (!get_instruction(&opcode, address + 3)) + return; + decode_opcode(opcode); + } } #endif @@ -397,7 +783,7 @@ void dump_bfin_mem(struct pt_regs *fp) if (!((unsigned long)addr & 0xF)) pr_notice("0x%p: ", addr); - if (!get_instruction(&val, addr)) { + if (!get_mem16(&val, addr)) { val = 0; sprintf(buf, "????"); } else diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 7c31a3d7af22..fffcf8a516bf 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -546,7 +546,7 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp) #ifdef CONFIG_BUG int is_valid_bugaddr(unsigned long addr) { - unsigned short opcode; + unsigned int opcode; if (!get_instruction(&opcode, (unsigned short *)addr)) return 0; -- cgit v1.2.3-59-g8ed1b From 2620c83668660d950cb4295aeb7147f1e599c638 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Tue, 16 Mar 2010 07:39:17 +0000 Subject: Blackfin: SMP: add flush_tlb_kernel_range stub Newer code in mm/page_alloc.c requires this function now in arches. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/tlbflush.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/blackfin/include/asm/tlbflush.h b/arch/blackfin/include/asm/tlbflush.h index f1a06c006ed0..7c368682c0a3 100644 --- a/arch/blackfin/include/asm/tlbflush.h +++ b/arch/blackfin/include/asm/tlbflush.h @@ -1 +1,2 @@ #include +#define flush_tlb_kernel_range(s, e) do { } while (0) -- cgit v1.2.3-59-g8ed1b From 2c3c8bea608866d8bd9dcf92657d57fdcac011c5 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Wed, 12 May 2010 18:28:57 -0700 Subject: sysfs: add struct file* to bin_attr callbacks This allows bin_attr->read,write,mmap callbacks to check file specific data (such as inode owner) as part of any privilege validation. Signed-off-by: Chris Wright Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/pci-sysfs.c | 8 ++++--- arch/mips/txx9/generic/setup.c | 4 ++-- arch/powerpc/sysdev/mv64x60_pci.c | 4 ++-- arch/s390/kernel/ipl.c | 14 ++++++------ drivers/acpi/system.c | 2 +- drivers/base/firmware_class.c | 11 ++++++---- drivers/firmware/dcdbas.c | 4 ++-- drivers/firmware/dell_rbu.c | 10 ++++----- drivers/firmware/efivars.c | 4 ++-- drivers/gpu/drm/drm_sysfs.c | 5 +++-- drivers/misc/c2port/core.c | 4 ++-- drivers/misc/ds1682.c | 6 ++++-- drivers/misc/eeprom/at24.c | 6 ++++-- drivers/misc/eeprom/at25.c | 6 ++++-- drivers/misc/eeprom/eeprom.c | 3 ++- drivers/misc/eeprom/max6875.c | 2 +- drivers/net/netxen/netxen_nic_main.c | 11 ++++++---- drivers/net/qlcnic/qlcnic_main.c | 12 +++++++---- drivers/pci/hotplug/acpiphp_ibm.c | 5 +++-- drivers/pci/pci-sysfs.c | 42 +++++++++++++++++++++++++----------- drivers/pcmcia/cistpl.c | 4 ++-- drivers/power/olpc_battery.c | 2 +- drivers/rapidio/rio-sysfs.c | 6 ++++-- drivers/rtc/rtc-cmos.c | 6 ++++-- drivers/rtc/rtc-ds1305.c | 6 ++++-- drivers/rtc/rtc-ds1307.c | 6 ++++-- drivers/rtc/rtc-ds1511.c | 10 +++++---- drivers/rtc/rtc-ds1553.c | 4 ++-- drivers/rtc/rtc-ds1742.c | 4 ++-- drivers/rtc/rtc-m48t59.c | 4 ++-- drivers/rtc/rtc-stk17ta8.c | 4 ++-- drivers/rtc/rtc-tx4939.c | 4 ++-- drivers/s390/cio/chp.c | 5 +++-- drivers/scsi/3w-sas.c | 4 ++-- drivers/scsi/arcmsr/arcmsr_attr.c | 9 +++++--- drivers/scsi/ibmvscsi/ibmvfc.c | 3 ++- drivers/scsi/ipr.c | 9 +++++--- drivers/scsi/lpfc/lpfc_attr.c | 20 ++++++++++++----- drivers/scsi/qla2xxx/qla_attr.c | 32 +++++++++++++-------------- drivers/staging/udlfb/udlfb.c | 3 ++- drivers/usb/core/sysfs.c | 3 ++- drivers/video/aty/radeon_base.c | 4 ++-- drivers/w1/slaves/w1_ds2431.c | 4 ++-- drivers/w1/slaves/w1_ds2433.c | 4 ++-- drivers/w1/slaves/w1_ds2760.c | 2 +- drivers/w1/w1.c | 4 ++-- drivers/zorro/zorro-sysfs.c | 2 +- fs/sysfs/bin.c | 24 ++++++++++----------- include/linux/sysfs.h | 7 +++--- kernel/ksysfs.c | 3 ++- kernel/module.c | 2 +- net/bridge/br_sysfs_br.c | 2 +- 52 files changed, 220 insertions(+), 149 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index d979e7c7bc4b..a5fffc882c72 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -53,6 +53,7 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, /** * pci_mmap_resource - map a PCI resource into user memory space + * @filp: open sysfs file * @kobj: kobject for mapping * @attr: struct bin_attribute for the file being mapped * @vma: struct vm_area_struct passed into the mmap @@ -60,7 +61,8 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, * * Use the bus mapping routines to map a PCI resource into userspace. */ -static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, +static int pci_mmap_resource(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma, int sparse) { struct pci_dev *pdev = to_pci_dev(container_of(kobj, @@ -89,14 +91,14 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, return hose_mmap_page_range(pdev->sysdata, vma, mmap_type, sparse); } -static int pci_mmap_resource_sparse(struct kobject *kobj, +static int pci_mmap_resource_sparse(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, struct vm_area_struct *vma) { return pci_mmap_resource(kobj, attr, vma, 1); } -static int pci_mmap_resource_dense(struct kobject *kobj, +static int pci_mmap_resource_dense(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, struct vm_area_struct *vma) { diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index adc69291f9e2..575d219b8001 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -905,7 +905,7 @@ struct txx9_sramc_sysdev { void __iomem *base; }; -static ssize_t txx9_sram_read(struct kobject *kobj, +static ssize_t txx9_sram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -920,7 +920,7 @@ static ssize_t txx9_sram_read(struct kobject *kobj, return size; } -static ssize_t txx9_sram_write(struct kobject *kobj, +static ssize_t txx9_sram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c index 1456015a22d8..198f288570cc 100644 --- a/arch/powerpc/sysdev/mv64x60_pci.c +++ b/arch/powerpc/sysdev/mv64x60_pci.c @@ -24,7 +24,7 @@ #define MV64X60_VAL_LEN_MAX 11 #define MV64X60_PCICFG_CPCI_HOTSWAP 0x68 -static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, +static ssize_t mv64x60_hs_reg_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { @@ -45,7 +45,7 @@ static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, return sprintf(buf, "0x%08x\n", v); } -static ssize_t mv64x60_hs_reg_write(struct kobject *kobj, +static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 72c8b0d070c8..a689070be287 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -403,8 +403,9 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj, static struct kobj_attribute sys_ipl_device_attr = __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL); -static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { return memory_read_from_buffer(buf, count, &off, IPL_PARMBLOCK_START, IPL_PARMBLOCK_SIZE); @@ -419,8 +420,9 @@ static struct bin_attribute ipl_parameter_attr = { .read = &ipl_parameter_read, }; -static ssize_t ipl_scp_data_read(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len; void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data; @@ -694,7 +696,7 @@ static struct kobj_attribute sys_reipl_ccw_vmparm_attr = /* FCP reipl device attributes */ -static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj, +static ssize_t reipl_fcp_scpdata_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { @@ -704,7 +706,7 @@ static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj, return memory_read_from_buffer(buf, count, &off, scp_data, size); } -static ssize_t reipl_fcp_scpdata_write(struct kobject *kobj, +static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index e35525b39f6b..c79e789ed03a 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -71,7 +71,7 @@ struct acpi_table_attr { struct list_head node; }; -static ssize_t acpi_table_show(struct kobject *kobj, +static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t offset, size_t count) { diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index d98e424675cf..3f093b0dd217 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -278,8 +278,9 @@ static ssize_t firmware_loading_store(struct device *dev, static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); static ssize_t -firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr, - char *buffer, loff_t offset, size_t count) +firmware_data_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buffer, loff_t offset, + size_t count) { struct device *dev = to_dev(kobj); struct firmware_priv *fw_priv = dev_get_drvdata(dev); @@ -362,6 +363,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) /** * firmware_data_write - write method for firmware + * @filp: open sysfs file * @kobj: kobject for the device * @bin_attr: bin_attr structure * @buffer: buffer being written @@ -372,8 +374,9 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) * the driver as a firmware image. **/ static ssize_t -firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr, - char *buffer, loff_t offset, size_t count) +firmware_data_write(struct file* filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buffer, + loff_t offset, size_t count) { struct device *dev = to_dev(kobj); struct firmware_priv *fw_priv = dev_get_drvdata(dev); diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index fb09bb3c0ad6..aa9bc9e980e1 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c @@ -149,7 +149,7 @@ static ssize_t smi_data_buf_size_store(struct device *dev, return count; } -static ssize_t smi_data_read(struct kobject *kobj, +static ssize_t smi_data_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { @@ -162,7 +162,7 @@ static ssize_t smi_data_read(struct kobject *kobj, return ret; } -static ssize_t smi_data_write(struct kobject *kobj, +static ssize_t smi_data_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index 3a4460265b10..2f452f1f7c8a 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c @@ -522,7 +522,7 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count) rbu_data.image_update_buffer, rbu_data.bios_image_size); } -static ssize_t read_rbu_data(struct kobject *kobj, +static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { @@ -576,7 +576,7 @@ static void callbackfn_rbu(const struct firmware *fw, void *context) release_firmware(fw); } -static ssize_t read_rbu_image_type(struct kobject *kobj, +static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { @@ -586,7 +586,7 @@ static ssize_t read_rbu_image_type(struct kobject *kobj, return size; } -static ssize_t write_rbu_image_type(struct kobject *kobj, +static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { @@ -647,7 +647,7 @@ static ssize_t write_rbu_image_type(struct kobject *kobj, return rc; } -static ssize_t read_rbu_packet_size(struct kobject *kobj, +static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { @@ -660,7 +660,7 @@ static ssize_t read_rbu_packet_size(struct kobject *kobj, return size; } -static ssize_t write_rbu_packet_size(struct kobject *kobj, +static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t count) { diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 81b70bd07586..2a62ec6390e0 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -402,7 +402,7 @@ efivar_unregister(struct efivar_entry *var) } -static ssize_t efivar_create(struct kobject *kobj, +static ssize_t efivar_create(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { @@ -461,7 +461,7 @@ static ssize_t efivar_create(struct kobject *kobj, return count; } -static ssize_t efivar_delete(struct kobject *kobj, +static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 25bbd30ed7af..387166d5a109 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -193,8 +193,9 @@ static ssize_t enabled_show(struct device *device, "disabled"); } -static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static ssize_t edid_show(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, + size_t count) { struct device *connector_dev = container_of(kobj, struct device, kobj); struct drm_connector *connector = to_drm_connector(connector_dev); diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c index ed090e77c9cd..19fc7c1cb428 100644 --- a/drivers/misc/c2port/core.c +++ b/drivers/misc/c2port/core.c @@ -707,7 +707,7 @@ static ssize_t __c2port_read_flash_data(struct c2port_device *dev, return nread; } -static ssize_t c2port_read_flash_data(struct kobject *kobj, +static ssize_t c2port_read_flash_data(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buffer, loff_t offset, size_t count) { @@ -824,7 +824,7 @@ static ssize_t __c2port_write_flash_data(struct c2port_device *dev, return nwrite; } -static ssize_t c2port_write_flash_data(struct kobject *kobj, +static ssize_t c2port_write_flash_data(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buffer, loff_t offset, size_t count) { diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c index 9197cfc55015..a513f0aa6432 100644 --- a/drivers/misc/ds1682.c +++ b/drivers/misc/ds1682.c @@ -140,7 +140,8 @@ static const struct attribute_group ds1682_group = { /* * User data attribute */ -static ssize_t ds1682_eeprom_read(struct kobject *kobj, struct bin_attribute *attr, +static ssize_t ds1682_eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client = kobj_to_i2c_client(kobj); @@ -163,7 +164,8 @@ static ssize_t ds1682_eeprom_read(struct kobject *kobj, struct bin_attribute *at return count; } -static ssize_t ds1682_eeprom_write(struct kobject *kobj, struct bin_attribute *attr, +static ssize_t ds1682_eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client = kobj_to_i2c_client(kobj); diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index db7d0f21b65d..a79a62f75481 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -274,7 +274,8 @@ static ssize_t at24_read(struct at24_data *at24, return retval; } -static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr, +static ssize_t at24_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct at24_data *at24; @@ -395,7 +396,8 @@ static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off, return retval; } -static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr, +static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct at24_data *at24; diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index d194212a41f6..c627e4174ccd 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -126,7 +126,8 @@ at25_ee_read( } static ssize_t -at25_bin_read(struct kobject *kobj, struct bin_attribute *bin_attr, +at25_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct device *dev; @@ -253,7 +254,8 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off, } static ssize_t -at25_bin_write(struct kobject *kobj, struct bin_attribute *bin_attr, +at25_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct device *dev; diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index e306a8cd2f96..45060ddc4e59 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -81,7 +81,8 @@ exit: mutex_unlock(&data->update_lock); } -static ssize_t eeprom_read(struct kobject *kobj, struct bin_attribute *bin_attr, +static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c index fe2909278507..5653a3ce0517 100644 --- a/drivers/misc/eeprom/max6875.c +++ b/drivers/misc/eeprom/max6875.c @@ -107,7 +107,7 @@ exit_up: mutex_unlock(&data->update_lock); } -static ssize_t max6875_read(struct kobject *kobj, +static ssize_t max6875_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index c61a61f177b7..6ce6ce1df6d2 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -2560,7 +2560,8 @@ netxen_sysfs_validate_crb(struct netxen_adapter *adapter, } static ssize_t -netxen_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, +netxen_sysfs_read_crb(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2587,7 +2588,8 @@ netxen_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -netxen_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, +netxen_sysfs_write_crb(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2627,7 +2629,8 @@ netxen_sysfs_validate_mem(struct netxen_adapter *adapter, } static ssize_t -netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, +netxen_sysfs_read_mem(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2647,7 +2650,7 @@ netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, return size; } -static ssize_t netxen_sysfs_write_mem(struct kobject *kobj, +static ssize_t netxen_sysfs_write_mem(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 1003eb76fda3..23ea9caa5261 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2464,7 +2464,8 @@ qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter, } static ssize_t -qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, +qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2488,7 +2489,8 @@ qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -qlcnic_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, +qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2525,7 +2527,8 @@ qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter, } static ssize_t -qlcnic_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, +qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); @@ -2546,7 +2549,8 @@ qlcnic_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -qlcnic_sysfs_write_mem(struct kobject *kobj, struct bin_attribute *attr, +qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 6ecbfb27db9d..e525263210ee 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -108,7 +108,7 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status); static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status); static void ibm_handle_events(acpi_handle handle, u32 event, void *context); static int ibm_get_table_from_acpi(char **bufp); -static ssize_t ibm_read_apci_table(struct kobject *kobj, +static ssize_t ibm_read_apci_table(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t size); static acpi_status __init ibm_find_acpi_device(acpi_handle handle, @@ -351,6 +351,7 @@ read_table_done: /** * ibm_read_apci_table - callback for the sysfs apci_table file + * @filp: the open sysfs file * @kobj: the kobject this binary attribute is a part of * @bin_attr: struct bin_attribute for this file * @buffer: the kernel space buffer to fill @@ -364,7 +365,7 @@ read_table_done: * things get really tricky here... * our solution is to only allow reading the table in all at once. */ -static ssize_t ibm_read_apci_table(struct kobject *kobj, +static ssize_t ibm_read_apci_table(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer, loff_t pos, size_t size) { diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index fad93983bfed..ad44557e65c4 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -357,7 +357,8 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) struct device_attribute vga_attr = __ATTR_RO(boot_vga); static ssize_t -pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_read_config(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj)); @@ -430,7 +431,8 @@ pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr, } static ssize_t -pci_write_config(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_write_config(struct file* filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj)); @@ -487,7 +489,8 @@ pci_write_config(struct kobject *kobj, struct bin_attribute *bin_attr, } static ssize_t -read_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, +read_vpd_attr(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *dev = @@ -502,7 +505,8 @@ read_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, } static ssize_t -write_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, +write_vpd_attr(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *dev = @@ -519,6 +523,7 @@ write_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, #ifdef HAVE_PCI_LEGACY /** * pci_read_legacy_io - read byte(s) from legacy I/O port space + * @filp: open sysfs file * @kobj: kobject corresponding to file to read from * @bin_attr: struct bin_attribute for this file * @buf: buffer to store results @@ -529,7 +534,8 @@ write_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, * callback routine (pci_legacy_read). */ static ssize_t -pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_read_legacy_io(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_bus *bus = to_pci_bus(container_of(kobj, @@ -545,6 +551,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, /** * pci_write_legacy_io - write byte(s) to legacy I/O port space + * @filp: open sysfs file * @kobj: kobject corresponding to file to read from * @bin_attr: struct bin_attribute for this file * @buf: buffer containing value to be written @@ -555,7 +562,8 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, * callback routine (pci_legacy_write). */ static ssize_t -pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_write_legacy_io(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_bus *bus = to_pci_bus(container_of(kobj, @@ -570,6 +578,7 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, /** * pci_mmap_legacy_mem - map legacy PCI memory into user memory space + * @filp: open sysfs file * @kobj: kobject corresponding to device to be mapped * @attr: struct bin_attribute for this file * @vma: struct vm_area_struct passed to mmap @@ -579,7 +588,8 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, * memory space. */ static int -pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, +pci_mmap_legacy_mem(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma) { struct pci_bus *bus = to_pci_bus(container_of(kobj, @@ -591,6 +601,7 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, /** * pci_mmap_legacy_io - map legacy PCI IO into user memory space + * @filp: open sysfs file * @kobj: kobject corresponding to device to be mapped * @attr: struct bin_attribute for this file * @vma: struct vm_area_struct passed to mmap @@ -600,7 +611,8 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, * memory space. Returns -ENOSYS if the operation isn't supported */ static int -pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr, +pci_mmap_legacy_io(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma) { struct pci_bus *bus = to_pci_bus(container_of(kobj, @@ -750,14 +762,16 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, } static int -pci_mmap_resource_uc(struct kobject *kobj, struct bin_attribute *attr, +pci_mmap_resource_uc(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma) { return pci_mmap_resource(kobj, attr, vma, 0); } static int -pci_mmap_resource_wc(struct kobject *kobj, struct bin_attribute *attr, +pci_mmap_resource_wc(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma) { return pci_mmap_resource(kobj, attr, vma, 1); @@ -861,6 +875,7 @@ void __weak pci_remove_resource_files(struct pci_dev *dev) { return; } /** * pci_write_rom - used to enable access to the PCI ROM display + * @filp: sysfs file * @kobj: kernel object handle * @bin_attr: struct bin_attribute for this file * @buf: user input @@ -870,7 +885,8 @@ void __weak pci_remove_resource_files(struct pci_dev *dev) { return; } * writing anything except 0 enables it */ static ssize_t -pci_write_rom(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_write_rom(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj)); @@ -885,6 +901,7 @@ pci_write_rom(struct kobject *kobj, struct bin_attribute *bin_attr, /** * pci_read_rom - read a PCI ROM + * @filp: sysfs file * @kobj: kernel object handle * @bin_attr: struct bin_attribute for this file * @buf: where to put the data we read from the ROM @@ -895,7 +912,8 @@ pci_write_rom(struct kobject *kobj, struct bin_attribute *bin_attr, * device corresponding to @kobj. */ static ssize_t -pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr, +pci_read_rom(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj)); diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 60d428be0b07..8844bc3e3118 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -1531,7 +1531,7 @@ static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, } -static ssize_t pccard_show_cis(struct kobject *kobj, +static ssize_t pccard_show_cis(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -1562,7 +1562,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, } -static ssize_t pccard_store_cis(struct kobject *kobj, +static ssize_t pccard_store_cis(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index 8fefe5a73558..baefcf1cffc9 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c @@ -354,7 +354,7 @@ static enum power_supply_property olpc_bat_props[] = { #define EEPROM_END 0x80 #define EEPROM_SIZE (EEPROM_END - EEPROM_START) -static ssize_t olpc_bat_eeprom_read(struct kobject *kobj, +static ssize_t olpc_bat_eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { uint8_t ec_byte; diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index ba742e82c57d..00b475658356 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c @@ -68,7 +68,8 @@ struct device_attribute rio_dev_attrs[] = { }; static ssize_t -rio_read_config(struct kobject *kobj, struct bin_attribute *bin_attr, +rio_read_config(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct rio_dev *dev = @@ -139,7 +140,8 @@ rio_read_config(struct kobject *kobj, struct bin_attribute *bin_attr, } static ssize_t -rio_write_config(struct kobject *kobj, struct bin_attribute *bin_attr, +rio_write_config(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct rio_dev *dev = diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index e9aa814ddd23..ece4dbddc0ea 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -519,7 +519,8 @@ static const struct rtc_class_ops cmos_rtc_ops = { #define NVRAM_OFFSET (RTC_REG_D + 1) static ssize_t -cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, +cmos_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { int retval; @@ -547,7 +548,8 @@ cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, +cmos_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct cmos_rtc *cmos; diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 7836c9cec557..48da85e97ca4 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -542,7 +542,8 @@ static void msg_init(struct spi_message *m, struct spi_transfer *x, } static ssize_t -ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, +ds1305_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct spi_device *spi; @@ -572,7 +573,8 @@ ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr, +ds1305_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct spi_device *spi; diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index c4ec5c158aa1..de033b7ac21f 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -556,7 +556,8 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { #define NVRAM_SIZE 56 static ssize_t -ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, +ds1307_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client; @@ -580,7 +581,8 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, +ds1307_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client; diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 06b8566c4532..37268e97de49 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -423,8 +423,9 @@ static const struct rtc_class_ops ds1511_rtc_ops = { }; static ssize_t -ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba, - char *buf, loff_t pos, size_t size) +ds1511_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *ba, + char *buf, loff_t pos, size_t size) { ssize_t count; @@ -452,8 +453,9 @@ ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba, } static ssize_t -ds1511_nvram_write(struct kobject *kobj, struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +ds1511_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t pos, size_t size) { ssize_t count; diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 244f9994bcbb..ff432e2ca275 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -252,7 +252,7 @@ static const struct rtc_class_ops ds1553_rtc_ops = { .update_irq_enable = ds1553_rtc_update_irq_enable, }; -static ssize_t ds1553_nvram_read(struct kobject *kobj, +static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -267,7 +267,7 @@ static ssize_t ds1553_nvram_read(struct kobject *kobj, return count; } -static ssize_t ds1553_nvram_write(struct kobject *kobj, +static ssize_t ds1553_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 2b4b0bc42d6f..042630c90dd3 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -128,7 +128,7 @@ static const struct rtc_class_ops ds1742_rtc_ops = { .set_time = ds1742_rtc_set_time, }; -static ssize_t ds1742_nvram_read(struct kobject *kobj, +static ssize_t ds1742_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -143,7 +143,7 @@ static ssize_t ds1742_nvram_read(struct kobject *kobj, return count; } -static ssize_t ds1742_nvram_write(struct kobject *kobj, +static ssize_t ds1742_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 365ff3ac2348..be8359fdb65a 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -343,7 +343,7 @@ static const struct rtc_class_ops m48t02_rtc_ops = { .set_time = m48t59_rtc_set_time, }; -static ssize_t m48t59_nvram_read(struct kobject *kobj, +static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -363,7 +363,7 @@ static ssize_t m48t59_nvram_read(struct kobject *kobj, return cnt; } -static ssize_t m48t59_nvram_write(struct kobject *kobj, +static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index b53a00198dbe..3b943673cd3e 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -244,7 +244,7 @@ static const struct rtc_class_ops stk17ta8_rtc_ops = { .alarm_irq_enable = stk17ta8_rtc_alarm_irq_enable, }; -static ssize_t stk17ta8_nvram_read(struct kobject *kobj, +static ssize_t stk17ta8_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t pos, size_t size) { @@ -259,7 +259,7 @@ static ssize_t stk17ta8_nvram_read(struct kobject *kobj, return count; } -static ssize_t stk17ta8_nvram_write(struct kobject *kobj, +static ssize_t stk17ta8_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 20bfc64a15c8..ec6313d15359 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -188,7 +188,7 @@ static const struct rtc_class_ops tx4939_rtc_ops = { .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, }; -static ssize_t tx4939_rtc_nvram_read(struct kobject *kobj, +static ssize_t tx4939_rtc_nvram_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { @@ -207,7 +207,7 @@ static ssize_t tx4939_rtc_nvram_read(struct kobject *kobj, return count; } -static ssize_t tx4939_rtc_nvram_write(struct kobject *kobj, +static ssize_t tx4939_rtc_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 1d16189f2f2d..6c9fa15aac7b 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -135,7 +135,8 @@ static int s390_vary_chpid(struct chp_id chpid, int on) /* * Channel measurement related functions */ -static ssize_t chp_measurement_chars_read(struct kobject *kobj, +static ssize_t chp_measurement_chars_read(struct file *filp, + struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -182,7 +183,7 @@ static void chp_measurement_copy_block(struct cmg_entry *buf, } while (reference_buf.values[0] != buf->values[0]); } -static ssize_t chp_measurement_read(struct kobject *kobj, +static ssize_t chp_measurement_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index 54c5ffb1eaa1..d38000db9237 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -98,7 +98,7 @@ static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_res /* Functions */ /* This function returns AENs through sysfs */ -static ssize_t twl_sysfs_aen_read(struct kobject *kobj, +static ssize_t twl_sysfs_aen_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *outbuf, loff_t offset, size_t count) { @@ -129,7 +129,7 @@ static struct bin_attribute twl_sysfs_aen_read_attr = { }; /* This function returns driver compatibility info through sysfs */ -static ssize_t twl_sysfs_compat_info(struct kobject *kobj, +static ssize_t twl_sysfs_compat_info(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *outbuf, loff_t offset, size_t count) { diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 5877f29a6005..a4e04c50c436 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c @@ -59,7 +59,8 @@ struct device_attribute *arcmsr_host_attrs[]; -static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, +static ssize_t arcmsr_sysfs_iop_message_read(struct file *filp, + struct kobject *kobj, struct bin_attribute *bin, char *buf, loff_t off, size_t count) @@ -105,7 +106,8 @@ static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, return (allxfer_len); } -static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, +static ssize_t arcmsr_sysfs_iop_message_write(struct file *filp, + struct kobject *kobj, struct bin_attribute *bin, char *buf, loff_t off, size_t count) @@ -153,7 +155,8 @@ static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, } } -static ssize_t arcmsr_sysfs_iop_message_clear(struct kobject *kobj, +static ssize_t arcmsr_sysfs_iop_message_clear(struct file *filp, + struct kobject *kobj, struct bin_attribute *bin, char *buf, loff_t off, size_t count) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index d18f45c95639..3eb2b7b3d8b0 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -2919,6 +2919,7 @@ static DEVICE_ATTR(log_level, S_IRUGO | S_IWUSR, #ifdef CONFIG_SCSI_IBMVFC_TRACE /** * ibmvfc_read_trace - Dump the adapter trace + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -2928,7 +2929,7 @@ static DEVICE_ATTR(log_level, S_IRUGO | S_IWUSR, * Return value: * number of bytes printed to buffer **/ -static ssize_t ibmvfc_read_trace(struct kobject *kobj, +static ssize_t ibmvfc_read_trace(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index b90c118119d7..6a6661c35b2f 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3120,6 +3120,7 @@ restart: #ifdef CONFIG_SCSI_IPR_TRACE /** * ipr_read_trace - Dump the adapter trace + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -3129,7 +3130,7 @@ restart: * Return value: * number of bytes printed to buffer **/ -static ssize_t ipr_read_trace(struct kobject *kobj, +static ssize_t ipr_read_trace(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -3764,6 +3765,7 @@ static struct device_attribute *ipr_ioa_attrs[] = { #ifdef CONFIG_SCSI_IPR_DUMP /** * ipr_read_dump - Dump the adapter + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -3773,7 +3775,7 @@ static struct device_attribute *ipr_ioa_attrs[] = { * Return value: * number of bytes printed to buffer **/ -static ssize_t ipr_read_dump(struct kobject *kobj, +static ssize_t ipr_read_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -3927,6 +3929,7 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) /** * ipr_write_dump - Setup dump state of adapter + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -3936,7 +3939,7 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) * Return value: * number of bytes printed to buffer **/ -static ssize_t ipr_write_dump(struct kobject *kobj, +static ssize_t ipr_write_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 2e5f376d9ccc..bf33b315f93e 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -2643,6 +2643,7 @@ static DEVICE_ATTR(lpfc_stat_data_ctrl, S_IRUGO | S_IWUSR, /** * sysfs_drvr_stat_data_read - Read function for lpfc_drvr_stat_data attribute + * @filp: sysfs file * @kobj: Pointer to the kernel object * @bin_attr: Attribute object * @buff: Buffer pointer @@ -2654,7 +2655,8 @@ static DEVICE_ATTR(lpfc_stat_data_ctrl, S_IRUGO | S_IWUSR, * applications. **/ static ssize_t -sysfs_drvr_stat_data_read(struct kobject *kobj, struct bin_attribute *bin_attr, +sysfs_drvr_stat_data_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, @@ -3362,6 +3364,7 @@ struct device_attribute *lpfc_vport_attrs[] = { /** * sysfs_ctlreg_write - Write method for writing to ctlreg + * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: contains the data to be written to the adapter IOREG space. @@ -3379,7 +3382,8 @@ struct device_attribute *lpfc_vport_attrs[] = { * value of count, buf contents written **/ static ssize_t -sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, +sysfs_ctlreg_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { size_t buf_off; @@ -3415,6 +3419,7 @@ sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, /** * sysfs_ctlreg_read - Read method for reading from ctlreg + * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: if successful contains the data from the adapter IOREG space. @@ -3431,7 +3436,8 @@ sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, * value of count, buf contents read **/ static ssize_t -sysfs_ctlreg_read(struct kobject *kobj, struct bin_attribute *bin_attr, +sysfs_ctlreg_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { size_t buf_off; @@ -3496,6 +3502,7 @@ sysfs_mbox_idle(struct lpfc_hba *phba) /** * sysfs_mbox_write - Write method for writing information via mbox + * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: contains the data to be written to sysfs mbox. @@ -3516,7 +3523,8 @@ sysfs_mbox_idle(struct lpfc_hba *phba) * count number of bytes transferred **/ static ssize_t -sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr, +sysfs_mbox_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); @@ -3571,6 +3579,7 @@ sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr, /** * sysfs_mbox_read - Read method for reading information via mbox + * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: contains the data to be read from sysfs mbox. @@ -3593,7 +3602,8 @@ sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr, * count number of bytes transferred **/ static ssize_t -sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, +sysfs_mbox_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 3b708606b932..1e4cafabba15 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -16,7 +16,7 @@ static int qla24xx_vport_disable(struct fc_vport *, bool); /* SYSFS attributes --------------------------------------------------------- */ static ssize_t -qla2x00_sysfs_read_fw_dump(struct kobject *kobj, +qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -32,7 +32,7 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, } static ssize_t -qla2x00_sysfs_write_fw_dump(struct kobject *kobj, +qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -92,7 +92,7 @@ static struct bin_attribute sysfs_fw_dump_attr = { }; static ssize_t -qla2x00_sysfs_read_nvram(struct kobject *kobj, +qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -111,7 +111,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, } static ssize_t -qla2x00_sysfs_write_nvram(struct kobject *kobj, +qla2x00_sysfs_write_nvram(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -177,7 +177,7 @@ static struct bin_attribute sysfs_nvram_attr = { }; static ssize_t -qla2x00_sysfs_read_optrom(struct kobject *kobj, +qla2x00_sysfs_read_optrom(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -193,7 +193,7 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj, } static ssize_t -qla2x00_sysfs_write_optrom(struct kobject *kobj, +qla2x00_sysfs_write_optrom(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -224,7 +224,7 @@ static struct bin_attribute sysfs_optrom_attr = { }; static ssize_t -qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, +qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -387,7 +387,7 @@ static struct bin_attribute sysfs_optrom_ctl_attr = { }; static ssize_t -qla2x00_sysfs_read_vpd(struct kobject *kobj, +qla2x00_sysfs_read_vpd(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -408,7 +408,7 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, } static ssize_t -qla2x00_sysfs_write_vpd(struct kobject *kobj, +qla2x00_sysfs_write_vpd(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -461,7 +461,7 @@ static struct bin_attribute sysfs_vpd_attr = { }; static ssize_t -qla2x00_sysfs_read_sfp(struct kobject *kobj, +qla2x00_sysfs_read_sfp(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -522,7 +522,7 @@ static struct bin_attribute sysfs_sfp_attr = { }; static ssize_t -qla2x00_sysfs_write_reset(struct kobject *kobj, +qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -592,7 +592,7 @@ static struct bin_attribute sysfs_reset_attr = { }; static ssize_t -qla2x00_sysfs_write_edc(struct kobject *kobj, +qla2x00_sysfs_write_edc(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -650,7 +650,7 @@ static struct bin_attribute sysfs_edc_attr = { }; static ssize_t -qla2x00_sysfs_write_edc_status(struct kobject *kobj, +qla2x00_sysfs_write_edc_status(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -700,7 +700,7 @@ qla2x00_sysfs_write_edc_status(struct kobject *kobj, } static ssize_t -qla2x00_sysfs_read_edc_status(struct kobject *kobj, +qla2x00_sysfs_read_edc_status(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -730,7 +730,7 @@ static struct bin_attribute sysfs_edc_status_attr = { }; static ssize_t -qla2x00_sysfs_read_xgmac_stats(struct kobject *kobj, +qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -782,7 +782,7 @@ static struct bin_attribute sysfs_xgmac_stats_attr = { }; static ssize_t -qla2x00_sysfs_read_dcbx_tlv(struct kobject *kobj, +qla2x00_sysfs_read_dcbx_tlv(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index aa8195199a2c..577f2bf6eb23 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -1063,7 +1063,8 @@ static ssize_t metrics_misc_show(struct device *fbdev, atomic_read(&dev->lost_pixels) ? "yes" : "no"); } -static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *a, +static ssize_t edid_show(struct file *filp, struct kobject *kobj, + struct bin_attribute *a, char *buf, loff_t off, size_t count) { struct device *fbdev = container_of(kobj, struct device, kobj); struct fb_info *fb_info = dev_get_drvdata(fbdev); diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 06863befaf3a..448f5b47fc48 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -658,7 +658,8 @@ const struct attribute_group *usb_device_groups[] = { /* Binary descriptors */ static ssize_t -read_descriptors(struct kobject *kobj, struct bin_attribute *attr, +read_descriptors(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 6c37e8ee5efe..3c1e13ed1cba 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -2099,7 +2099,7 @@ static ssize_t radeon_show_one_edid(char *buf, loff_t off, size_t count, const u } -static ssize_t radeon_show_edid1(struct kobject *kobj, +static ssize_t radeon_show_edid1(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -2112,7 +2112,7 @@ static ssize_t radeon_show_edid1(struct kobject *kobj, } -static ssize_t radeon_show_edid2(struct kobject *kobj, +static ssize_t radeon_show_edid2(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c index 2c6c0cf6a20f..84e2410aec1d 100644 --- a/drivers/w1/slaves/w1_ds2431.c +++ b/drivers/w1/slaves/w1_ds2431.c @@ -96,7 +96,7 @@ static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf) return -1; } -static ssize_t w1_f2d_read_bin(struct kobject *kobj, +static ssize_t w1_f2d_read_bin(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -202,7 +202,7 @@ retry: return 0; } -static ssize_t w1_f2d_write_bin(struct kobject *kobj, +static ssize_t w1_f2d_write_bin(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index d2bf32118a98..0f7b8f9c509a 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c @@ -92,7 +92,7 @@ static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data, } #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ -static ssize_t w1_f23_read_bin(struct kobject *kobj, +static ssize_t w1_f23_read_bin(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -206,7 +206,7 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data) return 0; } -static ssize_t w1_f23_write_bin(struct kobject *kobj, +static ssize_t w1_f23_write_bin(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index 6e153343e117..483d45180911 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c @@ -97,7 +97,7 @@ int w1_ds2760_recall_eeprom(struct device *dev, int addr) return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA); } -static ssize_t w1_ds2760_read_bin(struct kobject *kobj, +static ssize_t w1_ds2760_read_bin(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index ad5897dc4495..2839e281cd65 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -120,7 +120,7 @@ static struct device_attribute w1_slave_attr_id = /* Default family */ -static ssize_t w1_default_write(struct kobject *kobj, +static ssize_t w1_default_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -139,7 +139,7 @@ out_up: return count; } -static ssize_t w1_default_read(struct kobject *kobj, +static ssize_t w1_default_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c index eb924e0a64ce..26f7184ef9e1 100644 --- a/drivers/zorro/zorro-sysfs.c +++ b/drivers/zorro/zorro-sysfs.c @@ -49,7 +49,7 @@ static ssize_t zorro_show_resource(struct device *dev, struct device_attribute * static DEVICE_ATTR(resource, S_IRUGO, zorro_show_resource, NULL); -static ssize_t zorro_read_config(struct kobject *kobj, +static ssize_t zorro_read_config(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 806b277453f9..4e321f7353fa 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c @@ -46,9 +46,9 @@ struct bin_buffer { }; static int -fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) +fill_read(struct file *file, char *buffer, loff_t off, size_t count) { - struct sysfs_dirent *attr_sd = dentry->d_fsdata; + struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; int rc; @@ -59,7 +59,7 @@ fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) rc = -EIO; if (attr->read) - rc = attr->read(kobj, attr, buffer, off, count); + rc = attr->read(file, kobj, attr, buffer, off, count); sysfs_put_active(attr_sd); @@ -70,8 +70,7 @@ static ssize_t read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off) { struct bin_buffer *bb = file->private_data; - struct dentry *dentry = file->f_path.dentry; - int size = dentry->d_inode->i_size; + int size = file->f_path.dentry->d_inode->i_size; loff_t offs = *off; int count = min_t(size_t, bytes, PAGE_SIZE); char *temp; @@ -92,7 +91,7 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off) mutex_lock(&bb->mutex); - count = fill_read(dentry, bb->buffer, offs, count); + count = fill_read(file, bb->buffer, offs, count); if (count < 0) { mutex_unlock(&bb->mutex); goto out_free; @@ -117,9 +116,9 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off) } static int -flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) +flush_write(struct file *file, char *buffer, loff_t offset, size_t count) { - struct sysfs_dirent *attr_sd = dentry->d_fsdata; + struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; int rc; @@ -130,7 +129,7 @@ flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) rc = -EIO; if (attr->write) - rc = attr->write(kobj, attr, buffer, offset, count); + rc = attr->write(file, kobj, attr, buffer, offset, count); sysfs_put_active(attr_sd); @@ -141,8 +140,7 @@ static ssize_t write(struct file *file, const char __user *userbuf, size_t bytes, loff_t *off) { struct bin_buffer *bb = file->private_data; - struct dentry *dentry = file->f_path.dentry; - int size = dentry->d_inode->i_size; + int size = file->f_path.dentry->d_inode->i_size; loff_t offs = *off; int count = min_t(size_t, bytes, PAGE_SIZE); char *temp; @@ -165,7 +163,7 @@ static ssize_t write(struct file *file, const char __user *userbuf, memcpy(bb->buffer, temp, count); - count = flush_write(dentry, bb->buffer, offs, count); + count = flush_write(file, bb->buffer, offs, count); mutex_unlock(&bb->mutex); if (count > 0) @@ -363,7 +361,7 @@ static int mmap(struct file *file, struct vm_area_struct *vma) if (!attr->mmap) goto out_put; - rc = attr->mmap(kobj, attr, vma); + rc = attr->mmap(file, kobj, attr, vma); if (rc) goto out_put; diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 6903e9204032..f2694eb4dd3d 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -87,17 +87,18 @@ struct attribute_group { #define attr_name(_attr) (_attr).attr.name +struct file; struct vm_area_struct; struct bin_attribute { struct attribute attr; size_t size; void *private; - ssize_t (*read)(struct kobject *, struct bin_attribute *, + ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); - ssize_t (*write)(struct kobject *, struct bin_attribute *, + ssize_t (*write)(struct file *,struct kobject *, struct bin_attribute *, char *, loff_t, size_t); - int (*mmap)(struct kobject *, struct bin_attribute *attr, + int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr, struct vm_area_struct *vma); }; diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index 21fe3c426948..0b624e791805 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -138,7 +138,8 @@ extern const void __start_notes __attribute__((weak)); extern const void __stop_notes __attribute__((weak)); #define notes_size (&__stop_notes - &__start_notes) -static ssize_t notes_read(struct kobject *kobj, struct bin_attribute *bin_attr, +static ssize_t notes_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { memcpy(buf, &__start_notes + off, count); diff --git a/kernel/module.c b/kernel/module.c index e2564580f3f1..5e14483768bb 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1182,7 +1182,7 @@ struct module_notes_attrs { struct bin_attribute attrs[0]; }; -static ssize_t module_notes_read(struct kobject *kobj, +static ssize_t module_notes_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count) { diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c index dd321e39e621..486b8f3861d2 100644 --- a/net/bridge/br_sysfs_br.c +++ b/net/bridge/br_sysfs_br.c @@ -659,7 +659,7 @@ static struct attribute_group bridge_group = { * * Returns the number of bytes read. */ -static ssize_t brforward_read(struct kobject *kobj, +static ssize_t brforward_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { -- cgit v1.2.3-59-g8ed1b From ed1bbdefc39477a1301fb466139ffb0c00f0d006 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 26 Mar 2010 23:03:07 +0100 Subject: MIPS: Use set_cpus_allowed_ptr From: Julia Lawall Use set_cpus_allowed_ptr rather than set_cpus_allowed. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression E1,E2; @@ - set_cpus_allowed(E1, cpumask_of_cpu(E2)) + set_cpus_allowed_ptr(E1, cpumask_of(E2)) @@ expression E; identifier I; @@ - set_cpus_allowed(E, I) + set_cpus_allowed_ptr(E, &I) // Signed-off-by: Julia Lawall To: peterz@infradead.org To: mingo@elte.hu To: tglx@linutronix.de To: oleg@redhat.com To: linux-mips@linux-mips.org To: linux-kernel@vger.kernel.org To: kernel-janitors@vger.kernel.org Patchwork: http://patchwork.linux-mips.org/patch/1087/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpufreq/loongson2_cpufreq.c | 4 ++-- arch/mips/kernel/mips-mt-fpaff.c | 4 ++-- arch/mips/kernel/traps.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c index 2f6a0b147ab8..ae5db206347c 100644 --- a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c +++ b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c @@ -65,7 +65,7 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, return -ENODEV; cpus_allowed = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); if (cpufreq_frequency_table_target (policy, &loongson2_clockmod_table[0], target_freq, relation, @@ -91,7 +91,7 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, /* notifiers */ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - set_cpus_allowed(current, cpus_allowed); + set_cpus_allowed_ptr(current, &cpus_allowed); /* setting the cpu frequency */ clk_set_rate(cpuclk, freq); diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index cbc6182b0065..f5981c499109 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -100,10 +100,10 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, if (test_ti_thread_flag(ti, TIF_FPUBOUND) && cpus_intersects(new_mask, mt_fpu_cpumask)) { cpus_and(effective_mask, new_mask, mt_fpu_cpumask); - retval = set_cpus_allowed(p, effective_mask); + retval = set_cpus_allowed_ptr(p, &effective_mask); } else { clear_ti_thread_flag(ti, TIF_FPUBOUND); - retval = set_cpus_allowed(p, new_mask); + retval = set_cpus_allowed_ptr(p, &new_mask); } out_unlock: diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index d612c6dcb746..7e5e38c24cdc 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -854,7 +854,7 @@ static void mt_ase_fp_affinity(void) = current->cpus_allowed; cpus_and(tmask, current->cpus_allowed, mt_fpu_cpumask); - set_cpus_allowed(current, tmask); + set_cpus_allowed_ptr(current, &tmask); set_thread_flag(TIF_FPUBOUND); } } -- cgit v1.2.3-59-g8ed1b From b8853aa3d912f47f649ad8de784ac3afd932437d Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Tue, 13 Apr 2010 13:16:34 +0800 Subject: MIPS: Loongson: update cpu-feature-overrides.h Loongson doesn't support MIPSR2, therefore, MIPSR2 vectored interrupts (cpu_has_vint) and MIPSR2 external interrupt controller mode (cpu_has_veic) are 0. Signed-off-by: Wu Zhangjin Cc: Linux-MIPS Patchwork: http://patchwork.linux-mips.org/patch/1112/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h index 16210cedd929..675bd8641d5a 100644 --- a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h @@ -52,6 +52,8 @@ #define cpu_has_tx39_cache 0 #define cpu_has_userlocal 0 #define cpu_has_vce 0 +#define cpu_has_veic 0 +#define cpu_has_vint 0 #define cpu_has_vtag_icache 0 #define cpu_has_watch 1 -- cgit v1.2.3-59-g8ed1b From 7b5fcd694dffd1db294dd4ef9f90911852e422f5 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Thu, 25 Mar 2010 22:55:38 +0100 Subject: MIPS: Alchemy: Fix up residual devboard poweroff/reboot code. Clean out stray unused board_reset() calls in pb1x boards, the PB1000 is different from the rest and gets private methods. (Cleanup after 32fd6901a6d8d19f94e4de6be4e4b552ab078620) Signed-off-by: Manuel Lauss To: Linux-MIPS Patchwork: http://patchwork.linux-mips.org/patch/1085/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/devboards/pb1000/board_setup.c | 16 +++++++++++++++- arch/mips/alchemy/devboards/pb1100/board_setup.c | 5 ----- arch/mips/alchemy/devboards/pb1200/board_setup.c | 6 ------ arch/mips/alchemy/devboards/pb1500/board_setup.c | 5 ----- arch/mips/alchemy/devboards/pb1550/board_setup.c | 5 ----- 5 files changed, 15 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c index b5311d8a29ab..4ef50d86b181 100644 --- a/arch/mips/alchemy/devboards/pb1000/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c @@ -27,8 +27,10 @@ #include #include #include +#include #include #include +#include #include #include "../platform.h" @@ -38,8 +40,16 @@ const char *get_system_type(void) return "Alchemy Pb1000"; } -void board_reset(void) +static void board_reset(char *c) { + asm volatile ("jr %0" : : "r" (0xbfc00000)); +} + +static void board_power_off(void) +{ + printk(KERN_ALERT "It's now safe to remove power\n"); + while (1) + asm volatile (".set mips3 ; wait ; .set mips1"); } void __init board_setup(void) @@ -177,6 +187,10 @@ void __init board_setup(void) au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); break; } + + pm_power_off = board_power_off; + _machine_halt = board_power_off; + _machine_restart = board_reset; } static int __init pb1000_init_irq(void) diff --git a/arch/mips/alchemy/devboards/pb1100/board_setup.c b/arch/mips/alchemy/devboards/pb1100/board_setup.c index c7b4caa81a35..90dda5f3ecc5 100644 --- a/arch/mips/alchemy/devboards/pb1100/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1100/board_setup.c @@ -39,11 +39,6 @@ const char *get_system_type(void) return "Alchemy Pb1100"; } -void board_reset(void) -{ - bcsr_write(BCSR_SYSTEM, 0); -} - void __init board_setup(void) { volatile void __iomem *base = (volatile void __iomem *)0xac000000UL; diff --git a/arch/mips/alchemy/devboards/pb1200/board_setup.c b/arch/mips/alchemy/devboards/pb1200/board_setup.c index 3184063f8042..8b4466f2d44a 100644 --- a/arch/mips/alchemy/devboards/pb1200/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1200/board_setup.c @@ -48,12 +48,6 @@ const char *get_system_type(void) return "Alchemy Pb1200"; } -void board_reset(void) -{ - bcsr_write(BCSR_RESETS, 0); - bcsr_write(BCSR_SYSTEM, 0); -} - void __init board_setup(void) { printk(KERN_INFO "AMD Alchemy Pb1200 Board\n"); diff --git a/arch/mips/alchemy/devboards/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c index fa9770ac358a..9cd9dfa698e7 100644 --- a/arch/mips/alchemy/devboards/pb1500/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c @@ -45,11 +45,6 @@ const char *get_system_type(void) return "Alchemy Pb1500"; } -void board_reset(void) -{ - bcsr_write(BCSR_SYSTEM, 0); -} - void __init board_setup(void) { u32 pin_func; diff --git a/arch/mips/alchemy/devboards/pb1550/board_setup.c b/arch/mips/alchemy/devboards/pb1550/board_setup.c index 1e8fb3ddd726..9d7d6edafa8d 100644 --- a/arch/mips/alchemy/devboards/pb1550/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1550/board_setup.c @@ -48,11 +48,6 @@ const char *get_system_type(void) return "Alchemy Pb1550"; } -void board_reset(void) -{ - bcsr_write(BCSR_SYSTEM, 0); -} - void __init board_setup(void) { u32 pin_func; -- cgit v1.2.3-59-g8ed1b From 0f0d85bcc332ec8f0957378ea5fa3e553f80ae4b Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Tue, 13 Apr 2010 20:49:14 +0200 Subject: MIPS: Alchemy: add sysdev for IRQ PM. Use a sysdev to implement PM methods for the Au1000 interrupt controllers. Signed-off-by: Manuel Lauss To: Linux-MIPS Patchwork: http://patchwork.linux-mips.org/patch/1114/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/common/irq.c | 174 +++++++++++++++-------------- arch/mips/alchemy/common/power.c | 5 - arch/mips/include/asm/mach-au1x00/au1000.h | 34 +++++- 3 files changed, 122 insertions(+), 91 deletions(-) (limited to 'arch') diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index b2821ace4d00..9f78ada83b3c 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include @@ -216,90 +218,6 @@ struct au1xxx_irqmap au1200_irqmap[] __initdata = { }; -#ifdef CONFIG_PM - -/* - * Save/restore the interrupt controller state. - * Called from the save/restore core registers as part of the - * au_sleep function in power.c.....maybe I should just pm_register() - * them instead? - */ -static unsigned int sleep_intctl_config0[2]; -static unsigned int sleep_intctl_config1[2]; -static unsigned int sleep_intctl_config2[2]; -static unsigned int sleep_intctl_src[2]; -static unsigned int sleep_intctl_assign[2]; -static unsigned int sleep_intctl_wake[2]; -static unsigned int sleep_intctl_mask[2]; - -void save_au1xxx_intctl(void) -{ - sleep_intctl_config0[0] = au_readl(IC0_CFG0RD); - sleep_intctl_config1[0] = au_readl(IC0_CFG1RD); - sleep_intctl_config2[0] = au_readl(IC0_CFG2RD); - sleep_intctl_src[0] = au_readl(IC0_SRCRD); - sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD); - sleep_intctl_wake[0] = au_readl(IC0_WAKERD); - sleep_intctl_mask[0] = au_readl(IC0_MASKRD); - - sleep_intctl_config0[1] = au_readl(IC1_CFG0RD); - sleep_intctl_config1[1] = au_readl(IC1_CFG1RD); - sleep_intctl_config2[1] = au_readl(IC1_CFG2RD); - sleep_intctl_src[1] = au_readl(IC1_SRCRD); - sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD); - sleep_intctl_wake[1] = au_readl(IC1_WAKERD); - sleep_intctl_mask[1] = au_readl(IC1_MASKRD); -} - -/* - * For most restore operations, we clear the entire register and - * then set the bits we found during the save. - */ -void restore_au1xxx_intctl(void) -{ - au_writel(0xffffffff, IC0_MASKCLR); au_sync(); - - au_writel(0xffffffff, IC0_CFG0CLR); au_sync(); - au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync(); - au_writel(0xffffffff, IC0_CFG1CLR); au_sync(); - au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync(); - au_writel(0xffffffff, IC0_CFG2CLR); au_sync(); - au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync(); - au_writel(0xffffffff, IC0_SRCCLR); au_sync(); - au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync(); - au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync(); - au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync(); - au_writel(0xffffffff, IC0_WAKECLR); au_sync(); - au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync(); - au_writel(0xffffffff, IC0_RISINGCLR); au_sync(); - au_writel(0xffffffff, IC0_FALLINGCLR); au_sync(); - au_writel(0x00000000, IC0_TESTBIT); au_sync(); - - au_writel(0xffffffff, IC1_MASKCLR); au_sync(); - - au_writel(0xffffffff, IC1_CFG0CLR); au_sync(); - au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync(); - au_writel(0xffffffff, IC1_CFG1CLR); au_sync(); - au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync(); - au_writel(0xffffffff, IC1_CFG2CLR); au_sync(); - au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync(); - au_writel(0xffffffff, IC1_SRCCLR); au_sync(); - au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync(); - au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync(); - au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync(); - au_writel(0xffffffff, IC1_WAKECLR); au_sync(); - au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync(); - au_writel(0xffffffff, IC1_RISINGCLR); au_sync(); - au_writel(0xffffffff, IC1_FALLINGCLR); au_sync(); - au_writel(0x00000000, IC1_TESTBIT); au_sync(); - - au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync(); - - au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); -} -#endif /* CONFIG_PM */ - - static void au1x_ic0_unmask(unsigned int irq_nr) { unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; @@ -635,3 +553,91 @@ void __init arch_init_irq(void) break; } } + +struct alchemy_ic_sysdev { + struct sys_device sysdev; + void __iomem *base; + unsigned long pmdata[7]; +}; + +static int alchemy_ic_suspend(struct sys_device *dev, pm_message_t state) +{ + struct alchemy_ic_sysdev *icdev = + container_of(dev, struct alchemy_ic_sysdev, sysdev); + + icdev->pmdata[0] = __raw_readl(icdev->base + IC_CFG0RD); + icdev->pmdata[1] = __raw_readl(icdev->base + IC_CFG1RD); + icdev->pmdata[2] = __raw_readl(icdev->base + IC_CFG2RD); + icdev->pmdata[3] = __raw_readl(icdev->base + IC_SRCRD); + icdev->pmdata[4] = __raw_readl(icdev->base + IC_ASSIGNRD); + icdev->pmdata[5] = __raw_readl(icdev->base + IC_WAKERD); + icdev->pmdata[6] = __raw_readl(icdev->base + IC_MASKRD); + + return 0; +} + +static int alchemy_ic_resume(struct sys_device *dev) +{ + struct alchemy_ic_sysdev *icdev = + container_of(dev, struct alchemy_ic_sysdev, sysdev); + + __raw_writel(0xffffffff, icdev->base + IC_MASKCLR); + __raw_writel(0xffffffff, icdev->base + IC_CFG0CLR); + __raw_writel(0xffffffff, icdev->base + IC_CFG1CLR); + __raw_writel(0xffffffff, icdev->base + IC_CFG2CLR); + __raw_writel(0xffffffff, icdev->base + IC_SRCCLR); + __raw_writel(0xffffffff, icdev->base + IC_ASSIGNCLR); + __raw_writel(0xffffffff, icdev->base + IC_WAKECLR); + __raw_writel(0xffffffff, icdev->base + IC_RISINGCLR); + __raw_writel(0xffffffff, icdev->base + IC_FALLINGCLR); + __raw_writel(0x00000000, icdev->base + IC_TESTBIT); + wmb(); + __raw_writel(icdev->pmdata[0], icdev->base + IC_CFG0SET); + __raw_writel(icdev->pmdata[1], icdev->base + IC_CFG1SET); + __raw_writel(icdev->pmdata[2], icdev->base + IC_CFG2SET); + __raw_writel(icdev->pmdata[3], icdev->base + IC_SRCSET); + __raw_writel(icdev->pmdata[4], icdev->base + IC_ASSIGNSET); + __raw_writel(icdev->pmdata[5], icdev->base + IC_WAKESET); + wmb(); + + __raw_writel(icdev->pmdata[6], icdev->base + IC_MASKSET); + wmb(); + + return 0; +} + +static struct sysdev_class alchemy_ic_sysdev_class = { + .name = "ic", + .suspend = alchemy_ic_suspend, + .resume = alchemy_ic_resume, +}; + +static int __init alchemy_ic_sysdev_init(void) +{ + struct alchemy_ic_sysdev *icdev; + unsigned long icbase[2] = { IC0_PHYS_ADDR, IC1_PHYS_ADDR }; + int err, i; + + err = sysdev_class_register(&alchemy_ic_sysdev_class); + if (err) + return err; + + for (i = 0; i < 2; i++) { + icdev = kzalloc(sizeof(struct alchemy_ic_sysdev), GFP_KERNEL); + if (!icdev) + return -ENOMEM; + + icdev->base = ioremap(icbase[i], 0x1000); + + icdev->sysdev.id = i; + icdev->sysdev.cls = &alchemy_ic_sysdev_class; + err = sysdev_register(&icdev->sysdev); + if (err) { + kfree(icdev); + return err; + } + } + + return 0; +} +device_initcall(alchemy_ic_sysdev_init); diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index 6ab7b42aa1be..11e5ec748414 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c @@ -106,9 +106,6 @@ static void save_core_regs(void) sleep_usb[1] = au_readl(0xb4020024); /* OTG_MUX */ #endif - /* Save interrupt controller state. */ - save_au1xxx_intctl(); - /* Clocks and PLLs. */ sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); @@ -200,8 +197,6 @@ static void restore_core_regs(void) au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync(); } - restore_au1xxx_intctl(); - #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) au1xxx_dbdma_resume(); #endif diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h index ae07423e6e82..e76941db2312 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000.h +++ b/arch/mips/include/asm/mach-au1x00/au1000.h @@ -190,8 +190,6 @@ extern unsigned long au1xxx_calc_clock(void); /* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */ void au1xxx_save_and_sleep(void); void au_sleep(void); -void save_au1xxx_intctl(void); -void restore_au1xxx_intctl(void); /* SOC Interrupt numbers */ @@ -835,6 +833,38 @@ enum soc_au1200_ints { #define MEM_STNAND_DATA 0x20 #endif + +/* Interrupt Controller register offsets */ +#define IC_CFG0RD 0x40 +#define IC_CFG0SET 0x40 +#define IC_CFG0CLR 0x44 +#define IC_CFG1RD 0x48 +#define IC_CFG1SET 0x48 +#define IC_CFG1CLR 0x4C +#define IC_CFG2RD 0x50 +#define IC_CFG2SET 0x50 +#define IC_CFG2CLR 0x54 +#define IC_REQ0INT 0x54 +#define IC_SRCRD 0x58 +#define IC_SRCSET 0x58 +#define IC_SRCCLR 0x5C +#define IC_REQ1INT 0x5C +#define IC_ASSIGNRD 0x60 +#define IC_ASSIGNSET 0x60 +#define IC_ASSIGNCLR 0x64 +#define IC_WAKERD 0x68 +#define IC_WAKESET 0x68 +#define IC_WAKECLR 0x6C +#define IC_MASKRD 0x70 +#define IC_MASKSET 0x70 +#define IC_MASKCLR 0x74 +#define IC_RISINGRD 0x78 +#define IC_RISINGCLR 0x78 +#define IC_FALLINGRD 0x7C +#define IC_FALLINGCLR 0x7C +#define IC_TESTBIT 0x80 + + /* Interrupt Controller 0 */ #define IC0_CFG0RD 0xB0400040 #define IC0_CFG0SET 0xB0400040 -- cgit v1.2.3-59-g8ed1b From 96d660c482e03b2d7b6c0245b95a7cce537606c8 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Wed, 14 Apr 2010 20:33:44 +0200 Subject: MIPS: Alchemy: add sysdev for DBDMA PM. Add a sysdev for DBDMA PM. Signed-off-by: Manuel Lauss To: Linux-MIPS Patchwork: http://patchwork.linux-mips.org/patch/1119/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/common/dbdma.c | 101 ++++++++++++++++------- arch/mips/alchemy/common/power.c | 11 --- arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h | 4 - 3 files changed, 72 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 99ae84ce5af3..ca0506a8585a 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -174,10 +175,6 @@ static dbdev_tab_t dbdev_tab[] = { #define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) -#ifdef CONFIG_PM -static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][6]; -#endif - static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; @@ -960,29 +957,37 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr) return nbytes; } -#ifdef CONFIG_PM -void au1xxx_dbdma_suspend(void) + +struct alchemy_dbdma_sysdev { + struct sys_device sysdev; + u32 pm_regs[NUM_DBDMA_CHANS + 1][6]; +}; + +static int alchemy_dbdma_suspend(struct sys_device *dev, + pm_message_t state) { + struct alchemy_dbdma_sysdev *sdev = + container_of(dev, struct alchemy_dbdma_sysdev, sysdev); int i; u32 addr; addr = DDMA_GLOBAL_BASE; - au1xxx_dbdma_pm_regs[0][0] = au_readl(addr + 0x00); - au1xxx_dbdma_pm_regs[0][1] = au_readl(addr + 0x04); - au1xxx_dbdma_pm_regs[0][2] = au_readl(addr + 0x08); - au1xxx_dbdma_pm_regs[0][3] = au_readl(addr + 0x0c); + sdev->pm_regs[0][0] = au_readl(addr + 0x00); + sdev->pm_regs[0][1] = au_readl(addr + 0x04); + sdev->pm_regs[0][2] = au_readl(addr + 0x08); + sdev->pm_regs[0][3] = au_readl(addr + 0x0c); /* save channel configurations */ for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) { - au1xxx_dbdma_pm_regs[i][0] = au_readl(addr + 0x00); - au1xxx_dbdma_pm_regs[i][1] = au_readl(addr + 0x04); - au1xxx_dbdma_pm_regs[i][2] = au_readl(addr + 0x08); - au1xxx_dbdma_pm_regs[i][3] = au_readl(addr + 0x0c); - au1xxx_dbdma_pm_regs[i][4] = au_readl(addr + 0x10); - au1xxx_dbdma_pm_regs[i][5] = au_readl(addr + 0x14); + sdev->pm_regs[i][0] = au_readl(addr + 0x00); + sdev->pm_regs[i][1] = au_readl(addr + 0x04); + sdev->pm_regs[i][2] = au_readl(addr + 0x08); + sdev->pm_regs[i][3] = au_readl(addr + 0x0c); + sdev->pm_regs[i][4] = au_readl(addr + 0x10); + sdev->pm_regs[i][5] = au_readl(addr + 0x14); /* halt channel */ - au_writel(au1xxx_dbdma_pm_regs[i][0] & ~1, addr + 0x00); + au_writel(sdev->pm_regs[i][0] & ~1, addr + 0x00); au_sync(); while (!(au_readl(addr + 0x14) & 1)) au_sync(); @@ -992,32 +997,65 @@ void au1xxx_dbdma_suspend(void) /* disable channel interrupts */ au_writel(0, DDMA_GLOBAL_BASE + 0x0c); au_sync(); + + return 0; } -void au1xxx_dbdma_resume(void) +static int alchemy_dbdma_resume(struct sys_device *dev) { + struct alchemy_dbdma_sysdev *sdev = + container_of(dev, struct alchemy_dbdma_sysdev, sysdev); int i; u32 addr; addr = DDMA_GLOBAL_BASE; - au_writel(au1xxx_dbdma_pm_regs[0][0], addr + 0x00); - au_writel(au1xxx_dbdma_pm_regs[0][1], addr + 0x04); - au_writel(au1xxx_dbdma_pm_regs[0][2], addr + 0x08); - au_writel(au1xxx_dbdma_pm_regs[0][3], addr + 0x0c); + au_writel(sdev->pm_regs[0][0], addr + 0x00); + au_writel(sdev->pm_regs[0][1], addr + 0x04); + au_writel(sdev->pm_regs[0][2], addr + 0x08); + au_writel(sdev->pm_regs[0][3], addr + 0x0c); /* restore channel configurations */ for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) { - au_writel(au1xxx_dbdma_pm_regs[i][0], addr + 0x00); - au_writel(au1xxx_dbdma_pm_regs[i][1], addr + 0x04); - au_writel(au1xxx_dbdma_pm_regs[i][2], addr + 0x08); - au_writel(au1xxx_dbdma_pm_regs[i][3], addr + 0x0c); - au_writel(au1xxx_dbdma_pm_regs[i][4], addr + 0x10); - au_writel(au1xxx_dbdma_pm_regs[i][5], addr + 0x14); + au_writel(sdev->pm_regs[i][0], addr + 0x00); + au_writel(sdev->pm_regs[i][1], addr + 0x04); + au_writel(sdev->pm_regs[i][2], addr + 0x08); + au_writel(sdev->pm_regs[i][3], addr + 0x0c); + au_writel(sdev->pm_regs[i][4], addr + 0x10); + au_writel(sdev->pm_regs[i][5], addr + 0x14); au_sync(); addr += 0x100; /* next channel base */ } + + return 0; +} + +static struct sysdev_class alchemy_dbdma_sysdev_class = { + .name = "dbdma", + .suspend = alchemy_dbdma_suspend, + .resume = alchemy_dbdma_resume, +}; + +static int __init alchemy_dbdma_sysdev_init(void) +{ + struct alchemy_dbdma_sysdev *sdev; + int ret; + + ret = sysdev_class_register(&alchemy_dbdma_sysdev_class); + if (ret) + return ret; + + sdev = kzalloc(sizeof(struct alchemy_dbdma_sysdev), GFP_KERNEL); + if (!sdev) + return -ENOMEM; + + sdev->sysdev.id = -1; + sdev->sysdev.cls = &alchemy_dbdma_sysdev_class; + ret = sysdev_register(&sdev->sysdev); + if (ret) + kfree(sdev); + + return ret; } -#endif /* CONFIG_PM */ static int __init au1xxx_dbdma_init(void) { @@ -1046,6 +1084,11 @@ static int __init au1xxx_dbdma_init(void) else { dbdma_initialized = 1; printk(KERN_INFO "Alchemy DBDMA initialized\n"); + ret = alchemy_dbdma_sysdev_init(); + if (ret) { + printk(KERN_ERR "DBDMA PM init failed\n"); + ret = 0; + } } return ret; diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index 11e5ec748414..14eb8c492da2 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c @@ -36,9 +36,6 @@ #include #include -#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) -#include -#endif #ifdef CONFIG_PM @@ -129,10 +126,6 @@ static void save_core_regs(void) sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); - -#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) - au1xxx_dbdma_suspend(); -#endif } static void restore_core_regs(void) @@ -196,10 +189,6 @@ static void restore_core_regs(void) au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync(); au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync(); } - -#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) - au1xxx_dbdma_resume(); -#endif } void au_sleep(void) diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h index 8c6b1105ce0b..c8a553a36ba4 100644 --- a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h +++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h @@ -358,10 +358,6 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr); u32 au1xxx_ddma_add_device(dbdev_tab_t *dev); extern void au1xxx_ddma_del_device(u32 devid); void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp); -#ifdef CONFIG_PM -void au1xxx_dbdma_suspend(void); -void au1xxx_dbdma_resume(void); -#endif /* * Flags for the put_source/put_dest functions. -- cgit v1.2.3-59-g8ed1b From c197da9163a42e6faeb051f331868b9245836eef Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 29 Apr 2010 11:58:54 +0200 Subject: MIPS: Loongson 2F: Add gpio/gpioilb support Signed-off-by: Arnaud Patard To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1163/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 + arch/mips/include/asm/mach-loongson/gpio.h | 35 ++++++++ arch/mips/loongson/common/Makefile | 1 + arch/mips/loongson/common/gpio.c | 139 +++++++++++++++++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 arch/mips/include/asm/mach-loongson/gpio.h create mode 100644 arch/mips/loongson/common/gpio.c (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7e6fd1cbd3f8..cdaae942623d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1075,6 +1075,8 @@ config CPU_LOONGSON2F bool "Loongson 2F" depends on SYS_HAS_CPU_LOONGSON2F select CPU_LOONGSON2 + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB help The Loongson 2F processor implements the MIPS III instruction set with many extensions. diff --git a/arch/mips/include/asm/mach-loongson/gpio.h b/arch/mips/include/asm/mach-loongson/gpio.h new file mode 100644 index 000000000000..e30e73d443df --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/gpio.h @@ -0,0 +1,35 @@ +/* + * STLS2F GPIO Support + * + * Copyright (c) 2008 Richard Liu, STMicroelectronics + * Copyright (c) 2008-2010 Arnaud Patard + * + * 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. + */ + +#ifndef __STLS2F_GPIO_H +#define __STLS2F_GPIO_H + +#include + +extern void gpio_set_value(unsigned gpio, int value); +extern int gpio_get_value(unsigned gpio); +extern int gpio_cansleep(unsigned gpio); + +/* The chip can do interrupt + * but it has not been tested and doc not clear + */ +static inline int gpio_to_irq(int gpio) +{ + return -EINVAL; +} + +static inline int irq_to_gpio(int gpio) +{ + return -EINVAL; +} + +#endif /* __STLS2F_GPIO_H */ diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile index 7668c4de1151..cdd2e812ba1a 100644 --- a/arch/mips/loongson/common/Makefile +++ b/arch/mips/loongson/common/Makefile @@ -4,6 +4,7 @@ obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ pci.o bonito-irq.o mem.o machtype.o platform.o +obj-$(CONFIG_GENERIC_GPIO) += gpio.o # # Serial port support diff --git a/arch/mips/loongson/common/gpio.c b/arch/mips/loongson/common/gpio.c new file mode 100644 index 000000000000..e8a0ffa935b4 --- /dev/null +++ b/arch/mips/loongson/common/gpio.c @@ -0,0 +1,139 @@ +/* + * STLS2F GPIO Support + * + * Copyright (c) 2008 Richard Liu, STMicroelectronics + * Copyright (c) 2008-2010 Arnaud Patard + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define STLS2F_N_GPIO 4 +#define STLS2F_GPIO_IN_OFFSET 16 + +static DEFINE_SPINLOCK(gpio_lock); + +int gpio_get_value(unsigned gpio) +{ + u32 val; + u32 mask; + + if (gpio >= STLS2F_N_GPIO) + return __gpio_get_value(gpio); + + mask = 1 << (gpio + STLS2F_GPIO_IN_OFFSET); + spin_lock(&gpio_lock); + val = LOONGSON_GPIODATA; + spin_unlock(&gpio_lock); + + return ((val & mask) != 0); +} +EXPORT_SYMBOL(gpio_get_value); + +void gpio_set_value(unsigned gpio, int state) +{ + u32 val; + u32 mask; + + if (gpio >= STLS2F_N_GPIO) { + __gpio_set_value(gpio, state); + return ; + } + + mask = 1 << gpio; + + spin_lock(&gpio_lock); + val = LOONGSON_GPIODATA; + if (state) + val |= mask; + else + val &= (~mask); + LOONGSON_GPIODATA = val; + spin_unlock(&gpio_lock); +} +EXPORT_SYMBOL(gpio_set_value); + +int gpio_cansleep(unsigned gpio) +{ + if (gpio < STLS2F_N_GPIO) + return 0; + else + return __gpio_cansleep(gpio); +} +EXPORT_SYMBOL(gpio_cansleep); + +static int ls2f_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + u32 temp; + u32 mask; + + if (gpio >= STLS2F_N_GPIO) + return -EINVAL; + + spin_lock(&gpio_lock); + mask = 1 << gpio; + temp = LOONGSON_GPIOIE; + temp |= mask; + LOONGSON_GPIOIE = temp; + spin_unlock(&gpio_lock); + + return 0; +} + +static int ls2f_gpio_direction_output(struct gpio_chip *chip, + unsigned gpio, int level) +{ + u32 temp; + u32 mask; + + if (gpio >= STLS2F_N_GPIO) + return -EINVAL; + + gpio_set_value(gpio, level); + spin_lock(&gpio_lock); + mask = 1 << gpio; + temp = LOONGSON_GPIOIE; + temp &= (~mask); + LOONGSON_GPIOIE = temp; + spin_unlock(&gpio_lock); + + return 0; +} + +static int ls2f_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + return gpio_get_value(gpio); +} + +static void ls2f_gpio_set_value(struct gpio_chip *chip, + unsigned gpio, int value) +{ + gpio_set_value(gpio, value); +} + +static struct gpio_chip ls2f_chip = { + .label = "ls2f", + .direction_input = ls2f_gpio_direction_input, + .get = ls2f_gpio_get_value, + .direction_output = ls2f_gpio_direction_output, + .set = ls2f_gpio_set_value, + .base = 0, + .ngpio = STLS2F_N_GPIO, +}; + +static int __init ls2f_gpio_setup(void) +{ + return gpiochip_add(&ls2f_chip); +} +arch_initcall(ls2f_gpio_setup); -- cgit v1.2.3-59-g8ed1b From 3f135530448104c01153fe048024366203196798 Mon Sep 17 00:00:00 2001 From: Shane McDonald Date: Fri, 7 May 2010 00:02:09 -0600 Subject: MIPS: Coding style cleanups of access of FCSR rounding mode bits Replaces references to the magic number 0x3 with constants and macros indicating the real purpose of those bits. They are the rounding mode bits of the FCSR register. Signed-off-by: Shane McDonald To: anemo@mba.ocn.ne.jp To: kevink@paralogos.com To: linux-mips@linux-mips.org To: sshtylyov@mvista.com Patchwork: http://patchwork.linux-mips.org/patch/1206/ Signed-off-by: Ralf Baechle --- arch/mips/math-emu/cp1emu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index f2338d1c0b48..47842b7d26ae 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -354,7 +354,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) if (MIPSInst_RD(ir) == FPCREG_CSR) { value = ctx->fcr31; - value = (value & ~0x3) | mips_rm[value & 0x3]; + value = (value & ~FPU_CSR_RM) | + mips_rm[modeindex(value)]; #ifdef CSRTRACE printk("%p gpr[%d]<-csr=%08x\n", (void *) (xcp->cp0_epc), @@ -907,7 +908,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ieee754sp fs; SPFROMREG(fs, MIPSInst_FS(ir)); - ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; + ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; rv.w = ieee754sp_tint(fs); ieee754_csr.rm = oldrm; rfmt = w_fmt; @@ -933,7 +934,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ieee754sp fs; SPFROMREG(fs, MIPSInst_FS(ir)); - ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; + ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; rv.l = ieee754sp_tlong(fs); ieee754_csr.rm = oldrm; rfmt = l_fmt; @@ -1081,7 +1082,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ieee754dp fs; DPFROMREG(fs, MIPSInst_FS(ir)); - ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; + ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; rv.w = ieee754dp_tint(fs); ieee754_csr.rm = oldrm; rfmt = w_fmt; @@ -1107,7 +1108,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ieee754dp fs; DPFROMREG(fs, MIPSInst_FS(ir)); - ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; + ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; rv.l = ieee754dp_tlong(fs); ieee754_csr.rm = oldrm; rfmt = l_fmt; -- cgit v1.2.3-59-g8ed1b From 4f1e099582c119cf73d6a873b53e8edaa773d065 Mon Sep 17 00:00:00 2001 From: David VomLehn Date: Fri, 7 May 2010 15:17:02 -0700 Subject: MIPS: Clean up tables for bootmem allocation Modifications to the boot memory allocation structures to make them easier to read and maintain. Note that this will not pass checkpatch because it wants a structure element initializer to be enclosed in a do {...} while(...), which is obvious nonsensical. Signed-off-by: David VomLehn To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1207/ Signed-off-by: Ralf Baechle --- arch/mips/powertv/asic/prealloc-calliope.c | 673 +++++++++------------------ arch/mips/powertv/asic/prealloc-cronus.c | 668 ++++++++------------------ arch/mips/powertv/asic/prealloc-cronuslite.c | 302 ++++-------- arch/mips/powertv/asic/prealloc-zeus.c | 505 +++++++------------- arch/mips/powertv/asic/prealloc.h | 70 +++ 5 files changed, 757 insertions(+), 1461 deletions(-) create mode 100644 arch/mips/powertv/asic/prealloc.h (limited to 'arch') diff --git a/arch/mips/powertv/asic/prealloc-calliope.c b/arch/mips/powertv/asic/prealloc-calliope.c index cd5b76a1c951..3fc5d46687a9 100644 --- a/arch/mips/powertv/asic/prealloc-calliope.c +++ b/arch/mips/powertv/asic/prealloc-calliope.c @@ -22,7 +22,9 @@ */ #include +#include #include +#include "prealloc.h" /* * NON_DVR_CAPABLE CALLIOPE RESOURCES @@ -32,432 +34,234 @@ struct resource non_dvr_calliope_resources[] __initdata = /* * VIDEO / LX1 */ - { - .name = "ST231aImage", /* Delta-Mu 1 image and ram */ - .start = 0x24000000, - .end = 0x24200000 - 1, /*2MiB */ - .flags = IORESOURCE_MEM, - }, - { - .name = "ST231aMonitor", /*8KiB block ST231a monitor */ - .start = 0x24200000, - .end = 0x24202000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "MediaMemory1", - .start = 0x24202000, - .end = 0x26700000 - 1, /*~36.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_MEM, - }, + /* Delta-Mu 1 image (2MiB) */ + PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 monitor (8KiB) */ + PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 RAM (~36.9MiB (32MiB - (2MiB + 8KiB))) */ + PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26700000-1, + IORESOURCE_MEM) + /* * Sysaudio Driver */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, + /* DSP code and data images (1MiB) */ + PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC CPU PCM buffer (40KiB) */ + PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC AUX buffer (128KiB) */ + PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC Main buffer (128KiB) */ + PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * STAVEM driver/STAPI */ - { - .name = "AVMEMPartition0", - .start = 0x00000000, - .end = 0x00600000 - 1, /* 6 MB total */ - .flags = IORESOURCE_MEM, - }, + /* 6MiB */ + PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * DOCSIS Subsystem */ - { - .name = "Docsis", - .start = 0x22000000, - .end = 0x22700000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 7MiB */ + PREALLOC_DOCSIS("Docsis", 0x27500000, 0x27c00000-1, IORESOURCE_MEM) + /* * GHW HAL Driver */ - { - .name = "GraphicsHeap", - .start = 0x22700000, - .end = 0x23500000 - 1, /* 14 MB total */ - .flags = IORESOURCE_MEM, - }, + /* PowerTV Graphics Heap (14MiB) */ + PREALLOC_NORMAL("GraphicsHeap", 0x26700000, 0x26700000+(14*1048576)-1, + IORESOURCE_MEM) + /* * multi com buffer area */ - { - .name = "MulticomSHM", - .start = 0x23700000, - .end = 0x23720000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 128KiB */ + PREALLOC_NORMAL("MulticomSHM", 0x23700000, 0x23720000-1, + IORESOURCE_MEM) + /* * DMA Ring buffer (don't need recording buffers) */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x000AA000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 680KiB */ + PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Display bins buffer for unit0 */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * AVFS: player HAL memory - * - * */ - { - .name = "AvfsDmaMem", - .start = 0x00000000, - .end = 0x002c4c00 - 1, /* 945K * 3 for playback */ - .flags = IORESOURCE_MEM, - }, + /* 945K * 3 for playback */ + PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * PMEM */ - { - .name = "DiagPersistentMemory", - .start = 0x00000000, - .end = 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, + /* Persistent memory for diagnostics (64KiB) */ + PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Smartcard */ - { - .name = "SmartCardInfo", - .start = 0x00000000, - .end = 0x2800 - 1, - .flags = IORESOURCE_MEM, - }, + /* Read and write buffers for Internal/External cards (10KiB) */ + PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * NAND Flash */ - { - .name = "NandFlash", - .start = NAND_FLASH_BASE, - .end = NAND_FLASH_BASE + 0x400 - 1, - .flags = IORESOURCE_IO, - }, + /* 10KiB */ + PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, + IORESOURCE_MEM) + /* * Synopsys GMAC Memory Region */ - { - .name = "GMAC", - .start = 0x00000000, - .end = 0x00010000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 64KiB */ + PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * Add other resources here + * TFTPBuffer * + * This buffer is used in some minimal configurations (e.g. two-way + * loader) for storing software images */ - { }, -}; + PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) -struct resource non_dvr_vz_calliope_resources[] __initdata = -{ /* - * VIDEO / LX1 - */ - { - .name = "ST231aImage", /* Delta-Mu 1 image and ram */ - .start = 0x24000000, - .end = 0x24200000 - 1, /*2 Meg */ - .flags = IORESOURCE_MEM, - }, - { - .name = "ST231aMonitor", /* 8k block ST231a monitor */ - .start = 0x24200000, - .end = 0x24202000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "MediaMemory1", - .start = 0x22202000, - .end = 0x22C20B85 - 1, /* 10.12 Meg */ - .flags = IORESOURCE_MEM, - }, - /* - * Sysaudio Driver - */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - /* - * STAVEM driver/STAPI - */ - { - .name = "AVMEMPartition0", - .start = 0x20300000, - .end = 0x20620000-1, /*3.125 MB total */ - .flags = IORESOURCE_MEM, - }, - /* - * GHW HAL Driver - */ - { - .name = "GraphicsHeap", - .start = 0x20100000, - .end = 0x20300000 - 1, - .flags = IORESOURCE_MEM, - }, - /* - * multi com buffer area - */ - { - .name = "MulticomSHM", - .start = 0x23900000, - .end = 0x23920000 - 1, - .flags = IORESOURCE_MEM, - }, - /* - * DMA Ring buffer - */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x000AA000 - 1, - .flags = IORESOURCE_MEM, - }, - /* - * Display bins buffer for unit0 - */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, - .flags = IORESOURCE_MEM, - }, - /* - * PMEM - */ - { - .name = "DiagPersistentMemory", - .start = 0x00000000, - .end = 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, - /* - * Smartcard - */ - { - .name = "SmartCardInfo", - .start = 0x00000000, - .end = 0x2800 - 1, - .flags = IORESOURCE_MEM, - }, - /* - * NAND Flash + * Add other resources here */ - { - .name = "NandFlash", - .start = NAND_FLASH_BASE, - .end = NAND_FLASH_BASE+0x400 - 1, - .flags = IORESOURCE_IO, - }, + /* - * Synopsys GMAC Memory Region + * End of Resource marker */ { - .name = "GMAC", - .start = 0x00000000, - .end = 0x00010000 - 1, - .flags = IORESOURCE_MEM, + .flags = 0, }, - /* - * Add other resources here - */ - { }, }; + struct resource non_dvr_vze_calliope_resources[] __initdata = { /* * VIDEO / LX1 */ - { - .name = "ST231aImage", /* Delta-Mu 1 image and ram */ - .start = 0x22000000, - .end = 0x22200000 - 1, /*2 Meg */ - .flags = IORESOURCE_MEM, - }, - { - .name = "ST231aMonitor", /* 8k block ST231a monitor */ - .start = 0x22200000, - .end = 0x22202000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "MediaMemory1", - .start = 0x22202000, - .end = 0x22C20B85 - 1, /* 10.12 Meg */ - .flags = IORESOURCE_MEM, - }, + /* Delta-Mu 1 image (2MiB) */ + PREALLOC_NORMAL("ST231aImage", 0x22000000, 0x22200000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 monitor (8KiB) */ + PREALLOC_NORMAL("ST231aMonitor", 0x22200000, 0x22202000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 RAM (10.12MiB) */ + PREALLOC_NORMAL("MediaMemory1", 0x22202000, 0x22C20B85-1, + IORESOURCE_MEM) + /* * Sysaudio Driver */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, + /* DSP code and data images (1MiB) */ + PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC CPU PCM buffer (40KiB) */ + PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC AUX buffer (16KiB) */ + PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC Main buffer (16KiB) */ + PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * STAVEM driver/STAPI */ - { - .name = "AVMEMPartition0", - .start = 0x20396000, - .end = 0x206B6000 - 1, /* 3.125 MB total */ - .flags = IORESOURCE_MEM, - }, + /* 3.125MiB */ + PREALLOC_NORMAL("AVMEMPartition0", 0x20396000, 0x206B6000-1, + IORESOURCE_MEM) + /* * GHW HAL Driver */ - { - .name = "GraphicsHeap", - .start = 0x20100000, - .end = 0x20396000 - 1, - .flags = IORESOURCE_MEM, - }, + /* PowerTV Graphics Heap (2.59MiB) */ + PREALLOC_NORMAL("GraphicsHeap", 0x20100000, 0x20396000-1, + IORESOURCE_MEM) + /* * multi com buffer area */ - { - .name = "MulticomSHM", - .start = 0x206B6000, - .end = 0x206D6000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 128KiB */ + PREALLOC_NORMAL("MulticomSHM", 0x206B6000, 0x206D6000-1, + IORESOURCE_MEM) + /* - * DMA Ring buffer + * DMA Ring buffer (don't need recording buffers) */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x000AA000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 680KiB */ + PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Display bins buffer for unit0 */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, - .flags = IORESOURCE_MEM, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * PMEM */ - { - .name = "DiagPersistentMemory", - .start = 0x00000000, - .end = 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, + /* Persistent memory for diagnostics (64KiB) */ + PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Smartcard */ - { - .name = "SmartCardInfo", - .start = 0x00000000, - .end = 0x2800 - 1, - .flags = IORESOURCE_MEM, - }, + /* Read and write buffers for Internal/External cards (10KiB) */ + PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * NAND Flash */ - { - .name = "NandFlash", - .start = NAND_FLASH_BASE, - .end = NAND_FLASH_BASE+0x400 - 1, - .flags = IORESOURCE_MEM, - }, + /* 10KiB */ + PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, + IORESOURCE_MEM) + /* * Synopsys GMAC Memory Region */ - { - .name = "GMAC", - .start = 0x00000000, - .end = 0x00010000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 64KiB */ + PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Add other resources here */ - { }, + + /* + * End of Resource marker + */ + { + .flags = 0, + }, }; struct resource non_dvr_vzf_calliope_resources[] __initdata = @@ -465,156 +269,117 @@ struct resource non_dvr_vzf_calliope_resources[] __initdata = /* * VIDEO / LX1 */ - { - .name = "ST231aImage", /*Delta-Mu 1 image and ram */ - .start = 0x24000000, - .end = 0x24200000 - 1, /*2MiB */ - .flags = IORESOURCE_MEM, - }, - { - .name = "ST231aMonitor", /*8KiB block ST231a monitor */ - .start = 0x24200000, - .end = 0x24202000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "MediaMemory1", - .start = 0x24202000, - /* ~19.4 (21.5MiB - (2MiB + 8KiB)) */ - .end = 0x25580000 - 1, - .flags = IORESOURCE_MEM, - }, + /* Delta-Mu 1 image (2MiB) */ + PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 monitor (8KiB) */ + PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 RAM (~19.4 (21.5MiB - (2MiB + 8KiB))) */ + PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x25580000-1, + IORESOURCE_MEM) + /* * Sysaudio Driver */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, + /* DSP code and data images (1MiB) */ + PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC CPU PCM buffer (40KiB) */ + PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC AUX buffer (128KiB) */ + PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC Main buffer (128KiB) */ + PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * STAVEM driver/STAPI */ - { - .name = "AVMEMPartition0", - .start = 0x00000000, - .end = 0x00480000 - 1, /* 4.5 MB total */ - .flags = IORESOURCE_MEM, - }, + /* 4.5MiB */ + PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00480000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * GHW HAL Driver */ - { - .name = "GraphicsHeap", - .start = 0x22700000, - .end = 0x23500000 - 1, /* 14 MB total */ - .flags = IORESOURCE_MEM, - }, + /* PowerTV Graphics Heap (14MiB) */ + PREALLOC_NORMAL("GraphicsHeap", 0x25600000, 0x25600000+(14*1048576)-1, + IORESOURCE_MEM) + /* * multi com buffer area */ - { - .name = "MulticomSHM", - .start = 0x23700000, - .end = 0x23720000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 128KiB */ + PREALLOC_NORMAL("MulticomSHM", 0x23700000, 0x23720000-1, + IORESOURCE_MEM) + /* * DMA Ring buffer (don't need recording buffers) */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x000AA000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 680KiB */ + PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Display bins buffer for unit0 */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Display bins buffer for unit1 */ - { - .name = "DisplayBins1", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * AVFS: player HAL memory - * - * */ - { - .name = "AvfsDmaMem", - .start = 0x00000000, - .end = 0x002c4c00 - 1, /* 945K * 3 for playback */ - .flags = IORESOURCE_MEM, - }, + /* 945K * 3 for playback */ + PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * PMEM */ - { - .name = "DiagPersistentMemory", - .start = 0x00000000, - .end = 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, + /* Persistent memory for diagnostics (64KiB) */ + PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Smartcard */ - { - .name = "SmartCardInfo", - .start = 0x00000000, - .end = 0x2800 - 1, - .flags = IORESOURCE_MEM, - }, + /* Read and write buffers for Internal/External cards (10KiB) */ + PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * NAND Flash */ - { - .name = "NandFlash", - .start = NAND_FLASH_BASE, - .end = NAND_FLASH_BASE + 0x400 - 1, - .flags = IORESOURCE_MEM, - }, + /* 10KiB */ + PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, + IORESOURCE_MEM) + /* * Synopsys GMAC Memory Region */ - { - .name = "GMAC", - .start = 0x00000000, - .end = 0x00010000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 64KiB */ + PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Add other resources here */ - { }, + + /* + * End of Resource marker + */ + { + .flags = 0, + }, }; diff --git a/arch/mips/powertv/asic/prealloc-cronus.c b/arch/mips/powertv/asic/prealloc-cronus.c index 45a5c3ea718c..c532b50521ec 100644 --- a/arch/mips/powertv/asic/prealloc-cronus.c +++ b/arch/mips/powertv/asic/prealloc-cronus.c @@ -22,7 +22,9 @@ */ #include +#include #include +#include "prealloc.h" /* * DVR_CAPABLE CRONUS RESOURCES @@ -30,305 +32,161 @@ struct resource dvr_cronus_resources[] __initdata = { /* - * * VIDEO1 / LX1 - * */ - { - .name = "ST231aImage", /* Delta-Mu 1 image and ram */ - .start = 0x24000000, - .end = 0x241FFFFF, /* 2MiB */ - .flags = IORESOURCE_MEM, - }, - { - .name = "ST231aMonitor", /* 8KiB block ST231a monitor */ - .start = 0x24200000, - .end = 0x24201FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "MediaMemory1", - .start = 0x24202000, - .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_MEM, - }, + /* Delta-Mu 1 image (2MiB) */ + PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 monitor (8KiB) */ + PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ + PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26000000-1, + IORESOURCE_MEM) + /* - * * VIDEO2 / LX2 - * */ - { - .name = "ST231bImage", /* Delta-Mu 2 image and ram */ - .start = 0x60000000, - .end = 0x601FFFFF, /* 2MiB */ - .flags = IORESOURCE_IO, - }, - { - .name = "ST231bMonitor", /* 8KiB block ST231b monitor */ - .start = 0x60200000, - .end = 0x60201FFF, - .flags = IORESOURCE_IO, - }, - { - .name = "MediaMemory2", - .start = 0x60202000, - .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_IO, - }, + /* Delta-Mu 2 image (2MiB) */ + PREALLOC_NORMAL("ST231bImage", 0x60000000, 0x60200000-1, + IORESOURCE_MEM) + /* Delta-Mu 2 monitor (8KiB) */ + PREALLOC_NORMAL("ST231bMonitor", 0x60200000, 0x60202000-1, + IORESOURCE_MEM) + /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ + PREALLOC_NORMAL("MediaMemory2", 0x60202000, 0x62000000-1, + IORESOURCE_MEM) + /* - * * Sysaudio Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * DSP_Image_Buff - DSP code and data images (1MB) - * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB) - * ADSC_AUX_Buff - ADSC AUX buffer (16KB) - * ADSC_Main_Buff - ADSC Main buffer (16KB) - * */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, + /* DSP code and data images (1MiB) */ + PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC CPU PCM buffer (40KiB) */ + PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC AUX buffer (128KiB) */ + PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC Main buffer (128KiB) */ + PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * STAVEM driver/STAPI * - * This driver requires: - * - * Arbitrary Based Buffers: * This memory area is used for allocating buffers for Video decoding * purposes. Allocation/De-allocation within this buffer is managed * by the STAVMEM driver of the STAPI. They could be Decimated * Picture Buffers, Intermediate Buffers, as deemed necessary for * video decoding purposes, for any video decoders on Zeus. - * */ - { - .name = "AVMEMPartition0", - .start = 0x63580000, - .end = 0x64180000 - 1, /* 12 MB total */ - .flags = IORESOURCE_IO, - }, + /* 12MiB */ + PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1, + IORESOURCE_MEM) + /* - * * DOCSIS Subsystem - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "Docsis", - .start = 0x62000000, - .end = 0x62700000 - 1, /* 7 MB total */ - .flags = IORESOURCE_IO, - }, + /* 7MiB */ + PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM) + /* - * * GHW HAL Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * GraphicsHeap - PowerTV Graphics Heap - * */ - { - .name = "GraphicsHeap", - .start = 0x62700000, - .end = 0x63500000 - 1, /* 14 MB total */ - .flags = IORESOURCE_IO, - }, + /* PowerTV Graphics Heap (14MiB) */ + PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1, + IORESOURCE_MEM) + /* - * * multi com buffer area - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "MulticomSHM", - .start = 0x26000000, - .end = 0x26020000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 128KiB */ + PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1, + IORESOURCE_MEM) + /* - * * DMA Ring buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x00280000 - 1, - .flags = IORESOURCE_MEM, - }, + PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x002EA000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * Display bins buffer for unit0 - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit0 - * */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * - * Display bins buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit1 - * + * Display bins buffer for unit1 */ - { - .name = "DisplayBins1", - .start = 0x64AD4000, - .end = 0x64AD5000 - 1, /* 4 KB total */ - .flags = IORESOURCE_IO, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1, + IORESOURCE_MEM) + /* - * * ITFS - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "ITFS", - .start = 0x64180000, - /* 815,104 bytes each for 2 ITFS partitions. */ - .end = 0x6430DFFF, - .flags = IORESOURCE_IO, - }, + /* 815,104 bytes each for 2 ITFS partitions. */ + PREALLOC_NORMAL("ITFS", 0x00000000, 0x0018E000-1, IORESOURCE_MEM) + /* - * * AVFS - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "AvfsDmaMem", - .start = 0x6430E000, - /* (945K * 8) = (128K *3) 5 playbacks / 3 server */ - .end = 0x64AD0000 - 1, - .flags = IORESOURCE_IO, - }, - { - .name = "AvfsFileSys", - .start = 0x64AD0000, - .end = 0x64AD1000 - 1, /* 4K */ - .flags = IORESOURCE_IO, - }, + /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */ + PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x007c2000-1, + IORESOURCE_MEM) + + /* 4KiB */ + PREALLOC_NORMAL("AvfsFileSys", 0x00000000, 0x00001000-1, + IORESOURCE_MEM) + /* - * * PMEM - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Persistent memory for diagnostics. - * */ - { - .name = "DiagPersistentMemory", - .start = 0x00000000, - .end = 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, + /* Persistent memory for diagnostics (64KiB) */ + PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * Smartcard - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Read and write buffers for Internal/External cards - * */ - { - .name = "SmartCardInfo", - .start = 0x64AD1000, - .end = 0x64AD3800 - 1, - .flags = IORESOURCE_IO, - }, + /* Read and write buffers for Internal/External cards (10KiB) */ + PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, + IORESOURCE_MEM) + /* - * * KAVNET - * NP Reset Vector - must be of the form xxCxxxxx - * NP Image - must be video bank 1 - * NP IPC - must be video bank 2 */ - { - .name = "NP_Reset_Vector", - .start = 0x27c00000, - .end = 0x27c01000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "NP_Image", - .start = 0x27020000, - .end = 0x27060000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "NP_IPC", - .start = 0x63500000, - .end = 0x63580000 - 1, - .flags = IORESOURCE_IO, - }, + /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */ + PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1, + IORESOURCE_MEM) + /* NP Image - must be video bank 1 (320KiB) */ + PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM) + /* NP IPC - must be video bank 2 (512KiB) */ + PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM) + + /* + * TFTPBuffer + * + * This buffer is used in some minimal configurations (e.g. two-way + * loader) for storing software images + */ + PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Add other resources here */ - { }, + + /* + * End of Resource marker + */ + { + .flags = 0, + }, }; /* @@ -337,272 +195,146 @@ struct resource dvr_cronus_resources[] __initdata = struct resource non_dvr_cronus_resources[] __initdata = { /* - * * VIDEO1 / LX1 - * */ - { - .name = "ST231aImage", /* Delta-Mu 1 image and ram */ - .start = 0x24000000, - .end = 0x241FFFFF, /* 2MiB */ - .flags = IORESOURCE_MEM, - }, - { - .name = "ST231aMonitor", /* 8KiB block ST231a monitor */ - .start = 0x24200000, - .end = 0x24201FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "MediaMemory1", - .start = 0x24202000, - .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_MEM, - }, + /* Delta-Mu 1 image (2MiB) */ + PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 monitor (8KiB) */ + PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ + PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26000000-1, + IORESOURCE_MEM) + /* - * * VIDEO2 / LX2 - * */ - { - .name = "ST231bImage", /* Delta-Mu 2 image and ram */ - .start = 0x60000000, - .end = 0x601FFFFF, /* 2MiB */ - .flags = IORESOURCE_IO, - }, - { - .name = "ST231bMonitor", /* 8KiB block ST231b monitor */ - .start = 0x60200000, - .end = 0x60201FFF, - .flags = IORESOURCE_IO, - }, - { - .name = "MediaMemory2", - .start = 0x60202000, - .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_IO, - }, + /* Delta-Mu 2 image (2MiB) */ + PREALLOC_NORMAL("ST231bImage", 0x60000000, 0x60200000-1, + IORESOURCE_MEM) + /* Delta-Mu 2 monitor (8KiB) */ + PREALLOC_NORMAL("ST231bMonitor", 0x60200000, 0x60202000-1, + IORESOURCE_MEM) + /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ + PREALLOC_NORMAL("MediaMemory2", 0x60202000, 0x62000000-1, + IORESOURCE_MEM) + /* - * * Sysaudio Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * DSP_Image_Buff - DSP code and data images (1MB) - * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB) - * ADSC_AUX_Buff - ADSC AUX buffer (16KB) - * ADSC_Main_Buff - ADSC Main buffer (16KB) - * */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, + /* DSP code and data images (1MiB) */ + PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC CPU PCM buffer (40KiB) */ + PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC AUX buffer (128KiB) */ + PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC Main buffer (128KiB) */ + PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * STAVEM driver/STAPI * - * This driver requires: - * - * Arbitrary Based Buffers: * This memory area is used for allocating buffers for Video decoding * purposes. Allocation/De-allocation within this buffer is managed * by the STAVMEM driver of the STAPI. They could be Decimated * Picture Buffers, Intermediate Buffers, as deemed necessary for * video decoding purposes, for any video decoders on Zeus. - * */ - { - .name = "AVMEMPartition0", - .start = 0x63580000, - .end = 0x64180000 - 1, /* 12 MB total */ - .flags = IORESOURCE_IO, - }, + /* 12MiB */ + PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1, + IORESOURCE_MEM) + /* - * * DOCSIS Subsystem - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "Docsis", - .start = 0x62000000, - .end = 0x62700000 - 1, /* 7 MB total */ - .flags = IORESOURCE_IO, - }, + /* 7MiB */ + PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM) + /* - * * GHW HAL Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * GraphicsHeap - PowerTV Graphics Heap - * */ - { - .name = "GraphicsHeap", - .start = 0x62700000, - .end = 0x63500000 - 1, /* 14 MB total */ - .flags = IORESOURCE_IO, - }, + /* PowerTV Graphics Heap (14MiB) */ + PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1, + IORESOURCE_MEM) + /* - * * multi com buffer area - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "MulticomSHM", - .start = 0x26000000, - .end = 0x26020000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 128KiB */ + PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1, + IORESOURCE_MEM) + /* - * - * DMA Ring buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * + * DMA Ring buffer (don't need recording buffers) */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x000AA000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 680KiB */ + PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * Display bins buffer for unit0 - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit0 - * */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * - * Display bins buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit1 - * + * Display bins buffer for unit1 */ - { - .name = "DisplayBins1", - .start = 0x64AD4000, - .end = 0x64AD5000 - 1, /* 4 KB total */ - .flags = IORESOURCE_IO, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1, + IORESOURCE_MEM) + /* - * * AVFS: player HAL memory - * - * */ - { - .name = "AvfsDmaMem", - .start = 0x6430E000, - .end = 0x645D2C00 - 1, /* 945K * 3 for playback */ - .flags = IORESOURCE_IO, - }, + /* 945K * 3 for playback */ + PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, IORESOURCE_MEM) + /* - * * PMEM - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Persistent memory for diagnostics. - * */ - { - .name = "DiagPersistentMemory", - .start = 0x00000000, - .end = 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, + /* Persistent memory for diagnostics (64KiB) */ + PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * Smartcard - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Read and write buffers for Internal/External cards - * */ - { - .name = "SmartCardInfo", - .start = 0x64AD1000, - .end = 0x64AD3800 - 1, - .flags = IORESOURCE_IO, - }, + /* Read and write buffers for Internal/External cards (10KiB) */ + PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, IORESOURCE_MEM) + /* - * * KAVNET - * NP Reset Vector - must be of the form xxCxxxxx - * NP Image - must be video bank 1 - * NP IPC - must be video bank 2 + */ + /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */ + PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1, + IORESOURCE_MEM) + /* NP Image - must be video bank 1 (320KiB) */ + PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM) + /* NP IPC - must be video bank 2 (512KiB) */ + PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM) + + /* + * NAND Flash + */ + /* 10KiB */ + PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, + IORESOURCE_MEM) + + /* + * Add other resources here + */ + + /* + * End of Resource marker */ { - .name = "NP_Reset_Vector", - .start = 0x27c00000, - .end = 0x27c01000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "NP_Image", - .start = 0x27020000, - .end = 0x27060000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "NP_IPC", - .start = 0x63500000, - .end = 0x63580000 - 1, - .flags = IORESOURCE_IO, + .flags = 0, }, - { }, }; diff --git a/arch/mips/powertv/asic/prealloc-cronuslite.c b/arch/mips/powertv/asic/prealloc-cronuslite.c index 23a905613c04..b5537e49e7f5 100644 --- a/arch/mips/powertv/asic/prealloc-cronuslite.c +++ b/arch/mips/powertv/asic/prealloc-cronuslite.c @@ -22,7 +22,9 @@ */ #include +#include #include +#include "prealloc.h" /* * NON_DVR_CAPABLE CRONUSLITE RESOURCES @@ -30,261 +32,143 @@ struct resource non_dvr_cronuslite_resources[] __initdata = { /* - * * VIDEO2 / LX2 - * */ - { - .name = "ST231aImage", /* Delta-Mu 2 image and ram */ - .start = 0x60000000, - .end = 0x601FFFFF, /* 2MiB */ - .flags = IORESOURCE_IO, - }, - { - .name = "ST231aMonitor", /* 8KiB block ST231b monitor */ - .start = 0x60200000, - .end = 0x60201FFF, - .flags = IORESOURCE_IO, - }, - { - .name = "MediaMemory1", - .start = 0x60202000, - .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_IO, - }, + /* Delta-Mu 1 image (2MiB) */ + PREALLOC_NORMAL("ST231aImage", 0x60000000, 0x60200000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 monitor (8KiB) */ + PREALLOC_NORMAL("ST231aMonitor", 0x60200000, 0x60202000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ + PREALLOC_NORMAL("MediaMemory1", 0x60202000, 0x62000000-1, + IORESOURCE_MEM) + /* - * * Sysaudio Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * DSP_Image_Buff - DSP code and data images (1MB) - * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB) - * ADSC_AUX_Buff - ADSC AUX buffer (16KB) - * ADSC_Main_Buff - ADSC Main buffer (16KB) - * */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, + /* DSP code and data images (1MiB) */ + PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC CPU PCM buffer (40KiB) */ + PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC AUX buffer (128KiB) */ + PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC Main buffer (128KiB) */ + PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * STAVEM driver/STAPI * - * This driver requires: - * - * Arbitrary Based Buffers: * This memory area is used for allocating buffers for Video decoding * purposes. Allocation/De-allocation within this buffer is managed * by the STAVMEM driver of the STAPI. They could be Decimated * Picture Buffers, Intermediate Buffers, as deemed necessary for * video decoding purposes, for any video decoders on Zeus. - * */ - { - .name = "AVMEMPartition0", - .start = 0x63580000, - .end = 0x63B80000 - 1, /* 6 MB total */ - .flags = IORESOURCE_IO, - }, + /* 6MiB */ + PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1, + IORESOURCE_MEM) + /* - * * DOCSIS Subsystem - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "Docsis", - .start = 0x62000000, - .end = 0x62700000 - 1, /* 7 MB total */ - .flags = IORESOURCE_IO, - }, + /* 7MiB */ + PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM) + /* - * * GHW HAL Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * GraphicsHeap - PowerTV Graphics Heap - * */ - { - .name = "GraphicsHeap", - .start = 0x62700000, - .end = 0x63500000 - 1, /* 14 MB total */ - .flags = IORESOURCE_IO, - }, + /* PowerTV Graphics Heap (14MiB) */ + PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1, + IORESOURCE_MEM) + /* - * * multi com buffer area - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "MulticomSHM", - .start = 0x26000000, - .end = 0x26020000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 128KiB */ + PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1, + IORESOURCE_MEM) + /* - * - * DMA Ring buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * + * DMA Ring buffer (don't need recording buffers) */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x000AA000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 680KiB */ + PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * Display bins buffer for unit0 - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit0 - * */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * - * Display bins buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit1 - * + * Display bins buffer for unit1 */ - { - .name = "DisplayBins1", - .start = 0x63B83000, - .end = 0x63B84000 - 1, /* 4 KB total */ - .flags = IORESOURCE_IO, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1, + IORESOURCE_MEM) + /* - * * AVFS: player HAL memory - * - * */ - { - .name = "AvfsDmaMem", - .start = 0x63B84000, - .end = 0x63E48C00 - 1, /* 945K * 3 for playback */ - .flags = IORESOURCE_IO, - }, + /* 945K * 3 for playback */ + PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * PMEM - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Persistent memory for diagnostics. - * */ - { - .name = "DiagPersistentMemory", - .start = 0x00000000, - .end = 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, + /* Persistent memory for diagnostics (64KiB) */ + PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * Smartcard - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Read and write buffers for Internal/External cards - * */ - { - .name = "SmartCardInfo", - .start = 0x63B80000, - .end = 0x63B82800 - 1, - .flags = IORESOURCE_IO, - }, + /* Read and write buffers for Internal/External cards (10KiB) */ + PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, IORESOURCE_MEM) + /* - * * KAVNET - * NP Reset Vector - must be of the form xxCxxxxx - * NP Image - must be video bank 1 - * NP IPC - must be video bank 2 */ - { - .name = "NP_Reset_Vector", - .start = 0x27c00000, - .end = 0x27c01000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "NP_Image", - .start = 0x27020000, - .end = 0x27060000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "NP_IPC", - .start = 0x63500000, - .end = 0x63580000 - 1, - .flags = IORESOURCE_IO, - }, + /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */ + PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1, + IORESOURCE_MEM) + /* NP Image - must be video bank 1 (320KiB) */ + PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM) + /* NP IPC - must be video bank 2 (512KiB) */ + PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM) + /* * NAND Flash */ - { - .name = "NandFlash", - .start = NAND_FLASH_BASE, - .end = NAND_FLASH_BASE + 0x400 - 1, - .flags = IORESOURCE_IO, - }, + /* 10KiB */ + PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, + IORESOURCE_MEM) + + /* + * TFTPBuffer + * + * This buffer is used in some minimal configurations (e.g. two-way + * loader) for storing software images + */ + PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Add other resources here */ - { }, + + /* + * End of Resource marker + */ + { + .flags = 0, + }, }; diff --git a/arch/mips/powertv/asic/prealloc-zeus.c b/arch/mips/powertv/asic/prealloc-zeus.c index 018d4514dbe3..96480a2395c0 100644 --- a/arch/mips/powertv/asic/prealloc-zeus.c +++ b/arch/mips/powertv/asic/prealloc-zeus.c @@ -22,7 +22,9 @@ */ #include +#include #include +#include "prealloc.h" /* * DVR_CAPABLE RESOURCES @@ -30,280 +32,151 @@ struct resource dvr_zeus_resources[] __initdata = { /* - * * VIDEO1 / LX1 - * */ - { - .name = "ST231aImage", /* Delta-Mu 1 image and ram */ - .start = 0x20000000, - .end = 0x201FFFFF, /* 2MiB */ - .flags = IORESOURCE_IO, - }, - { - .name = "ST231aMonitor", /* 8KiB block ST231a monitor */ - .start = 0x20200000, - .end = 0x20201FFF, - .flags = IORESOURCE_IO, - }, - { - .name = "MediaMemory1", - .start = 0x20202000, - .end = 0x21FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_IO, - }, + /* Delta-Mu 1 image (2MiB) */ + PREALLOC_NORMAL("ST231aImage", 0x20000000, 0x20200000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 monitor (8KiB) */ + PREALLOC_NORMAL("ST231aMonitor", 0x20200000, 0x20202000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ + PREALLOC_NORMAL("MediaMemory1", 0x20202000, 0x22000000-1, + IORESOURCE_MEM) + /* - * * VIDEO2 / LX2 - * */ - { - .name = "ST231bImage", /* Delta-Mu 2 image and ram */ - .start = 0x30000000, - .end = 0x301FFFFF, /* 2MiB */ - .flags = IORESOURCE_IO, - }, - { - .name = "ST231bMonitor", /* 8KiB block ST231b monitor */ - .start = 0x30200000, - .end = 0x30201FFF, - .flags = IORESOURCE_IO, - }, - { - .name = "MediaMemory2", - .start = 0x30202000, - .end = 0x31FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_IO, - }, + /* Delta-Mu 2 image (2MiB) */ + PREALLOC_NORMAL("ST231bImage", 0x30000000, 0x30200000-1, + IORESOURCE_MEM) + /* Delta-Mu 2 monitor (8KiB) */ + PREALLOC_NORMAL("ST231bMonitor", 0x30200000, 0x30202000-1, + IORESOURCE_MEM) + /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ + PREALLOC_NORMAL("MediaMemory2", 0x30202000, 0x32000000-1, + IORESOURCE_MEM) + /* - * * Sysaudio Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * DSP_Image_Buff - DSP code and data images (1MB) - * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB) - * ADSC_AUX_Buff - ADSC AUX buffer (16KB) - * ADSC_Main_Buff - ADSC Main buffer (16KB) - * */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, + /* DSP code and data images (1MiB) */ + PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC CPU PCM buffer (40KiB) */ + PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC AUX buffer (16KiB) */ + PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC Main buffer (16KiB) */ + PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * STAVEM driver/STAPI * - * This driver requires: - * - * Arbitrary Based Buffers: * This memory area is used for allocating buffers for Video decoding * purposes. Allocation/De-allocation within this buffer is managed * by the STAVMEM driver of the STAPI. They could be Decimated * Picture Buffers, Intermediate Buffers, as deemed necessary for * video decoding purposes, for any video decoders on Zeus. - * */ - { - .name = "AVMEMPartition0", - .start = 0x00000000, - .end = 0x00c00000 - 1, /* 12 MB total */ - .flags = IORESOURCE_MEM, - }, + /* 12MiB */ + PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * DOCSIS Subsystem - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "Docsis", - .start = 0x40100000, - .end = 0x407fffff, - .flags = IORESOURCE_MEM, - }, + /* 7MiB */ + PREALLOC_DOCSIS("Docsis", 0x40100000, 0x40800000-1, IORESOURCE_MEM) + /* - * * GHW HAL Driver - * - * This driver requires: - * - * Arbitrary Based Buffers: - * GraphicsHeap - PowerTV Graphics Heap - * */ - { - .name = "GraphicsHeap", - .start = 0x46900000, - .end = 0x47700000 - 1, /* 14 MB total */ - .flags = IORESOURCE_MEM, - }, + /* PowerTV Graphics Heap (14MiB) */ + PREALLOC_NORMAL("GraphicsHeap", 0x46900000, 0x47700000-1, + IORESOURCE_MEM) + /* - * * multi com buffer area - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "MulticomSHM", - .start = 0x47900000, - .end = 0x47920000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 128KiB */ + PREALLOC_NORMAL("MulticomSHM", 0x47900000, 0x47920000-1, + IORESOURCE_MEM) + /* - * * DMA Ring buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x00280000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 2.5MiB */ + PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x00280000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * Display bins buffer for unit0 - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit0 - * */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * - * Display bins buffer - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Display Bins for unit1 - * + * Display bins buffer for unit1 */ - { - .name = "DisplayBins1", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * ITFS - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "ITFS", - .start = 0x00000000, - /* 815,104 bytes each for 2 ITFS partitions. */ - .end = 0x0018DFFF, - .flags = IORESOURCE_MEM, - }, + /* 815,104 bytes each for 2 ITFS partitions. */ + PREALLOC_NORMAL("ITFS", 0x00000000, 0x0018E000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * AVFS - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Docsis - - * */ - { - .name = "AvfsDmaMem", - .start = 0x00000000, - /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */ - .end = 0x007c2000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "AvfsFileSys", - .start = 0x00000000, - .end = 0x00001000 - 1, /* 4K */ - .flags = IORESOURCE_MEM, - }, + /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */ + PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x007c2000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* 4KiB */ + PREALLOC_NORMAL("AvfsFileSys", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * PMEM - * - * This driver requires: - * - * Arbitrary Based Buffers: - * Persistent memory for diagnostics. - * */ - { - .name = "DiagPersistentMemory", - .start = 0x00000000, - .end = 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, + /* Persistent memory for diagnostics (64KiB) */ + PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * Smartcard + */ + /* Read and write buffers for Internal/External cards (10KiB) */ + PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + + /* + * TFTPBuffer * - * This driver requires: - * - * Arbitrary Based Buffers: - * Read and write buffers for Internal/External cards - * + * This buffer is used in some minimal configurations (e.g. two-way + * loader) for storing software images */ - { - .name = "SmartCardInfo", - .start = 0x00000000, - .end = 0x2800 - 1, - .flags = IORESOURCE_MEM, - }, + PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Add other resources here */ - { }, + + /* + * End of Resource marker + */ + { + .flags = 0, + }, }; /* @@ -314,146 +187,118 @@ struct resource non_dvr_zeus_resources[] __initdata = /* * VIDEO1 / LX1 */ - { - .name = "ST231aImage", /* Delta-Mu 1 image and ram */ - .start = 0x20000000, - .end = 0x201FFFFF, /* 2MiB */ - .flags = IORESOURCE_IO, - }, - { - .name = "ST231aMonitor", /* 8KiB block ST231a monitor */ - .start = 0x20200000, - .end = 0x20201FFF, - .flags = IORESOURCE_IO, - }, - { - .name = "MediaMemory1", - .start = 0x20202000, - .end = 0x21FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */ - .flags = IORESOURCE_IO, - }, + /* Delta-Mu 1 image (2MiB) */ + PREALLOC_NORMAL("ST231aImage", 0x20000000, 0x20200000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 monitor (8KiB) */ + PREALLOC_NORMAL("ST231aMonitor", 0x20200000, 0x20202000-1, + IORESOURCE_MEM) + /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */ + PREALLOC_NORMAL("MediaMemory1", 0x20202000, 0x22000000-1, + IORESOURCE_MEM) + /* * Sysaudio Driver */ - { - .name = "DSP_Image_Buff", - .start = 0x00000000, - .end = 0x000FFFFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_CPU_PCM_Buff", - .start = 0x00000000, - .end = 0x00009FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_AUX_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, - { - .name = "ADSC_Main_Buff", - .start = 0x00000000, - .end = 0x00003FFF, - .flags = IORESOURCE_MEM, - }, + /* DSP code and data images (1MiB) */ + PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC CPU PCM buffer (40KiB) */ + PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC AUX buffer (16KiB) */ + PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* ADSC Main buffer (16KiB) */ + PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * STAVEM driver/STAPI */ - { - .name = "AVMEMPartition0", - .start = 0x00000000, - .end = 0x00600000 - 1, /* 6 MB total */ - .flags = IORESOURCE_MEM, - }, + /* 6MiB */ + PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * DOCSIS Subsystem */ - { - .name = "Docsis", - .start = 0x40100000, - .end = 0x407fffff, - .flags = IORESOURCE_MEM, - }, + /* 7MiB */ + PREALLOC_DOCSIS("Docsis", 0x40100000, 0x40800000-1, IORESOURCE_MEM) + /* * GHW HAL Driver */ - { - .name = "GraphicsHeap", - .start = 0x46900000, - .end = 0x47700000 - 1, /* 14 MB total */ - .flags = IORESOURCE_MEM, - }, + /* PowerTV Graphics Heap (14MiB) */ + PREALLOC_NORMAL("GraphicsHeap", 0x46900000, 0x47700000-1, + IORESOURCE_MEM) + /* * multi com buffer area */ - { - .name = "MulticomSHM", - .start = 0x47900000, - .end = 0x47920000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 128KiB */ + PREALLOC_NORMAL("MulticomSHM", 0x47900000, 0x47920000-1, + IORESOURCE_MEM) + /* * DMA Ring buffer */ - { - .name = "BMM_Buffer", - .start = 0x00000000, - .end = 0x00280000 - 1, - .flags = IORESOURCE_MEM, - }, + /* 2.5MiB */ + PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x00280000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Display bins buffer for unit0 */ - { - .name = "DisplayBins0", - .start = 0x00000000, - .end = 0x00000FFF, /* 4 KB total */ - .flags = IORESOURCE_MEM, - }, + /* 4KiB */ + PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* - * * AVFS: player HAL memory - * - * */ - { - .name = "AvfsDmaMem", - .start = 0x00000000, - .end = 0x002c4c00 - 1, /* 945K * 3 for playback */ - .flags = IORESOURCE_MEM, - }, + /* 945K * 3 for playback */ + PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * PMEM */ - { - .name = "DiagPersistentMemory", - .start = 0x00000000, - .end = 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, + /* Persistent memory for diagnostics (64KiB) */ + PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Smartcard */ - { - .name = "SmartCardInfo", - .start = 0x00000000, - .end = 0x2800 - 1, - .flags = IORESOURCE_MEM, - }, + /* Read and write buffers for Internal/External cards (10KiB) */ + PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * NAND Flash */ - { - .name = "NandFlash", - .start = NAND_FLASH_BASE, - .end = NAND_FLASH_BASE + 0x400 - 1, - .flags = IORESOURCE_IO, - }, + /* 10KiB */ + PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1, + IORESOURCE_MEM) + + /* + * TFTPBuffer + * + * This buffer is used in some minimal configurations (e.g. two-way + * loader) for storing software images + */ + PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1, + (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT)) + /* * Add other resources here */ - { }, + + /* + * End of Resource marker + */ + { + .flags = 0, + }, }; diff --git a/arch/mips/powertv/asic/prealloc.h b/arch/mips/powertv/asic/prealloc.h new file mode 100644 index 000000000000..8e682df17856 --- /dev/null +++ b/arch/mips/powertv/asic/prealloc.h @@ -0,0 +1,70 @@ +/* + * Definitions for memory preallocations + * + * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ARCH_MIPS_POWERTV_ASIC_PREALLOC_H +#define _ARCH_MIPS_POWERTV_ASIC_PREALLOC_H + +#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */ +#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */ + +/* "struct resource" array element definition */ +#define PREALLOC(NAME, START, END, FLAGS) { \ + .name = (NAME), \ + .start = (START), \ + .end = (END), \ + .flags = (FLAGS) \ + }, + +/* Individual resources in the preallocated resource arrays are defined using + * macros. These macros are conditionally defined based on their + * corresponding kernel configuration flag: + * - CONFIG_PREALLOC_NORMAL: preallocate resources for a normal settop box + * - CONFIG_PREALLOC_TFTP: preallocate the TFTP download resource + * - CONFIG_PREALLOC_DOCSIS: preallocate the DOCSIS resource + * - CONFIG_PREALLOC_PMEM: reserve space for persistent memory + */ +#ifdef CONFIG_PREALLOC_NORMAL +#define PREALLOC_NORMAL(name, start, end, flags) \ + PREALLOC(name, start, end, flags) +#else +#define PREALLOC_NORMAL(name, start, end, flags) +#endif + +#ifdef CONFIG_PREALLOC_TFTP +#define PREALLOC_TFTP(name, start, end, flags) \ + PREALLOC(name, start, end, flags) +#else +#define PREALLOC_TFTP(name, start, end, flags) +#endif + +#ifdef CONFIG_PREALLOC_DOCSIS +#define PREALLOC_DOCSIS(name, start, end, flags) \ + PREALLOC(name, start, end, flags) +#else +#define PREALLOC_DOCSIS(name, start, end, flags) +#endif + +#ifdef CONFIG_PREALLOC_PMEM +#define PREALLOC_PMEM(name, start, end, flags) \ + PREALLOC(name, start, end, flags) +#else +#define PREALLOC_PMEM(name, start, end, flags) +#endif +#endif -- cgit v1.2.3-59-g8ed1b From 0103d23f44b1e9f8d2e89cc197e21192f6914f24 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sun, 2 May 2010 14:43:52 -0700 Subject: MIPS: nofpu and nodsp only affect CPU0 The "nofpu" and "nodsp" kernel command line options currently do not affect CPUs that are brought online later in the boot process or hotplugged at runtime. It is desirable to apply the nofpu/nodsp options to all CPUs in the system, so that surprising results are not seen when a process migrates from one CPU to another. [Ralf: Moved definitions of mips_fpu_disabled, fpu_disable, mips_dsp_disabled and dsp_disable from setup.c to cpu-probe.c to allow making mips_fpu_disabled and mips_dsp_disabled static.] Signed-off-by: Kevin Cernekee Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: http://patchwork.linux-mips.org/patch/1169/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 30 ++++++++++++++++++++++++++++++ arch/mips/kernel/setup.c | 21 --------------------- 2 files changed, 30 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index be5bb16be4e0..3562b854f2cd 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -125,6 +125,30 @@ static int __init wait_disable(char *s) __setup("nowait", wait_disable); +static int __cpuinitdata mips_fpu_disabled; + +static int __init fpu_disable(char *s) +{ + cpu_data[0].options &= ~MIPS_CPU_FPU; + mips_fpu_disabled = 1; + + return 1; +} + +__setup("nofpu", fpu_disable); + +int __cpuinitdata mips_dsp_disabled; + +static int __init dsp_disable(char *s) +{ + cpu_data[0].ases &= ~MIPS_ASE_DSP; + mips_dsp_disabled = 1; + + return 1; +} + +__setup("nodsp", dsp_disable); + void __init check_wait(void) { struct cpuinfo_mips *c = ¤t_cpu_data; @@ -982,6 +1006,12 @@ __cpuinit void cpu_probe(void) */ BUG_ON(current_cpu_type() != c->cputype); + if (mips_fpu_disabled) + c->options &= ~MIPS_CPU_FPU; + + if (mips_dsp_disabled) + c->ases &= ~MIPS_ASE_DSP; + if (c->options & MIPS_CPU_FPU) { c->fpu_id = cpu_get_fpu_id(); diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index f9513f9e61d3..85aef3fc6716 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -569,27 +569,6 @@ void __init setup_arch(char **cmdline_p) plat_smp_setup(); } -static int __init fpu_disable(char *s) -{ - int i; - - for (i = 0; i < NR_CPUS; i++) - cpu_data[i].options &= ~MIPS_CPU_FPU; - - return 1; -} - -__setup("nofpu", fpu_disable); - -static int __init dsp_disable(char *s) -{ - cpu_data[0].ases &= ~MIPS_ASE_DSP; - - return 1; -} - -__setup("nodsp", dsp_disable); - unsigned long kernelsp[NR_CPUS]; unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3; -- cgit v1.2.3-59-g8ed1b From 86e5a5202148736bffed49499a1dc8c1a311d3ab Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 7 May 2010 01:29:44 +0800 Subject: MIPS: Oprofile: Loongson: Unify macro for setting events Unified macro for counter0 and counter1 to set the event in the control register. This will be needed by Perf. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1200/ Signed-off-by: Ralf Baechle --- arch/mips/oprofile/op_model_loongson2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c index fa3bf661ae29..93d8b7deb91d 100644 --- a/arch/mips/oprofile/op_model_loongson2.c +++ b/arch/mips/oprofile/op_model_loongson2.c @@ -24,8 +24,8 @@ */ #define LOONGSON2_CPU_TYPE "mips/loongson2" -#define LOONGSON2_COUNTER1_EVENT(event) ((event & 0x0f) << 5) -#define LOONGSON2_COUNTER2_EVENT(event) ((event & 0x0f) << 9) +#define LOONGSON2_PERFCTRL_EVENT(idx, event) \ + (((event) & 0x0f) << ((idx) ? 9 : 5)) #define LOONGSON2_PERFCNT_EXL (1UL << 0) #define LOONGSON2_PERFCNT_KERNEL (1UL << 1) @@ -60,12 +60,12 @@ static void loongson2_reg_setup(struct op_counter_config *cfg) /* Compute the performance counter ctrl word. */ /* For now count kernel and user mode */ if (cfg[0].enabled) { - ctrl |= LOONGSON2_COUNTER1_EVENT(cfg[0].event); + ctrl |= LOONGSON2_PERFCTRL_EVENT(0, cfg[0].event); reg.reset_counter1 = 0x80000000ULL - cfg[0].count; } if (cfg[1].enabled) { - ctrl |= LOONGSON2_COUNTER2_EVENT(cfg[1].event); + ctrl |= LOONGSON2_PERFCTRL_EVENT(1, cfg[1].event); reg.reset_counter2 = (0x80000000ULL - cfg[1].count); } -- cgit v1.2.3-59-g8ed1b From c838abc511ed710bdc2d93e0d8b5449be953849e Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 7 May 2010 01:29:45 +0800 Subject: MIPS: Oprofile: Loongson: Remove useless parentheses Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1201/ Signed-off-by: Ralf Baechle --- arch/mips/oprofile/op_model_loongson2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c index 93d8b7deb91d..596fb0817578 100644 --- a/arch/mips/oprofile/op_model_loongson2.c +++ b/arch/mips/oprofile/op_model_loongson2.c @@ -66,7 +66,7 @@ static void loongson2_reg_setup(struct op_counter_config *cfg) if (cfg[1].enabled) { ctrl |= LOONGSON2_PERFCTRL_EVENT(1, cfg[1].event); - reg.reset_counter2 = (0x80000000ULL - cfg[1].count); + reg.reset_counter2 = 0x80000000ULL - cfg[1].count; } if (cfg[0].enabled || cfg[1].enabled) { -- cgit v1.2.3-59-g8ed1b From 6d8c2873e06626c371bdedd5e00b00a60d3fde41 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 7 May 2010 01:29:46 +0800 Subject: MIPS: Oprofile: Loongson: Remove unused variable from loongson2_cpu_setup() Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1202/ Signed-off-by: Ralf Baechle --- arch/mips/oprofile/op_model_loongson2.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c index 596fb0817578..deefcee69a69 100644 --- a/arch/mips/oprofile/op_model_loongson2.c +++ b/arch/mips/oprofile/op_model_loongson2.c @@ -88,10 +88,7 @@ static void loongson2_reg_setup(struct op_counter_config *cfg) static void loongson2_cpu_setup(void *args) { - uint64_t perfcount; - - perfcount = (reg.reset_counter2 << 32) | reg.reset_counter1; - write_c0_perfcnt(perfcount); + write_c0_perfcnt((reg.reset_counter2 << 32) | reg.reset_counter1); } static void loongson2_cpu_start(void *args) -- cgit v1.2.3-59-g8ed1b From 852151bdb992874b3d625444a8c7c551f3a738b5 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 7 May 2010 01:29:47 +0800 Subject: MIPS: Oprofile: Loongson: Cleanup of the macros The _EXL, _KERNEL etc. bits are in the performance control register so use _PERFCTRL prefix instead of _PERFCNT. While at it make the macro more readable, use _ENABLE instead of _INT_EN suffix to describe the interrupt enable bit. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1203/ Signed-off-by: Ralf Baechle --- arch/mips/oprofile/op_model_loongson2.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c index deefcee69a69..515f7790c048 100644 --- a/arch/mips/oprofile/op_model_loongson2.c +++ b/arch/mips/oprofile/op_model_loongson2.c @@ -24,16 +24,16 @@ */ #define LOONGSON2_CPU_TYPE "mips/loongson2" +#define LOONGSON2_PERFCNT_OVERFLOW (1ULL << 31) + +#define LOONGSON2_PERFCTRL_EXL (1UL << 0) +#define LOONGSON2_PERFCTRL_KERNEL (1UL << 1) +#define LOONGSON2_PERFCTRL_SUPERVISOR (1UL << 2) +#define LOONGSON2_PERFCTRL_USER (1UL << 3) +#define LOONGSON2_PERFCTRL_ENABLE (1UL << 4) #define LOONGSON2_PERFCTRL_EVENT(idx, event) \ (((event) & 0x0f) << ((idx) ? 9 : 5)) -#define LOONGSON2_PERFCNT_EXL (1UL << 0) -#define LOONGSON2_PERFCNT_KERNEL (1UL << 1) -#define LOONGSON2_PERFCNT_SUPERVISOR (1UL << 2) -#define LOONGSON2_PERFCNT_USER (1UL << 3) -#define LOONGSON2_PERFCNT_INT_EN (1UL << 4) -#define LOONGSON2_PERFCNT_OVERFLOW (1ULL << 31) - /* Loongson2 performance counter register */ #define read_c0_perfctrl() __read_64bit_c0_register($24, 0) #define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val) @@ -70,11 +70,11 @@ static void loongson2_reg_setup(struct op_counter_config *cfg) } if (cfg[0].enabled || cfg[1].enabled) { - ctrl |= LOONGSON2_PERFCNT_EXL | LOONGSON2_PERFCNT_INT_EN; + ctrl |= LOONGSON2_PERFCTRL_EXL | LOONGSON2_PERFCTRL_ENABLE; if (cfg[0].kernel || cfg[1].kernel) - ctrl |= LOONGSON2_PERFCNT_KERNEL; + ctrl |= LOONGSON2_PERFCTRL_KERNEL; if (cfg[0].user || cfg[1].user) - ctrl |= LOONGSON2_PERFCNT_USER; + ctrl |= LOONGSON2_PERFCTRL_USER; } reg.ctrl = ctrl; @@ -119,7 +119,7 @@ static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id) */ /* Check whether the irq belongs to me */ - enabled = read_c0_perfctrl() & LOONGSON2_PERFCNT_INT_EN; + enabled = read_c0_perfctrl() & LOONGSON2_PERFCTRL_ENABLE; if (!enabled) return IRQ_NONE; enabled = reg.cnt1_enabled | reg.cnt2_enabled; -- cgit v1.2.3-59-g8ed1b From 893556e602d6d5d86ed401ff72bf63d8cfa4a9d0 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 7 May 2010 01:29:48 +0800 Subject: MIPS: Oprofile: Loongson: Cleanup the comments Removes some out-of-date comments and empty lines. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1204/ Signed-off-by: Ralf Baechle --- arch/mips/oprofile/op_model_loongson2.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c index 515f7790c048..d0d24e047676 100644 --- a/arch/mips/oprofile/op_model_loongson2.c +++ b/arch/mips/oprofile/op_model_loongson2.c @@ -8,7 +8,6 @@ * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. - * */ #include #include @@ -17,11 +16,6 @@ #include /* LOONGSON2_PERFCNT_IRQ */ #include "op_impl.h" -/* - * a patch should be sent to oprofile with the loongson-specific support. - * otherwise, the oprofile tool will not recognize this and complain about - * "cpu_type 'unset' is not valid". - */ #define LOONGSON2_CPU_TYPE "mips/loongson2" #define LOONGSON2_PERFCNT_OVERFLOW (1ULL << 31) @@ -34,7 +28,6 @@ #define LOONGSON2_PERFCTRL_EVENT(idx, event) \ (((event) & 0x0f) << ((idx) ? 9 : 5)) -/* Loongson2 performance counter register */ #define read_c0_perfctrl() __read_64bit_c0_register($24, 0) #define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val) #define read_c0_perfcnt() __read_64bit_c0_register($25, 0) @@ -49,7 +42,6 @@ static struct loongson2_register_config { static char *oprofid = "LoongsonPerf"; static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id); -/* Compute all of the registers in preparation for enabling profiling. */ static void loongson2_reg_setup(struct op_counter_config *cfg) { @@ -57,8 +49,11 @@ static void loongson2_reg_setup(struct op_counter_config *cfg) reg.reset_counter1 = 0; reg.reset_counter2 = 0; - /* Compute the performance counter ctrl word. */ - /* For now count kernel and user mode */ + + /* + * Compute the performance counter ctrl word. + * For now, count kernel and user mode. + */ if (cfg[0].enabled) { ctrl |= LOONGSON2_PERFCTRL_EVENT(0, cfg[0].event); reg.reset_counter1 = 0x80000000ULL - cfg[0].count; @@ -81,11 +76,8 @@ static void loongson2_reg_setup(struct op_counter_config *cfg) reg.cnt1_enabled = cfg[0].enabled; reg.cnt2_enabled = cfg[1].enabled; - } -/* Program all of the registers in preparation for enabling profiling. */ - static void loongson2_cpu_setup(void *args) { write_c0_perfcnt((reg.reset_counter2 << 32) | reg.reset_counter1); @@ -111,13 +103,6 @@ static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id) struct pt_regs *regs = get_irq_regs(); int enabled; - /* - * LOONGSON2 defines two 32-bit performance counters. - * To avoid a race updating the registers we need to stop the counters - * while we're messing with - * them ... - */ - /* Check whether the irq belongs to me */ enabled = read_c0_perfctrl() & LOONGSON2_PERFCTRL_ENABLE; if (!enabled) -- cgit v1.2.3-59-g8ed1b From a39ed2c98830bdb2575c18ad2c4b1bdb72fd5b3f Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 2 May 2010 11:38:57 +0200 Subject: MIPS: AR7: Update defconfig Update Texas Instruments AR7 defconfig with: - tiny RCU - LEDs GPIO - disable SSB - enable zboot support - enable GPIO sysfs support Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1165/ Signed-off-by: Ralf Baechle --- arch/mips/configs/ar7_defconfig | 196 +++++++++++++++++++++++++++++----------- 1 file changed, 143 insertions(+), 53 deletions(-) (limited to 'arch') diff --git a/arch/mips/configs/ar7_defconfig b/arch/mips/configs/ar7_defconfig index 5a5b6ba7514e..e70009584090 100644 --- a/arch/mips/configs/ar7_defconfig +++ b/arch/mips/configs/ar7_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.30 -# Wed Jun 24 14:08:59 2009 +# Linux kernel version: 2.6.34-rc6 +# Sat May 1 11:35:01 2010 # CONFIG_MIPS=y @@ -11,11 +11,12 @@ CONFIG_MIPS=y # CONFIG_MACH_ALCHEMY is not set CONFIG_AR7=y # CONFIG_BCM47XX is not set +# CONFIG_BCM63XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set -# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MACH_LOONGSON is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SIM is not set # CONFIG_NEC_MARKEINS is not set @@ -26,6 +27,7 @@ CONFIG_AR7=y # CONFIG_PNX8550_STB810 is not set # CONFIG_PMC_MSP is not set # CONFIG_PMC_YOSEMITE is not set +# CONFIG_POWERTV is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set # CONFIG_SGI_IP28 is not set @@ -46,6 +48,7 @@ CONFIG_AR7=y # CONFIG_CAVIUM_OCTEON_SIMULATOR is not set # CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set # CONFIG_ALCHEMY_GPIO_INDIRECT is not set +CONFIG_LOONGSON_UART_BASE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set @@ -63,10 +66,8 @@ CONFIG_CEVT_R4K=y CONFIG_CSRC_R4K_LIB=y CONFIG_CSRC_R4K=y CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_EARLY_PRINTK=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_SYS_HAS_EARLY_PRINTK=y -# CONFIG_HOTPLUG_CPU is not set # CONFIG_NO_IOPORT is not set CONFIG_GENERIC_GPIO=y # CONFIG_CPU_BIG_ENDIAN is not set @@ -81,7 +82,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 # # CPU selection # -# CONFIG_CPU_LOONGSON2 is not set +# CONFIG_CPU_LOONGSON2E is not set +# CONFIG_CPU_LOONGSON2F is not set CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set @@ -103,6 +105,8 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set # CONFIG_CPU_CAVIUM_OCTEON is not set +CONFIG_SYS_SUPPORTS_ZBOOT=y +CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y CONFIG_SYS_HAS_CPU_MIPS32_R1=y CONFIG_CPU_MIPS32=y CONFIG_CPU_MIPSR1=y @@ -124,6 +128,7 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y @@ -141,8 +146,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_TICK_ONESHOT=y # CONFIG_NO_HZ is not set @@ -165,6 +169,7 @@ CONFIG_KEXEC=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -174,6 +179,14 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -186,14 +199,12 @@ CONFIG_BSD_PROCESS_ACCT=y # # RCU Subsystem # -CONFIG_CLASSIC_RCU=y # CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_PREEMPT_RCU is not set +CONFIG_TINY_RCU=y # CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -204,6 +215,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set CONFIG_RD_LZMA=y +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -225,19 +237,22 @@ CONFIG_SHMEM=y CONFIG_AIO=y # -# Performance Counters +# Kernel Performance Events And Counters # # CONFIG_VM_EVENT_COUNTERS is not set -CONFIG_STRIP_ASM_SYMS=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set # CONFIG_SLOW_WORK is not set -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 @@ -248,7 +263,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y -# CONFIG_LBD is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -256,14 +271,41 @@ CONFIG_BLOCK=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set CONFIG_IOSCHED_DEADLINE=y # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -293,7 +335,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -377,6 +418,7 @@ CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NETFILTER_XTABLES=m # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_CT is not set # CONFIG_NETFILTER_XT_TARGET_DSCP is not set # CONFIG_NETFILTER_XT_TARGET_HL is not set # CONFIG_NETFILTER_XT_TARGET_LED is not set @@ -458,6 +500,7 @@ CONFIG_IP_NF_RAW=m # CONFIG_IP_NF_ARPTABLES is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set CONFIG_ATM=m # CONFIG_ATM_CLIP is not set @@ -466,6 +509,7 @@ CONFIG_ATM_BR2684=m CONFIG_ATM_BR2684_IPFILTER=y CONFIG_STP=y CONFIG_BRIDGE=y +CONFIG_BRIDGE_IGMP_SNOOPING=y # CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=y # CONFIG_VLAN_8021Q_GVRP is not set @@ -541,20 +585,19 @@ CONFIG_HAMRADIO=y # CONFIG_AF_RXRPC is not set CONFIG_FIB_RULES=y CONFIG_WIRELESS=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set # CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set CONFIG_MAC80211=m -CONFIG_MAC80211_DEFAULT_PS=y -CONFIG_MAC80211_DEFAULT_PS_VALUE=1 - -# -# Rate control algorithm selection -# CONFIG_MAC80211_RC_PID=y CONFIG_MAC80211_RC_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT_PID=y @@ -576,6 +619,7 @@ CONFIG_MAC80211_RC_DEFAULT="pid" # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y @@ -585,9 +629,9 @@ CONFIG_EXTRA_FIRMWARE="" # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_TESTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_CMDLINE_PARTS is not set # CONFIG_MTD_AR7_PARTS is not set @@ -636,6 +680,7 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=y # CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_GPIO_ADDR is not set # CONFIG_MTD_PLATRAM is not set # @@ -668,6 +713,10 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set @@ -687,6 +736,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -727,6 +777,7 @@ CONFIG_MII=y # CONFIG_SMC91X is not set # CONFIG_DM9000 is not set # CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set # CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set @@ -737,23 +788,21 @@ CONFIG_MII=y # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_CPMAC=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -CONFIG_WLAN_80211=y -# CONFIG_LIBERTAS is not set +CONFIG_WLAN=y # CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_MAC80211_HWSIM is not set -# CONFIG_P54_COMMON is not set -# CONFIG_HOSTAP is not set +# CONFIG_ATH_COMMON is not set # CONFIG_B43 is not set # CONFIG_B43LEGACY is not set +# CONFIG_HOSTAP is not set +# CONFIG_LIBERTAS is not set +# CONFIG_P54_COMMON is not set # CONFIG_RT2X00 is not set +# CONFIG_WL12XX is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -813,6 +862,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=2 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -824,11 +874,39 @@ CONFIG_HW_RANDOM=y # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set # CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -842,13 +920,7 @@ CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB=y -# CONFIG_SSB_SILENT is not set -# CONFIG_SSB_DEBUG is not set -CONFIG_SSB_SERIAL=y -CONFIG_SSB_DRIVER_MIPS=y -CONFIG_SSB_EMBEDDED=y -CONFIG_SSB_DRIVER_EXTIF=y +# CONFIG_SSB is not set # # Multifunction device drivers @@ -882,15 +954,18 @@ CONFIG_LEDS_CLASS=y # # LED drivers # -# CONFIG_LEDS_GPIO is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y # # LED Triggers # -CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # @@ -921,6 +996,7 @@ CONFIG_VLYNQ=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set @@ -984,6 +1060,7 @@ CONFIG_JFFS2_RTIME=y CONFIG_JFFS2_CMODE_PRIORITY=y # CONFIG_JFFS2_CMODE_SIZE is not set # CONFIG_JFFS2_CMODE_FAVOURLZO is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set CONFIG_SQUASHFS=y # CONFIG_SQUASHFS_EMBEDDED is not set @@ -996,11 +1073,11 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1039,21 +1116,29 @@ CONFIG_ENABLE_WARN_DEPRECATED=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +CONFIG_STRIP_ASM_SYMS=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y +CONFIG_EARLY_PRINTK=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="rootfstype=squashfs,jffs2" # CONFIG_CMDLINE_OVERRIDE is not set +# CONFIG_SPINLOCK_TEST is not set # # Security options @@ -1061,13 +1146,16 @@ CONFIG_CMDLINE="rootfstype=squashfs,jffs2" # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=m CONFIG_CRYPTO_ALGAPI2=m CONFIG_CRYPTO_AEAD2=m @@ -1108,11 +1196,13 @@ CONFIG_CRYPTO_ECB=m # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set -- cgit v1.2.3-59-g8ed1b From 75d56c6e70605357f30fd0e60cde67e82db14895 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 2 May 2010 11:39:02 +0200 Subject: MIPS: RB532: Update defconfig This updates the Mikrotik RB532 defconfig with: - tiny RCU - RB532 input buttons driver - RB532 LED driver - RC32434 watchdog driver - GPIO sysfs support - Wireless support - SquashFS support - more LED triggers Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1166/ Signed-off-by: Ralf Baechle --- arch/mips/configs/rb532_defconfig | 521 ++++++++++++++++++++++++++------------ 1 file changed, 364 insertions(+), 157 deletions(-) (limited to 'arch') diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig index 57a50483abdf..90a032af95ce 100644 --- a/arch/mips/configs/rb532_defconfig +++ b/arch/mips/configs/rb532_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25 -# Mon Apr 28 12:24:17 2008 +# Linux kernel version: 2.6.34-rc6 +# Sat May 1 11:49:51 2010 # CONFIG_MIPS=y @@ -9,22 +9,25 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set +# CONFIG_AR7 is not set # CONFIG_BCM47XX is not set +# CONFIG_BCM63XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set -# CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set +# CONFIG_MACH_LOONGSON is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set -# CONFIG_MARKEINS is not set +# CONFIG_NEC_MARKEINS is not set # CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_PMC_MSP is not set # CONFIG_PMC_YOSEMITE is not set +# CONFIG_POWERTV is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set # CONFIG_SGI_IP28 is not set @@ -38,11 +41,14 @@ CONFIG_MIPS=y # CONFIG_SIBYTE_SENTOSA is not set # CONFIG_SIBYTE_BIGSUR is not set # CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set CONFIG_MIKROTIK_RB532=y -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set # CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set +CONFIG_LOONGSON_UART_BASE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set @@ -53,14 +59,15 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_BOOT_RAW=y +CONFIG_CEVT_R4K_LIB=y CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K_LIB=y CONFIG_CSRC_R4K=y CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -# CONFIG_HOTPLUG_CPU is not set +CONFIG_NEED_DMA_MAP_STATE=y # CONFIG_NO_IOPORT is not set CONFIG_GENERIC_GPIO=y # CONFIG_CPU_BIG_ENDIAN is not set @@ -73,7 +80,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=4 # # CPU selection # -# CONFIG_CPU_LOONGSON2 is not set +# CONFIG_CPU_LOONGSON2E is not set +# CONFIG_CPU_LOONGSON2F is not set CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set @@ -86,6 +94,7 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R5500 is not set # CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set # CONFIG_CPU_R8000 is not set @@ -93,11 +102,13 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +# CONFIG_CPU_CAVIUM_OCTEON is not set CONFIG_SYS_HAS_CPU_MIPS32_R1=y CONFIG_CPU_MIPS32=y CONFIG_CPU_MIPSR1=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_HARDWARE_WATCHPOINTS=y # # Kernel type @@ -107,11 +118,13 @@ CONFIG_32BIT=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_32KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y @@ -124,12 +137,13 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -151,6 +165,7 @@ CONFIG_PREEMPT_NONE=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -168,23 +183,31 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +# CONFIG_TREE_RCU is not set +# CONFIG_TREE_PREEMPT_RCU is not set +CONFIG_TINY_RCU=y +# CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y # CONFIG_KALLSYMS is not set @@ -192,54 +215,87 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set -CONFIG_COMPAT_BRK=y +CONFIG_PCSPKR_PLATFORM=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# # CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_PCI_QUIRKS is not set +CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_KPROBES is not set -# CONFIG_HAVE_KRETPROBES is not set -CONFIG_PROC_PAGE_MONITOR=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set CONFIG_IOSCHED_DEADLINE=y # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" -CONFIG_CLASSIC_RCU=y +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set # # Bus options (PCI, PCMCIA, EISA, ISA, TC) @@ -248,7 +304,8 @@ CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set CONFIG_MMU=y # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set @@ -257,25 +314,22 @@ CONFIG_MMU=y # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set CONFIG_TRAD_SIGNALS=y # # Power management options # +CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y # CONFIG_PM is not set - -# -# Networking -# CONFIG_NET=y # # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -325,7 +379,6 @@ CONFIG_DEFAULT_VEGAS=y # CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="vegas" # CONFIG_TCP_MD5SIG is not set -# CONFIG_IP_VS is not set # CONFIG_IPV6 is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y @@ -336,8 +389,9 @@ CONFIG_NETFILTER_ADVANCED=y # # Core Netfilter Configuration # +CONFIG_NETFILTER_NETLINK=m # CONFIG_NETFILTER_NETLINK_QUEUE is not set -# CONFIG_NETFILTER_NETLINK_LOG is not set +CONFIG_NETFILTER_NETLINK_LOG=m CONFIG_NF_CONNTRACK=y CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y @@ -355,18 +409,23 @@ CONFIG_NF_CONNTRACK_IRC=m # CONFIG_NF_CONNTRACK_SIP is not set CONFIG_NF_CONNTRACK_TFTP=m # CONFIG_NF_CT_NETLINK is not set +# CONFIG_NETFILTER_TPROXY is not set CONFIG_NETFILTER_XTABLES=y # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_CT is not set # CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set # CONFIG_NETFILTER_XT_TARGET_MARK is not set -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m # CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set # CONFIG_NETFILTER_XT_TARGET_RATEEST is not set CONFIG_NETFILTER_XT_TARGET_TRACE=m # CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set # CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set CONFIG_NETFILTER_XT_MATCH_COMMENT=m # CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m @@ -375,18 +434,21 @@ CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_DCCP=m # CONFIG_NETFILTER_XT_MATCH_DSCP is not set # CONFIG_NETFILTER_XT_MATCH_ESP is not set +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m # CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_HL is not set # CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set # CONFIG_NETFILTER_XT_MATCH_LENGTH is not set CONFIG_NETFILTER_XT_MATCH_LIMIT=y # CONFIG_NETFILTER_XT_MATCH_MAC is not set # CONFIG_NETFILTER_XT_MATCH_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set # CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set # CONFIG_NETFILTER_XT_MATCH_QUOTA is not set # CONFIG_NETFILTER_XT_MATCH_RATEEST is not set CONFIG_NETFILTER_XT_MATCH_REALM=m +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STATE=y # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set @@ -394,20 +456,21 @@ CONFIG_NETFILTER_XT_MATCH_STATE=y # CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set # CONFIG_NETFILTER_XT_MATCH_TIME is not set CONFIG_NETFILTER_XT_MATCH_U32=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_IP_VS is not set # # IP: Netfilter Configuration # +CONFIG_NF_DEFRAG_IPV4=y CONFIG_NF_CONNTRACK_IPV4=y CONFIG_NF_CONNTRACK_PROC_COMPAT=y # CONFIG_IP_NF_QUEUE is not set CONFIG_IP_NF_IPTABLES=y -# CONFIG_IP_NF_MATCH_RECENT is not set -# CONFIG_IP_NF_MATCH_ECN is not set +CONFIG_IP_NF_MATCH_ADDRTYPE=m # CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_ECN is not set # CONFIG_IP_NF_MATCH_TTL is not set -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y # CONFIG_IP_NF_TARGET_LOG is not set @@ -415,8 +478,8 @@ CONFIG_IP_NF_TARGET_REJECT=y CONFIG_NF_NAT=y CONFIG_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=y -# CONFIG_IP_NF_TARGET_REDIRECT is not set # CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_REDIRECT is not set # CONFIG_NF_NAT_SNMP_BASIC is not set CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m @@ -426,17 +489,22 @@ CONFIG_NF_NAT_TFTP=m # CONFIG_NF_NAT_H323 is not set # CONFIG_NF_NAT_SIP is not set CONFIG_IP_NF_MANGLE=y +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set # CONFIG_IP_NF_TARGET_ECN is not set # CONFIG_IP_NF_TARGET_TTL is not set -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set CONFIG_IP_NF_RAW=m # CONFIG_IP_NF_ARPTABLES is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set +CONFIG_STP=y CONFIG_BRIDGE=y +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=y +# CONFIG_VLAN_8021Q_GVRP is not set # CONFIG_DECNET is not set CONFIG_LLC=y CONFIG_LLC2=m @@ -446,6 +514,8 @@ CONFIG_LLC2=m # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set CONFIG_NET_SCHED=y # @@ -455,7 +525,7 @@ CONFIG_NET_SCH_CBQ=m # CONFIG_NET_SCH_HTB is not set # CONFIG_NET_SCH_HFSC is not set CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RR=m +# CONFIG_NET_SCH_MULTIQ is not set # CONFIG_NET_SCH_RED is not set # CONFIG_NET_SCH_SFQ is not set # CONFIG_NET_SCH_TEQL is not set @@ -463,6 +533,7 @@ CONFIG_NET_SCH_RR=m # CONFIG_NET_SCH_GRED is not set # CONFIG_NET_SCH_DSMARK is not set CONFIG_NET_SCH_NETEM=m +# CONFIG_NET_SCH_DRR is not set # CONFIG_NET_SCH_INGRESS is not set # @@ -496,8 +567,10 @@ CONFIG_NET_ACT_IPT=m # CONFIG_NET_ACT_NAT is not set CONFIG_NET_ACT_PEDIT=m # CONFIG_NET_ACT_SIMP is not set +# CONFIG_NET_ACT_SKBEDIT is not set CONFIG_NET_CLS_IND=y CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set # # Network testing @@ -514,14 +587,19 @@ CONFIG_HAMRADIO=y # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set # -# Wireless +# CFG80211 needs to be enabled for MAC80211 # -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_EXT=y -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -533,13 +611,17 @@ CONFIG_WIRELESS_EXT=y # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -611,6 +693,11 @@ CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_PLATFORM=y # CONFIG_MTD_ONENAND is not set +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + # # UBI - Unsorted block images # @@ -623,23 +710,36 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y # CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_CB710_CORE is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -656,10 +756,6 @@ CONFIG_SCSI_PROC_FS=y # CONFIG_BLK_DEV_SR is not set # CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -676,27 +772,35 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_MVSAS is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set @@ -708,9 +812,15 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set +# CONFIG_ATA_VERBOSE_ERROR is not set # CONFIG_SATA_PMP is not set # CONFIG_SATA_AHCI is not set # CONFIG_SATA_SIL24 is not set @@ -732,6 +842,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_ALI is not set # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATP867X is not set # CONFIG_PATA_ATIIXP is not set # CONFIG_PATA_CMD640_PCI is not set # CONFIG_PATA_CMD64X is not set @@ -747,6 +858,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -757,29 +869,39 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set CONFIG_PATA_RB532=y +# CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set # CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_SCH is not set # CONFIG_MD is not set # CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support # + +# +# You can enable one or both FireWire driver stacks. +# + +# +# The newer stack is recommended. +# # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # CONFIG_I2O is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set CONFIG_IFB=m # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -797,21 +919,28 @@ CONFIG_KORINA=y # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set # CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set # CONFIG_TC35815 is not set -# CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -821,30 +950,27 @@ CONFIG_NET_PCI=y # CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_VIA_RHINE=y # CONFIG_VIA_RHINE_MMIO is not set -CONFIG_VIA_RHINE_NAPI=y # CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -CONFIG_WLAN_80211=y -# CONFIG_IPW2100 is not set -# CONFIG_IPW2200 is not set -# CONFIG_LIBERTAS is not set -# CONFIG_HERMES is not set +CONFIG_WLAN=y CONFIG_ATMEL=m # CONFIG_PCI_ATMEL is not set # CONFIG_PRISM54 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_HOSTAP is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -864,6 +990,7 @@ CONFIG_SLHC=m # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -872,7 +999,8 @@ CONFIG_SLHC=m # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -887,17 +1015,29 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set # CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set # CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set # CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_PCSPKR is not set +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +CONFIG_INPUT_RB532_BUTTON=y # # Hardware I/O ports @@ -909,6 +1049,7 @@ CONFIG_INPUT_KEYBOARD=y # Character devices # # CONFIG_VT is not set +CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_NOZOMI is not set @@ -928,105 +1069,95 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=2 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y -# CONFIG_RTC is not set +# CONFIG_HW_RANDOM_TIMERIOMEM is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set # -# Watchdog Device Drivers +# PPS support # -# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y # -# PCI-based Watchdog Cards +# Memory mapped GPIO expanders: # -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_SCH is not set # -# Sonics Silicon Backplane +# I2C GPIO expanders: # -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set # -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set - -# -# Multimedia devices -# -CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_V4L2_COMMON=m -CONFIG_VIDEO_ALLOW_V4L1=y -CONFIG_VIDEO_V4L1_COMPAT=y -CONFIG_VIDEO_V4L2=m -CONFIG_VIDEO_V4L1=m -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set - -# -# Encoders/decoders and other helper chips +# PCI GPIO expanders: # +# CONFIG_GPIO_CS5535 is not set +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_LANGWELL is not set # -# Audio decoders +# SPI GPIO expanders: # # -# Video decoders +# AC97 GPIO expanders: # +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y # -# Video and audio decoders +# Watchdog Device Drivers # +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_ALIM7101_WDT is not set +CONFIG_RC32434_WDT=y # -# MPEG video encoders +# PCI-based Watchdog Cards # -# CONFIG_VIDEO_CX2341X is not set +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +CONFIG_SSB_POSSIBLE=y # -# Video encoders +# Sonics Silicon Backplane # +# CONFIG_SSB is not set # -# Video improvement chips +# Multifunction device drivers # -# CONFIG_VIDEO_VIVI is not set -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_STRADIS is not set -# CONFIG_SOC_CAMERA is not set -# CONFIG_RADIO_ADAPTERS is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_TIMBERDALE is not set +# CONFIG_LPC_SCH is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support # +# CONFIG_VGA_ARB is not set # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1037,13 +1168,10 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y # Display device support # # CONFIG_DISPLAY_SUPPORT is not set - -# -# Sound -# # CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y # CONFIG_HID is not set +# CONFIG_HID_PID is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1053,9 +1181,18 @@ CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_USB_OTG_BLACKLIST_HUB is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# Enable Host or Gadget support to see Inventra options +# + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -1064,20 +1201,36 @@ CONFIG_LEDS_CLASS=y # # LED drivers # +CONFIG_LEDS_MIKROTIK_RB532=y # CONFIG_LEDS_GPIO is not set +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y # # LED Triggers # -CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_RTC_LIB=y # CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + # # File systems # @@ -1085,19 +1238,29 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY is not set +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1117,15 +1280,13 @@ CONFIG_EXT2_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_CONFIGFS_FS=y - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1148,9 +1309,14 @@ CONFIG_JFFS2_RTIME=y CONFIG_JFFS2_CMODE_PRIORITY=y # CONFIG_JFFS2_CMODE_SIZE is not set # CONFIG_JFFS2_CMODE_FAVOURLZO is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_ROMFS_FS is not set @@ -1160,6 +1326,7 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1198,11 +1365,22 @@ CONFIG_ENABLE_WARN_DEPRECATED=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +CONFIG_STRIP_ASM_SYMS=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set # CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y # CONFIG_CMDLINE_BOOL is not set # @@ -1210,18 +1388,32 @@ CONFIG_FRAME_WARN=1024 # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # # Crypto core or helper # +# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=m -CONFIG_CRYPTO_AEAD=m -CONFIG_CRYPTO_BLKCIPHER=m -# CONFIG_CRYPTO_MANAGER is not set +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_HASH2=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=m +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=m # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=m # CONFIG_CRYPTO_CRYPTD is not set # CONFIG_CRYPTO_AUTHENC is not set CONFIG_CRYPTO_TEST=m @@ -1249,14 +1441,20 @@ CONFIG_CRYPTO_TEST=m # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # -# CONFIG_CRYPTO_CRC32C is not set +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set # CONFIG_CRYPTO_SHA1 is not set # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set @@ -1266,7 +1464,7 @@ CONFIG_CRYPTO_TEST=m # # Ciphers # -# CONFIG_CRYPTO_AES is not set +CONFIG_CRYPTO_AES=m # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_ARC4 is not set # CONFIG_CRYPTO_BLOWFISH is not set @@ -1286,27 +1484,36 @@ CONFIG_CRYPTO_TEST=m # Compression # # CONFIG_CRYPTO_DEFLATE is not set +CONFIG_CRYPTO_ZLIB=y # CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m # CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m CONFIG_CRC16=m +# CONFIG_CRC_T10DIF is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m -CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- cgit v1.2.3-59-g8ed1b From 480f3b2dd36c4f5477d20c1bb53f25fc6c7ce38a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 2 May 2010 11:39:07 +0200 Subject: MIPS: BCM47xx: Update defconfig Update Broadcom BCM47xx defconfig with: - tiny RCU - BCM47xx watchdog driver - b43/b43legacy wireless as modules - SSB Gigabit Ethernet driver - disabled IRDA 6igned-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1167/ Signed-off-by: Ralf Baechle --- arch/mips/configs/bcm47xx_defconfig | 973 +++++++++++++++++++++++------------- 1 file changed, 628 insertions(+), 345 deletions(-) (limited to 'arch') diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index 267bd46120bc..bbd826b8032d 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc2 -# Mon Feb 18 11:55:24 2008 +# Linux kernel version: 2.6.34-rc6 +# Sat May 1 12:14:30 2010 # CONFIG_MIPS=y @@ -9,20 +9,25 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set +# CONFIG_AR7 is not set CONFIG_BCM47XX=y +# CONFIG_BCM63XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set -# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MACH_LOONGSON is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SIM is not set -# CONFIG_MARKEINS is not set +# CONFIG_NEC_MARKEINS is not set # CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_PMC_MSP is not set # CONFIG_PMC_YOSEMITE is not set +# CONFIG_POWERTV is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set # CONFIG_SGI_IP28 is not set @@ -36,10 +41,14 @@ CONFIG_BCM47XX=y # CONFIG_SIBYTE_SENTOSA is not set # CONFIG_SIBYTE_BIGSUR is not set # CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set # CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set +CONFIG_LOONGSON_UART_BASE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set @@ -50,16 +59,16 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K_LIB=y CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K_LIB=y CONFIG_CSRC_R4K=y CONFIG_CFE=y CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_EARLY_PRINTK=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_SYS_HAS_EARLY_PRINTK=y -# CONFIG_HOTPLUG_CPU is not set # CONFIG_NO_IOPORT is not set CONFIG_GENERIC_GPIO=y # CONFIG_CPU_BIG_ENDIAN is not set @@ -71,7 +80,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 # # CPU selection # -# CONFIG_CPU_LOONGSON2 is not set +# CONFIG_CPU_LOONGSON2E is not set +# CONFIG_CPU_LOONGSON2F is not set CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set @@ -84,6 +94,7 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R5500 is not set # CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set # CONFIG_CPU_R8000 is not set @@ -91,11 +102,13 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +# CONFIG_CPU_CAVIUM_OCTEON is not set CONFIG_SYS_HAS_CPU_MIPS32_R1=y CONFIG_CPU_MIPS32=y CONFIG_CPU_MIPSR1=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_HARDWARE_WATCHPOINTS=y # # Kernel type @@ -105,11 +118,13 @@ CONFIG_32BIT=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_32KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y @@ -122,12 +137,13 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -144,12 +160,12 @@ CONFIG_HZ=250 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_RCU_TRACE=y CONFIG_KEXEC=y # CONFIG_SECCOMP is not set CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -163,6 +179,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y @@ -170,25 +187,37 @@ CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y + +# +# RCU Subsystem +# +# CONFIG_TREE_RCU is not set +# CONFIG_TREE_PREEMPT_RCU is not set +CONFIG_TINY_RCU=y +# CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set CONFIG_CGROUP_NS=y -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CPUSETS is not set CONFIG_CGROUP_CPUACCT=y # CONFIG_RESOURCE_COUNTERS is not set -CONFIG_SYSFS_DEPRECATED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_LZMA=y +# CONFIG_RD_LZO is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y @@ -197,54 +226,90 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +CONFIG_PCSPKR_PLATFORM=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_KPROBES is not set -CONFIG_PROC_PAGE_MONITOR=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_SLOW_WORK_DEBUG is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -CONFIG_LBD=y -CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_LSF=y +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set +# CONFIG_CFQ_GROUP_IOSCHED is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y -# CONFIG_PREEMPT_RCU is not set +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set # # Bus options (PCI, PCMCIA, EISA, ISA, TC) @@ -253,7 +318,8 @@ CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set CONFIG_MMU=y # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set @@ -262,31 +328,30 @@ CONFIG_MMU=y # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set CONFIG_BINFMT_MISC=m CONFIG_TRAD_SIGNALS=y # # Power management options # +CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y # CONFIG_PM is not set - -# -# Networking -# CONFIG_NET=y # # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set # CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=m # CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y @@ -315,7 +380,7 @@ CONFIG_INET_TUNNEL=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_INET_LRO=m +CONFIG_INET_LRO=y CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m CONFIG_TCP_CONG_ADVANCED=y @@ -339,36 +404,6 @@ CONFIG_DEFAULT_BIC=y # CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="bic" # CONFIG_TCP_MD5SIG is not set -CONFIG_IP_VS=m -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y # CONFIG_IPV6_ROUTER_PREF is not set @@ -384,9 +419,12 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y +# CONFIG_IPV6_MROUTE is not set CONFIG_NETWORK_SECMARK=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -404,6 +442,7 @@ CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=m CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -417,20 +456,25 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CT_NETLINK=m +# CONFIG_NETFILTER_TPROXY is not set CONFIG_NETFILTER_XTABLES=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +# CONFIG_NETFILTER_XT_TARGET_CT is not set CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +# CONFIG_NETFILTER_XT_TARGET_LED is not set CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m CONFIG_NETFILTER_XT_TARGET_NOTRACK=m # CONFIG_NETFILTER_XT_TARGET_RATEEST is not set CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_SECMARK=m -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m # CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m @@ -439,20 +483,23 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_DCCP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m # CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m # CONFIG_NETFILTER_XT_MATCH_OWNER is not set CONFIG_NETFILTER_XT_MATCH_POLICY=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m CONFIG_NETFILTER_XT_MATCH_QUOTA=m # CONFIG_NETFILTER_XT_MATCH_RATEEST is not set CONFIG_NETFILTER_XT_MATCH_REALM=m +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STATE=m CONFIG_NETFILTER_XT_MATCH_STATISTIC=m @@ -460,20 +507,53 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +CONFIG_IP_VS=m +# CONFIG_IP_VS_IPV6 is not set +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +# CONFIG_IP_VS_PROTO_SCTP is not set + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m # # IP: Netfilter Configuration # +CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_PROC_COMPAT=y CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m @@ -481,10 +561,13 @@ CONFIG_IP_NF_TARGET_ULOG=m CONFIG_NF_NAT=m CONFIG_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -493,9 +576,9 @@ CONFIG_NF_NAT_PPTP=m CONFIG_NF_NAT_H323=m CONFIG_NF_NAT_SIP=m CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_RAW=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m @@ -507,24 +590,20 @@ CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_MH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_HL=m CONFIG_IP6_NF_RAW=m - -# -# Bridge: Netfilter Configuration -# CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -533,6 +612,7 @@ CONFIG_BRIDGE_EBT_802_3=m CONFIG_BRIDGE_EBT_AMONG=m CONFIG_BRIDGE_EBT_ARP=m CONFIG_BRIDGE_EBT_IP=m +# CONFIG_BRIDGE_EBT_IP6 is not set CONFIG_BRIDGE_EBT_LIMIT=m CONFIG_BRIDGE_EBT_MARK=m CONFIG_BRIDGE_EBT_PKTTYPE=m @@ -545,31 +625,30 @@ CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_ULOG=m +# CONFIG_BRIDGE_EBT_NFLOG is not set CONFIG_IP_DCCP=m CONFIG_INET_DCCP_DIAG=m -CONFIG_IP_DCCP_ACKVEC=y # # DCCP CCIDs Configuration (EXPERIMENTAL) # -CONFIG_IP_DCCP_CCID2=m # CONFIG_IP_DCCP_CCID2_DEBUG is not set -CONFIG_IP_DCCP_CCID3=m +CONFIG_IP_DCCP_CCID3=y # CONFIG_IP_DCCP_CCID3_DEBUG is not set CONFIG_IP_DCCP_CCID3_RTO=100 -CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_DCCP_TFRC_LIB=y CONFIG_IP_SCTP=m # CONFIG_SCTP_DBG_MSG is not set # CONFIG_SCTP_DBG_OBJCNT is not set # CONFIG_SCTP_HMAC_NONE is not set # CONFIG_SCTP_HMAC_SHA1 is not set CONFIG_SCTP_HMAC_MD5=y +# CONFIG_RDS is not set CONFIG_TIPC=m CONFIG_TIPC_ADVANCED=y CONFIG_TIPC_ZONES=3 CONFIG_TIPC_CLUSTERS=1 CONFIG_TIPC_NODES=255 -CONFIG_TIPC_SLAVE_NODES=0 CONFIG_TIPC_PORTS=8191 CONFIG_TIPC_LOG=0 # CONFIG_TIPC_DEBUG is not set @@ -580,8 +659,12 @@ CONFIG_ATM_LANE=m CONFIG_ATM_MPOA=m CONFIG_ATM_BR2684=m # CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_STP=m CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set # CONFIG_DECNET is not set CONFIG_LLC=m # CONFIG_LLC2 is not set @@ -591,6 +674,8 @@ CONFIG_LLC=m # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set CONFIG_NET_SCHED=y # @@ -601,7 +686,7 @@ CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m CONFIG_NET_SCH_ATM=m CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RR=m +# CONFIG_NET_SCH_MULTIQ is not set CONFIG_NET_SCH_RED=m CONFIG_NET_SCH_SFQ=m CONFIG_NET_SCH_TEQL=m @@ -609,6 +694,7 @@ CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_NETEM=m +# CONFIG_NET_SCH_DRR is not set CONFIG_NET_SCH_INGRESS=m # @@ -626,6 +712,7 @@ CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m # CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_CGROUP is not set CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 CONFIG_NET_EMATCH_CMP=m @@ -642,8 +729,10 @@ CONFIG_NET_ACT_IPT=m CONFIG_NET_ACT_NAT=m CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_ACT_SKBEDIT is not set CONFIG_NET_CLS_IND=y CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set # # Network testing @@ -651,58 +740,7 @@ CONFIG_NET_SCH_FIFO=y CONFIG_NET_PKTGEN=m # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set -CONFIG_IRDA=m - -# -# IrDA protocols -# -CONFIG_IRLAN=m -CONFIG_IRNET=m -CONFIG_IRCOMM=m -# CONFIG_IRDA_ULTRA is not set - -# -# IrDA options -# -CONFIG_IRDA_CACHE_LAST_LSAP=y -CONFIG_IRDA_FAST_RR=y -# CONFIG_IRDA_DEBUG is not set - -# -# Infrared-port device drivers -# - -# -# SIR device drivers -# -CONFIG_IRTTY_SIR=m - -# -# Dongle support -# -CONFIG_DONGLE=y -CONFIG_ESI_DONGLE=m -CONFIG_ACTISYS_DONGLE=m -CONFIG_TEKRAM_DONGLE=m -CONFIG_TOIM3232_DONGLE=m -CONFIG_LITELINK_DONGLE=m -CONFIG_MA600_DONGLE=m -CONFIG_GIRBIL_DONGLE=m -CONFIG_MCP2120_DONGLE=m -CONFIG_OLD_BELKIN_DONGLE=m -CONFIG_ACT200L_DONGLE=m -CONFIG_KINGSUN_DONGLE=m -CONFIG_KSDAZZLE_DONGLE=m -CONFIG_KS959_DONGLE=m - -# -# FIR device drivers -# -CONFIG_USB_IRDA=m -CONFIG_SIGMATEL_FIR=m -CONFIG_TOSHIBA_FIR=m -CONFIG_VLSI_FIR=m -CONFIG_MCS_FIR=m +# CONFIG_IRDA is not set CONFIG_BT=m # CONFIG_BT_L2CAP is not set # CONFIG_BT_SCO is not set @@ -710,8 +748,7 @@ CONFIG_BT=m # # Bluetooth device drivers # -CONFIG_BT_HCIUSB=m -CONFIG_BT_HCIUSB_SCO=y +# CONFIG_BT_HCIBTUSB is not set CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y @@ -720,51 +757,37 @@ CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m CONFIG_BT_HCIVHCI=m +# CONFIG_BT_MRVL is not set # CONFIG_AF_RXRPC is not set CONFIG_FIB_RULES=y - -# -# Wireless -# +CONFIG_WIRELESS=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y CONFIG_CFG80211=m -CONFIG_NL80211=y -CONFIG_WIRELESS_EXT=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set CONFIG_MAC80211=m - -# -# Rate control algorithm selection -# +CONFIG_MAC80211_RC_PID=y +CONFIG_MAC80211_RC_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT_PID=y -# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set -# CONFIG_MAC80211_RC_DEFAULT_NONE is not set - -# -# Selecting 'y' for an algorithm will -# - -# -# build the algorithm into mac80211. -# +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set CONFIG_MAC80211_RC_DEFAULT="pid" -CONFIG_MAC80211_RC_PID=y -# CONFIG_MAC80211_RC_SIMPLE is not set +CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set -# CONFIG_MAC80211_DEBUG is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_WIMAX is not set CONFIG_RFKILL=m -CONFIG_RFKILL_INPUT=m CONFIG_RFKILL_LEDS=y -CONFIG_NET_9P=m -CONFIG_NET_9P_FD=m -# CONFIG_NET_9P_DEBUG is not set +CONFIG_RFKILL_INPUT=y +# CONFIG_NET_9P is not set # # Device Drivers @@ -774,17 +797,22 @@ CONFIG_NET_9P_FD=m # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_SYS_HYPERVISOR is not set CONFIG_CONNECTOR=m CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers @@ -829,9 +857,7 @@ CONFIG_MTD_ABSENT=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x8000000 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_PHYSMAP_COMPAT is not set # CONFIG_MTD_INTEL_VR_NOR is not set # CONFIG_MTD_PLATRAM is not set @@ -853,6 +879,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MTD_NAND is not set # CONFIG_MTD_ONENAND is not set +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + # # UBI - Unsorted block images # @@ -866,6 +897,7 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_DRBD is not set CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set @@ -875,18 +907,27 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 # CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m +# CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y # CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_CB710_CORE is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # # SCSI device support # +CONFIG_SCSI_MOD=y CONFIG_RAID_ATTRS=m CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -904,10 +945,6 @@ CONFIG_BLK_DEV_SR=m CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_CHR_DEV_SCH=m - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -924,21 +961,30 @@ CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y CONFIG_ISCSI_TCP=m +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set @@ -954,7 +1000,12 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set # CONFIG_MD is not set # CONFIG_FUSION is not set @@ -962,11 +1013,18 @@ CONFIG_ISCSI_TCP=m # # IEEE 1394 (FireWire) support # + +# +# You can enable one or both FireWire driver stacks. +# + +# +# The newer stack is recommended. +# # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # CONFIG_I2O is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_IFB is not set CONFIG_DUMMY=m # CONFIG_BONDING is not set @@ -990,8 +1048,11 @@ CONFIG_SMSC_PHY=m CONFIG_BROADCOM_PHY=m CONFIG_ICPLUS_PHY=m # CONFIG_REALTEK_PHY is not set -# CONFIG_FIXED_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set CONFIG_MDIO_BITBANG=m +# CONFIG_MDIO_GPIO is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_AX88796 is not set @@ -999,24 +1060,31 @@ CONFIG_MII=y # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set # CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_KSZ884X_PCI is not set CONFIG_B44=y CONFIG_B44_PCI_AUTOSELECT=y CONFIG_B44_PCICORE_AUTOSELECT=y CONFIG_B44_PCI=y # CONFIG_FORCEDETH is not set # CONFIG_TC35815 is not set -# CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -1026,41 +1094,67 @@ CONFIG_B44_PCI=y # CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -CONFIG_WLAN_80211=y -# CONFIG_IPW2100 is not set -# CONFIG_IPW2200 is not set -# CONFIG_LIBERTAS is not set -# CONFIG_HERMES is not set +CONFIG_WLAN=y +# CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_ATMEL is not set +# CONFIG_AT76C50X_USB is not set # CONFIG_PRISM54 is not set # CONFIG_USB_ZD1201 is not set # CONFIG_USB_NET_RNDIS_WLAN is not set # CONFIG_RTL8180 is not set # CONFIG_RTL8187 is not set # CONFIG_ADM8211 is not set -# CONFIG_P54_COMMON is not set +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_MWL8K is not set +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set CONFIG_ATH5K=m -# CONFIG_IWL4965 is not set -# CONFIG_IWL3945 is not set +# CONFIG_ATH5K_DEBUG is not set +# CONFIG_ATH9K is not set +# CONFIG_AR9170_USB is not set +CONFIG_B43=m +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PIO=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_LEDS=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set # CONFIG_HOSTAP is not set -# CONFIG_BCM43XX is not set -# CONFIG_B43 is not set -# CONFIG_B43LEGACY is not set +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_IWLWIFI is not set +# CONFIG_LIBERTAS is not set +# CONFIG_HERMES is not set +# CONFIG_P54_COMMON is not set +# CONFIG_RT2X00 is not set +# CONFIG_WL12XX is not set CONFIG_ZD1211RW=m # CONFIG_ZD1211RW_DEBUG is not set -# CONFIG_RT2X00 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # # USB Network Adapters @@ -1072,7 +1166,10 @@ CONFIG_USB_RTL8150=m CONFIG_USB_USBNET=m CONFIG_USB_NET_AX8817X=m CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set CONFIG_USB_NET_DM9601=m +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set CONFIG_USB_NET_GL620A=m CONFIG_USB_NET_NET1080=m CONFIG_USB_NET_PLUSB=m @@ -1086,6 +1183,10 @@ CONFIG_USB_ARMLINUX=y CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +CONFIG_USB_SIERRA_NET=m # CONFIG_WAN is not set CONFIG_ATM_DRIVERS=y CONFIG_ATM_DUMMY=m @@ -1099,8 +1200,9 @@ CONFIG_ATM_TCP=m # CONFIG_ATM_AMBASSADOR is not set # CONFIG_ATM_HORIZON is not set # CONFIG_ATM_IA is not set -# CONFIG_ATM_FORE200E_MAYBE is not set +# CONFIG_ATM_FORE200E is not set # CONFIG_ATM_HE is not set +# CONFIG_ATM_SOLOS is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=m @@ -1120,11 +1222,10 @@ CONFIG_SLHC=m # CONFIG_SLIP_SMART is not set # CONFIG_SLIP_MODE_SLIP6 is not set # CONFIG_NET_FC is not set -CONFIG_NETCONSOLE=y -# CONFIG_NETCONSOLE_DYNAMIC is not set -CONFIG_NETPOLL=y -# CONFIG_NETPOLL_TRAP is not set -CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -1134,6 +1235,7 @@ CONFIG_NET_POLL_CONTROLLER=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -1166,6 +1268,7 @@ CONFIG_INPUT_EVDEV=m # Character devices # # CONFIG_VT is not set +CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_NOZOMI is not set @@ -1185,23 +1288,24 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=2 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set -# CONFIG_RTC is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y # CONFIG_I2C is not set +# CONFIG_SPI is not set # -# SPI support +# PPS support # -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +# CONFIG_PPS is not set CONFIG_W1=m CONFIG_W1_CON=y @@ -1217,21 +1321,45 @@ CONFIG_W1_MASTER_DS2490=m # CONFIG_W1_SLAVE_THERM=m CONFIG_W1_SLAVE_SMEM=m +# CONFIG_W1_SLAVE_DS2431 is not set CONFIG_W1_SLAVE_DS2433=m # CONFIG_W1_SLAVE_DS2433_CRC is not set CONFIG_W1_SLAVE_DS2760=m +# CONFIG_W1_SLAVE_BQ27000 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set CONFIG_THERMAL=y -# CONFIG_WATCHDOG is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y # -# Sonics Silicon Backplane +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_ALIM7101_WDT is not set +CONFIG_BCM47XX_WDT=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + # +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# CONFIG_SSB=y +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y CONFIG_SSB_PCIHOST_POSSIBLE=y CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y # CONFIG_SSB_SILENT is not set # CONFIG_SSB_DEBUG is not set CONFIG_SSB_SERIAL=y @@ -1239,24 +1367,26 @@ CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y CONFIG_SSB_DRIVER_PCICORE=y CONFIG_SSB_PCICORE_HOSTMODE=y CONFIG_SSB_DRIVER_MIPS=y +CONFIG_SSB_EMBEDDED=y CONFIG_SSB_DRIVER_EXTIF=y +CONFIG_SSB_DRIVER_GIGE=y # # Multifunction device drivers # +# CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -CONFIG_DAB=y -CONFIG_USB_DABUSB=m +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_LPC_SCH is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support # +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1271,15 +1401,9 @@ CONFIG_DISPLAY_SUPPORT=m # # Display hardware drivers # - -# -# Sound -# CONFIG_SOUND=m - -# -# Advanced Linux Sound Architecture -# +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m @@ -1292,24 +1416,24 @@ CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_HRTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set - -# -# Generic devices -# +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y CONFIG_SND_DUMMY=m CONFIG_SND_VIRMIDI=m # CONFIG_SND_MTPAV is not set # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set - -# -# PCI devices -# +CONFIG_SND_PCI=y # CONFIG_SND_AD1889 is not set # CONFIG_SND_ALS300 is not set # CONFIG_SND_ALI5451 is not set @@ -1318,6 +1442,7 @@ CONFIG_SND_VIRMIDI=m # CONFIG_SND_AU8810 is not set # CONFIG_SND_AU8820 is not set # CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set # CONFIG_SND_AZT3328 is not set # CONFIG_SND_BT87X is not set # CONFIG_SND_CA0106 is not set @@ -1325,6 +1450,8 @@ CONFIG_SND_VIRMIDI=m # CONFIG_SND_OXYGEN is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_CTXFI is not set # CONFIG_SND_DARLA20 is not set # CONFIG_SND_GINA20 is not set # CONFIG_SND_LAYLA20 is not set @@ -1337,6 +1464,8 @@ CONFIG_SND_VIRMIDI=m # CONFIG_SND_INDIGO is not set # CONFIG_SND_INDIGOIO is not set # CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set # CONFIG_SND_EMU10K1 is not set # CONFIG_SND_EMU10K1X is not set # CONFIG_SND_ENS1370 is not set @@ -1353,6 +1482,7 @@ CONFIG_SND_VIRMIDI=m # CONFIG_SND_INTEL8X0 is not set # CONFIG_SND_INTEL8X0M is not set # CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LX6464ES is not set # CONFIG_SND_MAESTRO3 is not set # CONFIG_SND_MIXART is not set # CONFIG_SND_NM256 is not set @@ -1368,45 +1498,22 @@ CONFIG_SND_VIRMIDI=m # CONFIG_SND_VIRTUOSO is not set # CONFIG_SND_VX222 is not set # CONFIG_SND_YMFPCI is not set - -# -# ALSA MIPS devices -# - -# -# USB devices -# +CONFIG_SND_MIPS=y +CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set # CONFIG_SND_USB_CAIAQ is not set - -# -# System on Chip audio support -# # CONFIG_SND_SOC is not set - -# -# SoC Audio support for SuperH -# - -# -# ALSA SoC audio for Freescale SOCs -# - -# -# Open Sound System -# # CONFIG_SOUND_PRIME is not set CONFIG_HID_SUPPORT=y CONFIG_HID=m -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # # USB Input Devices # CONFIG_USB_HID=m -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set +# CONFIG_HID_PID is not set CONFIG_USB_HIDDEV=y # @@ -1414,6 +1521,41 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_KBD is not set # CONFIG_USB_MOUSE is not set + +# +# Special HID drivers +# +# CONFIG_HID_3M_PCT is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MOSART is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_STANTUM is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1429,14 +1571,24 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers # +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_HCD_SSB is not set # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set @@ -1446,26 +1598,30 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_U132_HCD=m # CONFIG_USB_SL811_HCD is not set CONFIG_USB_R8A66597_HCD=m +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set # # USB Device Class drivers # CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # -# may also be needed; see USB_STORAGE Help for more information +# also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set CONFIG_USB_STORAGE_DATAFAB=y CONFIG_USB_STORAGE_FREECOM=y # CONFIG_USB_STORAGE_ISD200 is not set -CONFIG_USB_STORAGE_DPCM=y CONFIG_USB_STORAGE_USBAT=y CONFIG_USB_STORAGE_SDDR09=y CONFIG_USB_STORAGE_SDDR55=y @@ -1473,6 +1629,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=y CONFIG_USB_STORAGE_ALAUDA=y CONFIG_USB_STORAGE_ONETOUCH=y CONFIG_USB_STORAGE_KARMA=y +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1480,7 +1637,6 @@ CONFIG_USB_STORAGE_KARMA=y # CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m -# CONFIG_USB_MON is not set # # USB port drivers @@ -1489,13 +1645,12 @@ CONFIG_USB_SERIAL=m CONFIG_USB_EZUSB=y CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_AIRCABLE=m -CONFIG_USB_SERIAL_AIRPRIME=m CONFIG_USB_SERIAL_ARK3116=m CONFIG_USB_SERIAL_BELKIN=m CONFIG_USB_SERIAL_CH341=m # CONFIG_USB_SERIAL_WHITEHEAT is not set CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -CONFIG_USB_SERIAL_CP2101=m +# CONFIG_USB_SERIAL_CP210X is not set CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m @@ -1515,18 +1670,26 @@ CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_SERIAL_MOS7720=m CONFIG_USB_SERIAL_MOS7840=m +# CONFIG_USB_SERIAL_MOTOROLA is not set CONFIG_USB_SERIAL_NAVMAN=m CONFIG_USB_SERIAL_PL2303=m CONFIG_USB_SERIAL_OTI6858=m +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set CONFIG_USB_SERIAL_HP4X=m CONFIG_USB_SERIAL_SAFE=m # CONFIG_USB_SERIAL_SAFE_PADDED is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_SYMBOL is not set # CONFIG_USB_SERIAL_TI is not set CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OPTION=m CONFIG_USB_SERIAL_OMNINET=m +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set CONFIG_USB_SERIAL_DEBUG=m # @@ -1535,18 +1698,13 @@ CONFIG_USB_SERIAL_DEBUG=m # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set CONFIG_USB_ADUTUX=m -CONFIG_USB_AUERSWALD=m +# CONFIG_USB_SEVSEG is not set CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m -CONFIG_USB_BERRY_CHARGE=m CONFIG_USB_LED=m CONFIG_USB_CYPRESS_CY7C63=m CONFIG_USB_CYTHERM=m -CONFIG_USB_PHIDGET=m -CONFIG_USB_PHIDGETKIT=m -CONFIG_USB_PHIDGETMOTORCONTROL=m -CONFIG_USB_PHIDGETSERVO=m CONFIG_USB_IDMOUSE=m CONFIG_USB_FTDI_ELAN=m # CONFIG_USB_APPLEDISPLAY is not set @@ -1555,6 +1713,7 @@ CONFIG_USB_LD=m CONFIG_USB_TRANCEVIBRATOR=m CONFIG_USB_IOWARRIOR=m CONFIG_USB_TEST=m +# CONFIG_USB_ISIGHTFW is not set CONFIG_USB_ATM=m CONFIG_USB_SPEEDTOUCH=m CONFIG_USB_CXACRU=m @@ -1563,30 +1722,51 @@ CONFIG_USB_XUSBATM=m CONFIG_USB_GADGET=m # CONFIG_USB_GADGET_DEBUG_FILES is not set # CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set # CONFIG_USB_GADGET_ATMEL_USBA is not set # CONFIG_USB_GADGET_FSL_USB2 is not set -CONFIG_USB_GADGET_NET2280=y -CONFIG_USB_NET2280=m -# CONFIG_USB_GADGET_PXA2XX is not set -# CONFIG_USB_GADGET_M66592 is not set -# CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set # CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +CONFIG_USB_GADGET_NET2280=y +CONFIG_USB_NET2280=m +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=m CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_MASS_STORAGE is not set CONFIG_USB_G_SERIAL=m CONFIG_USB_MIDI_GADGET=m # CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -1596,21 +1776,33 @@ CONFIG_LEDS_CLASS=y # LED drivers # CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y # # LED Triggers # -CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_RTC_LIB=y # CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set # -# Userspace I/O +# TI VLYNQ # -# CONFIG_UIO is not set +# CONFIG_STAGING is not set # # File systems @@ -1621,10 +1813,11 @@ CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT4_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1642,27 +1835,38 @@ CONFIG_JFS_SECURITY=y CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m CONFIG_XFS_QUOTA=y -CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y +# CONFIG_XFS_DEBUG is not set CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_GFS2_FS_LOCKING_DLM is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QUOTA_DEBUG is not set +CONFIG_QUOTA_TREE=m CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m CONFIG_QUOTACTL=y CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set CONFIG_GENERIC_ACL=y +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1690,15 +1894,13 @@ CONFIG_NTFS_RW=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_HUGETLB_PAGE is not set CONFIG_CONFIGFS_FS=m - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y CONFIG_ADFS_FS=m # CONFIG_ADFS_FS_RW is not set CONFIG_AFFS_FS=m @@ -1721,12 +1923,19 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=m +# CONFIG_SQUASHFS is not set CONFIG_VXFS_FS=m CONFIG_MINIX_FS=m +# CONFIG_OMFS_FS is not set CONFIG_HPFS_FS=m CONFIG_QNX4FS_FS=m CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y CONFIG_SYSV_FS=m CONFIG_UFS_FS=m # CONFIG_UFS_FS_WRITE is not set @@ -1736,13 +1945,12 @@ CONFIG_NFS_FS=m CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFS_V4_1 is not set CONFIG_NFSD=m CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y -CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m @@ -1750,10 +1958,10 @@ CONFIG_NFS_ACL_SUPPORT=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m -CONFIG_SUNRPC_BIND34=y CONFIG_RPCSEC_GSS_KRB5=m CONFIG_RPCSEC_GSS_SPKM3=m # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set # CONFIG_CIFS_WEAK_PW_HASH is not set @@ -1771,9 +1979,7 @@ CONFIG_NCPFS_OS2_NS=y CONFIG_NCPFS_NLS=y CONFIG_NCPFS_EXTRAS=y CONFIG_CODA_FS=m -# CONFIG_CODA_FS_OLD_API is not set # CONFIG_AFS_FS is not set -CONFIG_9P_FS=m # # Partition Types @@ -1846,90 +2052,167 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_LKDTM is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_EARLY_PRINTK=y # CONFIG_CMDLINE_BOOL is not set +# CONFIG_SPINLOCK_TEST is not set # # Security options # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=m -# CONFIG_CRYPTO_SEQIV is not set +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_GHASH is not set CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m # CONFIG_CRYPTO_SALSA20 is not set +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m CONFIG_CRC16=m +# CONFIG_CRC_T10DIF is not set CONFIG_CRC_ITU_T=m CONFIG_CRC32=y CONFIG_CRC7=m CONFIG_LIBCRC32C=m CONFIG_AUDIT_GENERIC=y -CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_LZMA=y CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m -CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- cgit v1.2.3-59-g8ed1b From 32130ec2daa0aa095f7c5d915a11a18d33b35402 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 2 May 2010 11:39:11 +0200 Subject: MIPS: MTX-1: Update defconfig Updates the 4G Systems MTX-1 defconfig, and remove systems unavailable on this platform. Changes include: - built-in MTD char/block support - GPIO sysfs support - MTX-1 watchdog driver - I2C over GPIO driver as a module - SquashFS support Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1168/ Signed-off-by: Ralf Baechle --- arch/mips/configs/mtx1_defconfig | 2404 +++++++++++++++----------------------- 1 file changed, 955 insertions(+), 1449 deletions(-) (limited to 'arch') diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 144b94d9a6ad..cff8f4c0e57c 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.23-rc8 -# Sun Sep 30 12:56:10 2007 +# Linux kernel version: 2.6.34-rc6 +# Sat May 1 13:39:10 2010 # CONFIG_MIPS=y @@ -9,20 +9,28 @@ CONFIG_MIPS=y # Machine selection # CONFIG_MACH_ALCHEMY=y +# CONFIG_AR7 is not set +# CONFIG_BCM47XX is not set +# CONFIG_BCM63XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LEMOTE_FULONG is not set +# CONFIG_LASAT is not set +# CONFIG_MACH_LOONGSON is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SIM is not set -# CONFIG_MARKEINS is not set +# CONFIG_NEC_MARKEINS is not set # CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_PMC_MSP is not set # CONFIG_PMC_YOSEMITE is not set +# CONFIG_POWERTV is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set # CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CARMEL is not set @@ -33,10 +41,14 @@ CONFIG_MACH_ALCHEMY=y # CONFIG_SIBYTE_SENTOSA is not set # CONFIG_SIBYTE_BIGSUR is not set # CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set # CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +CONFIG_ALCHEMY_GPIOINT_AU1000=y +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set CONFIG_MIPS_MTX1=y # CONFIG_MIPS_BOSPORUS is not set # CONFIG_MIPS_DB1000 is not set @@ -53,29 +65,38 @@ CONFIG_MIPS_MTX1=y # CONFIG_MIPS_XXS1500 is not set CONFIG_SOC_AU1500=y CONFIG_SOC_AU1X00=y +CONFIG_LOONGSON_UART_BASE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_TIME=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K_LIB=y +CONFIG_CSRC_R4K_LIB=y CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -# CONFIG_HOTPLUG_CPU is not set +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_SYS_HAS_EARLY_PRINTK=y # CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_GPIO=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y CONFIG_MIPS_L1_CACHE_SHIFT=5 # # CPU selection # -# CONFIG_CPU_LOONGSON2 is not set +# CONFIG_CPU_LOONGSON2E is not set +# CONFIG_CPU_LOONGSON2F is not set CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set @@ -88,6 +109,7 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R5500 is not set # CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set # CONFIG_CPU_R8000 is not set @@ -95,11 +117,14 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +# CONFIG_CPU_CAVIUM_OCTEON is not set +CONFIG_SYS_SUPPORTS_ZBOOT=y CONFIG_SYS_HAS_CPU_MIPS32_R1=y CONFIG_CPU_MIPS32=y CONFIG_CPU_MIPSR1=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_HARDWARE_WATCHPOINTS=y # # Kernel type @@ -109,28 +134,36 @@ CONFIG_32BIT=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_32KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set CONFIG_64BIT_PHYS_ADDR=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_RESOURCES_64BIT=y +CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set @@ -148,6 +181,7 @@ CONFIG_SECCOMP=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -157,23 +191,49 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set CONFIG_AUDIT=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 -CONFIG_SYSFS_DEPRECATED=y +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y @@ -182,61 +242,104 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_SLOW_WORK_DEBUG is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_KMOD=y CONFIG_BLOCK=y -CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_FREEZER=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # CONFIG_HW_HAS_PCI=y CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set CONFIG_MMU=y - -# -# PCCARD (PCMCIA/CardBus) support -# CONFIG_PCCARD=m -# CONFIG_PCMCIA_DEBUG is not set CONFIG_PCMCIA=m CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y CONFIG_CARDBUS=y # @@ -251,6 +354,7 @@ CONFIG_YENTA_TOSHIBA=y CONFIG_PD6729=m CONFIG_I82092=m # CONFIG_PCMCIA_AU1X00 is not set +# CONFIG_PCMCIA_ALCHEMY_DEVBOARD is not set CONFIG_PCCARD_NONSTATIC=m # CONFIG_HOTPLUG_PCI is not set @@ -258,35 +362,38 @@ CONFIG_PCCARD_NONSTATIC=m # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set CONFIG_BINFMT_MISC=m CONFIG_TRAD_SIGNALS=y # # Power management options # +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_PM=y -# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set CONFIG_PM_SLEEP=y -CONFIG_SUSPEND_UP_POSSIBLE=y CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_HIBERNATION is not set # CONFIG_APM_EMULATION is not set - -# -# Networking -# +# CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y CONFIG_NET=y # # Networking options # CONFIG_PACKET=m -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=m # CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y @@ -315,42 +422,13 @@ CONFIG_INET_TUNNEL=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set -CONFIG_IP_VS=m -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y # CONFIG_IPV6_ROUTER_PREF is not set @@ -366,12 +444,15 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_NETLABEL is not set +# CONFIG_IPV6_MROUTE is not set CONFIG_NETWORK_SECMARK=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y CONFIG_BRIDGE_NETFILTER=y # @@ -380,57 +461,97 @@ CONFIG_BRIDGE_NETFILTER=y CONFIG_NETFILTER_NETLINK=m CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NETFILTER_NETLINK_LOG=m -# CONFIG_NF_CONNTRACK_ENABLED is not set # CONFIG_NF_CONNTRACK is not set +# CONFIG_NETFILTER_TPROXY is not set CONFIG_NETFILTER_XTABLES=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +# CONFIG_NETFILTER_XT_TARGET_LED is not set CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m # CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set # CONFIG_NETFILTER_XT_TARGET_TRACE is not set CONFIG_NETFILTER_XT_TARGET_SECMARK=m # CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_DCCP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +CONFIG_NETFILTER_XT_MATCH_HL=m +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m CONFIG_NETFILTER_XT_MATCH_QUOTA=m +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set CONFIG_NETFILTER_XT_MATCH_REALM=m +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STATISTIC=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +# CONFIG_NETFILTER_XT_MATCH_TIME is not set # CONFIG_NETFILTER_XT_MATCH_U32 is not set -# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +CONFIG_IP_VS=m +# CONFIG_IP_VS_IPV6 is not set +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +# CONFIG_IP_VS_PROTO_SCTP is not set + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m # # IP: Netfilter Configuration # +# CONFIG_NF_DEFRAG_IPV4 is not set CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m @@ -439,34 +560,29 @@ CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m # -# IPv6: Netfilter Configuration (EXPERIMENTAL) +# IPv6: Netfilter Configuration # CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_OWNER=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AH=m # CONFIG_IP6_NF_MATCH_MH is not set -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_HL=m CONFIG_IP6_NF_RAW=m # # DECnet: Netfilter Configuration # CONFIG_DECNET_NF_GRABULATOR=m - -# -# Bridge: Netfilter Configuration -# CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -475,6 +591,7 @@ CONFIG_BRIDGE_EBT_802_3=m CONFIG_BRIDGE_EBT_AMONG=m CONFIG_BRIDGE_EBT_ARP=m CONFIG_BRIDGE_EBT_IP=m +# CONFIG_BRIDGE_EBT_IP6 is not set CONFIG_BRIDGE_EBT_LIMIT=m CONFIG_BRIDGE_EBT_MARK=m CONFIG_BRIDGE_EBT_PKTTYPE=m @@ -487,25 +604,25 @@ CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_ULOG=m +# CONFIG_BRIDGE_EBT_NFLOG is not set CONFIG_IP_DCCP=m CONFIG_INET_DCCP_DIAG=m -CONFIG_IP_DCCP_ACKVEC=y # # DCCP CCIDs Configuration (EXPERIMENTAL) # -CONFIG_IP_DCCP_CCID2=m # CONFIG_IP_DCCP_CCID2_DEBUG is not set -CONFIG_IP_DCCP_CCID3=m -CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_DCCP_CCID3=y # CONFIG_IP_DCCP_CCID3_DEBUG is not set CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=y CONFIG_IP_SCTP=m # CONFIG_SCTP_DBG_MSG is not set # CONFIG_SCTP_DBG_OBJCNT is not set # CONFIG_SCTP_HMAC_NONE is not set # CONFIG_SCTP_HMAC_SHA1 is not set CONFIG_SCTP_HMAC_MD5=y +# CONFIG_RDS is not set CONFIG_TIPC=m # CONFIG_TIPC_ADVANCED is not set # CONFIG_TIPC_DEBUG is not set @@ -516,8 +633,12 @@ CONFIG_ATM_LANE=m CONFIG_ATM_MPOA=m CONFIG_ATM_BR2684=m # CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_STP=m CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set CONFIG_DECNET=m # CONFIG_DECNET_ROUTER is not set CONFIG_LLC=y @@ -535,12 +656,9 @@ CONFIG_ECONET=m CONFIG_ECONET_AUNUDP=y CONFIG_ECONET_NATIVE=y CONFIG_WAN_ROUTER=m - -# -# QoS and/or fair queueing -# +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set CONFIG_NET_SCHED=y -CONFIG_NET_SCH_FIFO=y # # Queueing/Scheduling @@ -550,7 +668,7 @@ CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m CONFIG_NET_SCH_ATM=m CONFIG_NET_SCH_PRIO=m -# CONFIG_NET_SCH_RR is not set +# CONFIG_NET_SCH_MULTIQ is not set CONFIG_NET_SCH_RED=m CONFIG_NET_SCH_SFQ=m CONFIG_NET_SCH_TEQL=m @@ -558,6 +676,7 @@ CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_NETEM=m +# CONFIG_NET_SCH_DRR is not set CONFIG_NET_SCH_INGRESS=m # @@ -574,6 +693,7 @@ CONFIG_NET_CLS_U32=m CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_CLS_FLOW is not set CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 CONFIG_NET_EMATCH_CMP=m @@ -586,10 +706,13 @@ CONFIG_NET_ACT_POLICE=y # CONFIG_NET_ACT_GACT is not set # CONFIG_NET_ACT_MIRRED is not set # CONFIG_NET_ACT_IPT is not set +# CONFIG_NET_ACT_NAT is not set # CONFIG_NET_ACT_PEDIT is not set # CONFIG_NET_ACT_SIMP is not set -CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_ACT_SKBEDIT is not set # CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set # # Network testing @@ -613,9 +736,8 @@ CONFIG_6PACK=m CONFIG_BPQETHER=m CONFIG_BAYCOM_SER_FDX=m CONFIG_BAYCOM_SER_HDX=m -CONFIG_BAYCOM_PAR=m -CONFIG_BAYCOM_EPP=m CONFIG_YAM=m +# CONFIG_CAN is not set CONFIG_IRDA=m # @@ -657,15 +779,8 @@ CONFIG_MCP2120_DONGLE=m CONFIG_OLD_BELKIN_DONGLE=m CONFIG_ACT200L_DONGLE=m # CONFIG_KINGSUN_DONGLE is not set - -# -# Old SIR device drivers -# -# CONFIG_IRPORT_SIR is not set - -# -# Old Serial dongle support -# +# CONFIG_KSDAZZLE_DONGLE is not set +# CONFIG_KS959_DONGLE is not set # # FIR device drivers @@ -683,17 +798,17 @@ CONFIG_BT_RFCOMM_TTY=y CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_CMTP=m CONFIG_BT_HIDP=m # # Bluetooth device drivers # -CONFIG_BT_HCIUSB=m -CONFIG_BT_HCIUSB_SCO=y +# CONFIG_BT_HCIBTUSB is not set +# CONFIG_BT_HCIBTSDIO is not set CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y +# CONFIG_BT_HCIUART_LL is not set CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m @@ -702,24 +817,19 @@ CONFIG_BT_HCIBT3C=m CONFIG_BT_HCIBLUECARD=m CONFIG_BT_HCIBTUART=m CONFIG_BT_HCIVHCI=m +# CONFIG_BT_MRVL is not set CONFIG_AF_RXRPC=m # CONFIG_AF_RXRPC_DEBUG is not set # CONFIG_RXKAD is not set CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set # -# Wireless +# CFG80211 needs to be enabled for MAC80211 # -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_EXT=y -# CONFIG_MAC80211 is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -730,40 +840,43 @@ CONFIG_IEEE80211_SOFTMAC=m # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_SYS_HYPERVISOR is not set CONFIG_CONNECTOR=m -CONFIG_MTD=m +CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=m +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_REDBOOT_PARTS=m -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set -# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers # -CONFIG_MTD_CHAR=m -CONFIG_MTD_BLKDEVS=m -CONFIG_MTD_BLOCK=m -CONFIG_MTD_BLOCK_RO=m -CONFIG_FTL=m -CONFIG_NFTL=m -CONFIG_NFTL_RW=y -CONFIG_INFTL=m -CONFIG_RFD_FTL=m -CONFIG_SSFDC=m +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers # -CONFIG_MTD_CFI=m -CONFIG_MTD_JEDECPROBE=m -CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y CONFIG_MTD_MAP_BANK_WIDTH_2=y @@ -775,206 +888,81 @@ CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=m -CONFIG_MTD_CFI_AMDSTD=m -CONFIG_MTD_CFI_STAA=m -CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_RAM=m -CONFIG_MTD_ROM=m -CONFIG_MTD_ABSENT=m +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set # # Mapping drivers for chip access # CONFIG_MTD_COMPLEX_MAPPINGS=y -CONFIG_MTD_PHYSMAP=m -CONFIG_MTD_PHYSMAP_START=0x8000000 -CONFIG_MTD_PHYSMAP_LEN=0x4000000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 -# CONFIG_MTD_ALCHEMY is not set -# CONFIG_MTD_MTX1 is not set -CONFIG_MTD_PCI=m -CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_GPIO_ADDR is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # -CONFIG_MTD_PMC551=m -# CONFIG_MTD_PMC551_BUGFIX is not set -# CONFIG_MTD_PMC551_DEBUG is not set -CONFIG_MTD_DATAFLASH=m -CONFIG_MTD_M25P80=m -CONFIG_MTD_SLRAM=m -CONFIG_MTD_PHRAM=m -CONFIG_MTD_MTDRAM=m -CONFIG_MTDRAM_TOTAL_SIZE=4096 -CONFIG_MTDRAM_ERASE_SIZE=128 -CONFIG_MTD_BLOCK2MTD=m +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set # # Disk-On-Chip Device Drivers # -CONFIG_MTD_DOC2000=m -CONFIG_MTD_DOC2001=m -CONFIG_MTD_DOC2001PLUS=m -CONFIG_MTD_DOCPROBE=m -CONFIG_MTD_DOCECC=m -# CONFIG_MTD_DOCPROBE_ADVANCED is not set -CONFIG_MTD_DOCPROBE_ADDRESS=0 -CONFIG_MTD_NAND=m -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_SMC is not set -# CONFIG_MTD_NAND_MUSEUM_IDS is not set -CONFIG_MTD_NAND_IDS=m -CONFIG_MTD_NAND_DISKONCHIP=m -# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set -CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 -# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set -# CONFIG_MTD_NAND_CAFE is not set -CONFIG_MTD_NAND_NANDSIM=m -# CONFIG_MTD_NAND_PLATFORM is not set -CONFIG_MTD_ONENAND=m -CONFIG_MTD_ONENAND_VERIFY_WRITE=y -# CONFIG_MTD_ONENAND_OTP is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set # # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_SERIAL=m -CONFIG_PARPORT_PC_FIFO=y -CONFIG_PARPORT_PC_SUPERIO=y -CONFIG_PARPORT_PC_PCMCIA=m -# CONFIG_PARPORT_GSC is not set -CONFIG_PARPORT_AX88796=m -CONFIG_PARPORT_1284=y -CONFIG_PARPORT_NOT_PC=y +# CONFIG_PARPORT is not set CONFIG_BLK_DEV=y -CONFIG_PARIDE=m - -# -# Parallel IDE high-level drivers -# -CONFIG_PARIDE_PD=m -CONFIG_PARIDE_PCD=m -CONFIG_PARIDE_PF=m -CONFIG_PARIDE_PT=m -CONFIG_PARIDE_PG=m - -# -# Parallel IDE protocol modules -# -CONFIG_PARIDE_ATEN=m -CONFIG_PARIDE_BPCK=m -CONFIG_PARIDE_BPCK6=m -CONFIG_PARIDE_COMM=m -CONFIG_PARIDE_DSTR=m -CONFIG_PARIDE_FIT2=m -CONFIG_PARIDE_FIT3=m -CONFIG_PARIDE_EPAT=m -CONFIG_PARIDE_EPATC8=y -CONFIG_PARIDE_EPIA=m -CONFIG_PARIDE_FRIQ=m -CONFIG_PARIDE_FRPW=m -CONFIG_PARIDE_KBIC=m -CONFIG_PARIDE_KTTI=m -CONFIG_PARIDE_ON20=m -CONFIG_PARIDE_ON26=m -CONFIG_BLK_CPQ_DA=m -CONFIG_BLK_CPQ_CISS_DA=m -CONFIG_CISS_SCSI_TAPE=y -CONFIG_BLK_DEV_DAC960=m -CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_DRBD is not set CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=65536 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_CDROM_PKTCDVD=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=m -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set -CONFIG_SGI_IOC4=m -CONFIG_TIFM_CORE=m -CONFIG_TIFM_7XX1=m -CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=m -# CONFIG_IDEDISK_MULTI_MODE is not set -CONFIG_BLK_DEV_IDECS=m -# CONFIG_BLK_DEV_DELKIN is not set -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_IDETAPE=m -CONFIG_BLK_DEV_IDEFLOPPY=m -CONFIG_BLK_DEV_IDESCSI=m -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_IDE_PROC_FS=y - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=m -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_IDEPCI_PCIBUS_ORDER=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=m -CONFIG_BLK_DEV_OPTI621=m -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_AEC62XX=m -CONFIG_BLK_DEV_ALI15X3=m -# CONFIG_WDC_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=m -CONFIG_BLK_DEV_CMD64X=m -CONFIG_BLK_DEV_TRIFLEX=m -CONFIG_BLK_DEV_CY82C693=m -# CONFIG_BLK_DEV_CS5520 is not set -CONFIG_BLK_DEV_CS5530=m -CONFIG_BLK_DEV_HPT34X=m -# CONFIG_HPT34X_AUTODMA is not set -CONFIG_BLK_DEV_HPT366=m -# CONFIG_BLK_DEV_JMICRON is not set -CONFIG_BLK_DEV_SC1200=m -CONFIG_BLK_DEV_PIIX=m -# CONFIG_BLK_DEV_IT8213 is not set -CONFIG_BLK_DEV_IT821X=m -CONFIG_BLK_DEV_NS87415=m -CONFIG_BLK_DEV_PDC202XX_OLD=m -CONFIG_PDC202XX_BURST=y -CONFIG_BLK_DEV_PDC202XX_NEW=m -CONFIG_BLK_DEV_SVWKS=m -CONFIG_BLK_DEV_SIIMAGE=m -# CONFIG_BLK_DEV_SLC90E66 is not set -CONFIG_BLK_DEV_TRM290=m -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_BLK_DEV_TC86C001 is not set -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_TIFM_CORE=m +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set # # SCSI device support # -CONFIG_RAID_ATTRS=m +CONFIG_SCSI_MOD=m +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=m CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set @@ -985,18 +973,13 @@ CONFIG_SCSI_PROC_FS=y # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=m -CONFIG_CHR_DEV_ST=m -CONFIG_CHR_DEV_OSST=m -CONFIG_BLK_DEV_SR=m -# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set CONFIG_CHR_DEV_SG=m -CONFIG_CHR_DEV_SCH=m - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# +# CONFIG_CHR_DEV_SCH is not set CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_CONSTANTS is not set CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_SCAN_ASYNC is not set CONFIG_SCSI_WAIT_SCAN=m @@ -1009,198 +992,39 @@ CONFIG_SCSI_FC_ATTRS=m CONFIG_SCSI_ISCSI_ATTRS=m CONFIG_SCSI_SAS_ATTRS=m CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_ATA is not set +CONFIG_SCSI_SAS_HOST_SMP=y # CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set -CONFIG_SCSI_LOWLEVEL=y -CONFIG_ISCSI_TCP=m -CONFIG_BLK_DEV_3W_XXXX_RAID=m -CONFIG_SCSI_3W_9XXX=m -CONFIG_SCSI_ACARD=m -CONFIG_SCSI_AACRAID=m -CONFIG_SCSI_AIC7XXX=m -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -CONFIG_AIC7XXX_DEBUG_ENABLE=y -CONFIG_AIC7XXX_DEBUG_MASK=0 -CONFIG_AIC7XXX_REG_PRETTY_PRINT=y -# CONFIG_SCSI_AIC7XXX_OLD is not set -CONFIG_SCSI_AIC79XX=m -CONFIG_AIC79XX_CMDS_PER_DEVICE=32 -CONFIG_AIC79XX_RESET_DELAY_MS=15000 -CONFIG_AIC79XX_DEBUG_ENABLE=y -CONFIG_AIC79XX_DEBUG_MASK=0 -CONFIG_AIC79XX_REG_PRETTY_PRINT=y -CONFIG_SCSI_AIC94XX=m -# CONFIG_AIC94XX_DEBUG is not set -CONFIG_SCSI_DPT_I2O=m -CONFIG_SCSI_ARCMSR=m -CONFIG_MEGARAID_NEWGEN=y -CONFIG_MEGARAID_MM=m -CONFIG_MEGARAID_MAILBOX=m -CONFIG_MEGARAID_LEGACY=m -CONFIG_MEGARAID_SAS=m -CONFIG_SCSI_HPTIOP=m -CONFIG_SCSI_DMX3191D=m -CONFIG_SCSI_FUTURE_DOMAIN=m -CONFIG_SCSI_IPS=m -CONFIG_SCSI_INITIO=m -# CONFIG_SCSI_INIA100 is not set -CONFIG_SCSI_PPA=m -CONFIG_SCSI_IMM=m -# CONFIG_SCSI_IZIP_EPP16 is not set -# CONFIG_SCSI_IZIP_SLOW_CTR is not set -CONFIG_SCSI_STEX=m -CONFIG_SCSI_SYM53C8XX_2=m -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -CONFIG_SCSI_SYM53C8XX_MMIO=y -CONFIG_SCSI_IPR=m -# CONFIG_SCSI_IPR_TRACE is not set -# CONFIG_SCSI_IPR_DUMP is not set -CONFIG_SCSI_QLOGIC_1280=m -CONFIG_SCSI_QLA_FC=m -CONFIG_SCSI_QLA_ISCSI=m -CONFIG_SCSI_LPFC=m -CONFIG_SCSI_DC395x=m -CONFIG_SCSI_DC390T=m -CONFIG_SCSI_NSP32=m -CONFIG_SCSI_DEBUG=m -# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set -CONFIG_ATA=m -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_SATA_AHCI=m -CONFIG_SATA_SVW=m -CONFIG_ATA_PIIX=m -CONFIG_SATA_MV=m -CONFIG_SATA_NV=m -CONFIG_PDC_ADMA=m -CONFIG_SATA_QSTOR=m -CONFIG_SATA_PROMISE=m -CONFIG_SATA_SX4=m -CONFIG_SATA_SIL=m -CONFIG_SATA_SIL24=m -CONFIG_SATA_SIS=m -CONFIG_SATA_ULI=m -CONFIG_SATA_VIA=m -CONFIG_SATA_VITESSE=m -# CONFIG_SATA_INIC162X is not set -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_CMD64X is not set -CONFIG_PATA_CS5520=m -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -CONFIG_PATA_EFAR=m -CONFIG_ATA_GENERIC=m -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_IT8213 is not set -CONFIG_PATA_JMICRON=m -CONFIG_PATA_TRIFLEX=m -# CONFIG_PATA_MARVELL is not set -CONFIG_PATA_MPIIX=m -# CONFIG_PATA_OLDPIIX is not set -CONFIG_PATA_NETCELL=m -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -CONFIG_PATA_PCMCIA=m -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -CONFIG_PATA_RZ1000=m -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -CONFIG_PATA_PDC2027X=m -CONFIG_PATA_SIL680=m -CONFIG_PATA_SIS=m -CONFIG_PATA_VIA=m -CONFIG_PATA_WINBOND=m -# CONFIG_PATA_PLATFORM is not set -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID456=m -# CONFIG_MD_RAID5_RESHAPE is not set -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m -CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_MIRROR=m -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -CONFIG_DM_MULTIPATH_EMC=m -# CONFIG_DM_MULTIPATH_RDAC is not set -# CONFIG_DM_DELAY is not set - -# -# Fusion MPT device support -# -CONFIG_FUSION=y -CONFIG_FUSION_SPI=m -CONFIG_FUSION_FC=m -CONFIG_FUSION_SAS=m -CONFIG_FUSION_MAX_SGE=128 -CONFIG_FUSION_CTL=m -CONFIG_FUSION_LAN=m -# CONFIG_FUSION_LOGGING is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support # -# CONFIG_FIREWIRE is not set -CONFIG_IEEE1394=m - -# -# Subsystem Options -# -# CONFIG_IEEE1394_VERBOSEDEBUG is not set # -# Controllers +# You can enable one or both FireWire driver stacks. # -CONFIG_IEEE1394_PCILYNX=m -CONFIG_IEEE1394_OHCI1394=m # -# Protocols +# The newer stack is recommended. # -CONFIG_IEEE1394_VIDEO1394=m -CONFIG_IEEE1394_SBP2=m -# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set -CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y -CONFIG_IEEE1394_ETH1394=m -CONFIG_IEEE1394_DV1394=m -CONFIG_IEEE1394_RAWIO=m -CONFIG_I2O=m -CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y -CONFIG_I2O_EXT_ADAPTEC=y -CONFIG_I2O_CONFIG=m -CONFIG_I2O_CONFIG_OLD_IOCTL=y -CONFIG_I2O_BUS=m -CONFIG_I2O_BLOCK=m -CONFIG_I2O_SCSI=m -CONFIG_I2O_PROC=m +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_IFB is not set CONFIG_DUMMY=m CONFIG_BONDING=m # CONFIG_MACVLAN is not set CONFIG_EQUALIZER=m CONFIG_TUN=m +# CONFIG_VETH is not set CONFIG_ARCNET=m CONFIG_ARCNET_1201=m CONFIG_ARCNET_1051=m @@ -1225,9 +1049,11 @@ CONFIG_VITESSE_PHY=m CONFIG_SMSC_PHY=m # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set -CONFIG_FIXED_PHY=m -# CONFIG_FIXED_MII_10_FDX is not set -# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=m # CONFIG_AX88796 is not set @@ -1240,8 +1066,12 @@ CONFIG_VORTEX=m CONFIG_TYPHOON=m # CONFIG_SMC91X is not set # CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set CONFIG_NET_TULIP=y CONFIG_DE2104X=m +CONFIG_DE2104X_DSL=0 CONFIG_TULIP=m # CONFIG_TULIP_MWI is not set # CONFIG_TULIP_MMIO is not set @@ -1251,21 +1081,26 @@ CONFIG_WINBOND_840=m CONFIG_DM9102=m CONFIG_ULI526X=m CONFIG_PCMCIA_XIRCOM=m -# CONFIG_PCMCIA_XIRTULIP is not set CONFIG_HP100=m +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set CONFIG_NET_PCI=y CONFIG_PCNET32=m -# CONFIG_PCNET32_NAPI is not set CONFIG_AMD8111_ETH=m -# CONFIG_AMD8111E_NAPI is not set CONFIG_ADAPTEC_STARFIRE=m -# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +# CONFIG_KSZ884X_PCI is not set CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y CONFIG_FORCEDETH=m # CONFIG_FORCEDETH_NAPI is not set # CONFIG_TC35815 is not set -CONFIG_DGRS=m -CONFIG_EEPRO100=m CONFIG_E100=m CONFIG_FEALNX=m CONFIG_NATSEMI=m @@ -1276,52 +1111,71 @@ CONFIG_8139TOO=m # CONFIG_8139TOO_TUNE_TWISTER is not set CONFIG_8139TOO_8129=y # CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_R6040 is not set CONFIG_SIS900=m CONFIG_EPIC100=m +# CONFIG_SMSC9420 is not set CONFIG_SUNDANCE=m # CONFIG_SUNDANCE_MMIO is not set CONFIG_TLAN=m +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set CONFIG_VIA_RHINE=m # CONFIG_VIA_RHINE_MMIO is not set -# CONFIG_VIA_RHINE_NAPI is not set # CONFIG_SC92031 is not set -CONFIG_NET_POCKET=y -CONFIG_DE600=m -CONFIG_DE620=m +# CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I is not set CONFIG_DL2K=m CONFIG_E1000=m -# CONFIG_E1000_NAPI is not set -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_E1000E is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set CONFIG_NS83820=m CONFIG_HAMACHI=m CONFIG_YELLOWFIN=m CONFIG_R8169=m -# CONFIG_R8169_NAPI is not set CONFIG_R8169_VLAN=y CONFIG_SIS190=m CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set CONFIG_SKY2=m -CONFIG_SK98LIN=m +# CONFIG_SKY2_DEBUG is not set CONFIG_VIA_VELOCITY=m CONFIG_TIGON3=m CONFIG_BNX2=m +# CONFIG_CNIC is not set CONFIG_QLA3XXX=m # CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set CONFIG_NETDEV_10000=y +CONFIG_MDIO=m CONFIG_CHELSIO_T1=m # CONFIG_CHELSIO_T1_1G is not set -CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +CONFIG_CHELSIO_T4_DEPENDS=y +# CONFIG_CHELSIO_T4 is not set +# CONFIG_ENIC is not set +# CONFIG_IXGBE is not set CONFIG_IXGB=m -# CONFIG_IXGB_NAPI is not set CONFIG_S2IO=m -# CONFIG_S2IO_NAPI is not set +# CONFIG_VXGE is not set CONFIG_MYRI10GE=m # CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_EN is not set # CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_SFC is not set +# CONFIG_BE2NET is not set CONFIG_TR=y CONFIG_IBMOL=m CONFIG_IBMLS=m @@ -1329,12 +1183,18 @@ CONFIG_3C359=m CONFIG_TMS380TR=m CONFIG_TMSPCI=m CONFIG_ABYSS=m +CONFIG_WLAN=y +# CONFIG_PCMCIA_RAYCS is not set +# CONFIG_ATMEL is not set +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set # # USB Network Adapters @@ -1343,11 +1203,13 @@ CONFIG_USB_CATC=m CONFIG_USB_KAWETH=m CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m -CONFIG_USB_USBNET_MII=m CONFIG_USB_USBNET=m CONFIG_USB_NET_AX8817X=m CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set # CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set CONFIG_USB_NET_GL620A=m CONFIG_USB_NET_NET1080=m CONFIG_USB_NET_PLUSB=m @@ -1361,6 +1223,9 @@ CONFIG_USB_ARMLINUX=y CONFIG_USB_EPSON2888=y # CONFIG_USB_KC2190 is not set CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +CONFIG_USB_SIERRA_NET=m CONFIG_NET_PCMCIA=y CONFIG_PCMCIA_3C589=m CONFIG_PCMCIA_3C574=m @@ -1383,16 +1248,6 @@ CONFIG_HDLC_PPP=m CONFIG_HDLC_X25=m CONFIG_PCI200SYN=m CONFIG_WANXL=m -CONFIG_PC300=m -CONFIG_PC300_MLPPP=y - -# -# Cyclades-PC300 MLPPP support is disabled. -# - -# -# Refer to the file README.mlppp, provided by PC300 package. -# # CONFIG_PC300TOO is not set CONFIG_FARSYNC=m CONFIG_DSCC4=m @@ -1428,15 +1283,13 @@ CONFIG_ATM_HORIZON=m # CONFIG_ATM_HORIZON_DEBUG is not set CONFIG_ATM_IA=m # CONFIG_ATM_IA_DEBUG is not set -CONFIG_ATM_FORE200E_MAYBE=m -CONFIG_ATM_FORE200E_PCA=y -CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E=m # CONFIG_ATM_FORE200E_USE_TASKLET is not set CONFIG_ATM_FORE200E_TX_RETRY=16 CONFIG_ATM_FORE200E_DEBUG=0 -CONFIG_ATM_FORE200E=m CONFIG_ATM_HE=m CONFIG_ATM_HE_USE_SUNI=y +# CONFIG_ATM_SOLOS is not set CONFIG_FDDI=y CONFIG_DEFXX=m # CONFIG_DEFXX_MMIO is not set @@ -1444,7 +1297,6 @@ CONFIG_SKFP=m CONFIG_HIPPI=y CONFIG_ROADRUNNER=m # CONFIG_ROADRUNNER_LARGE_RINGS is not set -CONFIG_PLIP=m CONFIG_PPP=m CONFIG_PPP_MULTILINK=y CONFIG_PPP_FILTER=y @@ -1462,219 +1314,53 @@ CONFIG_SLHC=m CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y CONFIG_NET_FC=y -CONFIG_SHAPER=m CONFIG_NETCONSOLE=m +# CONFIG_NETCONSOLE_DYNAMIC is not set CONFIG_NETPOLL=y # CONFIG_NETPOLL_TRAP is not set CONFIG_NET_POLL_CONTROLLER=y -CONFIG_ISDN=m -CONFIG_ISDN_I4L=m -CONFIG_ISDN_PPP=y -CONFIG_ISDN_PPP_VJ=y -CONFIG_ISDN_MPP=y -CONFIG_IPPP_FILTER=y -CONFIG_ISDN_PPP_BSDCOMP=m -CONFIG_ISDN_AUDIO=y -CONFIG_ISDN_TTY_FAX=y -CONFIG_ISDN_X25=y - -# -# ISDN feature submodules -# -# CONFIG_ISDN_DRV_LOOP is not set -CONFIG_ISDN_DIVERSION=m - -# -# ISDN4Linux hardware drivers -# - -# -# Passive cards -# -CONFIG_ISDN_DRV_HISAX=m - -# -# D-channel protocol features -# -CONFIG_HISAX_EURO=y -CONFIG_DE_AOC=y -# CONFIG_HISAX_NO_SENDCOMPLETE is not set -# CONFIG_HISAX_NO_LLC is not set -# CONFIG_HISAX_NO_KEYPAD is not set -CONFIG_HISAX_1TR6=y -CONFIG_HISAX_NI1=y -CONFIG_HISAX_MAX_CARDS=8 - -# -# HiSax supported cards -# -CONFIG_HISAX_16_3=y -CONFIG_HISAX_TELESPCI=y -CONFIG_HISAX_S0BOX=y -CONFIG_HISAX_FRITZPCI=y -CONFIG_HISAX_AVM_A1_PCMCIA=y -CONFIG_HISAX_ELSA=y -CONFIG_HISAX_DIEHLDIVA=y -CONFIG_HISAX_SEDLBAUER=y -CONFIG_HISAX_NETJET=y -CONFIG_HISAX_NETJET_U=y -CONFIG_HISAX_NICCY=y -CONFIG_HISAX_BKM_A4T=y -CONFIG_HISAX_SCT_QUADRO=y -CONFIG_HISAX_GAZEL=y -CONFIG_HISAX_HFC_PCI=y -CONFIG_HISAX_W6692=y -CONFIG_HISAX_HFC_SX=y -CONFIG_HISAX_ENTERNOW_PCI=y -# CONFIG_HISAX_DEBUG is not set - -# -# HiSax PCMCIA card service modules -# -CONFIG_HISAX_SEDLBAUER_CS=m -CONFIG_HISAX_ELSA_CS=m -CONFIG_HISAX_AVM_A1_CS=m -CONFIG_HISAX_TELES_CS=m - -# -# HiSax sub driver modules -# -CONFIG_HISAX_ST5481=m -CONFIG_HISAX_HFCUSB=m -CONFIG_HISAX_HFC4S8S=m -CONFIG_HISAX_FRITZ_PCIPNP=m -CONFIG_HISAX_HDLC=y - -# -# Active cards -# -# CONFIG_HYSDN is not set -CONFIG_ISDN_DRV_GIGASET=m -CONFIG_GIGASET_BASE=m -CONFIG_GIGASET_M105=m -# CONFIG_GIGASET_M101 is not set -# CONFIG_GIGASET_DEBUG is not set -# CONFIG_GIGASET_UNDOCREQ is not set -CONFIG_ISDN_CAPI=m -CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y -CONFIG_CAPI_TRACE=y -CONFIG_ISDN_CAPI_MIDDLEWARE=y -CONFIG_ISDN_CAPI_CAPI20=m -CONFIG_ISDN_CAPI_CAPIFS_BOOL=y -CONFIG_ISDN_CAPI_CAPIFS=m -CONFIG_ISDN_CAPI_CAPIDRV=m - -# -# CAPI hardware drivers -# -CONFIG_CAPI_AVM=y -CONFIG_ISDN_DRV_AVMB1_B1PCI=m -CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y -CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m -CONFIG_ISDN_DRV_AVMB1_AVM_CS=m -CONFIG_ISDN_DRV_AVMB1_T1PCI=m -CONFIG_ISDN_DRV_AVMB1_C4=m -CONFIG_CAPI_EICON=y -CONFIG_ISDN_DIVAS=m -CONFIG_ISDN_DIVAS_BRIPCI=y -CONFIG_ISDN_DIVAS_PRIPCI=y -CONFIG_ISDN_DIVAS_DIVACAPI=m -CONFIG_ISDN_DIVAS_USERIDI=m -CONFIG_ISDN_DIVAS_MAINT=m -CONFIG_PHONE=m -CONFIG_PHONE_IXJ=m -CONFIG_PHONE_IXJ_PCMCIA=m +# CONFIG_VMXNET3 is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set # # Input device support # CONFIG_INPUT=y -CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces # -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=m -CONFIG_INPUT_TSDEV=m -CONFIG_INPUT_TSDEV_SCREEN_X=240 -CONFIG_INPUT_TSDEV_SCREEN_Y=320 -CONFIG_INPUT_EVDEV=m -CONFIG_INPUT_EVBUG=m +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set # # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set CONFIG_KEYBOARD_GPIO=y -CONFIG_KEYBOARD_SUNKBD=m -CONFIG_KEYBOARD_LKKBD=m -CONFIG_KEYBOARD_XTKBD=m -CONFIG_KEYBOARD_NEWTON=m -CONFIG_KEYBOARD_STOWAWAY=m -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=m -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -CONFIG_MOUSE_SERIAL=m -# CONFIG_MOUSE_APPLETOUCH is not set -CONFIG_MOUSE_VSXXXAA=m -CONFIG_INPUT_JOYSTICK=y -CONFIG_JOYSTICK_ANALOG=m -CONFIG_JOYSTICK_A3D=m -CONFIG_JOYSTICK_ADI=m -CONFIG_JOYSTICK_COBRA=m -CONFIG_JOYSTICK_GF2K=m -CONFIG_JOYSTICK_GRIP=m -CONFIG_JOYSTICK_GRIP_MP=m -CONFIG_JOYSTICK_GUILLEMOT=m -CONFIG_JOYSTICK_INTERACT=m -CONFIG_JOYSTICK_SIDEWINDER=m -CONFIG_JOYSTICK_TMDC=m -CONFIG_JOYSTICK_IFORCE=m -CONFIG_JOYSTICK_IFORCE_USB=y -CONFIG_JOYSTICK_IFORCE_232=y -CONFIG_JOYSTICK_WARRIOR=m -CONFIG_JOYSTICK_MAGELLAN=m -CONFIG_JOYSTICK_SPACEORB=m -CONFIG_JOYSTICK_SPACEBALL=m -CONFIG_JOYSTICK_STINGER=m -CONFIG_JOYSTICK_TWIDJOY=m -CONFIG_JOYSTICK_DB9=m -CONFIG_JOYSTICK_GAMECON=m -CONFIG_JOYSTICK_TURBOGRAFX=m -CONFIG_JOYSTICK_JOYDUMP=m -# CONFIG_JOYSTICK_XPAD is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=m -# CONFIG_TOUCHSCREEN_FUJITSU is not set -CONFIG_TOUCHSCREEN_GUNZE=m -CONFIG_TOUCHSCREEN_ELO=m -CONFIG_TOUCHSCREEN_MTOUCH=m -CONFIG_TOUCHSCREEN_MK712=m -CONFIG_TOUCHSCREEN_PENMOUNT=m -CONFIG_TOUCHSCREEN_TOUCHRIGHT=m -CONFIG_TOUCHSCREEN_TOUCHWIN=m -# CONFIG_TOUCHSCREEN_UCB1400 is not set -# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set -CONFIG_INPUT_MISC=y -CONFIG_INPUT_PCSPKR=m -# CONFIG_INPUT_ATI_REMOTE is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set -CONFIG_INPUT_UINPUT=m +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Hardware I/O ports @@ -1682,10 +1368,10 @@ CONFIG_INPUT_UINPUT=m CONFIG_SERIO=y CONFIG_SERIO_I8042=y CONFIG_SERIO_SERPORT=m -CONFIG_SERIO_PARKBD=m CONFIG_SERIO_PCIPS2=m CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_RAW=m +# CONFIG_SERIO_ALTERA_PS2 is not set CONFIG_GAMEPORT=m CONFIG_GAMEPORT_NS558=m CONFIG_GAMEPORT_L4=m @@ -1696,30 +1382,13 @@ CONFIG_GAMEPORT_FM801=m # Character devices # CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_SERIAL_NONSTANDARD=y -# CONFIG_COMPUTONE is not set -CONFIG_ROCKETPORT=m -CONFIG_CYCLADES=m -# CONFIG_CYZ_INTR is not set -CONFIG_DIGIEPCA=m -# CONFIG_MOXA_INTELLIO is not set -CONFIG_MOXA_SMARTIO=m -# CONFIG_MOXA_SMARTIO_NEW is not set -# CONFIG_ISI is not set -CONFIG_SYNCLINKMP=m -CONFIG_SYNCLINK_GT=m -CONFIG_N_HDLC=m -# CONFIG_RISCOM8 is not set -CONFIG_SPECIALIX=m -# CONFIG_SPECIALIX_RTSCTS is not set -CONFIG_SX=m -# CONFIG_RIO is not set -CONFIG_STALDRV=y -# CONFIG_STALLION is not set -# CONFIG_ISTALLION is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -1741,161 +1410,128 @@ CONFIG_SERIAL_8250_RSA=y # CONFIG_SERIAL_CORE=m CONFIG_SERIAL_JSM=m +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 -CONFIG_PRINTER=m -# CONFIG_LP_CONSOLE is not set -CONFIG_PPDEV=m -CONFIG_TIPAR=m -CONFIG_IPMI_HANDLER=m -# CONFIG_IPMI_PANIC_EVENT is not set -CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_SI=m -CONFIG_IPMI_WATCHDOG=m -CONFIG_IPMI_POWEROFF=m -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -CONFIG_SOFT_WATCHDOG=m -# CONFIG_WDT_MTX1 is not set - -# -# PCI-based Watchdog Cards -# -CONFIG_PCIPCWATCHDOG=m -CONFIG_WDTPCI=m -CONFIG_WDT_501_PCI=y - -# -# USB-based Watchdog Cards -# -CONFIG_USBPCWATCHDOG=m +# CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y -CONFIG_RTC=y -CONFIG_R3964=m -CONFIG_APPLICOM=m -CONFIG_DRM=m -CONFIG_DRM_TDFX=m -CONFIG_DRM_R128=m -CONFIG_DRM_RADEON=m -CONFIG_DRM_MGA=m -CONFIG_DRM_VIA=m -CONFIG_DRM_SAVAGE=m +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set # # PCMCIA character devices # -CONFIG_SYNCLINK_CS=m -CONFIG_CARDMAN_4000=m -CONFIG_CARDMAN_4040=m -CONFIG_RAW_DRIVER=m -CONFIG_MAX_RAW_DEVS=256 -CONFIG_TCG_TPM=m -CONFIG_TCG_ATMEL=m +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_IPWIRELESS is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m # -# I2C Algorithms +# I2C Hardware Bus support # -CONFIG_I2C_ALGOBIT=m -CONFIG_I2C_ALGOPCF=m -CONFIG_I2C_ALGOPCA=m # -# I2C Hardware Bus support +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) # -CONFIG_I2C_ALI1535=m -CONFIG_I2C_ALI1563=m -CONFIG_I2C_ALI15X3=m -CONFIG_I2C_AMD756=m -CONFIG_I2C_AMD756_S4882=m -CONFIG_I2C_AMD8111=m -CONFIG_I2C_I801=m -CONFIG_I2C_I810=m -CONFIG_I2C_PIIX4=m -CONFIG_I2C_NFORCE2=m -CONFIG_I2C_OCORES=m -CONFIG_I2C_PARPORT=m -CONFIG_I2C_PARPORT_LIGHT=m -CONFIG_I2C_PROSAVAGE=m -CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_GPIO=m +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set -CONFIG_I2C_SIS5595=m -CONFIG_I2C_SIS630=m -CONFIG_I2C_SIS96X=m +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_TAOS_EVM is not set -CONFIG_I2C_STUB=m # CONFIG_I2C_TINY_USB is not set -CONFIG_I2C_VIA=m -CONFIG_I2C_VIAPRO=m -CONFIG_I2C_VOODOO3=m # -# Miscellaneous I2C Chip support +# Other I2C/SMBus bus drivers # -CONFIG_SENSORS_DS1337=m -CONFIG_SENSORS_DS1374=m -# CONFIG_DS1682 is not set -CONFIG_EEPROM_LEGACY=m -CONFIG_SENSORS_PCF8574=m -CONFIG_SENSORS_PCA9539=m -CONFIG_SENSORS_PCF8591=m -CONFIG_EEPROM_MAX6875=m -# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_SPI is not set # -# SPI support +# PPS support # -CONFIG_SPI=y -CONFIG_SPI_MASTER=y +# CONFIG_PPS is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y # -# SPI Master Controller Drivers +# Memory mapped GPIO expanders: # -CONFIG_SPI_BITBANG=m -CONFIG_SPI_BUTTERFLY=m -# CONFIG_SPI_LM70_LLP is not set +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_SCH is not set # -# SPI Protocol Masters +# I2C GPIO expanders: # -# CONFIG_EEPROM_AT25 is not set -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set -CONFIG_W1=m -CONFIG_W1_CON=y +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # -# 1-wire Bus Masters +# PCI GPIO expanders: # -CONFIG_W1_MASTER_MATROX=m -CONFIG_W1_MASTER_DS2490=m -CONFIG_W1_MASTER_DS2482=m +# CONFIG_GPIO_CS5535 is not set +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_LANGWELL is not set # -# 1-wire Slaves +# SPI GPIO expanders: # -CONFIG_W1_SLAVE_THERM=m -CONFIG_W1_SLAVE_SMEM=m -CONFIG_W1_SLAVE_DS2433=m -# CONFIG_W1_SLAVE_DS2433_CRC is not set -# CONFIG_W1_SLAVE_DS2760 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y CONFIG_HWMON_VID=m -CONFIG_SENSORS_ABITUGURU=m -# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7414 is not set # CONFIG_SENSORS_AD7418 is not set CONFIG_SENSORS_ADM1021=m CONFIG_SENSORS_ADM1025=m @@ -1903,17 +1539,23 @@ CONFIG_SENSORS_ADM1026=m # CONFIG_SENSORS_ADM1029 is not set CONFIG_SENSORS_ADM1031=m CONFIG_SENSORS_ADM9240=m -CONFIG_SENSORS_ASB100=m +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set CONFIG_SENSORS_ATXP1=m CONFIG_SENSORS_DS1621=m +# CONFIG_SENSORS_I5K_AMB is not set CONFIG_SENSORS_F71805F=m -CONFIG_SENSORS_FSCHER=m -CONFIG_SENSORS_FSCPOS=m +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set CONFIG_SENSORS_GL518SM=m CONFIG_SENSORS_GL520SM=m CONFIG_SENSORS_IT87=m CONFIG_SENSORS_LM63=m -CONFIG_SENSORS_LM70=m +# CONFIG_SENSORS_LM73 is not set CONFIG_SENSORS_LM75=m CONFIG_SENSORS_LM77=m CONFIG_SENSORS_LM78=m @@ -1924,16 +1566,25 @@ CONFIG_SENSORS_LM87=m CONFIG_SENSORS_LM90=m CONFIG_SENSORS_LM92=m # CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LM95241 is not set CONFIG_SENSORS_MAX1619=m # CONFIG_SENSORS_MAX6650 is not set CONFIG_SENSORS_PC87360=m # CONFIG_SENSORS_PC87427 is not set +CONFIG_SENSORS_PCF8591=m +# CONFIG_SENSORS_SHT15 is not set CONFIG_SENSORS_SIS5595=m # CONFIG_SENSORS_DME1737 is not set CONFIG_SENSORS_SMSC47M1=m CONFIG_SENSORS_SMSC47M192=m CONFIG_SENSORS_SMSC47B397=m +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set CONFIG_SENSORS_VIA686A=m CONFIG_SENSORS_VT1211=m CONFIG_SENSORS_VT8231=m @@ -1942,370 +1593,94 @@ CONFIG_SENSORS_W83791D=m CONFIG_SENSORS_W83792D=m # CONFIG_SENSORS_W83793 is not set CONFIG_SENSORS_W83L785TS=m +# CONFIG_SENSORS_W83L786NG is not set CONFIG_SENSORS_W83627HF=m CONFIG_SENSORS_W83627EHF=m -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_V4L1=y -CONFIG_VIDEO_V4L1_COMPAT=y -CONFIG_VIDEO_V4L2=y -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -CONFIG_VIDEO_HELPER_CHIPS_AUTO=y -CONFIG_VIDEO_TVAUDIO=m -CONFIG_VIDEO_TDA7432=m -CONFIG_VIDEO_TDA9840=m -CONFIG_VIDEO_TDA9875=m -CONFIG_VIDEO_TEA6415C=m -CONFIG_VIDEO_TEA6420=m -CONFIG_VIDEO_MSP3400=m -CONFIG_VIDEO_WM8775=m -CONFIG_VIDEO_BT819=m -CONFIG_VIDEO_BT856=m -CONFIG_VIDEO_KS0127=m -CONFIG_VIDEO_SAA7110=m -CONFIG_VIDEO_SAA7111=m -CONFIG_VIDEO_SAA7114=m -CONFIG_VIDEO_SAA711X=m -CONFIG_VIDEO_TVP5150=m -CONFIG_VIDEO_VPX3220=m -CONFIG_VIDEO_CX25840=m -CONFIG_VIDEO_CX2341X=m -CONFIG_VIDEO_SAA7185=m -CONFIG_VIDEO_ADV7170=m -CONFIG_VIDEO_ADV7175=m -CONFIG_VIDEO_VIVI=m -CONFIG_VIDEO_BT848=m -CONFIG_VIDEO_BT848_DVB=y -CONFIG_VIDEO_SAA6588=m -CONFIG_VIDEO_BWQCAM=m -CONFIG_VIDEO_CQCAM=m -CONFIG_VIDEO_W9966=m -CONFIG_VIDEO_CPIA=m -CONFIG_VIDEO_CPIA_PP=m -CONFIG_VIDEO_CPIA_USB=m -CONFIG_VIDEO_CPIA2=m -CONFIG_VIDEO_SAA5246A=m -CONFIG_VIDEO_SAA5249=m -CONFIG_TUNER_3036=m -# CONFIG_TUNER_TEA5761 is not set -CONFIG_VIDEO_STRADIS=m -CONFIG_VIDEO_ZORAN_ZR36060=m -CONFIG_VIDEO_ZORAN=m -CONFIG_VIDEO_ZORAN_BUZ=m -CONFIG_VIDEO_ZORAN_DC10=m -CONFIG_VIDEO_ZORAN_DC30=m -CONFIG_VIDEO_ZORAN_LML33=m -CONFIG_VIDEO_ZORAN_LML33R10=m -CONFIG_VIDEO_ZORAN_AVS6EYES=m -CONFIG_VIDEO_SAA7134=m -CONFIG_VIDEO_SAA7134_ALSA=m -CONFIG_VIDEO_SAA7134_OSS=m -CONFIG_VIDEO_SAA7134_DVB=m -CONFIG_VIDEO_MXB=m -CONFIG_VIDEO_DPC=m -CONFIG_VIDEO_HEXIUM_ORION=m -CONFIG_VIDEO_HEXIUM_GEMINI=m -CONFIG_VIDEO_CX88=m -CONFIG_VIDEO_CX88_ALSA=m -CONFIG_VIDEO_CX88_BLACKBIRD=m -CONFIG_VIDEO_CX88_DVB=m -CONFIG_VIDEO_CX88_VP3054=m -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_CAFE_CCIC is not set -CONFIG_V4L_USB_DRIVERS=y -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_PVRUSB2_29XXX=y -CONFIG_VIDEO_PVRUSB2_24XXX=y -CONFIG_VIDEO_PVRUSB2_SYSFS=y -# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set -CONFIG_VIDEO_EM28XX=m -# CONFIG_VIDEO_USBVISION is not set -CONFIG_VIDEO_USBVIDEO=m -CONFIG_USB_VICAM=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_QUICKCAM_MESSENGER=m -CONFIG_USB_ET61X251=m -CONFIG_VIDEO_OVCAMCHIP=m -CONFIG_USB_W9968CF=m -# CONFIG_USB_OV511 is not set -CONFIG_USB_SE401=m -CONFIG_USB_SN9C102=m -CONFIG_USB_STV680=m -CONFIG_USB_ZC0301=m -CONFIG_USB_PWC=m -# CONFIG_USB_PWC_DEBUG is not set -# CONFIG_USB_ZR364XX is not set -CONFIG_RADIO_ADAPTERS=y -CONFIG_RADIO_GEMTEK_PCI=m -CONFIG_RADIO_MAXIRADIO=m -CONFIG_RADIO_MAESTRO=m -CONFIG_USB_DSBR=m -CONFIG_DVB_CORE=m -CONFIG_DVB_CORE_ATTACH=y -CONFIG_DVB_CAPTURE_DRIVERS=y - -# -# Supported SAA7146 based PCI Adapters -# -CONFIG_DVB_AV7110=m -CONFIG_DVB_AV7110_OSD=y -CONFIG_DVB_BUDGET=m -CONFIG_DVB_BUDGET_CI=m -CONFIG_DVB_BUDGET_AV=m -CONFIG_DVB_BUDGET_PATCH=m - -# -# Supported USB Adapters -# -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -# CONFIG_DVB_USB_M920X is not set -# CONFIG_DVB_USB_GL861 is not set -# CONFIG_DVB_USB_AU6610 is not set -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -# CONFIG_DVB_USB_TTUSB2 is not set -CONFIG_DVB_USB_DTT200U=m -# CONFIG_DVB_USB_OPERA1 is not set -# CONFIG_DVB_USB_AF9005 is not set -CONFIG_DVB_TTUSB_BUDGET=m -CONFIG_DVB_TTUSB_DEC=m -CONFIG_DVB_CINERGYT2=m -CONFIG_DVB_CINERGYT2_TUNING=y -CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 -CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 -CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 -CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y -CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 - -# -# Supported FlexCopII (B2C2) Adapters -# -CONFIG_DVB_B2C2_FLEXCOP=m -CONFIG_DVB_B2C2_FLEXCOP_PCI=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set - -# -# Supported BT878 Adapters -# -CONFIG_DVB_BT8XX=m - -# -# Supported Pluto2 Adapters -# -CONFIG_DVB_PLUTO2=m - -# -# Supported DVB Frontends -# - -# -# Customise DVB Frontends -# -# CONFIG_DVB_FE_CUSTOMISE is not set - -# -# DVB-S (satellite) frontends -# -CONFIG_DVB_STV0299=m -CONFIG_DVB_CX24110=m -CONFIG_DVB_CX24123=m -CONFIG_DVB_TDA8083=m -CONFIG_DVB_MT312=m -CONFIG_DVB_VES1X93=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_TDA10086=m +# CONFIG_SENSORS_LIS3_I2C is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y # -# DVB-T (terrestrial) frontends +# Watchdog Device Drivers # -CONFIG_DVB_SP8870=m -CONFIG_DVB_SP887X=m -CONFIG_DVB_CX22700=m -CONFIG_DVB_CX22702=m -CONFIG_DVB_L64781=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_MT352=m -CONFIG_DVB_ZL10353=m -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_ALIM7101_WDT is not set +CONFIG_WDT_MTX1=y # -# DVB-C (cable) frontends +# PCI-based Watchdog Cards # -CONFIG_DVB_VES1820=m -CONFIG_DVB_TDA10021=m -CONFIG_DVB_TDA10023=m -CONFIG_DVB_STV0297=m +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set # -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# USB-based Watchdog Cards # -CONFIG_DVB_NXT200X=m -CONFIG_DVB_OR51211=m -CONFIG_DVB_OR51132=m -CONFIG_DVB_BCM3510=m -CONFIG_DVB_LGDT330X=m +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # -# Tuners/PLL support +# Sonics Silicon Backplane # -CONFIG_DVB_PLL=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_TDA827X=m -# CONFIG_DVB_TUNER_QT1010 is not set -CONFIG_DVB_TUNER_MT2060=m +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +# CONFIG_SSB_B43_PCI_BRIDGE is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_SDIOHOST_POSSIBLE=y +# CONFIG_SSB_SDIOHOST is not set +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_DRIVER_MIPS is not set # -# Miscellaneous devices +# Multifunction device drivers # -CONFIG_DVB_LNBP21=m -CONFIG_DVB_ISL6421=m -CONFIG_DVB_TUA6100=m -CONFIG_VIDEO_SAA7146=m -CONFIG_VIDEO_SAA7146_VV=m -CONFIG_VIDEO_TUNER=m -CONFIG_VIDEO_BUF=m -CONFIG_VIDEO_BUF_DVB=m -CONFIG_VIDEO_BTCX=m -CONFIG_VIDEO_IR_I2C=m -CONFIG_VIDEO_IR=m -CONFIG_VIDEO_TVEEPROM=m -CONFIG_DAB=y -CONFIG_USB_DABUSB=m +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_TIMBERDALE is not set +# CONFIG_LPC_SCH is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support # +# CONFIG_VGA_ARB is not set +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_GENERIC is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set -CONFIG_VGASTATE=m -CONFIG_VIDEO_OUTPUT_CONTROL=m -CONFIG_FB=y -CONFIG_FIRMWARE_EDID=y -CONFIG_FB_DDC=m -CONFIG_FB_CFB_FILLRECT=m -CONFIG_FB_CFB_COPYAREA=m -CONFIG_FB_CFB_IMAGEBLIT=m -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -CONFIG_FB_BACKLIGHT=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_TILEBLITTING=y - -# -# Frame buffer hardware drivers -# -CONFIG_FB_CIRRUS=m -CONFIG_FB_PM2=m -CONFIG_FB_PM2_FIFO_DISCONNECT=y -CONFIG_FB_CYBER2000=m -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -CONFIG_FB_S1D13XXX=m -CONFIG_FB_NVIDIA=m -CONFIG_FB_NVIDIA_I2C=y -# CONFIG_FB_NVIDIA_DEBUG is not set -CONFIG_FB_NVIDIA_BACKLIGHT=y -CONFIG_FB_RIVA=m -CONFIG_FB_RIVA_I2C=y -# CONFIG_FB_RIVA_DEBUG is not set -CONFIG_FB_RIVA_BACKLIGHT=y -CONFIG_FB_MATROX=m -CONFIG_FB_MATROX_MILLENIUM=y -CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G=y -CONFIG_FB_MATROX_I2C=m -CONFIG_FB_MATROX_MAVEN=m -CONFIG_FB_MATROX_MULTIHEAD=y -CONFIG_FB_RADEON=m -CONFIG_FB_RADEON_I2C=y -CONFIG_FB_RADEON_BACKLIGHT=y -# CONFIG_FB_RADEON_DEBUG is not set -CONFIG_FB_ATY128=m -CONFIG_FB_ATY128_BACKLIGHT=y -CONFIG_FB_ATY=m -CONFIG_FB_ATY_CT=y -CONFIG_FB_ATY_GENERIC_LCD=y -CONFIG_FB_ATY_GX=y -CONFIG_FB_ATY_BACKLIGHT=y -# CONFIG_FB_S3 is not set -CONFIG_FB_SAVAGE=m -CONFIG_FB_SAVAGE_I2C=y -CONFIG_FB_SAVAGE_ACCEL=y -CONFIG_FB_SIS=m -CONFIG_FB_SIS_300=y -CONFIG_FB_SIS_315=y -CONFIG_FB_NEOMAGIC=m -CONFIG_FB_KYRO=m -CONFIG_FB_3DFX=m -# CONFIG_FB_3DFX_ACCEL is not set -CONFIG_FB_VOODOO1=m -# CONFIG_FB_VT8623 is not set -CONFIG_FB_TRIDENT=m -# CONFIG_FB_TRIDENT_ACCEL is not set -# CONFIG_FB_ARK is not set -# CONFIG_FB_PM3 is not set -# CONFIG_FB_VIRTUAL is not set # # Console display driver support # -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set +# CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=m -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -# CONFIG_LOGO is not set - -# -# Sound -# CONFIG_SOUND=m - -# -# Advanced Linux Sound Architecture -# +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m @@ -2318,32 +1693,29 @@ CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y -CONFIG_SND_RTCTIMER=m -CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set - -# -# Generic devices -# +CONFIG_SND_VMASTER=y +CONFIG_SND_RAWMIDI_SEQ=m +CONFIG_SND_OPL3_LIB_SEQ=m +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +CONFIG_SND_EMU10K1_SEQ=m CONFIG_SND_MPU401_UART=m CONFIG_SND_OPL3_LIB=m CONFIG_SND_VX_LIB=m CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y CONFIG_SND_DUMMY=m CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=m -CONFIG_SND_MTS64=m CONFIG_SND_SERIAL_U16550=m CONFIG_SND_MPU401=m -# CONFIG_SND_PORTMAN2X4 is not set - -# -# PCI devices -# +# CONFIG_SND_AC97_POWER_SAVE is not set +CONFIG_SND_PCI=y CONFIG_SND_AD1889=m CONFIG_SND_ALS300=m CONFIG_SND_ALI5451=m @@ -2352,14 +1724,18 @@ CONFIG_SND_ATIIXP_MODEM=m CONFIG_SND_AU8810=m CONFIG_SND_AU8820=m CONFIG_SND_AU8830=m +# CONFIG_SND_AW2 is not set CONFIG_SND_AZT3328=m CONFIG_SND_BT87X=m # CONFIG_SND_BT87X_OVERCLOCK is not set CONFIG_SND_CA0106=m CONFIG_SND_CMIPCI=m +# CONFIG_SND_OXYGEN is not set CONFIG_SND_CS4281=m CONFIG_SND_CS46XX=m CONFIG_SND_CS46XX_NEW_DSP=y +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_CTXFI is not set CONFIG_SND_DARLA20=m CONFIG_SND_GINA20=m CONFIG_SND_LAYLA20=m @@ -2372,6 +1748,8 @@ CONFIG_SND_ECHO3G=m CONFIG_SND_INDIGO=m CONFIG_SND_INDIGOIO=m CONFIG_SND_INDIGODJ=m +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set CONFIG_SND_EMU10K1=m CONFIG_SND_EMU10K1X=m CONFIG_SND_ENS1370=m @@ -2379,19 +1757,36 @@ CONFIG_SND_ENS1371=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m CONFIG_SND_FM801=m -CONFIG_SND_FM801_TEA575X_BOOL=y -CONFIG_SND_FM801_TEA575X=m CONFIG_SND_HDA_INTEL=m +# CONFIG_SND_HDA_HWDEP is not set +# CONFIG_SND_HDA_INPUT_BEEP is not set +# CONFIG_SND_HDA_INPUT_JACK is not set +# CONFIG_SND_HDA_PATCH_LOADER is not set +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_CODEC_INTELHDMI=y +CONFIG_SND_HDA_ELD=y +CONFIG_SND_HDA_CODEC_CIRRUS=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_CA0110=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_GENERIC=y +# CONFIG_SND_HDA_POWER_SAVE is not set CONFIG_SND_HDSP=m CONFIG_SND_HDSPM=m +# CONFIG_SND_HIFIER is not set CONFIG_SND_ICE1712=m CONFIG_SND_ICE1724=m CONFIG_SND_INTEL8X0=m CONFIG_SND_INTEL8X0M=m CONFIG_SND_KORG1212=m -CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +# CONFIG_SND_LX6464ES is not set CONFIG_SND_MAESTRO3=m -CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y CONFIG_SND_MIXART=m CONFIG_SND_NM256=m CONFIG_SND_PCXHR=m @@ -2403,55 +1798,30 @@ CONFIG_SND_SONICVIBES=m CONFIG_SND_TRIDENT=m CONFIG_SND_VIA82XX=m CONFIG_SND_VIA82XX_MODEM=m +# CONFIG_SND_VIRTUOSO is not set CONFIG_SND_VX222=m CONFIG_SND_YMFPCI=m -CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y -# CONFIG_SND_AC97_POWER_SAVE is not set - -# -# ALSA MIPS devices -# +CONFIG_SND_MIPS=y # CONFIG_SND_AU1X00 is not set - -# -# USB devices -# +CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set # CONFIG_SND_USB_CAIAQ is not set - -# -# PCMCIA devices -# +CONFIG_SND_PCMCIA=y CONFIG_SND_VXPOCKET=m CONFIG_SND_PDAUDIOCF=m - -# -# System on Chip audio support -# # CONFIG_SND_SOC is not set - -# -# SoC Audio support for SuperH -# - -# -# Open Sound System -# CONFIG_SOUND_PRIME=m -CONFIG_SOUND_TRIDENT=m -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set # # USB Input Devices # CONFIG_USB_HID=m -CONFIG_USB_HIDINPUT_POWERBOOK=y -# CONFIG_HID_FF is not set +# CONFIG_HID_PID is not set CONFIG_USB_HIDDEV=y # @@ -2459,12 +1829,50 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_KBD=m CONFIG_USB_MOUSE=m + +# +# Special HID drivers +# +# CONFIG_HID_3M_PCT is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MOSART is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_STANTUM is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_ZEROPLUS is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=m # CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # # Miscellaneous USB options @@ -2472,19 +1880,27 @@ CONFIG_USB=m CONFIG_USB_DEVICEFS=y CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set -CONFIG_USB_SUSPEND=y -# CONFIG_USB_PERSIST is not set # CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=m +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers # +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set CONFIG_USB_EHCI_HCD=m -CONFIG_USB_EHCI_SPLIT_ISO=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y @@ -2493,32 +1909,38 @@ CONFIG_USB_U132_HCD=m CONFIG_USB_SL811_HCD=m CONFIG_USB_SL811_CS=m # CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set # # USB Device Class drivers # CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # -# may also be needed; see USB_STORAGE Help for more information +# also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_DPCM=y -CONFIG_USB_STORAGE_USBAT=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -CONFIG_USB_STORAGE_ALAUDA=y -CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_USB_STORAGE_KARMA=m +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set CONFIG_USB_LIBUSUAL=y # @@ -2526,25 +1948,20 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m -CONFIG_USB_MON=y # # USB port drivers # -CONFIG_USB_USS720=m - -# -# USB Serial Converter support -# CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_AIRCABLE=m -CONFIG_USB_SERIAL_AIRPRIME=m CONFIG_USB_SERIAL_ARK3116=m CONFIG_USB_SERIAL_BELKIN=m +# CONFIG_USB_SERIAL_CH341 is not set CONFIG_USB_SERIAL_WHITEHEAT=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -CONFIG_USB_SERIAL_CP2101=m +# CONFIG_USB_SERIAL_CP210X is not set CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m @@ -2556,6 +1973,7 @@ CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_GARMIN=m CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IUU is not set CONFIG_USB_SERIAL_KEYSPAN_PDA=m CONFIG_USB_SERIAL_KEYSPAN=m # CONFIG_USB_SERIAL_KEYSPAN_MPR is not set @@ -2575,20 +1993,27 @@ CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_SERIAL_MOS7720=m CONFIG_USB_SERIAL_MOS7840=m +# CONFIG_USB_SERIAL_MOTOROLA is not set CONFIG_USB_SERIAL_NAVMAN=m CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set CONFIG_USB_SERIAL_HP4X=m CONFIG_USB_SERIAL_SAFE=m # CONFIG_USB_SERIAL_SAFE_PADDED is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_SYMBOL is not set CONFIG_USB_SERIAL_TI=m CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OPTION=m CONFIG_USB_SERIAL_OMNINET=m +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set # CONFIG_USB_SERIAL_DEBUG is not set -CONFIG_USB_EZUSB=y # # USB Miscellaneous drivers @@ -2596,18 +2021,13 @@ CONFIG_USB_EZUSB=y CONFIG_USB_EMI62=m CONFIG_USB_EMI26=m CONFIG_USB_ADUTUX=m -CONFIG_USB_AUERSWALD=m +# CONFIG_USB_SEVSEG is not set CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m -# CONFIG_USB_BERRY_CHARGE is not set CONFIG_USB_LED=m CONFIG_USB_CYPRESS_CY7C63=m CONFIG_USB_CYTHERM=m -CONFIG_USB_PHIDGET=m -CONFIG_USB_PHIDGETKIT=m -CONFIG_USB_PHIDGETMOTORCONTROL=m -CONFIG_USB_PHIDGETSERVO=m CONFIG_USB_IDMOUSE=m CONFIG_USB_FTDI_ELAN=m CONFIG_USB_APPLEDISPLAY=m @@ -2617,86 +2037,113 @@ CONFIG_USB_LD=m CONFIG_USB_TRANCEVIBRATOR=m # CONFIG_USB_IOWARRIOR is not set CONFIG_USB_TEST=m - -# -# USB DSL modem support -# +# CONFIG_USB_ISIGHTFW is not set CONFIG_USB_ATM=m CONFIG_USB_SPEEDTOUCH=m CONFIG_USB_CXACRU=m CONFIG_USB_UEAGLEATM=m CONFIG_USB_XUSBATM=m - -# -# USB Gadget Support -# CONFIG_USB_GADGET=m # CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set # CONFIG_USB_GADGET_FSL_USB2 is not set -CONFIG_USB_GADGET_NET2280=y -CONFIG_USB_NET2280=m -# CONFIG_USB_GADGET_PXA2XX is not set -# CONFIG_USB_GADGET_M66592 is not set -# CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set # CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +CONFIG_USB_GADGET_NET2280=y +CONFIG_USB_NET2280=m +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=m CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_MASS_STORAGE is not set CONFIG_USB_G_SERIAL=m CONFIG_USB_MIDI_GADGET=m +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set CONFIG_MMC=m # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set # -# MMC/SD Card Drivers +# MMC/SD/SDIO Card Drivers # CONFIG_MMC_BLOCK=m CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set # -# MMC/SD Host Controller Drivers +# MMC/SD/SDIO Host Controller Drivers # CONFIG_MMC_SDHCI=m +# CONFIG_MMC_SDHCI_PCI is not set +# CONFIG_MMC_SDHCI_PLTFM is not set CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_SDRICOH_CS is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=m +CONFIG_LEDS_CLASS=y # # LED drivers # +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y # # LED Triggers # -# CONFIG_LEDS_TRIGGERS is not set -CONFIG_INFINIBAND=m -CONFIG_INFINIBAND_USER_MAD=m -CONFIG_INFINIBAND_USER_ACCESS=m -CONFIG_INFINIBAND_USER_MEM=y -CONFIG_INFINIBAND_ADDR_TRANS=y -CONFIG_INFINIBAND_MTHCA=m -CONFIG_INFINIBAND_MTHCA_DEBUG=y -CONFIG_INFINIBAND_AMSO1100=m -CONFIG_INFINIBAND_AMSO1100_DEBUG=y -# CONFIG_MLX4_INFINIBAND is not set -CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_CM is not set -CONFIG_INFINIBAND_IPOIB_DEBUG=y -# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set -CONFIG_INFINIBAND_SRP=m -CONFIG_INFINIBAND_ISER=m -CONFIG_RTC_LIB=m +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=m # @@ -2712,6 +2159,7 @@ CONFIG_RTC_DRV_TEST=m # I2C RTC drivers # CONFIG_RTC_DRV_DS1307=m +# CONFIG_RTC_DRV_DS1374 is not set CONFIG_RTC_DRV_DS1672=m # CONFIG_RTC_DRV_MAX6900 is not set CONFIG_RTC_DRV_RS5C372=m @@ -2720,48 +2168,45 @@ CONFIG_RTC_DRV_X1205=m CONFIG_RTC_DRV_PCF8563=m CONFIG_RTC_DRV_PCF8583=m # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers # -CONFIG_RTC_DRV_RS5C348=m -CONFIG_RTC_DRV_MAX6902=m # # Platform RTC drivers # # CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set CONFIG_RTC_DRV_DS1553=m -# CONFIG_RTC_DRV_STK17TA8 is not set CONFIG_RTC_DRV_DS1742=m +# CONFIG_RTC_DRV_STK17TA8 is not set CONFIG_RTC_DRV_M48T86=m +# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set CONFIG_RTC_DRV_V3020=m # # on-CPU RTC drivers # - -# -# DMA Engine support -# -CONFIG_DMA_ENGINE=y - -# -# DMA Clients -# -CONFIG_NET_DMA=y - -# -# DMA Devices -# -CONFIG_INTEL_IOATDMA=m +# CONFIG_RTC_DRV_AU1XXX is not set +# CONFIG_DMADEVICES is not set # CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set # -# Userspace I/O +# TI VLYNQ # -# CONFIG_UIO is not set +# CONFIG_STAGING is not set # # File systems @@ -2772,44 +2217,43 @@ CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=m +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT4_FS is not set CONFIG_JBD=m # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=m -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_POSIX_ACL=y -CONFIG_REISERFS_FS_SECURITY=y -CONFIG_JFS_FS=m -CONFIG_JFS_POSIX_ACL=y -CONFIG_JFS_SECURITY=y -# CONFIG_JFS_DEBUG is not set -CONFIG_JFS_STATISTICS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y -CONFIG_XFS_FS=m -CONFIG_XFS_QUOTA=y -CONFIG_XFS_SECURITY=y -CONFIG_XFS_POSIX_ACL=y -CONFIG_XFS_RT=y +# CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -CONFIG_MINIX_FS=m -CONFIG_ROMFS_FS=m +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y -CONFIG_QFMT_V1=m -CONFIG_QFMT_V2=m +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QUOTA_DEBUG is not set +# CONFIG_QFMT_V1 is not set +# CONFIG_QFMT_V2 is not set CONFIG_QUOTACTL=y -CONFIG_DNOTIFY=y -CONFIG_AUTOFS_FS=m -CONFIG_AUTOFS4_FS=m +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set # # CD-ROM/DVD Filesystems @@ -2838,73 +2282,79 @@ CONFIG_NTFS_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y CONFIG_CONFIGFS_FS=m - -# -# Miscellaneous filesystems -# -CONFIG_ADFS_FS=m -# CONFIG_ADFS_FS_RW is not set -CONFIG_AFFS_FS=m -CONFIG_ECRYPT_FS=m -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_JFFS2_FS=m +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y -CONFIG_VXFS_FS=m -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_UFS_DEBUG is not set - -# -# Network File Systems -# +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -CONFIG_NFS_DIRECTIO=y +# CONFIG_NFS_V4_1 is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set CONFIG_NFSD_V4=y -CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m -# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=m CONFIG_RPCSEC_GSS_SPKM3=m CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CEPH_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set # CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set # CONFIG_CIFS_XATTR is not set # CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set # CONFIG_CIFS_EXPERIMENTAL is not set CONFIG_NCP_FS=m CONFIG_NCPFS_PACKET_SIGNING=y @@ -2916,7 +2366,6 @@ CONFIG_NCPFS_OS2_NS=y CONFIG_NCPFS_NLS=y CONFIG_NCPFS_EXTRAS=y CONFIG_CODA_FS=m -# CONFIG_CODA_FS_OLD_API is not set CONFIG_AFS_FS=m # CONFIG_AFS_DEBUG is not set @@ -2948,10 +2397,6 @@ CONFIG_SUN_PARTITION=y CONFIG_KARMA_PARTITION=y CONFIG_EFI_PARTITION=y # CONFIG_SYSV68_PARTITION is not set - -# -# Native Language Support -# CONFIG_NLS=y CONFIG_NLS_DEFAULT="cp437" CONFIG_NLS_CODEPAGE_437=m @@ -2992,118 +2437,179 @@ CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m CONFIG_NLS_UTF8=m - -# -# Distributed Lock Manager -# -CONFIG_DLM=m -# CONFIG_DLM_DEBUG is not set - -# -# Profiling support -# -CONFIG_PROFILING=y -CONFIG_OPROFILE=m +# CONFIG_DLM is not set # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y # CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_MEMORY_INIT is not set +CONFIG_RCU_CPU_STALL_DETECTOR=y +# CONFIG_LKDTM is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_RING_BUFFER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_EARLY_PRINTK=y # CONFIG_CMDLINE_BOOL is not set +# CONFIG_SPINLOCK_TEST is not set # # Security options # CONFIG_KEYS=y # CONFIG_KEYS_DEBUG_PROC_KEYS is not set -CONFIG_SECURITY=y -CONFIG_SECURITY_NETWORK=y -# CONFIG_SECURITY_NETWORK_XFRM is not set -CONFIG_SECURITY_CAPABILITIES=m -CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SELINUX=y -CONFIG_SECURITY_SELINUX_BOOTPARAM=y -CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 -CONFIG_SECURITY_SELINUX_DISABLE=y -CONFIG_SECURITY_SELINUX_DEVELOP=y -CONFIG_SECURITY_SELINUX_AVC_STATS=y -CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 -# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set -# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set -CONFIG_XOR_BLOCKS=m -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_MEMCPY=m -CONFIG_ASYNC_XOR=m +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set -CONFIG_CRYPTO_NULL=m +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_GHASH is not set CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_DES=m -# CONFIG_CRYPTO_FCRYPT is not set -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +# CONFIG_CRYPTO_CAMELLIA is not set CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -# CONFIG_CRYPTO_CAMELLIA is not set -CONFIG_CRYPTO_TEST=m +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m CONFIG_AUDIT_GENERIC=y CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m -CONFIG_REED_SOLOMON=m -CONFIG_REED_SOLOMON_DEC16=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m -CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -CONFIG_CHECK_SIGNATURE=y +CONFIG_NLATTR=y -- cgit v1.2.3-59-g8ed1b From 3e1bf29f73ccb31b99215476b0278f477db1a247 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 4 May 2010 10:38:57 +0200 Subject: MIPS: BCM63xx: Avoid namespace clash on GPIO_DIR_{IN,OUT} This is too generic a name, so prefix it with BCM63XX_ to avoid potential namespace clashes when including . Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1171/ Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/gpio.c | 6 +++--- arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c index 315bc7f79ce1..f560fe7d38dd 100644 --- a/arch/mips/bcm63xx/gpio.c +++ b/arch/mips/bcm63xx/gpio.c @@ -91,7 +91,7 @@ static int bcm63xx_gpio_set_direction(struct gpio_chip *chip, spin_lock_irqsave(&bcm63xx_gpio_lock, flags); tmp = bcm_gpio_readl(reg); - if (dir == GPIO_DIR_IN) + if (dir == BCM63XX_GPIO_DIR_IN) tmp &= ~mask; else tmp |= mask; @@ -103,14 +103,14 @@ static int bcm63xx_gpio_set_direction(struct gpio_chip *chip, static int bcm63xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) { - return bcm63xx_gpio_set_direction(chip, gpio, GPIO_DIR_IN); + return bcm63xx_gpio_set_direction(chip, gpio, BCM63XX_GPIO_DIR_IN); } static int bcm63xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) { bcm63xx_gpio_set(chip, gpio, value); - return bcm63xx_gpio_set_direction(chip, gpio, GPIO_DIR_OUT); + return bcm63xx_gpio_set_direction(chip, gpio, BCM63XX_GPIO_DIR_OUT); } diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h index 43d4da0b1e9f..3999ec0aa7f5 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h @@ -20,7 +20,7 @@ static inline unsigned long bcm63xx_gpio_count(void) } } -#define GPIO_DIR_OUT 0x0 -#define GPIO_DIR_IN 0x1 +#define BCM63XX_GPIO_DIR_OUT 0x0 +#define BCM63XX_GPIO_DIR_IN 0x1 #endif /* !BCM63XX_GPIO_H */ -- cgit v1.2.3-59-g8ed1b From 9c1b013a3951671e219c32ca056fc07381a9e113 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 11 May 2010 11:20:09 +0200 Subject: MIPS: AR7: use ar7_has_high_vlynq() to determine watchdog base address Instead of doing yet another switch/case on the chip_id, use existing inline function to set the watchdog base address. Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1211/ Signed-off-by: Ralf Baechle --- arch/mips/ar7/platform.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 2fafc78e5ce1..1d4a466ccb6f 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -576,7 +576,6 @@ static int __init ar7_register_devices(void) { void __iomem *bootcr; u32 val; - u16 chip_id; int res; res = ar7_register_uarts(); @@ -635,18 +634,10 @@ static int __init ar7_register_devices(void) val = readl(bootcr); iounmap(bootcr); if (val & AR7_WDT_HW_ENA) { - chip_id = ar7_chip_id(); - switch (chip_id) { - case AR7_CHIP_7100: - case AR7_CHIP_7200: - ar7_wdt_res.start = AR7_REGS_WDT; - break; - case AR7_CHIP_7300: + if (ar7_has_high_vlynq()) ar7_wdt_res.start = UR8_REGS_WDT; - break; - default: - break; - } + else + ar7_wdt_res.start = AR7_REGS_WDT; ar7_wdt_res.end = ar7_wdt_res.start + 0x20; res = platform_device_register(&ar7_wdt); -- cgit v1.2.3-59-g8ed1b From 142a2ceea793b4d134757c226daeb4101d649df0 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 11 May 2010 11:20:14 +0200 Subject: MIPS: AR7: prevent race between clock initialization and devices registration ar7_regiser_devices needs ar7_clocks_init to have been called first, however clock.o is currently linked later due to its order in the Makefile, therefore ar7_clocks_init always gets called later than ar7_register_devices because both have the same initcall level. Fix this by moving ar7_register_devices to the right initcall level. Reported-by: Michael J. Evans Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Cc: Ralf Baechle Patchwork: http://patchwork.linux-mips.org/patch/1212/ Signed-off-by: Ralf Baechle --- arch/mips/ar7/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 1d4a466ccb6f..566f2d7f2ea3 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -647,4 +647,4 @@ static int __init ar7_register_devices(void) return 0; } -arch_initcall(ar7_register_devices); +device_initcall(ar7_register_devices); -- cgit v1.2.3-59-g8ed1b From 1dd5216e80318b4cb25c1785f5d11a6f042f0a3b Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 19 May 2010 14:16:31 -0700 Subject: MIPS: Octeon: Get rid of early serial. Get rid of early_serial_setup, we use CONFIG_EARLY_PRINTK instead. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1254/ Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/setup.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'arch') diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 9a06fa9f9f0c..44cb20cd3bdc 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -403,7 +403,6 @@ void __init prom_init(void) const int coreid = cvmx_get_core_num(); int i; int argc; - struct uart_port octeon_port; #ifdef CONFIG_CAVIUM_RESERVE32 int64_t addr = -1; #endif @@ -610,30 +609,6 @@ void __init prom_init(void) _machine_restart = octeon_restart; _machine_halt = octeon_halt; - memset(&octeon_port, 0, sizeof(octeon_port)); - /* - * For early_serial_setup we don't set the port type or - * UPF_FIXED_TYPE. - */ - octeon_port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ; - octeon_port.iotype = UPIO_MEM; - /* I/O addresses are every 8 bytes */ - octeon_port.regshift = 3; - /* Clock rate of the chip */ - octeon_port.uartclk = mips_hpt_frequency; - octeon_port.fifosize = 64; - octeon_port.mapbase = 0x0001180000000800ull + (1024 * octeon_uart); - octeon_port.membase = cvmx_phys_to_ptr(octeon_port.mapbase); - octeon_port.serial_in = octeon_serial_in; - octeon_port.serial_out = octeon_serial_out; -#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL - octeon_port.line = 0; -#else - octeon_port.line = octeon_uart; -#endif - octeon_port.irq = 42 + octeon_uart; - early_serial_setup(&octeon_port); - octeon_user_io_init(); register_smp_ops(&octeon_smp_ops); } -- cgit v1.2.3-59-g8ed1b From 606c958e2857d29106b8d3b2fc30e22f376c80c5 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 19 May 2010 14:16:32 -0700 Subject: MIPS: Octeon: Serial port fixes for OCTEON simulator. For the simulator, fake a slow clock to get fast output. In prom_putchar we have to mask the value so the simulator doesn't ASSERT when printing non-ASCII characters. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1255/ Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/serial.c | 6 +++++- arch/mips/cavium-octeon/setup.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c index 8240728d485a..83eac37a1ff9 100644 --- a/arch/mips/cavium-octeon/serial.c +++ b/arch/mips/cavium-octeon/serial.c @@ -65,7 +65,11 @@ static void __init octeon_uart_set_common(struct plat_serial8250_port *p) p->type = PORT_OCTEON; p->iotype = UPIO_MEM; p->regshift = 3; /* I/O addresses are every 8 bytes */ - p->uartclk = mips_hpt_frequency; + if (octeon_is_simulation()) + /* Make simulator output fast*/ + p->uartclk = 115200 * 16; + else + p->uartclk = mips_hpt_frequency; p->serial_in = octeon_serial_in; p->serial_out = octeon_serial_out; } diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 44cb20cd3bdc..d1b5ffaf0281 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -702,7 +702,7 @@ int prom_putchar(char c) } while ((lsrval & 0x20) == 0); /* Write the byte */ - cvmx_write_csr(CVMX_MIO_UARTX_THR(octeon_uart), c); + cvmx_write_csr(CVMX_MIO_UARTX_THR(octeon_uart), c & 0xffull); return 1; } -- cgit v1.2.3-59-g8ed1b From 0453fb3c528c5eb3483441a466b24a4cb409eec5 Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 14 May 2010 12:44:18 -0700 Subject: MIPS: Use GCC __builtin_prefetch() to implement prefetch(). GCC's __builtin_prefetch() was introduced a long time ago, all supported GCC versions have it. Lets do what the big boys up in linux/prefetch.h do, except we use '1' as the third parameter to provoke 'PREF 0,...' and 'PREF 1,...' instead of other prefetch hints. This allows for better code generation. In theory the existing embedded asm could be optimized, but the compiler has these builtins, so there is really no point. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1235/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/processor.h | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index ab387910009a..5d33b727acf5 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -344,16 +344,10 @@ unsigned long get_wchan(struct task_struct *p); #ifdef CONFIG_CPU_HAS_PREFETCH #define ARCH_HAS_PREFETCH +#define prefetch(x) __builtin_prefetch((x), 0, 1) -static inline void prefetch(const void *addr) -{ - __asm__ __volatile__( - " .set mips4 \n" - " pref %0, (%1) \n" - " .set mips0 \n" - : - : "i" (Pref_Load), "r" (addr)); -} +#define ARCH_HAS_PREFETCHW +#define prefetchw(x) __builtin_prefetch((x), 1, 1) #endif -- cgit v1.2.3-59-g8ed1b From 3f6ea84a3035cc0ef7488f8e93bc76766799e082 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Thu, 1 Apr 2010 11:43:30 -0700 Subject: PCI: read memory ranges out of Broadcom CNB20LE host bridge Read the memory ranges behind the Broadcom CNB20LE host bridge out of the hardware. This allows PCI hotplugging to work, since we know which memory range to allocate PCI BAR's from. The x86 PCI code automatically prefers the ACPI _CRS information when it is available. In that case, this information is not used. Signed-off-by: Ira W. Snyder Signed-off-by: Jesse Barnes --- arch/x86/Kconfig | 8 ++++ arch/x86/pci/Makefile | 2 + arch/x86/pci/broadcom_bus.c | 101 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 arch/x86/pci/broadcom_bus.c (limited to 'arch') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 9458685902bd..677b87d60a36 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1931,6 +1931,14 @@ config PCI_MMCONFIG bool "Support mmconfig PCI config space access" depends on X86_64 && PCI && ACPI +config PCI_CNB20LE_QUIRK + bool "Read CNB20LE Host Bridge Windows" + depends on PCI + help + Read the PCI windows out of the CNB20LE host bridge. This allows + PCI hotplug to work on systems with the CNB20LE chipset which do + not have ACPI. + config DMAR bool "Support for DMA Remapping Devices (EXPERIMENTAL)" depends on PCI_MSI && ACPI && EXPERIMENTAL diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index b110d97fb925..a0207a7fdf39 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -18,6 +18,8 @@ obj-$(CONFIG_X86_MRST) += mrst.o obj-y += common.o early.o obj-y += amd_bus.o bus_numa.o +obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o + ifeq ($(CONFIG_PCI_DEBUG),y) EXTRA_CFLAGS += -DDEBUG endif diff --git a/arch/x86/pci/broadcom_bus.c b/arch/x86/pci/broadcom_bus.c new file mode 100644 index 000000000000..0846a5bbbfbd --- /dev/null +++ b/arch/x86/pci/broadcom_bus.c @@ -0,0 +1,101 @@ +/* + * Read address ranges from a Broadcom CNB20LE Host Bridge + * + * Copyright (c) 2010 Ira W. Snyder + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include "bus_numa.h" + +static void __devinit cnb20le_res(struct pci_dev *dev) +{ + struct pci_root_info *info; + struct resource res; + u16 word1, word2; + u8 fbus, lbus; + int i; + + /* + * The x86_pci_root_bus_res_quirks() function already refuses to use + * this information if ACPI _CRS was used. Therefore, we don't bother + * checking if ACPI is enabled, and just generate the information + * for both the ACPI _CRS and no ACPI cases. + */ + + info = &pci_root_info[pci_root_num]; + pci_root_num++; + + /* read the PCI bus numbers */ + pci_read_config_byte(dev, 0x44, &fbus); + pci_read_config_byte(dev, 0x45, &lbus); + info->bus_min = fbus; + info->bus_max = lbus; + + /* + * Add the legacy IDE ports on bus 0 + * + * These do not exist anywhere in the bridge registers, AFAICT. I do + * not have the datasheet, so this is the best I can do. + */ + if (fbus == 0) { + update_res(info, 0x01f0, 0x01f7, IORESOURCE_IO, 0); + update_res(info, 0x03f6, 0x03f6, IORESOURCE_IO, 0); + update_res(info, 0x0170, 0x0177, IORESOURCE_IO, 0); + update_res(info, 0x0376, 0x0376, IORESOURCE_IO, 0); + update_res(info, 0xffa0, 0xffaf, IORESOURCE_IO, 0); + } + + /* read the non-prefetchable memory window */ + pci_read_config_word(dev, 0xc0, &word1); + pci_read_config_word(dev, 0xc2, &word2); + if (word1 != word2) { + res.start = (word1 << 16) | 0x0000; + res.end = (word2 << 16) | 0xffff; + res.flags = IORESOURCE_MEM; + update_res(info, res.start, res.end, res.flags, 0); + } + + /* read the prefetchable memory window */ + pci_read_config_word(dev, 0xc4, &word1); + pci_read_config_word(dev, 0xc6, &word2); + if (word1 != word2) { + res.start = (word1 << 16) | 0x0000; + res.end = (word2 << 16) | 0xffff; + res.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; + update_res(info, res.start, res.end, res.flags, 0); + } + + /* read the IO port window */ + pci_read_config_word(dev, 0xd0, &word1); + pci_read_config_word(dev, 0xd2, &word2); + if (word1 != word2) { + res.start = word1; + res.end = word2; + res.flags = IORESOURCE_IO; + update_res(info, res.start, res.end, res.flags, 0); + } + + /* print information about this host bridge */ + res.start = fbus; + res.end = lbus; + res.flags = IORESOURCE_BUS; + dev_info(&dev->dev, "CNB20LE PCI Host Bridge (domain %04x %pR)\n", + pci_domain_nr(dev->bus), &res); + + for (i = 0; i < info->res_num; i++) + dev_info(&dev->dev, "host bridge window %pR\n", &info->res[i]); +} + +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE, + cnb20le_res); + -- cgit v1.2.3-59-g8ed1b From 4f0447b8184acb1d21b0fd71683d72ef2b83167b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 21 May 2010 11:19:18 -0400 Subject: get rid of home-grown mutex in cris eeprom.c Signed-off-by: Al Viro --- arch/cris/arch-v10/drivers/eeprom.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index 1f2ae909d3e6..b04b22ba00d1 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c @@ -73,8 +73,7 @@ struct eeprom_type int adapt_state; /* 1 = To high , 0 = Even, -1 = To low */ /* this one is to keep the read/write operations atomic */ - wait_queue_head_t wait_q; - volatile int busy; + struct mutex lock; int retry_cnt_addr; /* Used to keep track of number of retries for adaptive timing adjustments */ int retry_cnt_read; @@ -115,8 +114,7 @@ const struct file_operations eeprom_fops = int __init eeprom_init(void) { - init_waitqueue_head(&eeprom.wait_q); - eeprom.busy = 0; + mutex_init(&eeprom.lock); #ifdef CONFIG_ETRAX_I2C_EEPROM_PROBE #define EETEXT "Found" @@ -461,12 +459,9 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t return -EFAULT; } - wait_event_interruptible(eeprom.wait_q, !eeprom.busy); - if (signal_pending(current)) + if (mutex_lock_interruptible(&eeprom.lock)) return -EINTR; - eeprom.busy++; - page = (unsigned char) (p >> 8); if(!eeprom_address(p)) @@ -476,8 +471,7 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t i2c_stop(); /* don't forget to wake them up */ - eeprom.busy--; - wake_up_interruptible(&eeprom.wait_q); + mutex_unlock(&eeprom.lock); return -EFAULT; } @@ -504,8 +498,7 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t file->f_pos += read; } - eeprom.busy--; - wake_up_interruptible(&eeprom.wait_q); + mutex_unlock(&eeprom.lock); return read; } @@ -534,11 +527,9 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, return -EFAULT; } - wait_event_interruptible(eeprom.wait_q, !eeprom.busy); /* bail out if we get interrupted */ - if (signal_pending(current)) + if (mutex_lock_interruptible(&eeprom.lock)) return -EINTR; - eeprom.busy++; for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++) { restart = 0; @@ -556,8 +547,7 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, i2c_stop(); /* don't forget to wake them up */ - eeprom.busy--; - wake_up_interruptible(&eeprom.wait_q); + mutex_unlock(&eeprom.lock); return -EFAULT; } #ifdef EEPROM_ADAPTIVE_TIMING @@ -669,8 +659,7 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, } /* while */ } /* for */ - eeprom.busy--; - wake_up_interruptible(&eeprom.wait_q); + mutex_unlock(&eeprom.lock); if (written == 0 && file->f_pos >= eeprom.size){ return -ENOSPC; } -- cgit v1.2.3-59-g8ed1b From 82f3952c02add60b15eea9151d4d99b6b82066c6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 21 May 2010 11:26:35 -0400 Subject: fix handling of offsets in cris eeprom.c, get rid of fake on-stack files Signed-off-by: Al Viro --- arch/cris/arch-v10/drivers/eeprom.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index b04b22ba00d1..c3405507a3d1 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c @@ -437,10 +437,7 @@ static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig) static int eeprom_read_buf(loff_t addr, char * buf, int count) { - struct file f; - - f.f_pos = addr; - return eeprom_read(&f, buf, count, &addr); + return eeprom_read(NULL, buf, count, &addr); } @@ -450,7 +447,7 @@ static int eeprom_read_buf(loff_t addr, char * buf, int count) static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off) { int read=0; - unsigned long p = file->f_pos; + unsigned long p = *off; unsigned char page; @@ -495,7 +492,7 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t if(read > 0) { - file->f_pos += read; + *off += read; } mutex_unlock(&eeprom.lock); @@ -506,11 +503,7 @@ static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t static int eeprom_write_buf(loff_t addr, const char * buf, int count) { - struct file f; - - f.f_pos = addr; - - return eeprom_write(&f, buf, count, &addr); + return eeprom_write(NULL, buf, count, &addr); } @@ -534,7 +527,7 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, { restart = 0; written = 0; - p = file->f_pos; + p = *off; while( (written < count) && (p < eeprom.size)) @@ -660,10 +653,10 @@ static ssize_t eeprom_write(struct file * file, const char * buf, size_t count, } /* for */ mutex_unlock(&eeprom.lock); - if (written == 0 && file->f_pos >= eeprom.size){ + if (written == 0 && p >= eeprom.size){ return -ENOSPC; } - file->f_pos += written; + *off = p; return written; } -- cgit v1.2.3-59-g8ed1b From cb6dc512b745292eaf123fedf437c211e27fb680 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:59 -0700 Subject: arch/powerpc: Move dma_mask from of_device into pdev_archdata By moving dma_mask into pdev_archdata, and adding archdata to struct of_device, it makes it possible to substitute of_device with struct platform_device, which is a stepping stone to removing the of_platform bus entirely. Signed-off-by: Grant Likely --- arch/powerpc/include/asm/device.h | 1 + arch/powerpc/include/asm/of_device.h | 2 +- arch/powerpc/kernel/of_device.c | 2 +- arch/powerpc/kernel/of_platform.c | 2 +- drivers/macintosh/macio_asic.c | 4 ++-- sound/aoa/soundbus/i2sbus/core.c | 4 ++-- 6 files changed, 8 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index f23f8d8bd68d..a3954e4fcbe2 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -28,6 +28,7 @@ struct dev_archdata { }; struct pdev_archdata { + u64 dma_mask; }; #endif /* _ASM_POWERPC_DEVICE_H */ diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h index 8b26f96b9f9e..444e97e2982e 100644 --- a/arch/powerpc/include/asm/of_device.h +++ b/arch/powerpc/include/asm/of_device.h @@ -12,8 +12,8 @@ */ struct of_device { - u64 dma_mask; /* DMA mask */ struct device dev; /* Generic device interface */ + struct pdev_archdata archdata; }; extern struct of_device *of_device_alloc(struct device_node *np, diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 20b3474b6f6b..df78e0236a02 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -70,7 +70,7 @@ struct of_device *of_device_alloc(struct device_node *np, return NULL; dev->dev.of_node = of_node_get(np); - dev->dev.dma_mask = &dev->dma_mask; + dev->dev.dma_mask = &dev->archdata.dma_mask; dev->dev.parent = parent; dev->dev.release = of_release_dev; diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 1c747c474415..218853466510 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -74,7 +74,7 @@ struct of_device* of_platform_device_create(struct device_node *np, if (!dev) return NULL; - dev->dma_mask = 0xffffffffUL; + dev->archdata.dma_mask = 0xffffffffUL; dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); dev->dev.bus = &of_platform_bus_type; diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 67fe13ffe90b..48a5f0406865 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -374,8 +374,8 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, dev->bus = &chip->lbus; dev->media_bay = in_bay; dev->ofdev.dev.of_node = np; - dev->ofdev.dma_mask = 0xffffffffUL; - dev->ofdev.dev.dma_mask = &dev->ofdev.dma_mask; + dev->ofdev.archdata.dma_mask = 0xffffffffUL; + dev->ofdev.dev.dma_mask = &dev->ofdev.archdata.dma_mask; dev->ofdev.dev.parent = parent; dev->ofdev.dev.bus = &macio_bus_type; dev->ofdev.dev.release = macio_release_dev; diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 7672b4d145ae..678933721735 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c @@ -221,9 +221,9 @@ static int i2sbus_add_dev(struct macio_dev *macio, mutex_init(&dev->lock); spin_lock_init(&dev->low_lock); - dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask; + dev->sound.ofdev.archdata.dma_mask = macio->ofdev.archdata.dma_mask; dev->sound.ofdev.dev.of_node = np; - dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask; + dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.archdata.dma_mask; dev->sound.ofdev.dev.parent = &macio->ofdev.dev; dev->sound.ofdev.dev.release = i2sbus_release_dev; dev->sound.attach_codec = i2sbus_attach_codec; -- cgit v1.2.3-59-g8ed1b From 173b3a7a059a6998a6c0733710818c473cc0de4c Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:13:00 -0700 Subject: arch/microblaze: Move dma_mask from of_device into pdev_archdata By moving dma_mask into pdev_archdata, and adding archdata to struct of_device, it makes it possible to substitute of_device with struct platform_device, which is a stepping stone to removing the of_platform bus entirely. Signed-off-by: Grant Likely --- arch/microblaze/include/asm/device.h | 1 + arch/microblaze/include/asm/of_device.h | 2 +- arch/microblaze/kernel/of_device.c | 2 +- arch/microblaze/kernel/of_platform.c | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h index 15b0058aa7ff..123b2fe72d01 100644 --- a/arch/microblaze/include/asm/device.h +++ b/arch/microblaze/include/asm/device.h @@ -18,6 +18,7 @@ struct dev_archdata { }; struct pdev_archdata { + u64 dma_mask; }; #endif /* _ASM_MICROBLAZE_DEVICE_H */ diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index ab25a40b481c..73cb98040982 100644 --- a/arch/microblaze/include/asm/of_device.h +++ b/arch/microblaze/include/asm/of_device.h @@ -21,8 +21,8 @@ * probed using OF properties. */ struct of_device { - u64 dma_mask; /* DMA mask */ struct device dev; /* Generic device interface */ + struct pdev_archdata archdata; }; extern ssize_t of_device_get_modalias(struct of_device *ofdev, diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index ac7e6e10d0ab..b372787886ed 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -50,7 +50,7 @@ struct of_device *of_device_alloc(struct device_node *np, return NULL; dev->dev.of_node = of_node_get(np); - dev->dev.dma_mask = &dev->dma_mask; + dev->dev.dma_mask = &dev->archdata.dma_mask; dev->dev.parent = parent; dev->dev.release = of_release_dev; diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index 46a1e105a6bd..ccf6f4257f4b 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -47,7 +47,7 @@ struct of_device *of_platform_device_create(struct device_node *np, if (!dev) return NULL; - dev->dma_mask = 0xffffffffUL; + dev->archdata.dma_mask = 0xffffffffUL; dev->dev.bus = &of_platform_bus_type; /* We do not fill the DMA ops for platform devices by default. -- cgit v1.2.3-59-g8ed1b From 597b9d1e44e9ba69f2454a5318bbe7a6d5e6930a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:13:01 -0700 Subject: drivercore: Add of_match_table to the common device drivers OF-style matching can be available to any device, on any type of bus. This patch allows any driver to provide an OF match table when CONFIG_OF is enabled so that drivers can be bound against devices described in the device tree. Signed-off-by: Grant Likely Acked-by: Greg Kroah-Hartman --- arch/powerpc/kernel/ibmebus.c | 5 ++++- drivers/macintosh/macio_asic.c | 5 ++--- drivers/of/platform.c | 7 ++++--- include/linux/device.h | 4 ++++ 4 files changed, 14 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index a9f31631a293..355257bb149d 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -201,8 +201,11 @@ static int ibmebus_create_devices(const struct of_device_id *matches) int ibmebus_register_driver(struct of_platform_driver *drv) { + if (!drv->driver.of_match_table) + drv->driver.of_match_table = drv->match_table; + /* If the driver uses devices that ibmebus doesn't know, add them */ - ibmebus_create_devices(drv->match_table); + ibmebus_create_devices(drv->driver.of_match_table); return of_register_driver(drv, &ibmebus_bus_type); } diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 48a5f0406865..e3ba1d8001a3 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -40,8 +40,7 @@ static struct macio_chip *macio_on_hold; static int macio_bus_match(struct device *dev, struct device_driver *drv) { struct macio_dev * macio_dev = to_macio_device(dev); - struct macio_driver * macio_drv = to_macio_driver(drv); - const struct of_device_id * matches = macio_drv->match_table; + const struct of_device_id * matches = drv->of_match_table; if (!matches) return 0; @@ -84,7 +83,7 @@ static int macio_device_probe(struct device *dev) macio_dev_get(macio_dev); - match = of_match_device(drv->match_table, &macio_dev->ofdev); + match = of_match_device(drv->driver.of_match_table, &macio_dev->ofdev); if (match) error = drv->probe(macio_dev, match); if (error) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index d58ade170c4b..9fd7f7d0a0d1 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -22,8 +22,7 @@ extern struct device_attribute of_platform_device_attrs[]; static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { struct of_device *of_dev = to_of_device(dev); - struct of_platform_driver *of_drv = to_of_platform_driver(drv); - const struct of_device_id *matches = of_drv->match_table; + const struct of_device_id *matches = drv->of_match_table; if (!matches) return 0; @@ -46,7 +45,7 @@ static int of_platform_device_probe(struct device *dev) of_dev_get(of_dev); - match = of_match_device(drv->match_table, of_dev); + match = of_match_device(drv->driver.of_match_table, of_dev); if (match) error = drv->probe(of_dev, match); if (error) @@ -391,6 +390,8 @@ int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) drv->driver.name = drv->name; if (!drv->driver.owner) drv->driver.owner = drv->owner; + if (!drv->driver.of_match_table) + drv->driver.of_match_table = drv->match_table; drv->driver.bus = bus; /* register with core */ diff --git a/include/linux/device.h b/include/linux/device.h index 7a968bdb02e2..cd7534cc42ab 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -129,6 +129,10 @@ struct device_driver { bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ +#if defined(CONFIG_OF) + const struct of_device_id *of_match_table; +#endif + int (*probe) (struct device *dev); int (*remove) (struct device *dev); void (*shutdown) (struct device *dev); -- cgit v1.2.3-59-g8ed1b From 4018294b53d1dae026880e45f174c1cc63b5d435 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:13:02 -0700 Subject: of: Remove duplicate fields from of_platform_driver .name, .match_table and .owner are duplicated in both of_platform_driver and device_driver. This patch is a removes the extra copies from struct of_platform_driver and converts all users to the device_driver members. This patch is a pretty mechanical change. The usage model doesn't change and if any drivers have been missed, or if anything has been fixed up incorrectly, then it will fail with a compile time error, and the fixup will be trivial. This patch looks big and scary because it touches so many files, but it should be pretty safe. Signed-off-by: Grant Likely Acked-by: Sean MacLennan --- arch/powerpc/kernel/ibmebus.c | 3 --- arch/powerpc/kernel/of_platform.c | 3 ++- arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 14 +++++++++---- arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 7 +++++-- arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 8 ++++--- arch/powerpc/platforms/82xx/ep8248e.c | 3 ++- arch/powerpc/platforms/83xx/suspend.c | 7 +++++-- arch/powerpc/platforms/cell/axon_msi.c | 7 ++++--- arch/powerpc/platforms/pasemi/gpio_mdio.c | 7 ++++--- arch/powerpc/sysdev/axonram.c | 8 +++---- arch/powerpc/sysdev/bestcomm/bestcomm.c | 10 ++++----- arch/powerpc/sysdev/fsl_msi.c | 7 +++++-- arch/powerpc/sysdev/fsl_pmc.c | 7 +++++-- arch/powerpc/sysdev/fsl_rio.c | 7 +++++-- arch/powerpc/sysdev/pmi.c | 7 ++++--- arch/powerpc/sysdev/qe_lib/qe.c | 7 +++++-- arch/sparc/include/asm/parport.h | 7 +++++-- arch/sparc/kernel/apc.c | 7 +++++-- arch/sparc/kernel/auxio_64.c | 7 ++++--- arch/sparc/kernel/central.c | 14 +++++++------ arch/sparc/kernel/chmc.c | 7 +++++-- arch/sparc/kernel/pci_fire.c | 7 +++++-- arch/sparc/kernel/pci_psycho.c | 7 +++++-- arch/sparc/kernel/pci_sabre.c | 7 +++++-- arch/sparc/kernel/pci_schizo.c | 7 +++++-- arch/sparc/kernel/pci_sun4v.c | 7 +++++-- arch/sparc/kernel/pmc.c | 7 +++++-- arch/sparc/kernel/power.c | 7 ++++--- arch/sparc/kernel/time_32.c | 7 ++++--- arch/sparc/kernel/time_64.c | 21 +++++++++++-------- drivers/ata/pata_mpc52xx.c | 4 +--- drivers/ata/pata_of_platform.c | 7 +++++-- drivers/ata/sata_fsl.c | 7 +++++-- drivers/atm/fore200e.c | 7 +++++-- drivers/block/xsysace.c | 5 ++--- drivers/char/hw_random/n2-drv.c | 7 +++++-- drivers/char/hw_random/pasemi-rng.c | 7 +++++-- drivers/char/ipmi/ipmi_si_intf.c | 7 +++++-- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 5 ++--- drivers/crypto/amcc/crypto4xx_core.c | 7 +++++-- drivers/crypto/talitos.c | 7 +++++-- drivers/dma/fsldma.c | 11 ++++++---- drivers/dma/ppc4xx/adma.c | 2 +- drivers/edac/mpc85xx_edac.c | 30 +++++++++++---------------- drivers/edac/ppc4xx_edac.c | 10 ++++----- drivers/hwmon/ultra45_env.c | 7 +++++-- drivers/i2c/busses/i2c-cpm.c | 10 ++++----- drivers/i2c/busses/i2c-ibm_iic.c | 7 +++++-- drivers/i2c/busses/i2c-mpc.c | 8 +++---- drivers/infiniband/hw/ehca/ehca_main.c | 7 ++++--- drivers/input/misc/sparcspkr.c | 14 +++++++++---- drivers/input/serio/i8042-sparcio.h | 7 +++++-- drivers/input/serio/xilinx_ps2.c | 7 +++++-- drivers/leds/leds-gpio.c | 2 +- drivers/macintosh/smu.c | 7 +++++-- drivers/macintosh/therm_pm72.c | 7 +++++-- drivers/macintosh/therm_windtunnel.c | 7 +++++-- drivers/mmc/host/sdhci-of-core.c | 7 +++++-- drivers/mtd/maps/physmap_of.c | 7 +++++-- drivers/mtd/maps/sun_uflash.c | 7 +++++-- drivers/mtd/nand/fsl_elbc_nand.c | 5 +++-- drivers/mtd/nand/fsl_upm.c | 7 +++++-- drivers/mtd/nand/ndfc.c | 5 +++-- drivers/mtd/nand/pasemi_nand.c | 7 +++++-- drivers/mtd/nand/socrates_nand.c | 7 +++++-- drivers/net/can/mscan/mpc5xxx_can.c | 8 ++++--- drivers/net/can/sja1000/sja1000_of_platform.c | 8 ++++--- drivers/net/ehea/ehea_main.c | 7 +++++-- drivers/net/fec_mpc52xx.c | 8 ++++--- drivers/net/fec_mpc52xx_phy.c | 7 +++++-- drivers/net/fs_enet/fs_enet-main.c | 7 +++++-- drivers/net/fs_enet/mii-bitbang.c | 7 +++++-- drivers/net/fs_enet/mii-fec.c | 7 +++++-- drivers/net/fsl_pq_mdio.c | 7 +++++-- drivers/net/gianfar.c | 10 +++++---- drivers/net/ibm_newemac/core.c | 8 ++++--- drivers/net/ibm_newemac/mal.c | 8 ++++--- drivers/net/ibm_newemac/rgmii.c | 8 ++++--- drivers/net/ibm_newemac/tah.c | 8 ++++--- drivers/net/ibm_newemac/zmii.c | 8 ++++--- drivers/net/ll_temac_main.c | 2 +- drivers/net/myri_sbus.c | 7 +++++-- drivers/net/niu.c | 7 +++++-- drivers/net/phy/mdio-gpio.c | 7 +++++-- drivers/net/sunbmac.c | 7 +++++-- drivers/net/sunhme.c | 7 +++++-- drivers/net/sunlance.c | 7 +++++-- drivers/net/sunqe.c | 7 +++++-- drivers/net/ucc_geth.c | 7 +++++-- drivers/net/xilinx_emaclite.c | 7 +++++-- drivers/of/platform.c | 7 ------- drivers/parport/parport_sunbpp.c | 7 +++++-- drivers/pcmcia/electra_cf.c | 7 +++++-- drivers/pcmcia/m8xx_pcmcia.c | 7 +++++-- drivers/sbus/char/bbc_i2c.c | 7 +++++-- drivers/sbus/char/display7seg.c | 7 +++++-- drivers/sbus/char/envctrl.c | 7 +++++-- drivers/sbus/char/flash.c | 7 +++++-- drivers/sbus/char/uctrl.c | 7 +++++-- drivers/scsi/qlogicpti.c | 7 +++++-- drivers/scsi/sun_esp.c | 7 +++++-- drivers/serial/apbuart.c | 8 +++---- drivers/serial/cpm_uart/cpm_uart_core.c | 7 +++++-- drivers/serial/mpc52xx_uart.c | 7 ++++--- drivers/serial/of_serial.c | 8 ++++--- drivers/serial/sunhv.c | 7 +++++-- drivers/serial/sunsab.c | 7 +++++-- drivers/serial/sunsu.c | 7 +++++-- drivers/serial/sunzilog.c | 7 +++++-- drivers/serial/uartlite.c | 5 ++--- drivers/serial/ucc_uart.c | 8 ++++--- drivers/spi/mpc52xx_psc_spi.c | 4 +--- drivers/spi/mpc52xx_spi.c | 8 ++++--- drivers/spi/spi_mpc8xxx.c | 7 +++++-- drivers/spi/spi_ppc4xx.c | 2 +- drivers/spi/xilinx_spi_of.c | 2 +- drivers/usb/gadget/fsl_qe_udc.c | 7 +++++-- drivers/usb/host/ehci-ppc-of.c | 9 ++++---- drivers/usb/host/ehci-xilinx-of.c | 9 ++++---- drivers/usb/host/fhci-hcd.c | 7 +++++-- drivers/usb/host/isp1760-if.c | 7 +++++-- drivers/usb/host/ohci-ppc-of.c | 13 ++++-------- drivers/video/bw2.c | 7 +++++-- drivers/video/cg14.c | 7 +++++-- drivers/video/cg3.c | 7 +++++-- drivers/video/cg6.c | 7 +++++-- drivers/video/ffb.c | 7 +++++-- drivers/video/fsl-diu-fb.c | 8 ++++--- drivers/video/leo.c | 7 +++++-- drivers/video/mb862xx/mb862xxfb.c | 8 ++++--- drivers/video/p9100.c | 7 +++++-- drivers/video/platinumfb.c | 7 +++++-- drivers/video/sunxvr1000.c | 7 +++++-- drivers/video/tcx.c | 7 +++++-- drivers/video/xilinxfb.c | 5 ++--- drivers/watchdog/cpwd.c | 7 +++++-- drivers/watchdog/gef_wdt.c | 8 ++++--- drivers/watchdog/mpc8xxx_wdt.c | 8 +++---- drivers/watchdog/riowd.c | 7 +++++-- include/linux/of_platform.h | 4 ---- sound/soc/fsl/mpc5200_psc_ac97.c | 2 +- sound/soc/fsl/mpc5200_psc_i2s.c | 2 +- sound/soc/fsl/mpc8610_hpcd.c | 8 ++++--- sound/sparc/amd7930.c | 7 +++++-- sound/sparc/cs4231.c | 7 +++++-- sound/sparc/dbri.c | 7 +++++-- 146 files changed, 671 insertions(+), 387 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 355257bb149d..21266abfbda6 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -201,9 +201,6 @@ static int ibmebus_create_devices(const struct of_device_id *matches) int ibmebus_register_driver(struct of_platform_driver *drv) { - if (!drv->driver.of_match_table) - drv->driver.of_match_table = drv->match_table; - /* If the driver uses devices that ibmebus doesn't know, add them */ ibmebus_create_devices(drv->driver.of_match_table); diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 218853466510..487a98851ba6 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -306,10 +306,11 @@ static struct of_device_id of_pci_phb_ids[] = { }; static struct of_platform_driver of_pci_phb_driver = { - .match_table = of_pci_phb_ids, .probe = of_pci_phb_probe, .driver = { .name = "of-pci", + .owner = THIS_MODULE, + .of_match_table = of_pci_phb_ids, }, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 576669fc4fbf..ca5305a5bd61 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -193,8 +193,11 @@ static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { }; static struct of_platform_driver mpc52xx_wkup_gpiochip_driver = { - .name = "gpio_wkup", - .match_table = mpc52xx_wkup_gpiochip_match, + .driver = { + .name = "gpio_wkup", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_wkup_gpiochip_match, + }, .probe = mpc52xx_wkup_gpiochip_probe, .remove = mpc52xx_gpiochip_remove, }; @@ -349,8 +352,11 @@ static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { }; static struct of_platform_driver mpc52xx_simple_gpiochip_driver = { - .name = "gpio", - .match_table = mpc52xx_simple_gpiochip_match, + .driver = { + .name = "gpio", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_simple_gpiochip_match, + }, .probe = mpc52xx_simple_gpiochip_probe, .remove = mpc52xx_gpiochip_remove, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 42c507f9c35b..46c93578cbf0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -784,8 +784,11 @@ static const struct of_device_id mpc52xx_gpt_match[] = { }; static struct of_platform_driver mpc52xx_gpt_driver = { - .name = "mpc52xx-gpt", - .match_table = mpc52xx_gpt_match, + .driver = { + .name = "mpc52xx-gpt", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_gpt_match, + }, .probe = mpc52xx_gpt_probe, .remove = mpc52xx_gpt_remove, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index 17b99ba7a8cc..e86aec644501 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -537,9 +537,11 @@ static struct of_device_id mpc52xx_lpbfifo_match[] __devinitconst = { }; static struct of_platform_driver mpc52xx_lpbfifo_driver = { - .owner = THIS_MODULE, - .name = "mpc52xx-lpbfifo", - .match_table = mpc52xx_lpbfifo_match, + .driver = { + .name = "mpc52xx-lpbfifo", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_lpbfifo_match, + }, .probe = mpc52xx_lpbfifo_probe, .remove = __devexit_p(mpc52xx_lpbfifo_remove), }; diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index 0176ae8249d5..9f2e52b36f91 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -170,8 +170,9 @@ static const struct of_device_id ep8248e_mdio_match[] = { static struct of_platform_driver ep8248e_mdio_driver = { .driver = { .name = "ep8248e-mdio-bitbang", + .owner = THIS_MODULE, + .of_match_table = ep8248e_mdio_match, }, - .match_table = ep8248e_mdio_match, .probe = ep8248e_mdio_probe, .remove = ep8248e_mdio_remove, }; diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index aa0b764b1cc4..ebe6c3537209 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -423,8 +423,11 @@ static struct of_device_id pmc_match[] = { }; static struct of_platform_driver pmc_driver = { - .name = "mpc83xx-pmc", - .match_table = pmc_match, + .driver = { + .name = "mpc83xx-pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_match, + }, .probe = pmc_probe, .remove = pmc_remove }; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 177a4f1369b4..6257e5378615 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -447,11 +447,12 @@ static const struct of_device_id axon_msi_device_id[] = { }; static struct of_platform_driver axon_msi_driver = { - .match_table = axon_msi_device_id, .probe = axon_msi_probe, .shutdown = axon_msi_shutdown, - .driver = { - .name = "axon-msi" + .driver = { + .name = "axon-msi", + .owner = THIS_MODULE, + .of_match_table = axon_msi_device_id, }, }; diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index c44e1b3b91db..627ee089e75d 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -301,11 +301,12 @@ MODULE_DEVICE_TABLE(of, gpio_mdio_match); static struct of_platform_driver gpio_mdio_driver = { - .match_table = gpio_mdio_match, .probe = gpio_mdio_probe, .remove = gpio_mdio_remove, - .driver = { - .name = "gpio-mdio-bitbang", + .driver = { + .name = "gpio-mdio-bitbang", + .owner = THIS_MODULE, + .of_match_table = gpio_mdio_match, }, }; diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 88b21fccf0c9..402d2212162f 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -327,12 +327,12 @@ static struct of_device_id axon_ram_device_id[] = { }; static struct of_platform_driver axon_ram_driver = { - .match_table = axon_ram_device_id, .probe = axon_ram_probe, .remove = axon_ram_remove, - .driver = { - .owner = THIS_MODULE, - .name = AXON_RAM_MODULE_NAME, + .driver = { + .name = AXON_RAM_MODULE_NAME, + .owner = THIS_MODULE, + .of_match_table = axon_ram_device_id, }, }; diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index d32d5389b67a..a7c5c470af14 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c @@ -494,14 +494,12 @@ MODULE_DEVICE_TABLE(of, mpc52xx_bcom_of_match); static struct of_platform_driver mpc52xx_bcom_of_platform_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = mpc52xx_bcom_of_match, .probe = mpc52xx_bcom_probe, .remove = mpc52xx_bcom_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = mpc52xx_bcom_of_match, }, }; diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 569dae8ea1ce..a7be144f5874 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -345,8 +345,11 @@ static const struct of_device_id fsl_of_msi_ids[] = { }; static struct of_platform_driver fsl_of_msi_driver = { - .name = "fsl-msi", - .match_table = fsl_of_msi_ids, + .driver = { + .name = "fsl-msi", + .owner = THIS_MODULE, + .of_match_table = fsl_of_msi_ids, + }, .probe = fsl_of_msi_probe, }; diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 2ebe817ca72f..9082eb921ad9 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -76,8 +76,11 @@ static const struct of_device_id pmc_ids[] = { }; static struct of_platform_driver pmc_driver = { - .driver.name = "fsl-pmc", - .match_table = pmc_ids, + .driver = { + .name = "fsl-pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_ids, + }, .probe = pmc_probe, }; diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index a98d51639243..6a1fde0d22b0 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1215,8 +1215,11 @@ static const struct of_device_id fsl_of_rio_rpn_ids[] = { }; static struct of_platform_driver fsl_of_rio_rpn_driver = { - .name = "fsl-of-rio", - .match_table = fsl_of_rio_rpn_ids, + .driver = { + .name = "fsl-of-rio", + .owner = THIS_MODULE, + .of_match_table = fsl_of_rio_rpn_ids, + }, .probe = fsl_of_rio_rpn_probe, }; diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index ff758bff1b7a..d07137a07d75 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -206,11 +206,12 @@ static int pmi_of_remove(struct of_device *dev) } static struct of_platform_driver pmi_of_platform_driver = { - .match_table = pmi_match, .probe = pmi_of_probe, .remove = pmi_of_remove, - .driver = { - .name = "pmi", + .driver = { + .name = "pmi", + .owner = THIS_MODULE, + .of_match_table = pmi_match, }, }; diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 149393c02c3f..093e0ae1a941 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -669,8 +669,11 @@ static const struct of_device_id qe_ids[] = { }; static struct of_platform_driver qe_driver = { - .driver.name = "fsl-qe", - .match_table = qe_ids, + .driver = { + .name = "fsl-qe", + .owner = THIS_MODULE, + .of_match_table = qe_ids, + }, .probe = qe_probe, .resume = qe_resume, }; diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index 1bb6a41b00f2..c333b8d0949b 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -232,8 +232,11 @@ static const struct of_device_id ecpp_match[] = { }; static struct of_platform_driver ecpp_driver = { - .name = "ecpp", - .match_table = ecpp_match, + .driver = { + .name = "ecpp", + .owner = THIS_MODULE, + .of_match_table = ecpp_match, + }, .probe = ecpp_probe, .remove = __devexit_p(ecpp_remove), }; diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index 71ec90b9e316..b27476caa133 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -174,8 +174,11 @@ static struct of_device_id __initdata apc_match[] = { MODULE_DEVICE_TABLE(of, apc_match); static struct of_platform_driver apc_driver = { - .name = "apc", - .match_table = apc_match, + .driver = { + .name = "apc", + .owner = THIS_MODULE, + .of_match_table = apc_match, + }, .probe = apc_probe, }; diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index bd8421a26856..ddc84128b3c2 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -132,10 +132,11 @@ static int __devinit auxio_probe(struct of_device *dev, const struct of_device_i } static struct of_platform_driver auxio_driver = { - .match_table = auxio_match, .probe = auxio_probe, - .driver = { - .name = "auxio", + .driver = { + .name = "auxio", + .owner = THIS_MODULE, + .of_match_table = auxio_match, }, }; diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index d533f3d5d484..434335f65823 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -149,10 +149,11 @@ static struct of_device_id __initdata clock_board_match[] = { }; static struct of_platform_driver clock_board_driver = { - .match_table = clock_board_match, .probe = clock_board_probe, - .driver = { - .name = "clock_board", + .driver = { + .name = "clock_board", + .owner = THIS_MODULE, + .of_match_table = clock_board_match, }, }; @@ -254,10 +255,11 @@ static struct of_device_id __initdata fhc_match[] = { }; static struct of_platform_driver fhc_driver = { - .match_table = fhc_match, .probe = fhc_probe, - .driver = { - .name = "fhc", + .driver = { + .name = "fhc", + .owner = THIS_MODULE, + .of_match_table = fhc_match, }, }; diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index 936879639eb6..870cb65b3f21 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -811,8 +811,11 @@ static const struct of_device_id us3mc_match[] = { MODULE_DEVICE_TABLE(of, us3mc_match); static struct of_platform_driver us3mc_driver = { - .name = "us3mc", - .match_table = us3mc_match, + .driver = { + .name = "us3mc", + .owner = THIS_MODULE, + .of_match_table = us3mc_match, + }, .probe = us3mc_probe, .remove = __devexit_p(us3mc_remove), }; diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index ff844baa28e6..51cfa09e392a 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -508,8 +508,11 @@ static struct of_device_id __initdata fire_match[] = { }; static struct of_platform_driver fire_driver = { - .name = DRIVER_NAME, - .match_table = fire_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = fire_match, + }, .probe = fire_probe, }; diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index e675e21c6df6..558a70512824 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -602,8 +602,11 @@ static struct of_device_id __initdata psycho_match[] = { }; static struct of_platform_driver psycho_driver = { - .name = DRIVER_NAME, - .match_table = psycho_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = psycho_match, + }, .probe = psycho_probe, }; diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 5048498daade..6dad8e3b7506 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -596,8 +596,11 @@ static struct of_device_id __initdata sabre_match[] = { }; static struct of_platform_driver sabre_driver = { - .name = DRIVER_NAME, - .match_table = sabre_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = sabre_match, + }, .probe = sabre_probe, }; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 2f3f9212b063..97a1ae2e1c02 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1491,8 +1491,11 @@ static struct of_device_id __initdata schizo_match[] = { }; static struct of_platform_driver schizo_driver = { - .name = DRIVER_NAME, - .match_table = schizo_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = schizo_match, + }, .probe = schizo_probe, }; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 5c11f56cedf8..a24af6f7e17f 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -1009,8 +1009,11 @@ static struct of_device_id __initdata pci_sun4v_match[] = { }; static struct of_platform_driver pci_sun4v_driver = { - .name = DRIVER_NAME, - .match_table = pci_sun4v_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = pci_sun4v_match, + }, .probe = pci_sun4v_probe, }; diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index 5e4563d86f19..9589d8b9b0c1 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c @@ -79,8 +79,11 @@ static struct of_device_id __initdata pmc_match[] = { MODULE_DEVICE_TABLE(of, pmc_match); static struct of_platform_driver pmc_driver = { - .name = "pmc", - .match_table = pmc_match, + .driver = { + .name = "pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_match, + }, .probe = pmc_probe, }; diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index e3f806a7423b..168d4cb63f5b 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -60,10 +60,11 @@ static struct of_device_id __initdata power_match[] = { }; static struct of_platform_driver power_driver = { - .match_table = power_match, .probe = power_probe, - .driver = { - .name = "power", + .driver = { + .name = "power", + .owner = THIS_MODULE, + .of_match_table = power_match, }, }; diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index e0dbed9503d4..217ba275cabf 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -185,10 +185,11 @@ static struct of_device_id __initdata clock_match[] = { }; static struct of_platform_driver clock_driver = { - .match_table = clock_match, .probe = clock_probe, - .driver = { - .name = "rtc", + .driver = { + .name = "rtc", + .owner = THIS_MODULE, + .of_match_table = clock_match, }, }; diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 9099ca095641..21e9fcae0668 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -463,10 +463,11 @@ static struct of_device_id __initdata rtc_match[] = { }; static struct of_platform_driver rtc_driver = { - .match_table = rtc_match, .probe = rtc_probe, - .driver = { - .name = "rtc", + .driver = { + .name = "rtc", + .owner = THIS_MODULE, + .of_match_table = rtc_match, }, }; @@ -495,10 +496,11 @@ static struct of_device_id __initdata bq4802_match[] = { }; static struct of_platform_driver bq4802_driver = { - .match_table = bq4802_match, .probe = bq4802_probe, - .driver = { - .name = "bq4802", + .driver = { + .name = "bq4802", + .owner = THIS_MODULE, + .of_match_table = bq4802_match, }, }; @@ -558,10 +560,11 @@ static struct of_device_id __initdata mostek_match[] = { }; static struct of_platform_driver mostek_driver = { - .match_table = mostek_match, .probe = mostek_probe, - .driver = { - .name = "mostek", + .driver = { + .name = "mostek", + .owner = THIS_MODULE, + .of_match_table = mostek_match, }, }; diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 4cce719add3f..88e6b6008bd6 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -884,9 +884,6 @@ static struct of_device_id mpc52xx_ata_of_match[] = { static struct of_platform_driver mpc52xx_ata_of_platform_driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - .match_table = mpc52xx_ata_of_match, .probe = mpc52xx_ata_probe, .remove = mpc52xx_ata_remove, #ifdef CONFIG_PM @@ -896,6 +893,7 @@ static struct of_platform_driver mpc52xx_ata_of_platform_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = mpc52xx_ata_of_match, }, }; diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index 19da29f011db..5a1b82c08be9 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -91,8 +91,11 @@ static struct of_device_id pata_of_platform_match[] = { MODULE_DEVICE_TABLE(of, pata_of_platform_match); static struct of_platform_driver pata_of_platform_driver = { - .name = "pata_of_platform", - .match_table = pata_of_platform_match, + .driver = { + .name = "pata_of_platform", + .owner = THIS_MODULE, + .of_match_table = pata_of_platform_match, + }, .probe = pata_of_platform_probe, .remove = __devexit_p(pata_of_platform_remove), }; diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index e3339e25b152..61c89b54ea23 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1427,8 +1427,11 @@ static struct of_device_id fsl_sata_match[] = { MODULE_DEVICE_TABLE(of, fsl_sata_match); static struct of_platform_driver fsl_sata_driver = { - .name = "fsl-sata", - .match_table = fsl_sata_match, + .driver = { + .name = "fsl-sata", + .owner = THIS_MODULE, + .of_match_table = fsl_sata_match, + }, .probe = sata_fsl_probe, .remove = sata_fsl_remove, #ifdef CONFIG_PM diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 593a03a376e4..da8f176c051e 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2695,8 +2695,11 @@ static const struct of_device_id fore200e_sba_match[] = { MODULE_DEVICE_TABLE(of, fore200e_sba_match); static struct of_platform_driver fore200e_sba_driver = { - .name = "fore_200e", - .match_table = fore200e_sba_match, + .driver = { + .name = "fore_200e", + .owner = THIS_MODULE, + .of_match_table = fore200e_sba_match, + }, .probe = fore200e_sba_probe, .remove = __devexit_p(fore200e_sba_remove), }; diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 3094909b0613..a7b83c0a7eb5 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1237,13 +1237,12 @@ static const struct of_device_id ace_of_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, ace_of_match); static struct of_platform_driver ace_of_driver = { - .owner = THIS_MODULE, - .name = "xsysace", - .match_table = ace_of_match, .probe = ace_of_probe, .remove = __devexit_p(ace_of_remove), .driver = { .name = "xsysace", + .owner = THIS_MODULE, + .of_match_table = ace_of_match, }, }; diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 0861d99cd75b..0f9cbf1aaf15 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -751,8 +751,11 @@ static const struct of_device_id n2rng_match[] = { MODULE_DEVICE_TABLE(of, n2rng_match); static struct of_platform_driver n2rng_driver = { - .name = "n2rng", - .match_table = n2rng_match, + .driver = { + .name = "n2rng", + .owner = THIS_MODULE, + .of_match_table = n2rng_match, + }, .probe = n2rng_probe, .remove = __devexit_p(n2rng_remove), }; diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index b213855bae68..261ba8f22b8b 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -140,8 +140,11 @@ static struct of_device_id rng_match[] = { }; static struct of_platform_driver rng_driver = { - .name = "pasemi-rng", - .match_table = rng_match, + .driver = { + .name = "pasemi-rng", + .owner = THIS_MODULE, + .of_match_table = rng_match, + }, .probe = rng_probe, .remove = rng_remove, }; diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 2b44a0e1b988..47ffe4a90a95 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2555,8 +2555,11 @@ static struct of_device_id ipmi_match[] = }; static struct of_platform_driver ipmi_of_platform_driver = { - .name = "ipmi", - .match_table = ipmi_match, + .driver = { + .name = "ipmi", + .owner = THIS_MODULE, + .of_match_table = ipmi_match, + }, .probe = ipmi_of_probe, .remove = __devexit_p(ipmi_of_remove), }; diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 5a0a31e2029c..ed8a9cec2a05 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -812,13 +812,12 @@ static const struct of_device_id __devinitconst hwicap_of_match[] = { MODULE_DEVICE_TABLE(of, hwicap_of_match); static struct of_platform_driver hwicap_of_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = hwicap_of_match, .probe = hwicap_of_probe, .remove = __devexit_p(hwicap_of_remove), .driver = { .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = hwicap_of_match, }, }; diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 6c4c8b7ce3aa..9d65b371de64 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -1281,8 +1281,11 @@ static const struct of_device_id crypto4xx_match[] = { }; static struct of_platform_driver crypto4xx_driver = { - .name = "crypto4xx", - .match_table = crypto4xx_match, + .driver = { + .name = "crypto4xx", + .owner = THIS_MODULE, + .of_match_table = crypto4xx_match, + }, .probe = crypto4xx_probe, .remove = crypto4xx_remove, }; diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 5a02f3482dba..7e4e42d85fe4 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1968,8 +1968,11 @@ static const struct of_device_id talitos_match[] = { MODULE_DEVICE_TABLE(of, talitos_match); static struct of_platform_driver talitos_driver = { - .name = "talitos", - .match_table = talitos_match, + .driver = { + .name = "talitos", + .owner = THIS_MODULE, + .of_match_table = talitos_match, + }, .probe = talitos_probe, .remove = talitos_remove, }; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 0e376eb37417..c3d74697f5a9 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1409,10 +1409,13 @@ static const struct of_device_id fsldma_of_ids[] = { }; static struct of_platform_driver fsldma_of_driver = { - .name = "fsl-elo-dma", - .match_table = fsldma_of_ids, - .probe = fsldma_of_probe, - .remove = fsldma_of_remove, + .driver = { + .name = "fsl-elo-dma", + .owner = THIS_MODULE, + .of_match_table = fsldma_of_ids, + }, + .probe = fsldma_of_probe, + .remove = fsldma_of_remove, }; /*----------------------------------------------------------------------------*/ diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index d44626fa35ad..a7b05447e0ab 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4949,12 +4949,12 @@ static const struct of_device_id ppc440spe_adma_of_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, ppc440spe_adma_of_match); static struct of_platform_driver ppc440spe_adma_driver = { - .match_table = ppc440spe_adma_of_match, .probe = ppc440spe_adma_probe, .remove = __devexit_p(ppc440spe_adma_remove), .driver = { .name = "PPC440SP(E)-ADMA", .owner = THIS_MODULE, + .of_match_table = ppc440spe_adma_of_match, }, }; diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 4471647b4807..6c1886b497ff 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -338,15 +338,13 @@ static struct of_device_id mpc85xx_pci_err_of_match[] = { }; static struct of_platform_driver mpc85xx_pci_err_driver = { - .owner = THIS_MODULE, - .name = "mpc85xx_pci_err", - .match_table = mpc85xx_pci_err_of_match, .probe = mpc85xx_pci_err_probe, .remove = __devexit_p(mpc85xx_pci_err_remove), .driver = { - .name = "mpc85xx_pci_err", - .owner = THIS_MODULE, - }, + .name = "mpc85xx_pci_err", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_pci_err_of_match, + }, }; #endif /* CONFIG_PCI */ @@ -654,15 +652,13 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = { }; static struct of_platform_driver mpc85xx_l2_err_driver = { - .owner = THIS_MODULE, - .name = "mpc85xx_l2_err", - .match_table = mpc85xx_l2_err_of_match, .probe = mpc85xx_l2_err_probe, .remove = mpc85xx_l2_err_remove, .driver = { - .name = "mpc85xx_l2_err", - .owner = THIS_MODULE, - }, + .name = "mpc85xx_l2_err", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_l2_err_of_match, + }, }; /**************************** MC Err device ***************************/ @@ -1131,15 +1127,13 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = { }; static struct of_platform_driver mpc85xx_mc_err_driver = { - .owner = THIS_MODULE, - .name = "mpc85xx_mc_err", - .match_table = mpc85xx_mc_err_of_match, .probe = mpc85xx_mc_err_probe, .remove = mpc85xx_mc_err_remove, .driver = { - .name = "mpc85xx_mc_err", - .owner = THIS_MODULE, - }, + .name = "mpc85xx_mc_err", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_mc_err_of_match, + }, }; #ifdef CONFIG_MPC85xx diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c index 11f2172aa1e6..9d6f6783328c 100644 --- a/drivers/edac/ppc4xx_edac.c +++ b/drivers/edac/ppc4xx_edac.c @@ -202,13 +202,13 @@ static struct of_device_id ppc4xx_edac_match[] = { }; static struct of_platform_driver ppc4xx_edac_driver = { - .match_table = ppc4xx_edac_match, .probe = ppc4xx_edac_probe, .remove = ppc4xx_edac_remove, - .driver = { - .owner = THIS_MODULE, - .name = PPC4XX_EDAC_MODULE_NAME - } + .driver = { + .owner = THIS_MODULE, + .name = PPC4XX_EDAC_MODULE_NAME + .of_match_table = ppc4xx_edac_match, + }, }; /* diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index 68e90abeba96..5da5942cf970 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c @@ -300,8 +300,11 @@ static const struct of_device_id env_match[] = { MODULE_DEVICE_TABLE(of, env_match); static struct of_platform_driver env_driver = { - .name = "ultra45_env", - .match_table = env_match, + .driver = { + .name = "ultra45_env", + .owner = THIS_MODULE, + .of_match_table = env_match, + }, .probe = env_probe, .remove = __devexit_p(env_remove), }; diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 48d2c1a0d4ce..7637e1234142 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -718,13 +718,13 @@ static const struct of_device_id cpm_i2c_match[] = { MODULE_DEVICE_TABLE(of, cpm_i2c_match); static struct of_platform_driver cpm_i2c_driver = { - .match_table = cpm_i2c_match, .probe = cpm_i2c_probe, .remove = __devexit_p(cpm_i2c_remove), - .driver = { - .name = "fsl-i2c-cpm", - .owner = THIS_MODULE, - } + .driver = { + .name = "fsl-i2c-cpm", + .owner = THIS_MODULE, + .of_match_table = cpm_i2c_match, + }, }; static int __init cpm_i2c_init(void) diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index e66dc83953c5..3876f993fe76 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -807,8 +807,11 @@ static const struct of_device_id ibm_iic_match[] = { }; static struct of_platform_driver ibm_iic_driver = { - .name = "ibm-iic", - .match_table = ibm_iic_match, + .driver = { + .name = "ibm-iic", + .owner = THIS_MODULE, + .of_match_table = ibm_iic_match, + }, .probe = iic_probe, .remove = __devexit_p(iic_remove), }; diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 69473b6c260c..791b71f46f7b 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -675,12 +675,12 @@ MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); /* Structure for a device driver */ static struct of_platform_driver mpc_i2c_driver = { - .match_table = mpc_i2c_of_match, .probe = fsl_i2c_probe, .remove = __devexit_p(fsl_i2c_remove), - .driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = mpc_i2c_of_match, }, }; diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 26391853277f..252489e88369 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -937,12 +937,13 @@ static struct of_device_id ehca_device_table[] = MODULE_DEVICE_TABLE(of, ehca_device_table); static struct of_platform_driver ehca_driver = { - .name = "ehca", - .match_table = ehca_device_table, .probe = ehca_probe, .remove = ehca_remove, - .driver = { + .driver = { + .name = "ehca", + .owner = THIS_MODULE, .groups = ehca_drv_attr_groups, + .of_match_table = ehca_device_table, }, }; diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 0d45422f8095..1dacae4b43f0 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -259,8 +259,11 @@ static const struct of_device_id bbc_beep_match[] = { }; static struct of_platform_driver bbc_beep_driver = { - .name = "bbcbeep", - .match_table = bbc_beep_match, + .driver = { + .name = "bbcbeep", + .owner = THIS_MODULE, + .of_match_table = bbc_beep_match, + }, .probe = bbc_beep_probe, .remove = __devexit_p(bbc_remove), .shutdown = sparcspkr_shutdown, @@ -338,8 +341,11 @@ static const struct of_device_id grover_beep_match[] = { }; static struct of_platform_driver grover_beep_driver = { - .name = "groverbeep", - .match_table = grover_beep_match, + .driver = { + .name = "groverbeep", + .owner = THIS_MODULE, + .of_match_table = grover_beep_match, + }, .probe = grover_beep_probe, .remove = __devexit_p(grover_remove), .shutdown = sparcspkr_shutdown, diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index 29e17698b2a4..04e32f2d1241 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -96,8 +96,11 @@ static const struct of_device_id sparc_i8042_match[] = { MODULE_DEVICE_TABLE(of, sparc_i8042_match); static struct of_platform_driver sparc_i8042_driver = { - .name = "i8042", - .match_table = sparc_i8042_match, + .driver = { + .name = "i8042", + .owner = THIS_MODULE, + .of_match_table = sparc_i8042_match, + }, .probe = sparc_i8042_probe, .remove = __devexit_p(sparc_i8042_remove), }; diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 7a288c0ef1a6..e2c028d2638f 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -362,8 +362,11 @@ static const struct of_device_id xps2_of_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, xps2_of_match); static struct of_platform_driver xps2_of_driver = { - .name = DRIVER_NAME, - .match_table = xps2_of_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = xps2_of_match, + }, .probe = xps2_of_probe, .remove = __devexit_p(xps2_of_remove), }; diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index a77a23e783db..6d94b0b9979c 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -291,8 +291,8 @@ static struct of_platform_driver of_gpio_leds_driver = { .driver = { .name = "of_gpio_leds", .owner = THIS_MODULE, + .of_match_table = of_gpio_leds_match, }, - .match_table = of_gpio_leds_match, .probe = of_gpio_leds_probe, .remove = __devexit_p(of_gpio_leds_remove), }; diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 888448cf7f1f..ef1f3330a10e 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -671,8 +671,11 @@ static const struct of_device_id smu_platform_match[] = static struct of_platform_driver smu_of_platform_driver = { - .name = "smu", - .match_table = smu_platform_match, + .driver = { + .name = "smu", + .owner = THIS_MODULE, + .of_match_table = smu_platform_match, + }, .probe = smu_platform_probe, }; diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 9314be9a2fc8..e60605bd0ea9 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -2238,8 +2238,11 @@ static const struct of_device_id fcu_match[] = static struct of_platform_driver fcu_of_platform_driver = { - .name = "temperature", - .match_table = fcu_match, + .driver = { + .name = "temperature", + .owner = THIS_MODULE, + .of_match_table = fcu_match, + }, .probe = fcu_of_probe, .remove = fcu_of_remove }; diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 0839770e4ec5..5c9367acf0cf 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -463,8 +463,11 @@ static const struct of_device_id therm_of_match[] = {{ }; static struct of_platform_driver therm_of_driver = { - .name = "temperature", - .match_table = therm_of_match, + .driver = { + .name = "temperature", + .owner = THIS_MODULE, + .of_match_table = therm_of_match, + }, .probe = therm_of_probe, .remove = therm_of_remove, }; diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index dfe5ceae6794..7802a543d8fc 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -205,8 +205,11 @@ static const struct of_device_id sdhci_of_match[] = { MODULE_DEVICE_TABLE(of, sdhci_of_match); static struct of_platform_driver sdhci_of_driver = { - .driver.name = "sdhci-of", - .match_table = sdhci_of_match, + .driver = { + .name = "sdhci-of", + .owner = THIS_MODULE, + .of_match_table = sdhci_of_match, + }, .probe = sdhci_of_probe, .remove = __devexit_p(sdhci_of_remove), .suspend = sdhci_of_suspend, diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 3dc7a2fbf025..4147fe328c55 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -375,8 +375,11 @@ static struct of_device_id of_flash_match[] = { MODULE_DEVICE_TABLE(of, of_flash_match); static struct of_platform_driver of_flash_driver = { - .name = "of-flash", - .match_table = of_flash_match, + .driver = { + .name = "of-flash", + .owner = THIS_MODULE, + .of_match_table = of_flash_match, + }, .probe = of_flash_probe, .remove = of_flash_remove, }; diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 5945a23e681f..0391c2527bd7 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -149,8 +149,11 @@ static const struct of_device_id uflash_match[] = { MODULE_DEVICE_TABLE(of, uflash_match); static struct of_platform_driver uflash_driver = { - .name = DRIVER_NAME, - .match_table = uflash_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = uflash_match, + }, .probe = uflash_probe, .remove = __devexit_p(uflash_remove), }; diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 4a6079588ab2..f45a8d0c1508 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -1078,9 +1078,10 @@ static const struct of_device_id fsl_elbc_match[] = { static struct of_platform_driver fsl_elbc_ctrl_driver = { .driver = { - .name = "fsl-elbc", + .name = "fsl-elbc", + .owner = THIS_MODULE, + .of_match_table = fsl_elbc_match, }, - .match_table = fsl_elbc_match, .probe = fsl_elbc_ctrl_probe, .remove = fsl_elbc_ctrl_remove, }; diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 4b96296af321..b7ab5a0ec35d 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -357,8 +357,11 @@ static struct of_device_id of_fun_match[] = { MODULE_DEVICE_TABLE(of, of_fun_match); static struct of_platform_driver of_fun_driver = { - .name = "fsl,upm-nand", - .match_table = of_fun_match, + .driver = { + .name = "fsl,upm-nand", + .owner = THIS_MODULE, + .of_match_table = of_fun_match, + }, .probe = fun_probe, .remove = __devexit_p(fun_remove), }; diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index c0e05f5ff8a4..98fd2bdf8be1 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -294,9 +294,10 @@ MODULE_DEVICE_TABLE(of, ndfc_match); static struct of_platform_driver ndfc_driver = { .driver = { - .name = "ndfc", + .name = "ndfc", + .owner = THIS_MODULE, + .of_match_table = ndfc_match, }, - .match_table = ndfc_match, .probe = ndfc_probe, .remove = __devexit_p(ndfc_remove), }; diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index edfc27b78513..a97e9c95ab6a 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -221,8 +221,11 @@ MODULE_DEVICE_TABLE(of, pasemi_nand_match); static struct of_platform_driver pasemi_nand_driver = { - .name = (char*)driver_name, - .match_table = pasemi_nand_match, + .driver = { + .name = (char*)driver_name, + .owner = THIS_MODULE, + .of_match_table = pasemi_nand_match, + }, .probe = pasemi_nand_probe, .remove = pasemi_nand_remove, }; diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index a4519a7bd683..edb9b1384143 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -301,8 +301,11 @@ static struct of_device_id socrates_nand_match[] = MODULE_DEVICE_TABLE(of, socrates_nand_match); static struct of_platform_driver socrates_nand_driver = { - .name = "socrates_nand", - .match_table = socrates_nand_match, + .driver = { + .name = "socrates_nand", + .owner = THIS_MODULE, + .of_match_table = socrates_nand_match, + }, .probe = socrates_nand_probe, .remove = __devexit_p(socrates_nand_remove), }; diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index 03e7c48465a2..2120784f8db4 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -393,15 +393,17 @@ static struct of_device_id __devinitdata mpc5xxx_can_table[] = { }; static struct of_platform_driver mpc5xxx_can_driver = { - .owner = THIS_MODULE, - .name = "mpc5xxx_can", + .driver = { + .name = "mpc5xxx_can", + .owner = THIS_MODULE, + .of_match_table = mpc5xxx_can_table, + }, .probe = mpc5xxx_can_probe, .remove = __devexit_p(mpc5xxx_can_remove), #ifdef CONFIG_PM .suspend = mpc5xxx_can_suspend, .resume = mpc5xxx_can_resume, #endif - .match_table = mpc5xxx_can_table, }; static int __init mpc5xxx_can_init(void) diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index dc5f20cdf93c..158b76ebf3ea 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -216,11 +216,13 @@ static struct of_device_id __devinitdata sja1000_ofp_table[] = { MODULE_DEVICE_TABLE(of, sja1000_ofp_table); static struct of_platform_driver sja1000_ofp_driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = sja1000_ofp_table, + }, .probe = sja1000_ofp_probe, .remove = __devexit_p(sja1000_ofp_remove), - .match_table = sja1000_ofp_table, }; static int __init sja1000_ofp_init(void) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 59dac232006c..b23173864c60 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -122,8 +122,11 @@ static struct of_device_id ehea_device_table[] = { MODULE_DEVICE_TABLE(of, ehea_device_table); static struct of_platform_driver ehea_driver = { - .name = "ehea", - .match_table = ehea_device_table, + .driver = { + .name = "ehea", + .owner = THIS_MODULE, + .of_match_table = ehea_device_table, + }, .probe = ehea_probe_adapter, .remove = ehea_remove, }; diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 3342056f8aac..be540b67ea57 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -1065,9 +1065,11 @@ static struct of_device_id mpc52xx_fec_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_fec_match); static struct of_platform_driver mpc52xx_fec_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = mpc52xx_fec_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = mpc52xx_fec_match, + }, .probe = mpc52xx_fec_probe, .remove = mpc52xx_fec_remove, #ifdef CONFIG_PM diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index 0d099e5a652d..006f64d9f96a 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -159,10 +159,13 @@ static struct of_device_id mpc52xx_fec_mdio_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_fec_mdio_match); struct of_platform_driver mpc52xx_fec_mdio_driver = { - .name = "mpc5200b-fec-phy", + .driver = { + .name = "mpc5200b-fec-phy", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_fec_mdio_match, + }, .probe = mpc52xx_fec_mdio_probe, .remove = mpc52xx_fec_mdio_remove, - .match_table = mpc52xx_fec_mdio_match, }; /* let fec driver call it, since this has to be registered before it */ diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index caeb88b67bc6..cae2d16858d1 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -1158,8 +1158,11 @@ static struct of_device_id fs_enet_match[] = { MODULE_DEVICE_TABLE(of, fs_enet_match); static struct of_platform_driver fs_enet_driver = { - .name = "fs_enet", - .match_table = fs_enet_match, + .driver = { + .owner = THIS_MODULE, + .name = "fs_enet", + .of_match_table = fs_enet_match, + }, .probe = fs_enet_probe, .remove = fs_enet_remove, }; diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index 24ff9f43a62b..0f90685d3d19 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -224,8 +224,11 @@ static struct of_device_id fs_enet_mdio_bb_match[] = { MODULE_DEVICE_TABLE(of, fs_enet_mdio_bb_match); static struct of_platform_driver fs_enet_bb_mdio_driver = { - .name = "fsl-bb-mdio", - .match_table = fs_enet_mdio_bb_match, + .driver = { + .name = "fsl-bb-mdio", + .owner = THIS_MODULE, + .of_match_table = fs_enet_mdio_bb_match, + }, .probe = fs_enet_mdio_probe, .remove = fs_enet_mdio_remove, }; diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index dc862e779c1f..bddffd169b93 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -222,8 +222,11 @@ static struct of_device_id fs_enet_mdio_fec_match[] = { MODULE_DEVICE_TABLE(of, fs_enet_mdio_fec_match); static struct of_platform_driver fs_enet_fec_mdio_driver = { - .name = "fsl-fec-mdio", - .match_table = fs_enet_mdio_fec_match, + .driver = { + .name = "fsl-fec-mdio", + .owner = THIS_MODULE, + .of_match_table = fs_enet_mdio_fec_match, + }, .probe = fs_enet_mdio_probe, .remove = fs_enet_mdio_remove, }; diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 72489a213bf7..16508535720a 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -461,10 +461,13 @@ static struct of_device_id fsl_pq_mdio_match[] = { MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match); static struct of_platform_driver fsl_pq_mdio_driver = { - .name = "fsl-pq_mdio", + .driver = { + .name = "fsl-pq_mdio", + .owner = THIS_MODULE, + .of_match_table = fsl_pq_mdio_match, + }, .probe = fsl_pq_mdio_probe, .remove = fsl_pq_mdio_remove, - .match_table = fsl_pq_mdio_match, }; int __init fsl_pq_mdio_init(void) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index b71bba91064c..c3b292a31328 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -3054,14 +3054,16 @@ MODULE_DEVICE_TABLE(of, gfar_match); /* Structure for a device driver */ static struct of_platform_driver gfar_driver = { - .name = "fsl-gianfar", - .match_table = gfar_match, - + .driver = { + .name = "fsl-gianfar", + .owner = THIS_MODULE, + .pm = GFAR_PM_OPS, + .of_match_table = gfar_match, + }, .probe = gfar_probe, .remove = gfar_remove, .suspend = gfar_legacy_suspend, .resume = gfar_legacy_resume, - .driver.pm = GFAR_PM_OPS, }; static int __init gfar_init(void) diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index cda2ba891344..f8c36a5eb4d7 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2996,9 +2996,11 @@ static struct of_device_id emac_match[] = MODULE_DEVICE_TABLE(of, emac_match); static struct of_platform_driver emac_driver = { - .name = "emac", - .match_table = emac_match, - + .driver = { + .name = "emac", + .owner = THIS_MODULE, + .of_match_table = emac_match, + }, .probe = emac_probe, .remove = emac_remove, }; diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index aba17947e208..fcff9e0bd382 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -790,9 +790,11 @@ static struct of_device_id mal_platform_match[] = }; static struct of_platform_driver mal_of_driver = { - .name = "mcmal", - .match_table = mal_platform_match, - + .driver = { + .name = "mcmal", + .owner = THIS_MODULE, + .of_match_table = mal_platform_match, + }, .probe = mal_probe, .remove = mal_remove, }; diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 6ab630a79e31..108919bcdf13 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -319,9 +319,11 @@ static struct of_device_id rgmii_match[] = }; static struct of_platform_driver rgmii_driver = { - .name = "emac-rgmii", - .match_table = rgmii_match, - + .driver = { + .name = "emac-rgmii", + .owner = THIS_MODULE, + .of_match_table = rgmii_match, + }, .probe = rgmii_probe, .remove = rgmii_remove, }; diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index 4f64b00dd5e8..044637144c43 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -166,9 +166,11 @@ static struct of_device_id tah_match[] = }; static struct of_platform_driver tah_driver = { - .name = "emac-tah", - .match_table = tah_match, - + .driver = { + .name = "emac-tah", + .owner = THIS_MODULE, + .of_match_table = tah_match, + }, .probe = tah_probe, .remove = tah_remove, }; diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c index b4fa823ed201..046dcd069c45 100644 --- a/drivers/net/ibm_newemac/zmii.c +++ b/drivers/net/ibm_newemac/zmii.c @@ -313,9 +313,11 @@ static struct of_device_id zmii_match[] = }; static struct of_platform_driver zmii_driver = { - .name = "emac-zmii", - .match_table = zmii_match, - + .driver = { + .name = "emac-zmii", + .owner = THIS_MODULE, + .of_match_table = zmii_match, + }, .probe = zmii_probe, .remove = zmii_remove, }; diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 9c7395c10e44..dc318330ec79 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -955,12 +955,12 @@ static struct of_device_id temac_of_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, temac_of_match); static struct of_platform_driver temac_of_driver = { - .match_table = temac_of_match, .probe = temac_of_probe, .remove = __devexit_p(temac_of_remove), .driver = { .owner = THIS_MODULE, .name = "xilinx_temac", + .of_match_table = temac_of_match, }, }; diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index e21439f1e775..77835df4d013 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -1161,8 +1161,11 @@ static const struct of_device_id myri_sbus_match[] = { MODULE_DEVICE_TABLE(of, myri_sbus_match); static struct of_platform_driver myri_sbus_driver = { - .name = "myri", - .match_table = myri_sbus_match, + .driver = { + .name = "myri", + .owner = THIS_MODULE, + .of_match_table = myri_sbus_match, + }, .probe = myri_sbus_probe, .remove = __devexit_p(myri_sbus_remove), }; diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 9c1604c04450..406d72c4eb71 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -10207,8 +10207,11 @@ static const struct of_device_id niu_match[] = { MODULE_DEVICE_TABLE(of, niu_match); static struct of_platform_driver niu_of_driver = { - .name = "niu", - .match_table = niu_match, + .driver = { + .name = "niu", + .owner = THIS_MODULE, + .of_match_table = niu_match, + }, .probe = niu_of_probe, .remove = __devexit_p(niu_of_remove), }; diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 641973ca2417..fc5fef2a8175 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -241,8 +241,11 @@ static struct of_device_id mdio_ofgpio_match[] = { MODULE_DEVICE_TABLE(of, mdio_ofgpio_match); static struct of_platform_driver mdio_ofgpio_driver = { - .name = "mdio-gpio", - .match_table = mdio_ofgpio_match, + .driver = { + .name = "mdio-gpio", + .owner = THIS_MODULE, + .of_match_table = mdio_ofgpio_match, + }, .probe = mdio_ofgpio_probe, .remove = __devexit_p(mdio_ofgpio_remove), }; diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index bd286ec5abd9..5f0ec390d6fc 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1292,8 +1292,11 @@ static const struct of_device_id bigmac_sbus_match[] = { MODULE_DEVICE_TABLE(of, bigmac_sbus_match); static struct of_platform_driver bigmac_sbus_driver = { - .name = "sunbmac", - .match_table = bigmac_sbus_match, + .driver = { + .name = "sunbmac", + .owner = THIS_MODULE, + .of_match_table = bigmac_sbus_match, + }, .probe = bigmac_sbus_probe, .remove = __devexit_p(bigmac_sbus_remove), }; diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index c6463f71c916..ad2cfc5bb9e1 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -3295,8 +3295,11 @@ static const struct of_device_id hme_sbus_match[] = { MODULE_DEVICE_TABLE(of, hme_sbus_match); static struct of_platform_driver hme_sbus_driver = { - .name = "hme", - .match_table = hme_sbus_match, + .driver = { + .name = "hme", + .owner = THIS_MODULE, + .of_match_table = hme_sbus_match, + }, .probe = hme_sbus_probe, .remove = __devexit_p(hme_sbus_remove), }; diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 28afc86e0694..0fc014ef9e98 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1546,8 +1546,11 @@ static const struct of_device_id sunlance_sbus_match[] = { MODULE_DEVICE_TABLE(of, sunlance_sbus_match); static struct of_platform_driver sunlance_sbus_driver = { - .name = "sunlance", - .match_table = sunlance_sbus_match, + .driver = { + .name = "sunlance", + .owner = THIS_MODULE, + .of_match_table = sunlance_sbus_match, + }, .probe = sunlance_sbus_probe, .remove = __devexit_p(sunlance_sbus_remove), }; diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 9864f4fa69d5..8fe86b287e51 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -978,8 +978,11 @@ static const struct of_device_id qec_sbus_match[] = { MODULE_DEVICE_TABLE(of, qec_sbus_match); static struct of_platform_driver qec_sbus_driver = { - .name = "qec", - .match_table = qec_sbus_match, + .driver = { + .name = "qec", + .owner = THIS_MODULE, + .of_match_table = qec_sbus_match, + }, .probe = qec_sbus_probe, .remove = __devexit_p(qec_sbus_remove), }; diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 88ebfc976735..0ab51037bf88 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3965,8 +3965,11 @@ static struct of_device_id ucc_geth_match[] = { MODULE_DEVICE_TABLE(of, ucc_geth_match); static struct of_platform_driver ucc_geth_driver = { - .name = DRV_NAME, - .match_table = ucc_geth_match, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = ucc_geth_match, + }, .probe = ucc_geth_probe, .remove = ucc_geth_remove, .suspend = ucc_geth_suspend, diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 3dd2416db540..67f9237237dd 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -1293,8 +1293,11 @@ static struct of_device_id xemaclite_of_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, xemaclite_of_match); static struct of_platform_driver xemaclite_of_driver = { - .name = DRIVER_NAME, - .match_table = xemaclite_of_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = xemaclite_of_match, + }, .probe = xemaclite_of_probe, .remove = __devexit_p(xemaclite_of_remove), }; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 9fd7f7d0a0d1..ba402c613ede 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -385,13 +385,6 @@ int of_bus_type_init(struct bus_type *bus, const char *name) int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) { - /* initialize common driver fields */ - if (!drv->driver.name) - drv->driver.name = drv->name; - if (!drv->driver.owner) - drv->driver.owner = drv->owner; - if (!drv->driver.of_match_table) - drv->driver.of_match_table = drv->match_table; drv->driver.bus = bus; /* register with core */ diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 065f229580d5..9a5b4b894161 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -382,8 +382,11 @@ static const struct of_device_id bpp_match[] = { MODULE_DEVICE_TABLE(of, bpp_match); static struct of_platform_driver bpp_sbus_driver = { - .name = "bpp", - .match_table = bpp_match, + .driver = { + .name = "bpp", + .owner = THIS_MODULE, + .of_match_table = bpp_match, + }, .probe = bpp_probe, .remove = __devexit_p(bpp_remove), }; diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index a22d32d71bf2..f94d8281cfb0 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -357,8 +357,11 @@ static const struct of_device_id electra_cf_match[] = { MODULE_DEVICE_TABLE(of, electra_cf_match); static struct of_platform_driver electra_cf_driver = { - .name = (char *)driver_name, - .match_table = electra_cf_match, + .driver = { + .name = (char *)driver_name, + .owner = THIS_MODULE, + .of_match_table = electra_cf_match, + }, .probe = electra_cf_probe, .remove = electra_cf_remove, }; diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 41cc954a5ffe..1a648b90b634 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -1298,8 +1298,11 @@ static const struct of_device_id m8xx_pcmcia_match[] = { MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match); static struct of_platform_driver m8xx_pcmcia_driver = { - .name = driver_name, - .match_table = m8xx_pcmcia_match, + .driver = { + .name = driver_name, + .owner = THIS_MODULE, + .match_table = m8xx_pcmcia_match, + }, .probe = m8xx_probe, .remove = m8xx_remove, }; diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 1543ac32b79b..8bfdd63a1fcb 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -414,8 +414,11 @@ static const struct of_device_id bbc_i2c_match[] = { MODULE_DEVICE_TABLE(of, bbc_i2c_match); static struct of_platform_driver bbc_i2c_driver = { - .name = "bbc_i2c", - .match_table = bbc_i2c_match, + .driver = { + .name = "bbc_i2c", + .owner = THIS_MODULE, + .of_match_table = bbc_i2c_match, + }, .probe = bbc_i2c_probe, .remove = __devexit_p(bbc_i2c_remove), }; diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 7fc7f34f3466..7baf1b644039 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -266,8 +266,11 @@ static const struct of_device_id d7s_match[] = { MODULE_DEVICE_TABLE(of, d7s_match); static struct of_platform_driver d7s_driver = { - .name = DRIVER_NAME, - .match_table = d7s_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = d7s_match, + }, .probe = d7s_probe, .remove = __devexit_p(d7s_remove), }; diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index a5fe20faf4f7..c8166ecf5276 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1131,8 +1131,11 @@ static const struct of_device_id envctrl_match[] = { MODULE_DEVICE_TABLE(of, envctrl_match); static struct of_platform_driver envctrl_driver = { - .name = DRIVER_NAME, - .match_table = envctrl_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = envctrl_match, + }, .probe = envctrl_probe, .remove = __devexit_p(envctrl_remove), }; diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 202ff8f75afb..0427e586975f 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -207,8 +207,11 @@ static const struct of_device_id flash_match[] = { MODULE_DEVICE_TABLE(of, flash_match); static struct of_platform_driver flash_driver = { - .name = "flash", - .match_table = flash_match, + .driver = { + .name = "flash", + .owner = THIS_MODULE, + .of_match_table = flash_match, + }, .probe = flash_probe, .remove = __devexit_p(flash_remove), }; diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index acc6738aa61f..5f253665a1da 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -425,8 +425,11 @@ static const struct of_device_id uctrl_match[] = { MODULE_DEVICE_TABLE(of, uctrl_match); static struct of_platform_driver uctrl_driver = { - .name = "uctrl", - .match_table = uctrl_match, + .driver = { + .name = "uctrl", + .owner = THIS_MODULE, + .of_match_table = uctrl_match, + }, .probe = uctrl_probe, .remove = __devexit_p(uctrl_remove), }; diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 35433d23b7ce..ca5c15c779cf 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1456,8 +1456,11 @@ static const struct of_device_id qpti_match[] = { MODULE_DEVICE_TABLE(of, qpti_match); static struct of_platform_driver qpti_sbus_driver = { - .name = "qpti", - .match_table = qpti_match, + .driver = { + .name = "qpti", + .owner = THIS_MODULE, + .of_match_table = qpti_match, + }, .probe = qpti_sbus_probe, .remove = __devexit_p(qpti_sbus_remove), }; diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index 151df73df475..386dd9d602b6 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -633,8 +633,11 @@ static const struct of_device_id esp_match[] = { MODULE_DEVICE_TABLE(of, esp_match); static struct of_platform_driver esp_sbus_driver = { - .name = "esp", - .match_table = esp_match, + .driver = { + .name = "esp", + .owner = THIS_MODULE, + .of_match_table = esp_match, + }, .probe = esp_sbus_probe, .remove = __devexit_p(esp_sbus_remove), }; diff --git a/drivers/serial/apbuart.c b/drivers/serial/apbuart.c index 52015d7031bb..0099b8692b60 100644 --- a/drivers/serial/apbuart.c +++ b/drivers/serial/apbuart.c @@ -584,12 +584,12 @@ static struct of_device_id __initdata apbuart_match[] = { }; static struct of_platform_driver grlib_apbuart_of_driver = { - .match_table = apbuart_match, .probe = apbuart_probe, .driver = { - .owner = THIS_MODULE, - .name = "grlib-apbuart", - }, + .owner = THIS_MODULE, + .name = "grlib-apbuart", + .of_match_table = apbuart_match, + }, }; diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 7866cdf8a754..9eb62a256e9a 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1372,8 +1372,11 @@ static struct of_device_id cpm_uart_match[] = { }; static struct of_platform_driver cpm_uart_driver = { - .name = "cpm_uart", - .match_table = cpm_uart_match, + .driver = { + .name = "cpm_uart", + .owner = THIS_MODULE, + .of_match_table = cpm_uart_match, + }, .probe = cpm_uart_probe, .remove = cpm_uart_remove, }; diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index cb079387c5ae..4fb32e3748c2 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -1464,15 +1464,16 @@ mpc52xx_uart_of_enumerate(void) MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); static struct of_platform_driver mpc52xx_uart_of_driver = { - .match_table = mpc52xx_uart_of_match, .probe = mpc52xx_uart_of_probe, .remove = mpc52xx_uart_of_remove, #ifdef CONFIG_PM .suspend = mpc52xx_uart_of_suspend, .resume = mpc52xx_uart_of_resume, #endif - .driver = { - .name = "mpc52xx-psc-uart", + .driver = { + .name = "mpc52xx-psc-uart", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_uart_of_match, }, }; diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 29539805e593..a48d9080f552 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -175,11 +175,13 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { }; static struct of_platform_driver of_platform_serial_driver = { - .owner = THIS_MODULE, - .name = "of_serial", + .driver = { + .name = "of_serial", + .owner = THIS_MODULE, + .of_match_table = of_platform_serial_table, + }, .probe = of_platform_serial_probe, .remove = of_platform_serial_remove, - .match_table = of_platform_serial_table, }; static int __init of_platform_serial_init(void) diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index d1eedf13d85c..890f91742962 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c @@ -630,8 +630,11 @@ static const struct of_device_id hv_match[] = { MODULE_DEVICE_TABLE(of, hv_match); static struct of_platform_driver hv_driver = { - .name = "hv", - .match_table = hv_match, + .driver = { + .name = "hv", + .owner = THIS_MODULE, + .of_match_table = hv_match, + }, .probe = hv_probe, .remove = __devexit_p(hv_remove), }; diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 9176c41b74ad..5e81bc6b48b0 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -1093,8 +1093,11 @@ static const struct of_device_id sab_match[] = { MODULE_DEVICE_TABLE(of, sab_match); static struct of_platform_driver sab_driver = { - .name = "sab", - .match_table = sab_match, + .driver = { + .name = "sab", + .owner = THIS_MODULE, + .of_match_table = sab_match, + }, .probe = sab_probe, .remove = __devexit_p(sab_remove), }; diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index a647b2448071..234459c2f012 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1539,8 +1539,11 @@ static const struct of_device_id su_match[] = { MODULE_DEVICE_TABLE(of, su_match); static struct of_platform_driver su_driver = { - .name = "su", - .match_table = su_match, + .driver = { + .name = "su", + .owner = THIS_MODULE, + .of_match_table = su_match, + }, .probe = su_probe, .remove = __devexit_p(su_remove), }; diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 20f9be8cd949..34fb8e84504f 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1491,8 +1491,11 @@ static const struct of_device_id zs_match[] = { MODULE_DEVICE_TABLE(of, zs_match); static struct of_platform_driver zs_driver = { - .name = "zs", - .match_table = zs_match, + .driver = { + .name = "zs", + .owner = THIS_MODULE, + .of_match_table = zs_match, + }, .probe = zs_probe, .remove = __devexit_p(zs_remove), }; diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 8fc2583d06ff..81073e3426e0 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -610,13 +610,12 @@ static int __devexit ulite_of_remove(struct of_device *op) } static struct of_platform_driver ulite_of_driver = { - .owner = THIS_MODULE, - .name = "uartlite", - .match_table = ulite_of_match, .probe = ulite_of_probe, .remove = __devexit_p(ulite_of_remove), .driver = { .name = "uartlite", + .owner = THIS_MODULE, + .of_match_table = ulite_of_match, }, }; diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 529890f044e2..907b06f5c447 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c @@ -1486,9 +1486,11 @@ static struct of_device_id ucc_uart_match[] = { MODULE_DEVICE_TABLE(of, ucc_uart_match); static struct of_platform_driver ucc_uart_of_driver = { - .owner = THIS_MODULE, - .name = "ucc_uart", - .match_table = ucc_uart_match, + .driver = { + .name = "ucc_uart", + .owner = THIS_MODULE, + .of_match_table = ucc_uart_match, + }, .probe = ucc_uart_probe, .remove = ucc_uart_remove, }; diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 7fcf28405860..7104cb739da7 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -514,14 +514,12 @@ static const struct of_device_id mpc52xx_psc_spi_of_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match); static struct of_platform_driver mpc52xx_psc_spi_of_driver = { - .owner = THIS_MODULE, - .name = "mpc52xx-psc-spi", - .match_table = mpc52xx_psc_spi_of_match, .probe = mpc52xx_psc_spi_of_probe, .remove = __exit_p(mpc52xx_psc_spi_of_remove), .driver = { .name = "mpc52xx-psc-spi", .owner = THIS_MODULE, + .of_match_table = mpc52xx_psc_spi_of_match, }, }; diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index 6573233bf7c9..b1a76bff775f 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -558,9 +558,11 @@ static const struct of_device_id mpc52xx_spi_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, mpc52xx_spi_match); static struct of_platform_driver mpc52xx_spi_of_driver = { - .owner = THIS_MODULE, - .name = "mpc52xx-spi", - .match_table = mpc52xx_spi_match, + .driver = { + .name = "mpc52xx-spi", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_spi_match, + }, .probe = mpc52xx_spi_probe, .remove = __exit_p(mpc52xx_spi_remove), }; diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 7572f98a419e..77ab15e330d0 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -1312,8 +1312,11 @@ static const struct of_device_id of_mpc8xxx_spi_match[] = { MODULE_DEVICE_TABLE(of, of_mpc8xxx_spi_match); static struct of_platform_driver of_mpc8xxx_spi_driver = { - .name = "mpc8xxx_spi", - .match_table = of_mpc8xxx_spi_match, + .driver = { + .name = "mpc8xxx_spi", + .owner = THIS_MODULE, + .of_match_table = of_mpc8xxx_spi_match, + }, .probe = of_mpc8xxx_spi_probe, .remove = __devexit_p(of_mpc8xxx_spi_remove), }; diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c index 7cb5ff37f6e2..19c0b3b34fce 100644 --- a/drivers/spi/spi_ppc4xx.c +++ b/drivers/spi/spi_ppc4xx.c @@ -587,12 +587,12 @@ static const struct of_device_id spi_ppc4xx_of_match[] = { MODULE_DEVICE_TABLE(of, spi_ppc4xx_of_match); static struct of_platform_driver spi_ppc4xx_of_driver = { - .match_table = spi_ppc4xx_of_match, .probe = spi_ppc4xx_of_probe, .remove = __exit_p(spi_ppc4xx_of_remove), .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .of_match_table = spi_ppc4xx_of_match, }, }; diff --git a/drivers/spi/xilinx_spi_of.c b/drivers/spi/xilinx_spi_of.c index 748d33a76d29..55c58012a028 100644 --- a/drivers/spi/xilinx_spi_of.c +++ b/drivers/spi/xilinx_spi_of.c @@ -109,12 +109,12 @@ static const struct of_device_id xilinx_spi_of_match[] = { MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); static struct of_platform_driver xilinx_spi_of_driver = { - .match_table = xilinx_spi_of_match, .probe = xilinx_spi_of_probe, .remove = __exit_p(xilinx_spi_of_remove), .driver = { .name = "xilinx-xps-spi", .owner = THIS_MODULE, + .of_match_table = xilinx_spi_of_match, }, }; diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 3537d51073b2..2928523268b5 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2768,8 +2768,11 @@ static const struct of_device_id qe_udc_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, qe_udc_match); static struct of_platform_driver udc_driver = { - .name = (char *)driver_name, - .match_table = qe_udc_match, + .driver = { + .name = (char *)driver_name, + .owner = THIS_MODULE, + .of_match_table = qe_udc_match, + }, .probe = qe_udc_probe, .remove = __devexit_p(qe_udc_remove), #ifdef CONFIG_PM diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index ad0662354a5e..5aec92866ab3 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -274,13 +274,12 @@ MODULE_DEVICE_TABLE(of, ehci_hcd_ppc_of_match); static struct of_platform_driver ehci_hcd_ppc_of_driver = { - .name = "ppc-of-ehci", - .match_table = ehci_hcd_ppc_of_match, .probe = ehci_hcd_ppc_of_probe, .remove = ehci_hcd_ppc_of_remove, .shutdown = ehci_hcd_ppc_of_shutdown, - .driver = { - .name = "ppc-of-ehci", - .owner = THIS_MODULE, + .driver = { + .name = "ppc-of-ehci", + .owner = THIS_MODULE, + .of_match_table = ehci_hcd_ppc_of_match, }, }; diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index f603bb2c0a8e..013972bbde57 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -288,13 +288,12 @@ static const struct of_device_id ehci_hcd_xilinx_of_match[] = { MODULE_DEVICE_TABLE(of, ehci_hcd_xilinx_of_match); static struct of_platform_driver ehci_hcd_xilinx_of_driver = { - .name = "xilinx-of-ehci", - .match_table = ehci_hcd_xilinx_of_match, .probe = ehci_hcd_xilinx_of_probe, .remove = ehci_hcd_xilinx_of_remove, .shutdown = ehci_hcd_xilinx_of_shutdown, - .driver = { - .name = "xilinx-of-ehci", - .owner = THIS_MODULE, + .driver = { + .name = "xilinx-of-ehci", + .owner = THIS_MODULE, + .of_match_table = ehci_hcd_xilinx_of_match, }, }; diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 6135732d8057..7b5c62654bfd 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -813,8 +813,11 @@ static const struct of_device_id of_fhci_match[] = { MODULE_DEVICE_TABLE(of, of_fhci_match); static struct of_platform_driver of_fhci_driver = { - .name = "fsl,usb-fhci", - .match_table = of_fhci_match, + .driver = { + .name = "fsl,usb-fhci", + .owner = THIS_MODULE, + .of_match_table = of_fhci_match, + }, .probe = of_fhci_probe, .remove = __devexit_p(of_fhci_remove), }; diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 36360e24a9b9..100d5faebe3c 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -121,8 +121,11 @@ static const struct of_device_id of_isp1760_match[] = { MODULE_DEVICE_TABLE(of, of_isp1760_match); static struct of_platform_driver isp1760_of_driver = { - .name = "nxp-isp1760", - .match_table = of_isp1760_match, + .driver = { + .name = "nxp-isp1760", + .owner = THIS_MODULE, + .of_match_table = of_isp1760_match, + }, .probe = of_isp1760_probe, .remove = of_isp1760_remove, }; diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 003aea21c35e..df165917412a 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -244,18 +244,13 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match); static struct of_platform_driver ohci_hcd_ppc_of_driver = { - .name = "ppc-of-ohci", - .match_table = ohci_hcd_ppc_of_match, .probe = ohci_hcd_ppc_of_probe, .remove = ohci_hcd_ppc_of_remove, .shutdown = ohci_hcd_ppc_of_shutdown, -#ifdef CONFIG_PM - /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ - /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ -#endif - .driver = { - .name = "ppc-of-ohci", - .owner = THIS_MODULE, + .driver = { + .name = "ppc-of-ohci", + .owner = THIS_MODULE, + .of_match_table = ohci_hcd_ppc_of_match, }, }; diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 43320925c4ce..2c371c07f0da 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -376,8 +376,11 @@ static const struct of_device_id bw2_match[] = { MODULE_DEVICE_TABLE(of, bw2_match); static struct of_platform_driver bw2_driver = { - .name = "bw2", - .match_table = bw2_match, + .driver = { + .name = "bw2", + .owner = THIS_MODULE, + .of_match_table = bw2_match, + }, .probe = bw2_probe, .remove = __devexit_p(bw2_remove), }; diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 77a040af20a7..d12e05b6e63f 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -596,8 +596,11 @@ static const struct of_device_id cg14_match[] = { MODULE_DEVICE_TABLE(of, cg14_match); static struct of_platform_driver cg14_driver = { - .name = "cg14", - .match_table = cg14_match, + .driver = { + .name = "cg14", + .owner = THIS_MODULE, + .of_match_table = cg14_match, + }, .probe = cg14_probe, .remove = __devexit_p(cg14_remove), }; diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 30eedf79322c..b98f93f7f663 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -463,8 +463,11 @@ static const struct of_device_id cg3_match[] = { MODULE_DEVICE_TABLE(of, cg3_match); static struct of_platform_driver cg3_driver = { - .name = "cg3", - .match_table = cg3_match, + .driver = { + .name = "cg3", + .owner = THIS_MODULE, + .of_match_table = cg3_match, + }, .probe = cg3_probe, .remove = __devexit_p(cg3_remove), }; diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 7f59b0fe5dc2..480d761a27a8 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -856,8 +856,11 @@ static const struct of_device_id cg6_match[] = { MODULE_DEVICE_TABLE(of, cg6_match); static struct of_platform_driver cg6_driver = { - .name = "cg6", - .match_table = cg6_match, + .driver = { + .name = "cg6", + .owner = THIS_MODULE, + .of_match_table = cg6_match, + }, .probe = cg6_probe, .remove = __devexit_p(cg6_remove), }; diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index ddd46f71e250..95c0227f47fc 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -1053,8 +1053,11 @@ static const struct of_device_id ffb_match[] = { MODULE_DEVICE_TABLE(of, ffb_match); static struct of_platform_driver ffb_driver = { - .name = "ffb", - .match_table = ffb_match, + .driver = { + .name = "ffb", + .owner = THIS_MODULE, + .of_match_table = ffb_match, + }, .probe = ffb_probe, .remove = __devexit_p(ffb_remove), }; diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 930a2522a631..27455ce298b7 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -1647,9 +1647,11 @@ static struct of_device_id fsl_diu_match[] = { MODULE_DEVICE_TABLE(of, fsl_diu_match); static struct of_platform_driver fsl_diu_driver = { - .owner = THIS_MODULE, - .name = "fsl_diu", - .match_table = fsl_diu_match, + .driver = { + .name = "fsl_diu", + .owner = THIS_MODULE, + .of_match_table = fsl_diu_match, + }, .probe = fsl_diu_probe, .remove = fsl_diu_remove, .suspend = fsl_diu_suspend, diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 1db55f128490..3d7895316eaf 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -663,8 +663,11 @@ static const struct of_device_id leo_match[] = { MODULE_DEVICE_TABLE(of, leo_match); static struct of_platform_driver leo_driver = { - .name = "leo", - .match_table = leo_match, + .driver = { + .name = "leo", + .owner = THIS_MODULE, + .of_match_table = leo_match, + }, .probe = leo_probe, .remove = __devexit_p(leo_remove), }; diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c index 8280a58a0e55..0540de4f5cb4 100644 --- a/drivers/video/mb862xx/mb862xxfb.c +++ b/drivers/video/mb862xx/mb862xxfb.c @@ -718,9 +718,11 @@ static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = { }; static struct of_platform_driver of_platform_mb862xxfb_driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - .match_table = of_platform_mb862xx_tbl, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = of_platform_mb862xx_tbl, + }, .probe = of_platform_mb862xx_probe, .remove = __devexit_p(of_platform_mb862xx_remove), }; diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index 81440f2b9091..c85dd408a9b8 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -353,8 +353,11 @@ static const struct of_device_id p9100_match[] = { MODULE_DEVICE_TABLE(of, p9100_match); static struct of_platform_driver p9100_driver = { - .name = "p9100", - .match_table = p9100_match, + .driver = { + .name = "p9100", + .owner = THIS_MODULE, + .of_match_table = p9100_match, + }, .probe = p9100_probe, .remove = __devexit_p(p9100_remove), }; diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 69d78d50f0f6..72a1f4c04732 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -679,8 +679,11 @@ static struct of_device_id platinumfb_match[] = static struct of_platform_driver platinum_driver = { - .name = "platinumfb", - .match_table = platinumfb_match, + .driver = { + .name = "platinumfb", + .owner = THIS_MODULE, + .of_match_table = platinumfb_match, + }, .probe = platinumfb_probe, .remove = platinumfb_remove, }; diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c index ad92a200fafa..489b44e8db81 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/sunxvr1000.c @@ -199,10 +199,13 @@ static const struct of_device_id gfb_match[] = { MODULE_DEVICE_TABLE(of, ffb_match); static struct of_platform_driver gfb_driver = { - .name = "gfb", - .match_table = gfb_match, .probe = gfb_probe, .remove = __devexit_p(gfb_remove), + .driver = { + .name = "gfb", + .owner = THIS_MODULE, + .of_match_table = gfb_match, + }, }; static int __init gfb_init(void) diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index c0c2b18fcdcf..ef7a7bd8b503 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -512,8 +512,11 @@ static const struct of_device_id tcx_match[] = { MODULE_DEVICE_TABLE(of, tcx_match); static struct of_platform_driver tcx_driver = { - .name = "tcx", - .match_table = tcx_match, + .driver = { + .name = "tcx", + .owner = THIS_MODULE, + .of_match_table = tcx_match, + }, .probe = tcx_probe, .remove = __devexit_p(tcx_remove), }; diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 6fcec553662c..574dc54e12d4 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -492,13 +492,12 @@ static struct of_device_id xilinxfb_of_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, xilinxfb_of_match); static struct of_platform_driver xilinxfb_of_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = xilinxfb_of_match, .probe = xilinxfb_of_probe, .remove = __devexit_p(xilinxfb_of_remove), .driver = { .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = xilinxfb_of_match, }, }; diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 2fcc3cf7ef62..d62b9ce8f773 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -677,8 +677,11 @@ static const struct of_device_id cpwd_match[] = { MODULE_DEVICE_TABLE(of, cpwd_match); static struct of_platform_driver cpwd_driver = { - .name = DRIVER_NAME, - .match_table = cpwd_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = cpwd_match, + }, .probe = cpwd_probe, .remove = __devexit_p(cpwd_remove), }; diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index abdbad034a6c..ca0f4c6cf5ab 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -303,9 +303,11 @@ static const struct of_device_id gef_wdt_ids[] = { }; static struct of_platform_driver gef_wdt_driver = { - .owner = THIS_MODULE, - .name = "gef_wdt", - .match_table = gef_wdt_ids, + .driver = { + .name = "gef_wdt", + .owner = THIS_MODULE, + .of_match_table = gef_wdt_ids, + }, .probe = gef_wdt_probe, }; diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 4e3941c5e293..7b55974191dd 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -273,12 +273,12 @@ static const struct of_device_id mpc8xxx_wdt_match[] = { MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match); static struct of_platform_driver mpc8xxx_wdt_driver = { - .match_table = mpc8xxx_wdt_match, .probe = mpc8xxx_wdt_probe, .remove = __devexit_p(mpc8xxx_wdt_remove), - .driver = { - .name = "mpc8xxx_wdt", - .owner = THIS_MODULE, + .driver = { + .name = "mpc8xxx_wdt", + .owner = THIS_MODULE, + .of_match_table = mpc8xxx_wdt_match, }, }; diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index ea7f803f6248..5dceeddc8859 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -239,8 +239,11 @@ static const struct of_device_id riowd_match[] = { MODULE_DEVICE_TABLE(of, riowd_match); static struct of_platform_driver riowd_driver = { - .name = DRIVER_NAME, - .match_table = riowd_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = riowd_match, + }, .probe = riowd_probe, .remove = __devexit_p(riowd_remove), }; diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index ac3ae0758fbe..1643d3761eb4 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -31,10 +31,6 @@ extern struct bus_type of_platform_bus_type; */ struct of_platform_driver { - const char *name; - const struct of_device_id *match_table; - struct module *owner; - int (*probe)(struct of_device* dev, const struct of_device_id *match); int (*remove)(struct of_device* dev); diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 3dbc7f7cd7b9..e2ee220bfb7e 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -317,12 +317,12 @@ static struct of_device_id psc_ac97_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, psc_ac97_match); static struct of_platform_driver psc_ac97_driver = { - .match_table = psc_ac97_match, .probe = psc_ac97_of_probe, .remove = __devexit_p(psc_ac97_of_remove), .driver = { .name = "mpc5200-psc-ac97", .owner = THIS_MODULE, + .of_match_table = psc_ac97_match, }, }; diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index 748cc0f0df38..4f455bd6851f 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -220,12 +220,12 @@ static struct of_device_id psc_i2s_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, psc_i2s_match); static struct of_platform_driver psc_i2s_driver = { - .match_table = psc_i2s_match, .probe = psc_i2s_of_probe, .remove = __devexit_p(psc_i2s_of_remove), .driver = { .name = "mpc5200-psc-i2s", .owner = THIS_MODULE, + .of_match_table = psc_i2s_match, }, }; diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index e3f78f255a60..6a2764ee8203 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -580,9 +580,11 @@ static struct of_device_id mpc8610_hpcd_match[] = { MODULE_DEVICE_TABLE(of, mpc8610_hpcd_match); static struct of_platform_driver mpc8610_hpcd_of_driver = { - .owner = THIS_MODULE, - .name = "mpc8610_hpcd", - .match_table = mpc8610_hpcd_match, + .driver = { + .name = "mpc8610_hpcd", + .owner = THIS_MODULE, + .of_match_table = mpc8610_hpcd_match, + }, .probe = mpc8610_hpcd_probe, .remove = mpc8610_hpcd_remove, }; diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 574af56ba8a6..71221fd20944 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -1065,8 +1065,11 @@ static const struct of_device_id amd7930_match[] = { }; static struct of_platform_driver amd7930_sbus_driver = { - .name = "audio", - .match_table = amd7930_match, + .driver = { + .name = "audio", + .owner = THIS_MODULE, + .of_match_table = amd7930_match, + }, .probe = amd7930_sbus_probe, }; diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 6a4c872e00df..fb4c6f2f29e5 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -2109,8 +2109,11 @@ static const struct of_device_id cs4231_match[] = { MODULE_DEVICE_TABLE(of, cs4231_match); static struct of_platform_driver cs4231_driver = { - .name = "audio", - .match_table = cs4231_match, + .driver = { + .name = "audio", + .owner = THIS_MODULE, + .of_match_table = cs4231_match, + }, .probe = cs4231_probe, .remove = __devexit_p(cs4231_remove), }; diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 1b5192eb5ae5..1557bf132e73 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2687,8 +2687,11 @@ static const struct of_device_id dbri_match[] = { MODULE_DEVICE_TABLE(of, dbri_match); static struct of_platform_driver dbri_sbus_driver = { - .name = "dbri", - .match_table = dbri_match, + .driver = { + .name = "dbri", + .owner = THIS_MODULE, + .of_match_table = dbri_match, + }, .probe = dbri_probe, .remove = __devexit_p(dbri_remove), }; -- cgit v1.2.3-59-g8ed1b From b2e25838c5f3508ccd6184be65aca228fc600540 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Wed, 19 May 2010 23:12:19 +0000 Subject: sh: remove duplicated #include Remove duplicated #include('s) in arch/sh/kernel/cpu/sh4a/clock-sh7786.c Signed-off-by: Huang Weiyi Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 105a6d41b569..597c9fbe49c6 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From d8252d6272682096835b4e1ef714cb1b593aa7fb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 20 May 2010 20:46:27 +0900 Subject: sh: fix up the dwarf unwinder build for MODULES=n. Presently the dwarf unwinder build blows up if modules are disabled, fix it up. Signed-off-by: Paul Mundt --- arch/sh/kernel/dwarf.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 5ec1d1818691..886d7d83ace3 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -845,8 +845,10 @@ static int dwarf_parse_cie(void *entry, void *p, unsigned long len, rb_link_node(&cie->node, parent, rb_node); rb_insert_color(&cie->node, &cie_root); +#ifdef CONFIG_MODULES if (mod != NULL) list_add_tail(&cie->link, &mod->arch.cie_list); +#endif spin_unlock_irqrestore(&dwarf_cie_lock, flags); @@ -935,8 +937,10 @@ static int dwarf_parse_fde(void *entry, u32 entry_type, rb_link_node(&fde->node, parent, rb_node); rb_insert_color(&fde->node, &fde_root); +#ifdef CONFIG_MODULES if (mod != NULL) list_add_tail(&fde->link, &mod->arch.fde_list); +#endif spin_unlock_irqrestore(&dwarf_fde_lock, flags); -- cgit v1.2.3-59-g8ed1b From aee5ab0bbd224b618408cacfcc656699feec4230 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 21 Apr 2010 08:45:25 +0000 Subject: sh: add Video Output Unit and AK8813 video encoder support on ecovec Ecovec uses the AK8813 video envoder similarly to the ms7724se platform with the only difference, that on ecovec GPIOs are used for resetting and powering up and down the chip. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 78 ++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'arch') diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 62123885a6fa..7bca78118039 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -769,6 +769,51 @@ static struct platform_device irda_device = { .resource = irda_resources, }; +#include +#include + +struct ak881x_pdata ak881x_pdata = { + .flags = AK881X_IF_MODE_SLAVE, +}; + +static struct i2c_board_info ak8813 = { + I2C_BOARD_INFO("ak8813", 0x20), + .platform_data = &ak881x_pdata, +}; + +struct sh_vou_pdata sh_vou_pdata = { + .bus_fmt = SH_VOU_BUS_8BIT, + .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, + .board_info = &ak8813, + .i2c_adap = 0, + .module_name = "ak881x", +}; + +static struct resource sh_vou_resources[] = { + [0] = { + .start = 0xfe960000, + .end = 0xfe962043, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 55, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device vou_device = { + .name = "sh-vou", + .id = -1, + .num_resources = ARRAY_SIZE(sh_vou_resources), + .resource = sh_vou_resources, + .dev = { + .platform_data = &sh_vou_pdata, + }, + .archdata = { + .hwblk_id = HWBLK_VOU, + }, +}; + static struct platform_device *ecovec_devices[] __initdata = { &heartbeat_device, &nor_flash_device, @@ -790,6 +835,7 @@ static struct platform_device *ecovec_devices[] __initdata = { &camera_devices[2], &fsi_device, &irda_device, + &vou_device, }; #ifdef CONFIG_I2C @@ -1179,6 +1225,38 @@ static int __init arch_setup(void) i2c_register_board_info(1, i2c1_devices, ARRAY_SIZE(i2c1_devices)); + /* VOU */ + gpio_request(GPIO_FN_DV_D15, NULL); + gpio_request(GPIO_FN_DV_D14, NULL); + gpio_request(GPIO_FN_DV_D13, NULL); + gpio_request(GPIO_FN_DV_D12, NULL); + gpio_request(GPIO_FN_DV_D11, NULL); + gpio_request(GPIO_FN_DV_D10, NULL); + gpio_request(GPIO_FN_DV_D9, NULL); + gpio_request(GPIO_FN_DV_D8, NULL); + gpio_request(GPIO_FN_DV_CLKI, NULL); + gpio_request(GPIO_FN_DV_CLK, NULL); + gpio_request(GPIO_FN_DV_VSYNC, NULL); + gpio_request(GPIO_FN_DV_HSYNC, NULL); + + /* AK8813 power / reset sequence */ + gpio_request(GPIO_PTG4, NULL); + gpio_request(GPIO_PTU3, NULL); + /* Reset */ + gpio_direction_output(GPIO_PTG4, 0); + /* Power down */ + gpio_direction_output(GPIO_PTU3, 1); + + udelay(10); + + /* Power up, reset */ + gpio_set_value(GPIO_PTU3, 0); + + udelay(10); + + /* Remove reset */ + gpio_set_value(GPIO_PTG4, 1); + return platform_add_devices(ecovec_devices, ARRAY_SIZE(ecovec_devices)); } -- cgit v1.2.3-59-g8ed1b From 2d151248286d438e97ebb22ff676423df299da86 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 29 Mar 2010 07:45:28 +0000 Subject: sh: add Video Output Unit (VOU) and AK8813 TV-encoder support to ms7724se Add platform bindings, GPIO initialisation and allocation and AK8813 reset code to ms7724se. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/setup.c | 90 +++++++++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index e74ae7b0d8bf..60f0387a69d1 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -515,6 +515,52 @@ static struct platform_device irda_device = { .resource = irda_resources, }; +#include +#include + +struct ak881x_pdata ak881x_pdata = { + .flags = AK881X_IF_MODE_SLAVE, +}; + +static struct i2c_board_info ak8813 = { + /* With open J18 jumper address is 0x21 */ + I2C_BOARD_INFO("ak8813", 0x20), + .platform_data = &ak881x_pdata, +}; + +struct sh_vou_pdata sh_vou_pdata = { + .bus_fmt = SH_VOU_BUS_8BIT, + .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, + .board_info = &ak8813, + .i2c_adap = 0, + .module_name = "ak881x", +}; + +static struct resource sh_vou_resources[] = { + [0] = { + .start = 0xfe960000, + .end = 0xfe962043, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 55, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device vou_device = { + .name = "sh-vou", + .id = -1, + .num_resources = ARRAY_SIZE(sh_vou_resources), + .resource = sh_vou_resources, + .dev = { + .platform_data = &sh_vou_pdata, + }, + .archdata = { + .hwblk_id = HWBLK_VOU, + }, +}; + static struct platform_device *ms7724se_devices[] __initdata = { &heartbeat_device, &smc91x_eth_device, @@ -530,6 +576,7 @@ static struct platform_device *ms7724se_devices[] __initdata = { &sdhi0_cn7_device, &sdhi1_cn8_device, &irda_device, + &vou_device, }; /* I2C device */ @@ -614,6 +661,7 @@ static int __init devices_setup(void) { u16 sw = __raw_readw(SW4140); /* select camera, monitor */ struct clk *clk; + u16 fpga_out; /* register board specific self-refresh code */ sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF | @@ -623,14 +671,26 @@ static int __init devices_setup(void) &ms7724se_sdram_leave_start, &ms7724se_sdram_leave_end); /* Reset Release */ - __raw_writew(__raw_readw(FPGA_OUT) & - ~((1 << 1) | /* LAN */ - (1 << 6) | /* VIDEO DAC */ - (1 << 7) | /* AK4643 */ - (1 << 8) | /* IrDA */ - (1 << 12) | /* USB0 */ - (1 << 14)), /* RMII */ - FPGA_OUT); + fpga_out = __raw_readw(FPGA_OUT); + /* bit4: NTSC_PDN, bit5: NTSC_RESET */ + fpga_out &= ~((1 << 1) | /* LAN */ + (1 << 4) | /* AK8813 PDN */ + (1 << 5) | /* AK8813 RESET */ + (1 << 6) | /* VIDEO DAC */ + (1 << 7) | /* AK4643 */ + (1 << 8) | /* IrDA */ + (1 << 12) | /* USB0 */ + (1 << 14)); /* RMII */ + __raw_writew(fpga_out | (1 << 4), FPGA_OUT); + + udelay(10); + + /* AK8813 RESET */ + __raw_writew(fpga_out | (1 << 5), FPGA_OUT); + + udelay(10); + + __raw_writew(fpga_out, FPGA_OUT); /* turn on USB clocks, use external clock */ __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB); @@ -862,6 +922,20 @@ static int __init devices_setup(void) lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL; } + /* VOU */ + gpio_request(GPIO_FN_DV_D15, NULL); + gpio_request(GPIO_FN_DV_D14, NULL); + gpio_request(GPIO_FN_DV_D13, NULL); + gpio_request(GPIO_FN_DV_D12, NULL); + gpio_request(GPIO_FN_DV_D11, NULL); + gpio_request(GPIO_FN_DV_D10, NULL); + gpio_request(GPIO_FN_DV_D9, NULL); + gpio_request(GPIO_FN_DV_D8, NULL); + gpio_request(GPIO_FN_DV_CLKI, NULL); + gpio_request(GPIO_FN_DV_CLK, NULL); + gpio_request(GPIO_FN_DV_VSYNC, NULL); + gpio_request(GPIO_FN_DV_HSYNC, NULL); + return platform_add_devices(ms7724se_devices, ARRAY_SIZE(ms7724se_devices)); } -- cgit v1.2.3-59-g8ed1b From 10440af1bc8082c78186e7f4ea94124acee6625e Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:33:54 +0000 Subject: sh: define DMA slaves per CPU type, remove now redundant header Now that DMA slave IDs are only used used in platform specific code and have become opaque cookies for the rest of the code, we can make the, CPU specific too. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/include/asm/dmaengine.h | 34 ---------------------------------- arch/sh/include/asm/siu.h | 2 -- arch/sh/include/cpu-sh4/cpu/sh7722.h | 15 +++++++++++++++ arch/sh/include/cpu-sh4/cpu/sh7724.h | 19 +++++++++++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 1 - arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 3 +-- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 2 +- sound/soc/sh/siu.h | 3 +-- sound/soc/sh/siu_pcm.c | 9 ++++----- 10 files changed, 42 insertions(+), 48 deletions(-) delete mode 100644 arch/sh/include/asm/dmaengine.h (limited to 'arch') diff --git a/arch/sh/include/asm/dmaengine.h b/arch/sh/include/asm/dmaengine.h deleted file mode 100644 index 2a02b611a9ad..000000000000 --- a/arch/sh/include/asm/dmaengine.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Header for the new SH dmaengine driver - * - * Copyright (C) 2010 Guennadi Liakhovetski - * - * 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. - */ -#ifndef ASM_DMAENGINE_H -#define ASM_DMAENGINE_H - -#include - -enum { - SHDMA_SLAVE_SCIF0_TX, - SHDMA_SLAVE_SCIF0_RX, - SHDMA_SLAVE_SCIF1_TX, - SHDMA_SLAVE_SCIF1_RX, - SHDMA_SLAVE_SCIF2_TX, - SHDMA_SLAVE_SCIF2_RX, - SHDMA_SLAVE_SCIF3_TX, - SHDMA_SLAVE_SCIF3_RX, - SHDMA_SLAVE_SCIF4_TX, - SHDMA_SLAVE_SCIF4_RX, - SHDMA_SLAVE_SCIF5_TX, - SHDMA_SLAVE_SCIF5_RX, - SHDMA_SLAVE_SIUA_TX, - SHDMA_SLAVE_SIUA_RX, - SHDMA_SLAVE_SIUB_TX, - SHDMA_SLAVE_SIUB_RX, -}; - -#endif diff --git a/arch/sh/include/asm/siu.h b/arch/sh/include/asm/siu.h index e8d4142baf59..1d95c78808d1 100644 --- a/arch/sh/include/asm/siu.h +++ b/arch/sh/include/asm/siu.h @@ -11,8 +11,6 @@ #ifndef ASM_SIU_H #define ASM_SIU_H -#include - struct device; struct siu_platform { diff --git a/arch/sh/include/cpu-sh4/cpu/sh7722.h b/arch/sh/include/cpu-sh4/cpu/sh7722.h index 48560407cbe1..7a5b8a331b4a 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7722.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7722.h @@ -235,4 +235,19 @@ enum { HWBLK_NR, }; +enum { + SHDMA_SLAVE_SCIF0_TX, + SHDMA_SLAVE_SCIF0_RX, + SHDMA_SLAVE_SCIF1_TX, + SHDMA_SLAVE_SCIF1_RX, + SHDMA_SLAVE_SCIF2_TX, + SHDMA_SLAVE_SCIF2_RX, + SHDMA_SLAVE_SIUA_TX, + SHDMA_SLAVE_SIUA_RX, + SHDMA_SLAVE_SIUB_TX, + SHDMA_SLAVE_SIUB_RX, + SHDMA_SLAVE_SDHI0_TX, + SHDMA_SLAVE_SDHI0_RX, +}; + #endif /* __ASM_SH7722_H__ */ diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h index 0cd1f71a1116..fbbf550cc529 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7724.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h @@ -283,4 +283,23 @@ enum { HWBLK_NR, }; +enum { + SHDMA_SLAVE_SCIF0_TX, + SHDMA_SLAVE_SCIF0_RX, + SHDMA_SLAVE_SCIF1_TX, + SHDMA_SLAVE_SCIF1_RX, + SHDMA_SLAVE_SCIF2_TX, + SHDMA_SLAVE_SCIF2_RX, + SHDMA_SLAVE_SCIF3_TX, + SHDMA_SLAVE_SCIF3_RX, + SHDMA_SLAVE_SCIF4_TX, + SHDMA_SLAVE_SCIF4_RX, + SHDMA_SLAVE_SCIF5_TX, + SHDMA_SLAVE_SCIF5_RX, + SHDMA_SLAVE_SDHI0_TX, + SHDMA_SLAVE_SDHI0_RX, + SHDMA_SLAVE_SDHI1_TX, + SHDMA_SLAVE_SDHI1_RX, +}; + #endif /* __ASM_SH7724_H__ */ diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 24c6167a7181..c7219de6c4e4 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 89fe16d20fdb..abd4c2e501db 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -18,13 +18,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index b12f537e4dde..0f414864f76b 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -12,10 +12,9 @@ #include #include #include +#include #include -#include - #include static struct plat_sci_port scif0_platform_data = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index f3e3ea0ce050..c9a572bc6dc8 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -13,9 +13,9 @@ #include #include #include +#include #include -#include #include #include diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h index c0bfab8fed3d..492b1cae24cc 100644 --- a/sound/soc/sh/siu.h +++ b/sound/soc/sh/siu.h @@ -71,8 +71,7 @@ struct siu_firmware { #include #include #include - -#include +#include #include #include diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index 8f85719212f9..36170be15aa7 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -31,7 +31,6 @@ #include #include -#include #include #include "siu.h" @@ -358,13 +357,13 @@ static int siu_pcm_open(struct snd_pcm_substream *ss) if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) { siu_stream = &port_info->playback; param = &siu_stream->param; - param->slave_id = port ? SHDMA_SLAVE_SIUB_TX : - SHDMA_SLAVE_SIUA_TX; + param->slave_id = port ? pdata->dma_slave_tx_b : + pdata->dma_slave_tx_a; } else { siu_stream = &port_info->capture; param = &siu_stream->param; - param->slave_id = port ? SHDMA_SLAVE_SIUB_RX : - SHDMA_SLAVE_SIUA_RX; + param->slave_id = port ? pdata->dma_slave_rx_b : + pdata->dma_slave_rx_a; } param->dma_dev = pdata->dma_dev; -- cgit v1.2.3-59-g8ed1b From afd46501586a399bba73e4a5879e8a864ad083fe Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:33:59 +0000 Subject: sh: add DMA slaves for two SDHI controllers to sh7722 SuperH SDHI controllers can use DMA, add slave definitions to sh7722. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index c7219de6c4e4..156ccc960015 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -74,6 +74,16 @@ static const struct sh_dmae_slave_config sh7722_dmae_slaves[] = { .addr = 0xa454c094, .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), .mid_rid = 0xb6, + }, { + .slave_id = SHDMA_SLAVE_SDHI0_TX, + .addr = 0x04ce0030, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xc1, + }, { + .slave_id = SHDMA_SLAVE_SDHI0_RX, + .addr = 0x04ce0030, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xc2, }, }; -- cgit v1.2.3-59-g8ed1b From d62b8a985b74ac741233396b847562dacc45a5c1 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:34:03 +0000 Subject: sh: add DMA slave definitions to sh7724 Add a list of SCIF and SDHI DMA slave definitions to sh7724. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 86 ++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index abd4c2e501db..79c556e56262 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -31,6 +31,90 @@ #include /* DMA */ +static const struct sh_dmae_slave_config sh7724_dmae_slaves[] = { + { + .slave_id = SHDMA_SLAVE_SCIF0_TX, + .addr = 0xffe0000c, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x21, + }, { + .slave_id = SHDMA_SLAVE_SCIF0_RX, + .addr = 0xffe00014, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x22, + }, { + .slave_id = SHDMA_SLAVE_SCIF1_TX, + .addr = 0xffe1000c, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x25, + }, { + .slave_id = SHDMA_SLAVE_SCIF1_RX, + .addr = 0xffe10014, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x26, + }, { + .slave_id = SHDMA_SLAVE_SCIF2_TX, + .addr = 0xffe2000c, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x29, + }, { + .slave_id = SHDMA_SLAVE_SCIF2_RX, + .addr = 0xffe20014, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x2a, + }, { + .slave_id = SHDMA_SLAVE_SCIF3_TX, + .addr = 0xa4e30020, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x2d, + }, { + .slave_id = SHDMA_SLAVE_SCIF3_RX, + .addr = 0xa4e30024, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x2e, + }, { + .slave_id = SHDMA_SLAVE_SCIF4_TX, + .addr = 0xa4e40020, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x31, + }, { + .slave_id = SHDMA_SLAVE_SCIF4_RX, + .addr = 0xa4e40024, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x32, + }, { + .slave_id = SHDMA_SLAVE_SCIF5_TX, + .addr = 0xa4e50020, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x35, + }, { + .slave_id = SHDMA_SLAVE_SCIF5_RX, + .addr = 0xa4e50024, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x36, + }, { + .slave_id = SHDMA_SLAVE_SDHI0_TX, + .addr = 0x04ce0030, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xc1, + }, { + .slave_id = SHDMA_SLAVE_SDHI0_RX, + .addr = 0x04ce0030, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xc2, + }, { + .slave_id = SHDMA_SLAVE_SDHI1_TX, + .addr = 0x04cf0030, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xc9, + }, { + .slave_id = SHDMA_SLAVE_SDHI1_RX, + .addr = 0x04cf0030, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xca, + }, +}; + static const struct sh_dmae_channel sh7724_dmae_channels[] = { { .offset = 0, @@ -62,6 +146,8 @@ static const struct sh_dmae_channel sh7724_dmae_channels[] = { static const unsigned int ts_shift[] = TS_SHIFT; static struct sh_dmae_pdata dma_platform_data = { + .slave = sh7724_dmae_slaves, + .slave_num = ARRAY_SIZE(sh7724_dmae_slaves), .channel = sh7724_dmae_channels, .channel_num = ARRAY_SIZE(sh7724_dmae_channels), .ts_low_shift = CHCR_TS_LOW_SHIFT, -- cgit v1.2.3-59-g8ed1b From 815f1995f03112dec0767a6ab88cccf8cf198509 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:34:27 +0000 Subject: sh: Add SDHI DMA support to ecovec Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 7bca78118039..49714258732e 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -442,7 +443,9 @@ static void sdhi0_set_pwr(struct platform_device *pdev, int state) } static struct sh_mobile_sdhi_info sdhi0_info = { - .set_pwr = sdhi0_set_pwr, + .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, + .set_pwr = sdhi0_set_pwr, }; static struct resource sdhi0_resources[] = { @@ -478,7 +481,9 @@ static void sdhi1_set_pwr(struct platform_device *pdev, int state) } static struct sh_mobile_sdhi_info sdhi1_info = { - .set_pwr = sdhi1_set_pwr, + .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, + .set_pwr = sdhi1_set_pwr, }; static struct resource sdhi1_resources[] = { -- cgit v1.2.3-59-g8ed1b From 470ef1a71891102d300ed741164eb3c8c10c9190 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:34:32 +0000 Subject: sh: Add SDHI DMA support to ms7724se Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/setup.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'arch') diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 60f0387a69d1..f9b82546c2df 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -462,11 +463,19 @@ static struct resource sdhi0_cn7_resources[] = { }, }; +static struct sh_mobile_sdhi_info sh7724_sdhi0_data = { + .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, +}; + static struct platform_device sdhi0_cn7_device = { .name = "sh_mobile_sdhi", .id = 0, .num_resources = ARRAY_SIZE(sdhi0_cn7_resources), .resource = sdhi0_cn7_resources, + .dev = { + .platform_data = &sh7724_sdhi0_data, + }, .archdata = { .hwblk_id = HWBLK_SDHI0, }, @@ -485,11 +494,19 @@ static struct resource sdhi1_cn8_resources[] = { }, }; +static struct sh_mobile_sdhi_info sh7724_sdhi1_data = { + .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, +}; + static struct platform_device sdhi1_cn8_device = { .name = "sh_mobile_sdhi", .id = 1, .num_resources = ARRAY_SIZE(sdhi1_cn8_resources), .resource = sdhi1_cn8_resources, + .dev = { + .platform_data = &sh7724_sdhi1_data, + }, .archdata = { .hwblk_id = HWBLK_SDHI1, }, -- cgit v1.2.3-59-g8ed1b From 9e526bc70ae0a82d345e86aa85ebdccff2fd15b6 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:34:36 +0000 Subject: sh: Add SDHI DMA support to kfr2r09 Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/boards/mach-kfr2r09/setup.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index b2cd0ed8664e..95850aa1ee3c 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -356,10 +357,18 @@ static struct resource kfr2r09_sh_sdhi0_resources[] = { }, }; +static struct sh_mobile_sdhi_info sh7724_sdhi0_data = { + .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, +}; + static struct platform_device kfr2r09_sh_sdhi0_device = { .name = "sh_mobile_sdhi", .num_resources = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources), .resource = kfr2r09_sh_sdhi0_resources, + .dev = { + .platform_data = &sh7724_sdhi0_data, + }, .archdata = { .hwblk_id = HWBLK_SDHI0, }, -- cgit v1.2.3-59-g8ed1b From 65a1b0347a329422e939e14daae6dad9a29e9cf2 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:34:39 +0000 Subject: sh: Add SDHI DMA support to migor Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/boards/mach-migor/setup.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 7da0fc94a01e..87185de20446 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -402,10 +403,18 @@ static struct resource sdhi_cn9_resources[] = { }, }; +static struct sh_mobile_sdhi_info sh7724_sdhi_data = { + .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, +}; + static struct platform_device sdhi_cn9_device = { .name = "sh_mobile_sdhi", .num_resources = ARRAY_SIZE(sdhi_cn9_resources), .resource = sdhi_cn9_resources, + .dev = { + .platform_data = &sh7724_sdhi_data, + }, .archdata = { .hwblk_id = HWBLK_SDHI, }, -- cgit v1.2.3-59-g8ed1b From 8f4b3036d1b9bdb6f5fa0b920e0163d64a990327 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:36:13 +0000 Subject: sh: disable SD-card write-protection detection on kfr2r09 kfr2r09 board has a micro-SD card slot, therefore card write-protection detection cannot work there, disable it. Signed-off-by: Guennadi Liakhovetski Acked-by: Ian Molton Signed-off-by: Paul Mundt --- arch/sh/boards/mach-kfr2r09/setup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 95850aa1ee3c..68994a163f6c 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -358,8 +359,9 @@ static struct resource kfr2r09_sh_sdhi0_resources[] = { }; static struct sh_mobile_sdhi_info sh7724_sdhi0_data = { - .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, + .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, + .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, }; static struct platform_device kfr2r09_sh_sdhi0_device = { -- cgit v1.2.3-59-g8ed1b From ed0ad6d3a0720faa999e4bf9d4ed404cfd5eb4cc Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 22 May 2010 17:12:23 +0900 Subject: sh: fix up sh7786 dmaengine build. The asm/dmaengine.h header is gone now, update accordingly. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 81657091da46..8797723231ea 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -21,10 +21,10 @@ #include #include #include +#include #include #include #include -#include static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffea0000, -- cgit v1.2.3-59-g8ed1b From 9f37af654fda88a8dcca74c785f6c20e52758866 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 19 May 2010 15:08:17 +0200 Subject: uml: Pushdown the bkl from harddog_kern ioctl Pushdown the bkl to harddog_ioctl. Signed-off-by: Frederic Weisbecker Cc: Jeff Dike Cc: Uml Cc: Thomas Gleixner Cc: John Kacur Cc: Arnd Bergmann --- arch/um/drivers/harddog_kern.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c index d332503fa1be..cfcac1ff4cf2 100644 --- a/arch/um/drivers/harddog_kern.c +++ b/arch/um/drivers/harddog_kern.c @@ -124,8 +124,8 @@ static ssize_t harddog_write(struct file *file, const char __user *data, size_t return 0; } -static int harddog_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int harddog_ioctl_unlocked(struct file *file, + unsigned int cmd, unsigned long arg) { void __user *argp= (void __user *)arg; static struct watchdog_info ident = { @@ -148,10 +148,22 @@ static int harddog_ioctl(struct inode *inode, struct file *file, } } +static long harddog_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + long ret; + + lock_kernel(); + ret = harddog_ioctl_unlocked(file, cmd, arg); + unlock_kernel(); + + return ret; +} + static const struct file_operations harddog_fops = { .owner = THIS_MODULE, .write = harddog_write, - .ioctl = harddog_ioctl, + .unlocked_ioctl = harddog_ioctl, .open = harddog_open, .release = harddog_release, }; -- cgit v1.2.3-59-g8ed1b From 6ce3e9c2a2cfb8849dd471349fe5e6bc37c0f13f Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Tue, 16 Mar 2010 14:40:17 +0000 Subject: Blackfin: add support for the DBGA (debug assert) pseudo insn A few pseudo debug insns exist to make testing of simulators easier. Since these don't actually exist in the hardware, we have to have the exception handler take care of emulating these. This allows sim test cases to be executed unmodified under Linux and thus simplify debugging greatly. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/Kconfig.debug | 9 +++ arch/blackfin/include/asm/pseudo_instructions.h | 17 ++++++ arch/blackfin/kernel/Makefile | 1 + arch/blackfin/kernel/pseudodbg.c | 73 +++++++++++++++++++++++++ arch/blackfin/kernel/traps.c | 15 +++++ 5 files changed, 115 insertions(+) create mode 100644 arch/blackfin/include/asm/pseudo_instructions.h create mode 100644 arch/blackfin/kernel/pseudodbg.c (limited to 'arch') diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index aec89a5280b2..3c49f76b37bc 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug @@ -264,4 +264,13 @@ config BFIN_ISRAM_SELF_TEST help Run some self tests of the isram driver code at boot. +config BFIN_PSEUDODBG_INSNS + bool "Support pseudo debug instructions" + default n + help + This option allows the kernel to emulate some pseudo instructions which + allow simulator test cases to be run under Linux with no changes. + + Most people should say N here. + endmenu diff --git a/arch/blackfin/include/asm/pseudo_instructions.h b/arch/blackfin/include/asm/pseudo_instructions.h new file mode 100644 index 000000000000..7173719fb531 --- /dev/null +++ b/arch/blackfin/include/asm/pseudo_instructions.h @@ -0,0 +1,17 @@ +/* + * header file for pseudo instructions + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _BLACKFIN_PSEUDO_ +#define _BLACKFIN_PSEUDO_ + +#include +#include + +extern bool execute_pseudodbg_assert(struct pt_regs *fp, unsigned int opcode); + +#endif diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 2fc7f32ae32f..30d0d1f01dc7 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_EARLY_PRINTK) += shadow_console.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_DEBUG_VERBOSE) += trace.o +obj-$(CONFIG_BFIN_PSEUDODBG_INSNS) += pseudodbg.o # the kgdb test puts code into L2 and without linker # relaxation, we need to force long calls to/from it diff --git a/arch/blackfin/kernel/pseudodbg.c b/arch/blackfin/kernel/pseudodbg.c new file mode 100644 index 000000000000..4474b8db3501 --- /dev/null +++ b/arch/blackfin/kernel/pseudodbg.c @@ -0,0 +1,73 @@ +/* The fake debug assert instructions + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later + */ + +#include +#include +#include + +#define PseudoDbg_Assert_opcode 0xf0000000 +#define PseudoDbg_Assert_expected_bits 0 +#define PseudoDbg_Assert_expected_mask 0xffff +#define PseudoDbg_Assert_regtest_bits 16 +#define PseudoDbg_Assert_regtest_mask 0x7 +#define PseudoDbg_Assert_grp_bits 19 +#define PseudoDbg_Assert_grp_mask 0x7 +#define PseudoDbg_Assert_dbgop_bits 22 +#define PseudoDbg_Assert_dbgop_mask 0x3 +#define PseudoDbg_Assert_dontcare_bits 24 +#define PseudoDbg_Assert_dontcare_mask 0x7 +#define PseudoDbg_Assert_code_bits 27 +#define PseudoDbg_Assert_code_mask 0x1f + +bool execute_pseudodbg_assert(struct pt_regs *fp, unsigned int opcode) +{ + int expected = ((opcode >> PseudoDbg_Assert_expected_bits) & PseudoDbg_Assert_expected_mask); + int dbgop = ((opcode >> (PseudoDbg_Assert_dbgop_bits)) & PseudoDbg_Assert_dbgop_mask); + int grp = ((opcode >> (PseudoDbg_Assert_grp_bits)) & PseudoDbg_Assert_grp_mask); + int regtest = ((opcode >> (PseudoDbg_Assert_regtest_bits)) & PseudoDbg_Assert_regtest_mask); + long *value = &fp->r0; + + if ((opcode & 0xFF000000) != PseudoDbg_Assert_opcode) + return false; + + /* Only do Dregs and Pregs for now */ + if (grp > 1) + return false; + + /* + * Unfortunately, the pt_regs structure is not laid out the same way as the + * hardware register file, so we need to do some fix ups. + */ + if (grp == 0 || (grp == 1 && regtest < 6)) + value -= (regtest + 8 * grp); + else if (grp == 1 && regtest == 6) + value = &fp->usp; + else if (grp == 1 && regtest == 7) + value = &fp->fp; + + if (dbgop == 0 || dbgop == 2) { + /* DBGA ( regs_lo , uimm16 ) */ + /* DBGAL ( regs , uimm16 ) */ + if (expected != (*value & 0xFFFF)) { + pr_notice("DBGA (%s%i.L,0x%x) failure, got 0x%x\n", grp ? "P" : "R", + regtest, expected, (unsigned int)(*value & 0xFFFF)); + return false; + } + + } else if (dbgop == 1 || dbgop == 3) { + /* DBGA ( regs_hi , uimm16 ) */ + /* DBGAH ( regs , uimm16 ) */ + if (expected != ((*value >> 16) & 0xFFFF)) { + pr_notice("DBGA (%s%i.H,0x%x) failure, got 0x%x\n", grp ? "P" : "R", + regtest, expected, (unsigned int)((*value >> 16) & 0xFFFF)); + return false; + } + } + + fp->pc += 4; + return true; +} diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index fffcf8a516bf..9369836365bb 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef CONFIG_KGDB # include @@ -67,6 +68,9 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) { #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON int j; +#endif +#ifdef CONFIG_BFIN_PSEUDODBG_INSNS + int opcode; #endif unsigned int cpu = raw_smp_processor_id(); const char *strerror = NULL; @@ -199,6 +203,17 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) panic("BUG()"); } } +#endif +#ifdef CONFIG_BFIN_PSEUDODBG_INSNS + /* + * Support for the fake instructions, if the instruction fails, + * then just execute a illegal opcode failure (like normal). + * Don't support these instructions inside the kernel + */ + if (!kernel_mode_regs(fp) && get_instruction(&opcode, (unsigned short *)fp->pc)) { + if (execute_pseudodbg_assert(fp, opcode)) + goto traps_done; + } #endif info.si_code = ILL_ILLOPC; sig = SIGILL; -- cgit v1.2.3-59-g8ed1b From c429886a7091f9d26dee7d01c20fd822f62c35e0 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Wed, 17 Mar 2010 09:00:32 +0000 Subject: Blackfin: allow NMI watchdog to be used w/RETN as a scratch reg NMIs are not safe to return from because many anomaly workarounds are implemented by disabling interrupts. The NMI obviously violates this assumption. Since the NMI watchdog never returns, we don't have to worry about it clobbering RETN when it is being used as a scratch register with the exception stack. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger --- arch/blackfin/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index 3c49f76b37bc..d1825cb24768 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug @@ -238,7 +238,7 @@ config EARLY_PRINTK config NMI_WATCHDOG bool "Enable NMI watchdog to help debugging lockup on SMP" default n - depends on (SMP && !BFIN_SCRATCH_REG_RETN) + depends on SMP help If any CPU in the system does not execute the period local timer interrupt for more than 5 seconds, then the NMI handler dumps debug -- cgit v1.2.3-59-g8ed1b From 6a4110c2b38da51b767e389a6fb477072cf5843c Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Tue, 23 Mar 2010 17:27:41 +0000 Subject: Blackfin: change the BUG opcode to an unused 16-bit opcode The current BUG opcode includes the bit that flags the insn as a 32bit opcode, but it wasn't declaring it as 32bits. So pick an unused 16bit. URL: http://blackfin.uclinux.org/gf/tracker/5973 Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/bug.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/blackfin/include/asm/bug.h b/arch/blackfin/include/asm/bug.h index 75f6dc336d46..8d9b1eba89c4 100644 --- a/arch/blackfin/include/asm/bug.h +++ b/arch/blackfin/include/asm/bug.h @@ -9,7 +9,12 @@ #ifdef CONFIG_BUG -#define BFIN_BUG_OPCODE 0xefcd +/* + * This can be any undefined 16-bit opcode, meaning + * ((opcode & 0xc000) != 0xc000) + * Anything from 0x0001 to 0x000A (inclusive) will work + */ +#define BFIN_BUG_OPCODE 0x0001 #ifdef CONFIG_DEBUG_BUGVERBOSE -- cgit v1.2.3-59-g8ed1b From dc89d97fc73176c883b32ff21ae6f1164ca20d05 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sun, 28 Mar 2010 12:50:53 +0000 Subject: Blackfin: add support for the DBG (debug output) pseudo insn Another pseudo insn used by Blackfin simulators. Also factor some now common register lookup code out of the DBGA handlers. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/pseudo_instructions.h | 1 + arch/blackfin/kernel/pseudodbg.c | 86 +++++++++++++++++++------ arch/blackfin/kernel/traps.c | 2 + 3 files changed, 71 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/include/asm/pseudo_instructions.h b/arch/blackfin/include/asm/pseudo_instructions.h index 7173719fb531..b00adfa08169 100644 --- a/arch/blackfin/include/asm/pseudo_instructions.h +++ b/arch/blackfin/include/asm/pseudo_instructions.h @@ -13,5 +13,6 @@ #include extern bool execute_pseudodbg_assert(struct pt_regs *fp, unsigned int opcode); +extern bool execute_pseudodbg(struct pt_regs *fp, unsigned int opcode); #endif diff --git a/arch/blackfin/kernel/pseudodbg.c b/arch/blackfin/kernel/pseudodbg.c index 4474b8db3501..a5a4636124aa 100644 --- a/arch/blackfin/kernel/pseudodbg.c +++ b/arch/blackfin/kernel/pseudodbg.c @@ -9,6 +9,30 @@ #include #include +/* + * Unfortunately, the pt_regs structure is not laid out the same way as the + * hardware register file, so we need to do some fix ups. + */ +static bool fix_up_reg(struct pt_regs *fp, long *value, int grp, int reg) +{ + long *val = &fp->r0; + + /* Only do Dregs and Pregs for now */ + if (grp > 1) + return false; + + if (grp == 0 || (grp == 1 && reg < 6)) + val -= (reg + 8 * grp); + else if (grp == 1 && reg == 6) + val = &fp->usp; + else if (grp == 1 && reg == 7) + val = &fp->fp; + + *value = *val; + return true; + +} + #define PseudoDbg_Assert_opcode 0xf0000000 #define PseudoDbg_Assert_expected_bits 0 #define PseudoDbg_Assert_expected_mask 0xffff @@ -23,47 +47,38 @@ #define PseudoDbg_Assert_code_bits 27 #define PseudoDbg_Assert_code_mask 0x1f +/* + * DBGA - debug assert + */ bool execute_pseudodbg_assert(struct pt_regs *fp, unsigned int opcode) { int expected = ((opcode >> PseudoDbg_Assert_expected_bits) & PseudoDbg_Assert_expected_mask); int dbgop = ((opcode >> (PseudoDbg_Assert_dbgop_bits)) & PseudoDbg_Assert_dbgop_mask); int grp = ((opcode >> (PseudoDbg_Assert_grp_bits)) & PseudoDbg_Assert_grp_mask); int regtest = ((opcode >> (PseudoDbg_Assert_regtest_bits)) & PseudoDbg_Assert_regtest_mask); - long *value = &fp->r0; + long value; if ((opcode & 0xFF000000) != PseudoDbg_Assert_opcode) return false; - /* Only do Dregs and Pregs for now */ - if (grp > 1) + if (!fix_up_reg(fp, &value, grp, regtest)) return false; - /* - * Unfortunately, the pt_regs structure is not laid out the same way as the - * hardware register file, so we need to do some fix ups. - */ - if (grp == 0 || (grp == 1 && regtest < 6)) - value -= (regtest + 8 * grp); - else if (grp == 1 && regtest == 6) - value = &fp->usp; - else if (grp == 1 && regtest == 7) - value = &fp->fp; - if (dbgop == 0 || dbgop == 2) { /* DBGA ( regs_lo , uimm16 ) */ /* DBGAL ( regs , uimm16 ) */ - if (expected != (*value & 0xFFFF)) { + if (expected != (value & 0xFFFF)) { pr_notice("DBGA (%s%i.L,0x%x) failure, got 0x%x\n", grp ? "P" : "R", - regtest, expected, (unsigned int)(*value & 0xFFFF)); + regtest, expected, (unsigned int)(value & 0xFFFF)); return false; } } else if (dbgop == 1 || dbgop == 3) { /* DBGA ( regs_hi , uimm16 ) */ /* DBGAH ( regs , uimm16 ) */ - if (expected != ((*value >> 16) & 0xFFFF)) { + if (expected != ((value >> 16) & 0xFFFF)) { pr_notice("DBGA (%s%i.H,0x%x) failure, got 0x%x\n", grp ? "P" : "R", - regtest, expected, (unsigned int)((*value >> 16) & 0xFFFF)); + regtest, expected, (unsigned int)((value >> 16) & 0xFFFF)); return false; } } @@ -71,3 +86,38 @@ bool execute_pseudodbg_assert(struct pt_regs *fp, unsigned int opcode) fp->pc += 4; return true; } + +#define PseudoDbg_opcode 0xf8000000 +#define PseudoDbg_reg_bits 0 +#define PseudoDbg_reg_mask 0x7 +#define PseudoDbg_grp_bits 3 +#define PseudoDbg_grp_mask 0x7 +#define PseudoDbg_fn_bits 6 +#define PseudoDbg_fn_mask 0x3 +#define PseudoDbg_code_bits 8 +#define PseudoDbg_code_mask 0xff + +/* + * DBG - debug (dump a register value out) + */ +bool execute_pseudodbg(struct pt_regs *fp, unsigned int opcode) +{ + int grp, fn, reg; + long value; + + if ((opcode & 0xFF000000) != PseudoDbg_opcode) + return false; + + opcode >>= 16; + grp = ((opcode >> PseudoDbg_grp_bits) & PseudoDbg_reg_mask); + fn = ((opcode >> PseudoDbg_fn_bits) & PseudoDbg_fn_mask); + reg = ((opcode >> PseudoDbg_reg_bits) & PseudoDbg_reg_mask); + + if (!fix_up_reg(fp, &value, grp, reg)) + return false; + + pr_notice("DBG %s%d = %08lx\n", grp ? "P" : "R", reg, value); + + fp->pc += 2; + return true; +} diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 9369836365bb..59c1df75e4de 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -213,6 +213,8 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) if (!kernel_mode_regs(fp) && get_instruction(&opcode, (unsigned short *)fp->pc)) { if (execute_pseudodbg_assert(fp, opcode)) goto traps_done; + if (execute_pseudodbg(fp, opcode)) + goto traps_done; } #endif info.si_code = ILL_ILLOPC; -- cgit v1.2.3-59-g8ed1b From 5a132f7aeba772e1e1f9ccbad14a6779cd40cdfb Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Mon, 29 Mar 2010 02:04:45 +0000 Subject: Blackfin: support all possible registers in the pseudo instructions Rather than decoding just the common R/P registers, handle all of them. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/kernel/pseudodbg.c | 67 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/kernel/pseudodbg.c b/arch/blackfin/kernel/pseudodbg.c index a5a4636124aa..e57ce2f64bfe 100644 --- a/arch/blackfin/kernel/pseudodbg.c +++ b/arch/blackfin/kernel/pseudodbg.c @@ -9,16 +9,43 @@ #include #include +const char * const greg_names[] = { + "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", + "P0", "P1", "P2", "P3", "P4", "P5", "SP", "FP", + "I0", "I1", "I2", "I3", "M0", "M1", "M2", "M3", + "B0", "B1", "B2", "B3", "L0", "L1", "L2", "L3", + "A0.X", "A0.W", "A1.X", "A1.W", "", "", "ASTAT", "RETS", + "", "", "", "", "", "", "", "", + "LC0", "LT0", "LB0", "LC1", "LT1", "LB1", "CYCLES", "CYCLES2", + "USP", "SEQSTAT", "SYSCFG", "RETI", "RETX", "RETN", "RETE", "EMUDAT", +}; + +static const char *get_allreg_name(int grp, int reg) +{ + return greg_names[(grp << 3) | reg]; +} + /* * Unfortunately, the pt_regs structure is not laid out the same way as the * hardware register file, so we need to do some fix ups. + * + * CYCLES is not stored in the pt_regs structure - so, we just read it from + * the hardware. + * + * Don't support: + * - All reserved registers + * - All in group 7 are (supervisors only) */ + static bool fix_up_reg(struct pt_regs *fp, long *value, int grp, int reg) { long *val = &fp->r0; + unsigned long tmp; /* Only do Dregs and Pregs for now */ - if (grp > 1) + if (grp == 5 || + (grp == 4 && (reg == 4 || reg == 5)) || + (grp == 7)) return false; if (grp == 0 || (grp == 1 && reg < 6)) @@ -27,6 +54,32 @@ static bool fix_up_reg(struct pt_regs *fp, long *value, int grp, int reg) val = &fp->usp; else if (grp == 1 && reg == 7) val = &fp->fp; + else if (grp == 2) { + val = &fp->i0; + val -= reg; + } else if (grp == 3 && reg >= 4) { + val = &fp->l0; + val -= (reg - 4); + } else if (grp == 3 && reg < 4) { + val = &fp->b0; + val -= reg; + } else if (grp == 4 && reg < 4) { + val = &fp->a0x; + val -= reg; + } else if (grp == 4 && reg == 6) + val = &fp->astat; + else if (grp == 4 && reg == 7) + val = &fp->rets; + else if (grp == 6 && reg < 6) { + val = &fp->lc0; + val -= reg; + } else if (grp == 6 && reg == 6) { + __asm__ __volatile__("%0 = cycles;\n" : "=d"(tmp)); + val = &tmp; + } else if (grp == 6 && reg == 7) { + __asm__ __volatile__("%0 = cycles2;\n" : "=d"(tmp)); + val = &tmp; + } *value = *val; return true; @@ -68,8 +121,9 @@ bool execute_pseudodbg_assert(struct pt_regs *fp, unsigned int opcode) /* DBGA ( regs_lo , uimm16 ) */ /* DBGAL ( regs , uimm16 ) */ if (expected != (value & 0xFFFF)) { - pr_notice("DBGA (%s%i.L,0x%x) failure, got 0x%x\n", grp ? "P" : "R", - regtest, expected, (unsigned int)(value & 0xFFFF)); + pr_notice("DBGA (%s.L,0x%x) failure, got 0x%x\n", + get_allreg_name(grp, regtest), + expected, (unsigned int)(value & 0xFFFF)); return false; } @@ -77,8 +131,9 @@ bool execute_pseudodbg_assert(struct pt_regs *fp, unsigned int opcode) /* DBGA ( regs_hi , uimm16 ) */ /* DBGAH ( regs , uimm16 ) */ if (expected != ((value >> 16) & 0xFFFF)) { - pr_notice("DBGA (%s%i.H,0x%x) failure, got 0x%x\n", grp ? "P" : "R", - regtest, expected, (unsigned int)((value >> 16) & 0xFFFF)); + pr_notice("DBGA (%s.H,0x%x) failure, got 0x%x\n", + get_allreg_name(grp, regtest), + expected, (unsigned int)((value >> 16) & 0xFFFF)); return false; } } @@ -116,7 +171,7 @@ bool execute_pseudodbg(struct pt_regs *fp, unsigned int opcode) if (!fix_up_reg(fp, &value, grp, reg)) return false; - pr_notice("DBG %s%d = %08lx\n", grp ? "P" : "R", reg, value); + pr_notice("DBG %s = %08lx\n", get_allreg_name(grp, reg), value); fp->pc += 2; return true; -- cgit v1.2.3-59-g8ed1b From a6d9dbf5e4daaf21b33917a809a5ac1e7bce9e05 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Mon, 29 Mar 2010 04:30:40 +0000 Subject: Blackfin: show the whole accumulator in the pseudo DBG insn Rather than print just part of the accumulator register, show the whole 40 bits. This matches the simulator behavior better. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/kernel/pseudodbg.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/kernel/pseudodbg.c b/arch/blackfin/kernel/pseudodbg.c index e57ce2f64bfe..db85bc94334e 100644 --- a/arch/blackfin/kernel/pseudodbg.c +++ b/arch/blackfin/kernel/pseudodbg.c @@ -158,7 +158,7 @@ bool execute_pseudodbg_assert(struct pt_regs *fp, unsigned int opcode) bool execute_pseudodbg(struct pt_regs *fp, unsigned int opcode) { int grp, fn, reg; - long value; + long value, value1; if ((opcode & 0xFF000000) != PseudoDbg_opcode) return false; @@ -168,11 +168,24 @@ bool execute_pseudodbg(struct pt_regs *fp, unsigned int opcode) fn = ((opcode >> PseudoDbg_fn_bits) & PseudoDbg_fn_mask); reg = ((opcode >> PseudoDbg_reg_bits) & PseudoDbg_reg_mask); - if (!fix_up_reg(fp, &value, grp, reg)) - return false; + if (fn == 3 && (reg == 0 || reg == 1)) { + if (!fix_up_reg(fp, &value, 4, 2 * reg)) + return false; + if (!fix_up_reg(fp, &value1, 4, 2 * reg + 1)) + return false; - pr_notice("DBG %s = %08lx\n", get_allreg_name(grp, reg), value); + pr_notice("DBG A%i = %02lx%08lx\n", reg, value & 0xFF, value1); + fp->pc += 2; + return true; - fp->pc += 2; - return true; + } else if (fn == 0) { + if (!fix_up_reg(fp, &value, grp, reg)) + return false; + + pr_notice("DBG %s = %08lx\n", get_allreg_name(grp, reg), value); + fp->pc += 2; + return true; + } + + return false; } -- cgit v1.2.3-59-g8ed1b From a80d5f449d1794d8e402f28cf3e1e9b57cb9f2d4 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Mon, 29 Mar 2010 14:07:33 +0000 Subject: Blackfin: handle HW errors in the new "FAULT" printing code Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/kernel/trace.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c index 317d4273ca60..59fcdf6b0138 100644 --- a/arch/blackfin/kernel/trace.c +++ b/arch/blackfin/kernel/trace.c @@ -672,6 +672,15 @@ void dump_bfin_trace_buffer(void) * the trace buffer, (since it doesn't commit), so * we print out the fault address here */ + if (!fault && addr == ((unsigned short *)evt_ivhw)) { + addr = (unsigned short *)bfin_read_TBUF(); + decode_address(buf, (unsigned long)addr); + pr_notice(" FAULT : %s ", buf); + decode_instruction(addr); + pr_cont("\n"); + fault = 1; + continue; + } if (!fault && addr == (unsigned short *)trap && (cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE) > VEC_EXCPT15) { decode_address(buf, cpu_pda[cpu].icplb_fault_addr); -- cgit v1.2.3-59-g8ed1b From d2db97bf6bafde4ec114d1837dd3fc4cea64b2ea Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 12 Apr 2010 05:53:35 +0000 Subject: Blackfin: kgdb: pass up the CC register instead of a 0 stub While the CC pseudo register can be deduced from the ASTAT register, make sure we set its value correctly instead of always stubbing it out as 0. GDB itself looks at this pseudo register instead of ASTAT, so we have to supply the right value. Signed-off-by: Mike Frysinger --- arch/blackfin/kernel/kgdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index 2c501ceb1e55..ad1c05308485 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c @@ -66,7 +66,7 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) gdb_regs[BFIN_RETN] = regs->retn; gdb_regs[BFIN_RETE] = regs->rete; gdb_regs[BFIN_PC] = regs->pc; - gdb_regs[BFIN_CC] = 0; + gdb_regs[BFIN_CC] = (regs->astat >> 5) & 1; gdb_regs[BFIN_EXTRA1] = 0; gdb_regs[BFIN_EXTRA2] = 0; gdb_regs[BFIN_EXTRA3] = 0; -- cgit v1.2.3-59-g8ed1b From 11cabcb95e0d9de15f3d8a9d25336edfc5444337 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Apr 2010 16:31:43 +0000 Subject: Blackfin: bf537-minotaur: fix build errors due to header changes Signed-off-by: Mike Frysinger --- arch/blackfin/mach-bf537/boards/minotaur.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c index c489d602c590..05d45994480e 100644 --- a/arch/blackfin/mach-bf537/boards/minotaur.c +++ b/arch/blackfin/mach-bf537/boards/minotaur.c @@ -23,12 +23,13 @@ #include #include #include +#include #include /* * Name the Board for the /proc/cpuinfo */ -char *bfin_board_name = "CamSig Minotaur BF537"; +const char bfin_board_name[] = "CamSig Minotaur BF537"; #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) static struct resource bfin_pcmcia_cf_resources[] = { -- cgit v1.2.3-59-g8ed1b From 80fcdb959343ab9e0ee95c11b5ea47c44a2c3004 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 22 Apr 2010 21:15:00 +0000 Subject: Blackfin: SIC: cut down on IAR MMR reads a bit Tweak the for loops that operate on the SIC IAR system MMRs to avoid re-reading them multiple times in a row. System MMRs are a little slower to access, so avoid the penalty when possible. Signed-off-by: Mike Frysinger --- arch/blackfin/mach-common/ints-priority.c | 33 +++++++++++++++++-------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index ce988713445d..1c8c4c7245c3 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -92,26 +92,29 @@ static void __init search_IAR(void) { unsigned ivg, irq_pos = 0; for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) { - int irqn; + int irqN; ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = &ivg_table[irq_pos]; - for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { - int iar_shift = (irqn & 7) * 4; - if (ivg == (0xf & -#if defined(CONFIG_BF52x) || defined(CONFIG_BF538) \ - || defined(CONFIG_BF539) || defined(CONFIG_BF51x) - bfin_read32((unsigned long *)SIC_IAR0 + - ((irqn % 32) >> 3) + ((irqn / 32) * - ((SIC_IAR4 - SIC_IAR0) / 4))) >> iar_shift)) { + for (irqN = 0; irqN < NR_PERI_INTS; irqN += 4) { + int irqn; + u32 iar = bfin_read32((unsigned long *)SIC_IAR0 + +#if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || \ + defined(CONFIG_BF538) || defined(CONFIG_BF539) + ((irqN % 32) >> 3) + ((irqN / 32) * ((SIC_IAR4 - SIC_IAR0) / 4)) #else - bfin_read32((unsigned long *)SIC_IAR0 + - (irqn >> 3)) >> iar_shift)) { + (irqN >> 3) #endif - ivg_table[irq_pos].irqno = IVG7 + irqn; - ivg_table[irq_pos].isrflag = 1 << (irqn % 32); - ivg7_13[ivg].istop++; - irq_pos++; + ); + + for (irqn = irqN; irqn < irqN + 4; ++irqn) { + int iar_shift = (irqn & 7) * 4; + if (ivg == (0xf & (iar >> iar_shift))) { + ivg_table[irq_pos].irqno = IVG7 + irqn; + ivg_table[irq_pos].isrflag = 1 << (irqn % 32); + ivg7_13[ivg].istop++; + irq_pos++; + } } } } -- cgit v1.2.3-59-g8ed1b From 479ba6035862a9c08ce4351c7fff8926fde4ede5 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Mon, 3 May 2010 17:23:20 +0000 Subject: Blackfin: move string functions to normal lib/ assembly Since 'extern inline' doesn't work correctly in the context of the Linux kernel (too many overriding defines), move the string functions to normal lib/ assembly files (like the existing mem funcs). This avoids the forced inline all over the kernel and allows us to place them constantly in L1. This also avoids some module failures when gcc inserts calls to string functions but the kernel build system doesn't fully consult the library archives. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/Kconfig | 28 +++++++++ arch/blackfin/include/asm/string.h | 113 ++----------------------------------- arch/blackfin/kernel/bfin_ksyms.c | 12 ++++ arch/blackfin/lib/strcmp.S | 43 ++++++++++++++ arch/blackfin/lib/strcmp.c | 19 ------- arch/blackfin/lib/strcpy.S | 35 ++++++++++++ arch/blackfin/lib/strcpy.c | 19 ------- arch/blackfin/lib/strncmp.S | 52 +++++++++++++++++ arch/blackfin/lib/strncmp.c | 18 ------ arch/blackfin/lib/strncpy.S | 52 +++++++++++++++++ arch/blackfin/lib/strncpy.c | 19 ------- 11 files changed, 226 insertions(+), 184 deletions(-) create mode 100644 arch/blackfin/lib/strcmp.S delete mode 100644 arch/blackfin/lib/strcmp.c create mode 100644 arch/blackfin/lib/strcpy.S delete mode 100644 arch/blackfin/lib/strcpy.c create mode 100644 arch/blackfin/lib/strncmp.S delete mode 100644 arch/blackfin/lib/strncmp.c create mode 100644 arch/blackfin/lib/strncpy.S delete mode 100644 arch/blackfin/lib/strncpy.c (limited to 'arch') diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 405bdaa17333..7b9fc9c9c0c2 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -791,6 +791,34 @@ config MEMCPY_L1 If enabled, the memcpy function is linked into L1 instruction memory. (less latency) +config STRCMP_L1 + bool "locate strcmp function in L1 Memory" + default y + help + If enabled, the strcmp function is linked + into L1 instruction memory (less latency). + +config STRNCMP_L1 + bool "locate strncmp function in L1 Memory" + default y + help + If enabled, the strncmp function is linked + into L1 instruction memory (less latency). + +config STRCPY_L1 + bool "locate strcpy function in L1 Memory" + default y + help + If enabled, the strcpy function is linked + into L1 instruction memory (less latency). + +config STRNCPY_L1 + bool "locate strncpy function in L1 Memory" + default y + help + If enabled, the strncpy function is linked + into L1 instruction memory (less latency). + config SYS_BFIN_SPINLOCK_L1 bool "Locate sys_bfin_spinlock function in L1 Memory" default y diff --git a/arch/blackfin/include/asm/string.h b/arch/blackfin/include/asm/string.h index d7f0ccb418c3..423c099aa988 100644 --- a/arch/blackfin/include/asm/string.h +++ b/arch/blackfin/include/asm/string.h @@ -12,121 +12,16 @@ #ifdef __KERNEL__ /* only set these up for kernel code */ #define __HAVE_ARCH_STRCPY -extern inline char *strcpy(char *dest, const char *src) -{ - char *xdest = dest; - char temp = 0; - - __asm__ __volatile__ ( - "1:" - "%2 = B [%1++] (Z);" - "B [%0++] = %2;" - "CC = %2;" - "if cc jump 1b (bp);" - : "+&a" (dest), "+&a" (src), "=&d" (temp) - : - : "memory", "CC"); - - return xdest; -} +extern char *strcpy(char *dest, const char *src); #define __HAVE_ARCH_STRNCPY -extern inline char *strncpy(char *dest, const char *src, size_t n) -{ - char *xdest = dest; - char temp = 0; - - if (n == 0) - return xdest; - - __asm__ __volatile__ ( - "1:" - "%3 = B [%1++] (Z);" - "B [%0++] = %3;" - "CC = %3;" - "if ! cc jump 2f;" - "%2 += -1;" - "CC = %2 == 0;" - "if ! cc jump 1b (bp);" - "jump 4f;" - "2:" - /* if src is shorter than n, we need to null pad bytes now */ - "%3 = 0;" - "3:" - "%2 += -1;" - "CC = %2 == 0;" - "if cc jump 4f;" - "B [%0++] = %3;" - "jump 3b;" - "4:" - : "+&a" (dest), "+&a" (src), "+&da" (n), "=&d" (temp) - : - : "memory", "CC"); - - return xdest; -} +extern char *strncpy(char *dest, const char *src, size_t n); #define __HAVE_ARCH_STRCMP -extern inline int strcmp(const char *cs, const char *ct) -{ - /* need to use int's here so the char's in the assembly don't get - * sign extended incorrectly when we don't want them to be - */ - int __res1, __res2; - - __asm__ __volatile__ ( - "1:" - "%2 = B[%0++] (Z);" /* get *cs */ - "%3 = B[%1++] (Z);" /* get *ct */ - "CC = %2 == %3;" /* compare a byte */ - "if ! cc jump 2f;" /* not equal, break out */ - "CC = %2;" /* at end of cs? */ - "if cc jump 1b (bp);" /* no, keep going */ - "jump.s 3f;" /* strings are equal */ - "2:" - "%2 = %2 - %3;" /* *cs - *ct */ - "3:" - : "+&a" (cs), "+&a" (ct), "=&d" (__res1), "=&d" (__res2) - : - : "memory", "CC"); - - return __res1; -} +extern int strcmp(const char *cs, const char *ct); #define __HAVE_ARCH_STRNCMP -extern inline int strncmp(const char *cs, const char *ct, size_t count) -{ - /* need to use int's here so the char's in the assembly don't get - * sign extended incorrectly when we don't want them to be - */ - int __res1, __res2; - - if (!count) - return 0; - - __asm__ __volatile__ ( - "1:" - "%3 = B[%0++] (Z);" /* get *cs */ - "%4 = B[%1++] (Z);" /* get *ct */ - "CC = %3 == %4;" /* compare a byte */ - "if ! cc jump 3f;" /* not equal, break out */ - "CC = %3;" /* at end of cs? */ - "if ! cc jump 4f;" /* yes, all done */ - "%2 += -1;" /* no, adjust count */ - "CC = %2 == 0;" - "if ! cc jump 1b;" /* more to do, keep going */ - "2:" - "%3 = 0;" /* strings are equal */ - "jump.s 4f;" - "3:" - "%3 = %3 - %4;" /* *cs - *ct */ - "4:" - : "+&a" (cs), "+&a" (ct), "+&da" (count), "=&d" (__res1), "=&d" (__res2) - : - : "memory", "CC"); - - return __res1; -} +extern int strncmp(const char *cs, const char *ct, size_t count); #define __HAVE_ARCH_MEMSET extern void *memset(void *s, int c, size_t count); diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c index ed8392c117ea..2c264b51566a 100644 --- a/arch/blackfin/kernel/bfin_ksyms.c +++ b/arch/blackfin/kernel/bfin_ksyms.c @@ -32,6 +32,18 @@ EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memchr); +/* + * Because string functions are both inline and exported functions and + * folder arch/blackfin/lib is configured as a library path in Makefile, + * symbols exported in folder lib is not linked into built-in.o but + * inlined only. In order to export string symbols to kernel module + * properly, they should be exported here. + */ +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); + /* * libgcc functions - functions that are used internally by the * compiler... (prototypes are not correct though, but that diff --git a/arch/blackfin/lib/strcmp.S b/arch/blackfin/lib/strcmp.S new file mode 100644 index 000000000000..d7c1d158973b --- /dev/null +++ b/arch/blackfin/lib/strcmp.S @@ -0,0 +1,43 @@ +/* + * Copyright 2005-2010 Analog Devices Inc. + * + * Licensed under the ADI BSD license or the GPL-2 (or later) + */ + +#include + +/* void *strcmp(char *s1, const char *s2); + * R0 = address (s1) + * R1 = address (s2) + * + * Returns an integer less than, equal to, or greater than zero if s1 + * (or the first n bytes thereof) is found, respectively, to be less + * than, to match, or be greater than s2. + */ + +#ifdef CONFIG_STRCMP_L1 +.section .l1.text +#else +.text +#endif + +.align 2 + +ENTRY(_strcmp) + P0 = R0 ; /* s1 */ + P1 = R1 ; /* s2 */ + +1: + R0 = B[P0++] (Z); /* get *s1 */ + R1 = B[P1++] (Z); /* get *s2 */ + CC = R0 == R1; /* compare a byte */ + if ! cc jump 2f; /* not equal, break out */ + CC = R0; /* at end of s1? */ + if cc jump 1b (bp); /* no, keep going */ + jump.s 3f; /* strings are equal */ +2: + R0 = R0 - R1; /* *s1 - *s2 */ +3: + RTS; + +ENDPROC(_strcmp) diff --git a/arch/blackfin/lib/strcmp.c b/arch/blackfin/lib/strcmp.c deleted file mode 100644 index fde39a1950ce..000000000000 --- a/arch/blackfin/lib/strcmp.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Provide symbol in case str func is not inlined. - * - * Copyright (c) 2006-2007 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#define strcmp __inline_strcmp -#include -#undef strcmp - -#include - -int strcmp(const char *dest, const char *src) -{ - return __inline_strcmp(dest, src); -} -EXPORT_SYMBOL(strcmp); diff --git a/arch/blackfin/lib/strcpy.S b/arch/blackfin/lib/strcpy.S new file mode 100644 index 000000000000..a6a0c6363806 --- /dev/null +++ b/arch/blackfin/lib/strcpy.S @@ -0,0 +1,35 @@ +/* + * Copyright 2005-2010 Analog Devices Inc. + * + * Licensed under the ADI BSD license or the GPL-2 (or later) + */ + +#include + +/* void *strcpy(char *dest, const char *src); + * R0 = address (dest) + * R1 = address (src) + * + * Returns a pointer to the destination string dest + */ + +#ifdef CONFIG_STRCPY_L1 +.section .l1.text +#else +.text +#endif + +.align 2 + +ENTRY(_strcpy) + P0 = R0 ; /* dst*/ + P1 = R1 ; /* src*/ + +1: + R1 = B [P1++] (Z); + B [P0++] = R1; + CC = R1; + if cc jump 1b (bp); + RTS; + +ENDPROC(_strcpy) diff --git a/arch/blackfin/lib/strcpy.c b/arch/blackfin/lib/strcpy.c deleted file mode 100644 index 2a8836b1f4d3..000000000000 --- a/arch/blackfin/lib/strcpy.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Provide symbol in case str func is not inlined. - * - * Copyright (c) 2006-2007 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#define strcpy __inline_strcpy -#include -#undef strcpy - -#include - -char *strcpy(char *dest, const char *src) -{ - return __inline_strcpy(dest, src); -} -EXPORT_SYMBOL(strcpy); diff --git a/arch/blackfin/lib/strncmp.S b/arch/blackfin/lib/strncmp.S new file mode 100644 index 000000000000..6da37c34a847 --- /dev/null +++ b/arch/blackfin/lib/strncmp.S @@ -0,0 +1,52 @@ +/* + * Copyright 2005-2010 Analog Devices Inc. + * + * Licensed under the ADI BSD license or the GPL-2 (or later) + */ + +#include + +/* void *strncpy(char *s1, const char *s2, size_t n); + * R0 = address (dest) + * R1 = address (src) + * R2 = size (n) + * Returns a pointer to the destination string dest + */ + +#ifdef CONFIG_STRNCMP_L1 +.section .l1.text +#else +.text +#endif + +.align 2 + +ENTRY(_strncmp) + CC = R2 == 0; + if CC JUMP 5f; + + P0 = R0 ; /* s1 */ + P1 = R1 ; /* s2 */ +1: + R0 = B[P0++] (Z); /* get *s1 */ + R1 = B[P1++] (Z); /* get *s2 */ + CC = R0 == R1; /* compare a byte */ + if ! cc jump 3f; /* not equal, break out */ + CC = R0; /* at end of s1? */ + if ! cc jump 4f; /* yes, all done */ + R2 += -1; /* no, adjust count */ + CC = R2 == 0; + if ! cc jump 1b (bp); /* more to do, keep going */ +2: + R0 = 0; /* strings are equal */ + jump.s 4f; +3: + R0 = R0 - R1; /* *s1 - *s2 */ +4: + RTS; + +5: + R0 = 0; + RTS; + +ENDPROC(_strncmp) diff --git a/arch/blackfin/lib/strncmp.c b/arch/blackfin/lib/strncmp.c deleted file mode 100644 index 46518b1d2983..000000000000 --- a/arch/blackfin/lib/strncmp.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Provide symbol in case str func is not inlined. - * - * Copyright (c) 2006-2007 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#define strncmp __inline_strncmp -#include -#include -#undef strncmp - -int strncmp(const char *cs, const char *ct, size_t count) -{ - return __inline_strncmp(cs, ct, count); -} -EXPORT_SYMBOL(strncmp); diff --git a/arch/blackfin/lib/strncpy.S b/arch/blackfin/lib/strncpy.S new file mode 100644 index 000000000000..39fbbe6523e5 --- /dev/null +++ b/arch/blackfin/lib/strncpy.S @@ -0,0 +1,52 @@ +/* + * Copyright 2005-2010 Analog Devices Inc. + * + * Licensed under the ADI BSD license or the GPL-2 (or later) + */ + +#include + +/* void *strncpy(char *dest, const char *src, size_t n); + * R0 = address (dest) + * R1 = address (src) + * R2 = size + * Returns a pointer to the destination string dest + */ + +#ifdef CONFIG_STRNCPY_L1 +.section .l1.text +#else +.text +#endif + +.align 2 + +ENTRY(_strncpy) + CC = R2 == 0; + if CC JUMP 4f; + P0 = R0 ; /* dst*/ + P1 = R1 ; /* src*/ + +1: + R1 = B [P1++] (Z); + B [P0++] = R1; + CC = R1; + if ! cc jump 2f; + R2 += -1; + CC = R2 == 0; + if ! cc jump 1b (bp); + jump 4f; +2: + /* if src is shorter than n, we need to null pad bytes in dest */ + R1 = 0; +3: + R2 += -1; + CC = R2 == 0; + if cc jump 4f; + B [P0++] = R1; + jump 3b; + +4: + RTS; + +ENDPROC(_strncpy) diff --git a/arch/blackfin/lib/strncpy.c b/arch/blackfin/lib/strncpy.c deleted file mode 100644 index ea1dc6bf2373..000000000000 --- a/arch/blackfin/lib/strncpy.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Provide symbol in case str func is not inlined. - * - * Copyright (c) 2006-2007 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#define strncpy __inline_strncpy -#include -#undef strncpy - -#include - -char *strncpy(char *dest, const char *src, size_t n) -{ - return __inline_strncpy(dest, src, n); -} -EXPORT_SYMBOL(strncpy); -- cgit v1.2.3-59-g8ed1b From c70dcabc8eba18113a4735e7b1bd09f7493e38f0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 4 May 2010 04:14:08 +0000 Subject: Blackfin: isram: clean up ITEST_COMMAND macro and improve the selftests The IADDR2DTEST() macro had some duplicated logic with bit 11 and some incorrect comments, so scrub all of that. In order to verify these aren't a problem (and won't be in the future), extend the self tests to operate on as much L1 SRAM as possible. Signed-off-by: Mike Frysinger --- arch/blackfin/mm/isram-driver.c | 94 ++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c index 39b058564f62..7e2e674ed444 100644 --- a/arch/blackfin/mm/isram-driver.c +++ b/arch/blackfin/mm/isram-driver.c @@ -43,13 +43,12 @@ static DEFINE_SPINLOCK(dtest_lock); /* Takes a void pointer */ #define IADDR2DTEST(x) \ ({ unsigned long __addr = (unsigned long)(x); \ - (__addr & 0x47F8) | /* address bits 14 & 10:3 */ \ - (__addr & 0x8000) << 23 | /* Bank A/B */ \ - (__addr & 0x0800) << 15 | /* address bit 11 */ \ - (__addr & 0x3000) << 4 | /* address bits 13:12 */ \ - (__addr & 0x8000) << 8 | /* address bit 15 */ \ - (0x1000000) | /* instruction access = 1 */ \ - (0x4); /* data array = 1 */ \ + ((__addr & (1 << 11)) << (26 - 11)) | /* addr bit 11 (Way0/Way1) */ \ + (1 << 24) | /* instruction access = 1 */ \ + ((__addr & (1 << 15)) << (23 - 15)) | /* addr bit 15 (Data Bank) */ \ + ((__addr & (3 << 12)) << (16 - 12)) | /* addr bits 13:12 (Subbank) */ \ + (__addr & 0x47F8) | /* addr bits 14 & 10:3 */ \ + (1 << 2); /* data array = 1 */ \ }) /* Takes a pointer, and returns the offset (in bits) which things should be shifted */ @@ -196,7 +195,7 @@ EXPORT_SYMBOL(isram_memcpy); #ifdef CONFIG_BFIN_ISRAM_SELF_TEST -#define TEST_LEN 0x100 +static int test_len = 0x20000; static __init void hex_dump(unsigned char *buf, int len) { @@ -212,15 +211,15 @@ static __init int isram_read_test(char *sdram, void *l1inst) pr_info("INFO: running isram_read tests\n"); /* setup some different data to play with */ - for (i = 0; i < TEST_LEN; ++i) - sdram[i] = i; - dma_memcpy(l1inst, sdram, TEST_LEN); + for (i = 0; i < test_len; ++i) + sdram[i] = i % 255; + dma_memcpy(l1inst, sdram, test_len); /* make sure we can read the L1 inst */ - for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) { + for (i = 0; i < test_len; i += sizeof(uint64_t)) { data1 = isram_read(l1inst + i); memcpy(&data2, sdram + i, sizeof(data2)); - if (memcmp(&data1, &data2, sizeof(uint64_t))) { + if (data1 != data2) { pr_err("FAIL: isram_read(%p) returned %#llx but wanted %#llx\n", l1inst + i, data1, data2); ++ret; @@ -238,25 +237,25 @@ static __init int isram_write_test(char *sdram, void *l1inst) pr_info("INFO: running isram_write tests\n"); /* setup some different data to play with */ - memset(sdram, 0, TEST_LEN * 2); - dma_memcpy(l1inst, sdram, TEST_LEN); - for (i = 0; i < TEST_LEN; ++i) - sdram[i] = i; + memset(sdram, 0, test_len * 2); + dma_memcpy(l1inst, sdram, test_len); + for (i = 0; i < test_len; ++i) + sdram[i] = i % 255; /* make sure we can write the L1 inst */ - for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) { + for (i = 0; i < test_len; i += sizeof(uint64_t)) { memcpy(&data1, sdram + i, sizeof(data1)); isram_write(l1inst + i, data1); data2 = isram_read(l1inst + i); - if (memcmp(&data1, &data2, sizeof(uint64_t))) { + if (data1 != data2) { pr_err("FAIL: isram_write(%p, %#llx) != %#llx\n", l1inst + i, data1, data2); ++ret; } } - dma_memcpy(sdram + TEST_LEN, l1inst, TEST_LEN); - if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) { + dma_memcpy(sdram + test_len, l1inst, test_len); + if (memcmp(sdram, sdram + test_len, test_len)) { pr_err("FAIL: isram_write() did not work properly\n"); ++ret; } @@ -268,12 +267,12 @@ static __init int _isram_memcpy_test(char pattern, void *sdram, void *l1inst, const char *smemcpy, void *(*fmemcpy)(void *, const void *, size_t)) { - memset(sdram, pattern, TEST_LEN); - fmemcpy(l1inst, sdram, TEST_LEN); - fmemcpy(sdram + TEST_LEN, l1inst, TEST_LEN); - if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) { + memset(sdram, pattern, test_len); + fmemcpy(l1inst, sdram, test_len); + fmemcpy(sdram + test_len, l1inst, test_len); + if (memcmp(sdram, sdram + test_len, test_len)) { pr_err("FAIL: %s(%p <=> %p, %#x) failed (data is %#x)\n", - smemcpy, l1inst, sdram, TEST_LEN, pattern); + smemcpy, l1inst, sdram, test_len, pattern); return 1; } return 0; @@ -292,12 +291,13 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst) /* check read of small, unaligned, and hardware 64bit limits */ pr_info("INFO: running isram_memcpy (read) tests\n"); - for (i = 0; i < TEST_LEN; ++i) - sdram[i] = i; - dma_memcpy(l1inst, sdram, TEST_LEN); + /* setup some different data to play with */ + for (i = 0; i < test_len; ++i) + sdram[i] = i % 255; + dma_memcpy(l1inst, sdram, test_len); thisret = 0; - for (i = 0; i < TEST_LEN - 32; ++i) { + for (i = 0; i < test_len - 32; ++i) { unsigned char cmp[32]; for (j = 1; j <= 32; ++j) { memset(cmp, 0, sizeof(cmp)); @@ -310,7 +310,7 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst) pr_cont("\n"); if (++thisret > 20) { pr_err("FAIL: skipping remaining series\n"); - i = TEST_LEN; + i = test_len; break; } } @@ -321,11 +321,11 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst) /* check write of small, unaligned, and hardware 64bit limits */ pr_info("INFO: running isram_memcpy (write) tests\n"); - memset(sdram + TEST_LEN, 0, TEST_LEN); - dma_memcpy(l1inst, sdram + TEST_LEN, TEST_LEN); + memset(sdram + test_len, 0, test_len); + dma_memcpy(l1inst, sdram + test_len, test_len); thisret = 0; - for (i = 0; i < TEST_LEN - 32; ++i) { + for (i = 0; i < test_len - 32; ++i) { unsigned char cmp[32]; for (j = 1; j <= 32; ++j) { isram_memcpy(l1inst + i, sdram + i, j); @@ -338,7 +338,7 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst) pr_cont("\n"); if (++thisret > 20) { pr_err("FAIL: skipping remaining series\n"); - i = TEST_LEN; + i = test_len; break; } } @@ -355,22 +355,30 @@ static __init int isram_test_init(void) char *sdram; void *l1inst; - sdram = kmalloc(TEST_LEN * 2, GFP_KERNEL); - if (!sdram) { - pr_warning("SKIP: could not allocate sdram\n"); - return 0; + /* Try to test as much of L1SRAM as possible */ + while (test_len) { + test_len >>= 1; + l1inst = l1_inst_sram_alloc(test_len); + if (l1inst) + break; } - - l1inst = l1_inst_sram_alloc(TEST_LEN); if (!l1inst) { - kfree(sdram); pr_warning("SKIP: could not allocate L1 inst\n"); return 0; } + pr_info("INFO: testing %#x bytes (%p - %p)\n", + test_len, l1inst, l1inst + test_len); + + sdram = kmalloc(test_len * 2, GFP_KERNEL); + if (!sdram) { + sram_free(l1inst); + pr_warning("SKIP: could not allocate sdram\n"); + return 0; + } /* sanity check initial L1 inst state */ ret = 1; - pr_info("INFO: running initial dma_memcpy checks\n"); + pr_info("INFO: running initial dma_memcpy checks %p\n", sdram); if (_isram_memcpy_test(0xa, sdram, l1inst, dma_memcpy)) goto abort; if (_isram_memcpy_test(0x5, sdram, l1inst, dma_memcpy)) -- cgit v1.2.3-59-g8ed1b From 648eee52ccdc623e21b920d6048e93490a4860a7 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Tue, 4 May 2010 14:59:21 +0000 Subject: Blackfin: optimize strncpy a bit Add a little strncpy optimization which can easily cut boot time by 20%. When the kernel is booting with initramfs, it builds up the filesystem from a cpio archive by calling strncpy_from_user() via fs/namei.c's do_getname() on every file in the archive (which can be lots) with a length of PATH_MAX (1024). This causes the dest of the strncpy to be padded with many NUL bytes. This optimization mostly causes these NUL bytes to be padded with a call to memset() which is already optimized for filling memory quickly, but the hardware loop helps a little bit as well. Boot time measured with 'loglevel=0' so UART speed doesn't get in the way. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/lib/memset.S | 1 + arch/blackfin/lib/strncpy.S | 59 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/lib/memset.S b/arch/blackfin/lib/memset.S index c30d99b10969..eab1bef3f5bf 100644 --- a/arch/blackfin/lib/memset.S +++ b/arch/blackfin/lib/memset.S @@ -20,6 +20,7 @@ * R1 = filler byte * R2 = count * Favours word aligned data. + * The strncpy assumes that I0 and I1 are not used in this function */ ENTRY(_memset) diff --git a/arch/blackfin/lib/strncpy.S b/arch/blackfin/lib/strncpy.S index 39fbbe6523e5..f3931d50b4a7 100644 --- a/arch/blackfin/lib/strncpy.S +++ b/arch/blackfin/lib/strncpy.S @@ -5,12 +5,14 @@ */ #include +#include /* void *strncpy(char *dest, const char *src, size_t n); * R0 = address (dest) * R1 = address (src) * R2 = size - * Returns a pointer to the destination string dest + * Returns a pointer (R0) to the destination string dest + * we do this by not changing R0 */ #ifdef CONFIG_STRNCPY_L1 @@ -24,29 +26,60 @@ ENTRY(_strncpy) CC = R2 == 0; if CC JUMP 4f; + + P2 = R2 ; /* size */ P0 = R0 ; /* dst*/ P1 = R1 ; /* src*/ + LSETUP (1f, 2f) LC0 = P2; 1: R1 = B [P1++] (Z); B [P0++] = R1; - CC = R1; - if ! cc jump 2f; - R2 += -1; - CC = R2 == 0; - if ! cc jump 1b (bp); - jump 4f; + CC = R1 == 0; 2: - /* if src is shorter than n, we need to null pad bytes in dest */ - R1 = 0; + if CC jump 3f; + + RTS; + + /* if src is shorter than n, we need to null pad bytes in dest + * but, we can get here when the last byte is zero, and we don't + * want to copy an extra byte at the end, so we need to check + */ 3: + R2 = LC0; + CC = R2 + if ! CC jump 6f; + + /* if the required null padded portion is small, do it here, rather than + * handling the overhead of memset (which is OK when things are big). + */ + R3 = 0x20; + CC = R2 < R3; + IF CC jump 4f; + R2 += -1; - CC = R2 == 0; - if cc jump 4f; - B [P0++] = R1; - jump 3b; + + /* Set things up for memset + * R0 = address + * R1 = filler byte (this case it's zero, set above) + * R2 = count (set above) + */ + + I1 = R0; + R0 = RETS; + I0 = R0; + R0 = P0; + pseudo_long_call _memset, p0; + R0 = I0; + RETS = R0; + R0 = I1; + RTS; 4: + LSETUP(5f, 5f) LC0; +5: + B [P0++] = R1; +6: RTS; ENDPROC(_strncpy) -- cgit v1.2.3-59-g8ed1b From be1577e3787536290cc17afaeb2cd58bbcc7ed6c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 10 May 2010 05:21:50 +0000 Subject: Blackfin: another year of changes (update copyright in boot log) Signed-off-by: Mike Frysinger --- arch/blackfin/kernel/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 8e2efceb364b..d37a397f43f5 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2009 Analog Devices Inc. + * Copyright 2004-2010 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -925,7 +925,7 @@ void __init setup_arch(char **cmdline_p) else if (_bfin_swrst & RESET_SOFTWARE) printk(KERN_NOTICE "Reset caused by Software reset\n"); - printk(KERN_INFO "Blackfin support (C) 2004-2009 Analog Devices, Inc.\n"); + printk(KERN_INFO "Blackfin support (C) 2004-2010 Analog Devices, Inc.\n"); if (bfin_compiled_revid() == 0xffff) printk(KERN_INFO "Compiled for ADSP-%s Rev any, running on 0.%d\n", CPU, bfin_revid()); else if (bfin_compiled_revid() == -1) -- cgit v1.2.3-59-g8ed1b From eb5400b6131e6ebaacf809357643a22a72d5cc4c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 11 May 2010 04:43:19 +0000 Subject: Blackfin: use atomic kmalloc in L1 alloc so it too can be atomic Some drivers allocate L1 SRAM in atomic contexts, so make sure these functions also use GFP_ATOMIC to avoid BUG()'s. Signed-off-by: Mike Frysinger --- arch/blackfin/mm/sram-alloc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c index 49b2ff2c8b74..627e04b5ba9a 100644 --- a/arch/blackfin/mm/sram-alloc.c +++ b/arch/blackfin/mm/sram-alloc.c @@ -256,7 +256,8 @@ static void *_sram_alloc(size_t size, struct sram_piece *pfree_head, plast->next = pslot->next; pavail = pslot; } else { - pavail = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + /* use atomic so our L1 allocator can be used atomically */ + pavail = kmem_cache_alloc(sram_piece_cache, GFP_ATOMIC); if (!pavail) return NULL; -- cgit v1.2.3-59-g8ed1b From 76b99699a2bbf9efdb578f9a38a202af2ecb354b Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 19 May 2010 23:21:38 -0400 Subject: Blackfin: set ARCH_KMALLOC_MINALIGN Architectures that handle DMA-non-coherent memory need to set ARCH_KMALLOC_MINALIGN to make sure that kmalloc'ed buffer is DMA-safe: the buffer doesn't share a cache with the others. Signed-off-by: FUJITA Tomonori Acked-by: Pekka Enberg Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/cache.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/blackfin/include/asm/cache.h b/arch/blackfin/include/asm/cache.h index 8542bc31f63c..93f6c634fdf4 100644 --- a/arch/blackfin/include/asm/cache.h +++ b/arch/blackfin/include/asm/cache.h @@ -15,6 +15,8 @@ #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) #define SMP_CACHE_BYTES L1_CACHE_BYTES +#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES + #ifdef CONFIG_SMP #define __cacheline_aligned #else -- cgit v1.2.3-59-g8ed1b From 084f9ebfd0915203b603392a66be15009b348fe1 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 20 May 2010 04:26:54 +0000 Subject: Blackfin: unify duplicate MEM_MT48LC32M8A2_75 kconfig options Reported-by: Christoph Egger Signed-off-by: Mike Frysinger --- arch/blackfin/Kconfig | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 7b9fc9c9c0c2..f66294b4f9d2 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -348,7 +348,7 @@ config MEM_MT48LC16M16A2TG_75 config MEM_MT48LC32M8A2_75 bool - depends on (BFIN537_STAMP || PNAV10 || BFIN538_EZKIT) + depends on (BFIN518F_EZBRD || BFIN537_STAMP || PNAV10 || BFIN538_EZKIT) default y config MEM_MT48LC8M32B2B5_7 @@ -361,11 +361,6 @@ config MEM_MT48LC32M16A2TG_75 depends on (BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN532_IP0X || BLACKSTAMP) default y -config MEM_MT48LC32M8A2_75 - bool - depends on (BFIN518F_EZBRD) - default y - config MEM_MT48H32M16LFCJ_75 bool depends on (BFIN526_EZBRD) -- cgit v1.2.3-59-g8ed1b From d016a21362194826518d4ac9ca3f768d0345cd2c Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 21 May 2010 09:36:51 +0000 Subject: Blackfin: fix typo in BF537 IRQ comment Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger --- arch/blackfin/mach-bf537/include/mach/irq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/blackfin/mach-bf537/include/mach/irq.h b/arch/blackfin/mach-bf537/include/mach/irq.h index 789a4f226f7b..1a6d617c5fcf 100644 --- a/arch/blackfin/mach-bf537/include/mach/irq.h +++ b/arch/blackfin/mach-bf537/include/mach/irq.h @@ -74,7 +74,7 @@ #define IRQ_PPI_ERROR 42 /*PPI Error Interrupt */ #define IRQ_CAN_ERROR 43 /*CAN Error Interrupt */ -#define IRQ_MAC_ERROR 44 /*PPI Error Interrupt */ +#define IRQ_MAC_ERROR 44 /*MAC Status/Error Interrupt */ #define IRQ_SPORT0_ERROR 45 /*SPORT0 Error Interrupt */ #define IRQ_SPORT1_ERROR 46 /*SPORT1 Error Interrupt */ #define IRQ_SPI_ERROR 47 /*SPI Error Interrupt */ -- cgit v1.2.3-59-g8ed1b From efc5863eb52a04134869f5ceb5f81a6fe9b47469 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 4 Apr 2010 16:04:16 +0200 Subject: Blackfin: acvilon: fix timeout usage for I2C The timeout value is in jiffies, so it should be using HZ, not a plain number. As '10000' is ambiguous, 1HZ is used as conservative default. Signed-off-by: Wolfram Sang Cc: Valentin Yakovenkov Signed-off-by: Mike Frysinger --- arch/blackfin/mach-bf561/boards/acvilon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c index 5163e2c383c5..bfcfa86db2b5 100644 --- a/arch/blackfin/mach-bf561/boards/acvilon.c +++ b/arch/blackfin/mach-bf561/boards/acvilon.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -112,7 +113,7 @@ static struct resource bfin_i2c_pca_resources[] = { struct i2c_pca9564_pf_platform_data pca9564_platform_data = { .gpio = -1, .i2c_clock_speed = 330000, - .timeout = 10000 + .timeout = HZ, }; /* PCA9564 I2C Bus driver */ -- cgit v1.2.3-59-g8ed1b From db52ecc2953d932b2fc1c62e585231659edd1d98 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 26 Mar 2010 19:27:51 -0700 Subject: Blackfin: SMP: fix continuation lines Signed-off-by: Joe Perches Signed-off-by: Mike Frysinger --- arch/blackfin/mach-common/smp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 7cecbaf0358a..a17107a700d5 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -170,8 +170,8 @@ static irqreturn_t ipi_handler(int irq, void *dev_instance) kfree(msg); break; default: - printk(KERN_CRIT "CPU%u: Unknown IPI message \ - 0x%lx\n", cpu, msg->type); + printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%lx\n", + cpu, msg->type); kfree(msg); break; } -- cgit v1.2.3-59-g8ed1b From a5c4300389bb33ade2515c082709217f0614cf15 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sun, 23 May 2010 20:02:06 +0000 Subject: arch/sh/lib/strlen.S: Checkpatch cleanup arch/sh/lib/strlen.S:38: ERROR: trailing whitespace Signed-off-by: Andrea Gelmini Signed-off-by: Paul Mundt --- arch/sh/lib/strlen.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/lib/strlen.S b/arch/sh/lib/strlen.S index f8ab296047b3..1bcc13f05962 100644 --- a/arch/sh/lib/strlen.S +++ b/arch/sh/lib/strlen.S @@ -35,7 +35,7 @@ ENTRY(strlen) mov.b @r4+,r1 tst r1,r1 bt 8f - add #1,r2 + add #1,r2 1: mov #0,r3 -- cgit v1.2.3-59-g8ed1b From 41ec7ebee14189a0424176279c227168960c28ad Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 24 May 2010 08:33:53 +0900 Subject: sh: fix up sh7785lcr_32bit_defconfig. The build scripts inadvertently dropped this down to 29-bit, fix it back up. Reported-by: Raul Porcel Signed-off-by: Paul Mundt --- arch/sh/configs/sh7785lcr_32bit_defconfig | 273 ++++++++++++++++++------------ 1 file changed, 164 insertions(+), 109 deletions(-) (limited to 'arch') diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig index e9af616b2160..71f39c71b04b 100644 --- a/arch/sh/configs/sh7785lcr_32bit_defconfig +++ b/arch/sh/configs/sh7785lcr_32bit_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.34-rc5 -# Tue May 18 17:22:09 2010 +# Linux kernel version: 2.6.34 +# Mon May 24 08:33:02 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -76,7 +76,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 +CONFIG_LOG_BUF_SHIFT=16 # CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -111,18 +111,17 @@ CONFIG_PERF_USE_VMALLOC=y # CONFIG_PERF_EVENTS=y CONFIG_PERF_COUNTERS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y -CONFIG_OPROFILE=y +# CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y -CONFIG_KPROBES=y -CONFIG_KRETPROBES=y +# CONFIG_KPROBES is not set CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y @@ -130,6 +129,7 @@ CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y # # GCOV-based kernel profiling @@ -243,8 +243,9 @@ CONFIG_PAGE_OFFSET=0x80000000 CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x40000000 CONFIG_MEMORY_SIZE=0x20000000 -CONFIG_29BIT=y -# CONFIG_PMB is not set +# CONFIG_29BIT is not set +CONFIG_32BIT=y +CONFIG_PMB=y CONFIG_X2TLB=y CONFIG_VSYSCALL=y # CONFIG_NUMA is not set @@ -262,9 +263,9 @@ CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set -CONFIG_HUGETLB_PAGE_SIZE_64K=y +# CONFIG_HUGETLB_PAGE_SIZE_64K is not set # CONFIG_HUGETLB_PAGE_SIZE_256K is not set -# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +CONFIG_HUGETLB_PAGE_SIZE_1MB=y # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set # CONFIG_HUGETLB_PAGE_SIZE_512MB is not set @@ -276,7 +277,7 @@ CONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_STATIC=y # CONFIG_MEMORY_HOTPLUG is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SPLIT_PTLOCK_CPUS=999999 CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 @@ -298,7 +299,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y CONFIG_SH_STORE_QUEUES=y -# CONFIG_SPECULATIVE_EXECUTION is not set +CONFIG_SPECULATIVE_EXECUTION=y CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_FPU=y @@ -308,7 +309,7 @@ CONFIG_CPU_HAS_FPU=y # # CONFIG_SH_HIGHLANDER is not set CONFIG_SH_SH7785LCR=y -CONFIG_SH_SH7785LCR_29BIT_PHYSMAPS=y +# CONFIG_SH_SH7785LCR_PT is not set # # Timer and clock configuration @@ -371,7 +372,7 @@ CONFIG_SECCOMP=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_INTC_USERIMASK is not set +CONFIG_INTC_USERIMASK=y # # Boot options @@ -389,6 +390,7 @@ CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_DEBUG=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set @@ -465,6 +467,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set +# CONFIG_L2TP is not set # CONFIG_BRIDGE is not set # CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set @@ -485,8 +488,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_TCPPROBE is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set @@ -499,10 +500,19 @@ CONFIG_WIRELESS=y # # CFG80211 needs to be enabled for MAC80211 # + +# +# Some wireless drivers require a rate control algorithm +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set +# +# CAIF Support +# +# CONFIG_CAIF is not set + # # Device Drivers # @@ -514,7 +524,11 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set CONFIG_MTD=y @@ -537,6 +551,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set # CONFIG_MTD_OOPS is not set # @@ -668,7 +683,9 @@ CONFIG_ATA=y CONFIG_ATA_VERBOSE_ERROR=y CONFIG_SATA_PMP=y # CONFIG_SATA_AHCI is not set +# CONFIG_SATA_AHCI_PLATFORM is not set # CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_INIC162X is not set CONFIG_ATA_SFF=y # CONFIG_SATA_SVW is not set # CONFIG_ATA_PIIX is not set @@ -683,7 +700,6 @@ CONFIG_SATA_SIL=y # CONFIG_SATA_ULI is not set # CONFIG_SATA_VIA is not set # CONFIG_SATA_VITESSE is not set -# CONFIG_SATA_INIC162X is not set # CONFIG_PATA_ALI is not set # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set @@ -753,8 +769,36 @@ CONFIG_NETDEVICES=y # CONFIG_TUN is not set # CONFIG_VETH is not set # CONFIG_ARCNET is not set -# CONFIG_NET_ETHERNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_STNIC is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +CONFIG_NET_VENDOR_3COM=y +CONFIG_VORTEX=y +# CONFIG_TYPHOON is not set +# CONFIG_SMC91X is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set @@ -836,6 +880,7 @@ CONFIG_INPUT_KEYBOARD=y CONFIG_KEYBOARD_ATKBD=y # CONFIG_QT2160 is not set # CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_TCA6416 is not set # CONFIG_KEYBOARD_MAX7359 is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_OPENCORES is not set @@ -884,6 +929,7 @@ CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set # CONFIG_NOZOMI is not set # @@ -901,6 +947,8 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set CONFIG_UNIX98_PTYS=y CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_LEGACY_PTYS is not set @@ -1071,7 +1119,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SIS is not set # CONFIG_FB_VIA is not set # CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set +CONFIG_FB_KYRO=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_VT8623 is not set @@ -1097,15 +1145,15 @@ CONFIG_FB_SM501=y # CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y CONFIG_LOGO_SUPERH_MONO=y CONFIG_LOGO_SUPERH_VGA16=y CONFIG_LOGO_SUPERH_CLUT224=y @@ -1129,15 +1177,18 @@ CONFIG_SND_SEQ_HRTIMER_DEFAULT=y CONFIG_SND_DYNAMIC_MINORS=y # CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_VERBOSE_PROCFS is not set -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set +CONFIG_SND_VERBOSE_PRINTK=y +CONFIG_SND_DEBUG=y +CONFIG_SND_DEBUG_VERBOSE=y +CONFIG_SND_VMASTER=y CONFIG_SND_RAWMIDI_SEQ=y CONFIG_SND_OPL3_LIB_SEQ=y # CONFIG_SND_OPL4_LIB_SEQ is not set # CONFIG_SND_SBAWE_SEQ is not set -# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_EMU10K1_SEQ=y CONFIG_SND_MPU401_UART=y CONFIG_SND_OPL3_LIB=y +CONFIG_SND_AC97_CODEC=y # CONFIG_SND_DRIVERS is not set CONFIG_SND_PCI=y # CONFIG_SND_AD1889 is not set @@ -1172,7 +1223,7 @@ CONFIG_SND_CMIPCI=y # CONFIG_SND_INDIGODJ is not set # CONFIG_SND_INDIGOIOX is not set # CONFIG_SND_INDIGODJX is not set -# CONFIG_SND_EMU10K1 is not set +CONFIG_SND_EMU10K1=y # CONFIG_SND_EMU10K1X is not set # CONFIG_SND_ENS1370 is not set # CONFIG_SND_ENS1371 is not set @@ -1211,6 +1262,7 @@ CONFIG_SND_USB=y # CONFIG_SND_USB_CAIAQ is not set # CONFIG_SND_SOC is not set # CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=y CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HIDRAW is not set @@ -1226,44 +1278,42 @@ CONFIG_USB_HID=y # Special HID drivers # # CONFIG_HID_3M_PCT is not set -CONFIG_HID_A4TECH=m -CONFIG_HID_APPLE=m -CONFIG_HID_BELKIN=m -CONFIG_HID_CHERRY=m -CONFIG_HID_CHICONY=m -CONFIG_HID_CYPRESS=m -CONFIG_HID_DRAGONRISE=m -# CONFIG_DRAGONRISE_FF is not set -CONFIG_HID_EZKEY=m -CONFIG_HID_KYE=m -CONFIG_HID_GYRATION=m -CONFIG_HID_TWINHAN=m -CONFIG_HID_KENSINGTON=m -CONFIG_HID_LOGITECH=m -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -# CONFIG_LOGIG940_FF is not set -CONFIG_HID_MICROSOFT=m +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CANDO is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EGALAX is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set # CONFIG_HID_MOSART is not set -CONFIG_HID_MONTEREY=m -CONFIG_HID_NTRIG=m +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set # CONFIG_HID_ORTEK is not set -CONFIG_HID_PANTHERLORD=m -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=m +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set # CONFIG_HID_QUANTA is not set -CONFIG_HID_SAMSUNG=m -CONFIG_HID_SONY=m +# CONFIG_HID_ROCCAT_KONE is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set # CONFIG_HID_STANTUM is not set -CONFIG_HID_SUNPLUS=m -CONFIG_HID_GREENASIA=m -# CONFIG_GREENASIA_FF is not set -CONFIG_HID_SMARTJOYPLUS=m -# CONFIG_SMARTJOYPLUS_FF is not set -CONFIG_HID_TOPSEED=m +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set # CONFIG_HID_THRUSTMASTER is not set -CONFIG_HID_ZEROPLUS=m -# CONFIG_ZEROPLUS_FF is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1276,9 +1326,8 @@ CONFIG_USB=y # Miscellaneous USB options # # CONFIG_USB_DEVICEFS is not set -CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set # CONFIG_USB_MON is not set @@ -1290,9 +1339,7 @@ CONFIG_USB_DEVICE_CLASS=y # # CONFIG_USB_C67X00_HCD is not set # CONFIG_USB_XHCI_HCD is not set -CONFIG_USB_EHCI_HCD=m -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_EHCI_HCD is not set # CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set @@ -1361,7 +1408,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set @@ -1464,6 +1510,7 @@ CONFIG_DMADEVICES=y # # DMA Devices # +# CONFIG_TIMB_DMA is not set # CONFIG_AUXDISPLAY is not set CONFIG_UIO=m # CONFIG_UIO_CIF is not set @@ -1473,10 +1520,6 @@ CONFIG_UIO=m # CONFIG_UIO_SERCOS3 is not set # CONFIG_UIO_PCI_GENERIC is not set # CONFIG_UIO_NETX is not set - -# -# TI VLYNQ -# # CONFIG_STAGING is not set # @@ -1653,63 +1696,75 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y -CONFIG_TRACE_IRQFLAGS=y +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_KMEMLEAK=y +CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=400 +# CONFIG_DEBUG_KMEMLEAK_TEST is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set CONFIG_FRAME_POINTER=y +# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set CONFIG_LATENCYTOP=y CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FTRACE_NMI_ENTER=y +# CONFIG_PAGE_POISONING is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_TRACER_MAX_TRACE=y -CONFIG_RING_BUFFER=y -CONFIG_FTRACE_NMI_ENTER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y -CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y -CONFIG_GENERIC_TRACER=y CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -CONFIG_FUNCTION_TRACER=y -CONFIG_FUNCTION_GRAPH_TRACER=y -CONFIG_IRQSOFF_TRACER=y -# CONFIG_PREEMPT_TRACER is not set -CONFIG_SCHED_TRACER=y -# CONFIG_FTRACE_SYSCALLS is not set -# CONFIG_BOOT_TRACER is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_KSYM_TRACER is not set -CONFIG_STACK_TRACER=y -CONFIG_KMEMTRACE=y -CONFIG_WORKQUEUE_TRACER=y -# CONFIG_BLK_DEV_IO_TRACE is not set -CONFIG_DYNAMIC_FTRACE=y -# CONFIG_FUNCTION_PROFILER is not set -CONFIG_FTRACE_MCOUNT_RECORD=y -# CONFIG_FTRACE_STARTUP_TEST is not set -# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_FTRACE is not set # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_DWARF_UNWINDER=y -CONFIG_MCOUNT=y +# CONFIG_STACK_DEBUG is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_4KSTACKS is not set +CONFIG_DUMP_CODE=y +# CONFIG_DWARF_UNWINDER is not set +# CONFIG_SH_NO_BSS_INIT is not set # # Security options @@ -1820,7 +1875,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set # CONFIG_VIRTUALIZATION is not set -CONFIG_BINARY_PRINTF=y +# CONFIG_BINARY_PRINTF is not set # # Library routines -- cgit v1.2.3-59-g8ed1b